使用文件提供程序检索内容 URI 失败
Retrieving Content Uri using File Provider fails
我花了几天时间阅读文档并遵循各种教程,但无论我做什么,我都会遇到错误。我正在尝试将图像保存在内部存储中,然后将其转换为内容 Uri,以便我可以使用系统裁剪和调整大小功能。如果有人能发现我的代码哪里有问题,我将不胜感激:
主要Activity:
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.lambda$onResourceReady[=14=]$MainActivity(MainActivity.java:82)
W/System.err(12162): at com.me.wallpaper_app.-$$Lambda$MainActivity$Xm-7yym42zTgTZOFP5GGtbF6p2U.run(Unknown Source:4)
W/System.err(12162): at java.lang.Thread.run(Thread.java:919)
"@string/file_provider_authority"
不是您在 Java 中引用字符串资源的方式。使用 getString(R.string.file_provider_authority)
.
UPDATE:根据评论,第二个主要问题是此内容的消费者没有使用 Intent
中的 MIME 类型,而是正在 ContentResolver
上调用 getType()
以从 ContentProvider
获取类型。在这种情况下,那是您的 FileProvider
,而 FileProvider
只知道如何使用文件扩展名并将其转换为 MIME 类型。因此,使用 temp.jpeg
为 FileProvider
提供了 return 正确 MIME 类型所需的信息。
试试这个
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>
我花了几天时间阅读文档并遵循各种教程,但无论我做什么,我都会遇到错误。我正在尝试将图像保存在内部存储中,然后将其转换为内容 Uri,以便我可以使用系统裁剪和调整大小功能。如果有人能发现我的代码哪里有问题,我将不胜感激:
主要Activity:
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.lambda$onResourceReady[=14=]$MainActivity(MainActivity.java:82)
W/System.err(12162): at com.me.wallpaper_app.-$$Lambda$MainActivity$Xm-7yym42zTgTZOFP5GGtbF6p2U.run(Unknown Source:4)
W/System.err(12162): at java.lang.Thread.run(Thread.java:919)
"@string/file_provider_authority"
不是您在 Java 中引用字符串资源的方式。使用 getString(R.string.file_provider_authority)
.
UPDATE:根据评论,第二个主要问题是此内容的消费者没有使用 Intent
中的 MIME 类型,而是正在 ContentResolver
上调用 getType()
以从 ContentProvider
获取类型。在这种情况下,那是您的 FileProvider
,而 FileProvider
只知道如何使用文件扩展名并将其转换为 MIME 类型。因此,使用 temp.jpeg
为 FileProvider
提供了 return 正确 MIME 类型所需的信息。
试试这个
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>