【问题标题】:Retrieving Content Uri using File Provider fails使用文件提供程序检索内容 Uri 失败
【发布时间】:2019-05-25 15:40:58
【问题描述】:

我花了几天时间阅读文档并遵循各种教程,但无论我做什么都会出错。我正在尝试将图像保存在内部存储中,然后将其转换为内容 Uri,以便我可以使用系统裁剪和调整大小功能。如果有人能发现我的代码错误的地方,我将不胜感激:

主要活动:

new Thread(() -> {
try {
    String temp = "temp";

    //Convert bitmap to byte array
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
    byte[] bitmapData = bos.toByteArray();

    //Write the bytes in file
    FileOutputStream fos = openFileOutput(temp, MODE_PRIVATE);
    fos.write(bitmapData);
    fos.flush();
    fos.close();

    //Convert file to contentUri
    File file = new File(getFilesDir(), temp);

    Intent intent = new Intent();
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    Uri imageUri = FileProvider.getUriForFile(MainActivity.this, "@string/file_provider_authority", file);
    intent.setDataAndType(imageUri, "image/jpg");

    intent = WallpaperManager.getInstance(getApplicationContext()).getCropAndSetWallpaperIntent(imageUri);
    startActivityForResult(intent, ACTIVITY_CROP);

} catch (Exception e) {
    e.printStackTrace();
}
}).start();

清单:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="@string/file_provider_authority"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>
</application>

file_provider_paths.xml

<paths>
<files-path
    path="/" name="temp" />

strings.xml

<resources>
<string name="file_provider_authority"
    translatable="false">com.me.wallpaper_app.provider
</string>

错误:

    W/System.err(12162): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
    W/System.err(12162):    at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:604)
    W/System.err(12162):    at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:578)
    W/System.err(12162):    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:416)
    W/System.err(12162):    at com.me.wallpaper_app.MainActivity$1$1.lambda$onResourceReady$0$MainActivity$1$1(MainActivity.java:82)
    W/System.err(12162):    at com.me.wallpaper_app.-$$Lambda$MainActivity$1$1$Xm-7yym42zTgTZOFP5GGtbF6p2U.run(Unknown Source:4)
    W/System.err(12162):    at java.lang.Thread.run(Thread.java:919)

【问题讨论】:

    标签: java android android-fileprovider


    【解决方案1】:

    "@string/file_provider_authority" 不是您在 Java 中引用字符串资源的方式。使用getString(R.string.file_provider_authority)

    更新:基于 cmets,第二个主要问题是该内容的使用者没有使用来自 Intent 的 MIME 类型,而是在ContentResolverContentProvider 获取类型。在这种情况下,这就是您的FileProvider,而FileProvider 只知道如何使用文件扩展名并将其转换为 MIME 类型。因此,使用 temp.jpegFileProvider 提供了返回正确 MIME 类型所需的信息。

    【讨论】:

    • 哦,谢谢!现在我收到此错误:“无法使用传递的 URI 设置壁纸;检查 ContentProvider 返回的类型是否与 image/* 匹配”。但我确实将数据和类型设置为图像。嗯……
    • @user9480972:尝试使用"image/jpeg" 而不是"image/jpg" 作为 MIME 类型。
    • @user9480972:在这两个地方将setFlags() 更改为addFlags()。现在,您的第二个 setFlags() 调用会覆盖第一个调用的结果。
    • 好的,完成。我显然做错了什么,因为这就是我现在得到的:“I/System.out(20634): Image Data and Type = Intent { dat=content://com.me.wallpaper_app.provider/files/temp typ=image/* flg=0x3 } I/System.out(20634): Image Uri = content://com.me.wallpaper_app.provider/files/temp W/System.err(20634): java.lang.IllegalArgumentException : 不能使用传递的 URI 设置壁纸;检查 ContentProvider 返回的类型是否匹配 image/* 我应该以不同的方式调用“temp”吗?比如像“image”?
    • @user9480972:在Intent 中使用image/jpeg,而不是image/*。我还建议从openFileOutput() 切换到直接使用与FileProvider.getUriForFile() 一起使用的File 对象来创建FileOutputStream。然后,将compress() 直接与FileOutputStream 一起使用(摆脱ByteArrayOutputStream 中介)。最后,使用temp.jpgtemp.jpeg 作为文件名,以防壁纸忽略Intent 中的MIME 类型并询问FileProvider 的MIME 类型`。
    【解决方案2】:

    试试这个

          Uri imageUri = FileProvider.getUriForFile(MainActivity.this, R.string.file_provider_authority, file);
    

    也改变

        <paths>
        <files-path
        path="/" name="temp" />
    

    收件人

        <?xml version="1.0" encoding="utf-8"?>
        <paths xmlns:android="http://schemas.android.com/apk/res/android"> 
        <external-path name="external_files" path="."/>
        </paths>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多