【发布时间】:2018-02-04 03:58:43
【问题描述】:
我的应用程序允许用户选择图像,然后为图像设置动画。这是一件简单的事情,我希望它在 4.2 及更高版本上运行。现在完美运行。
应用程序应该记住选择的图像,并在用户下次运行应用程序时将这些图像设为默认值 - 当应用程序重新启动时。
这在我的 Galaxy Nexus (4.2.1) 上运行良好,但在我的 Galaxy S8+ (7.0) 上效果不佳。因为我喜欢它在 4.2.1 上的工作方式,所以它不能简单地在以后的平台上运行它有点令人沮丧。
这是在onCreate()里面:
((ImageButton) findViewById(R.id.imagex))
.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select image"), SELECT_IMAGEX);
}
});
来自onActivityResult:
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// [snip unimportant code]
Uri uri = intent.getData();
Bitmap bitmap = getBitmap(uri);
final int takeFlags = intent.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
try {
getContentResolver().takePersistableUriPermission(uri, takeFlags);
} catch (SecurityException e) {
Log.w(myLog, "SecurityException: " + e.getMessage());
}
// [snip]
editor.putString("imagex", uri.toString());
editor.commit();
}
稍后,应用重新启动,这部分方法onCreate() 执行:
String tmp = preferences.getString("imagex", null);
if (tmp != null) {
uri = Uri.parse(tmp);
Bitmap bitmap = getBitmap(uri);
// etc
}
在 S8+ 上,getBitmap() 给出异常 Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS(意味着该方法返回 null)。
为什么它会在一个异常消息中抱怨一个丢失的权限 TWICE,这很令人困惑。顺便说一句,添加<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />后仍然如此。
在这个很棒的网站上阅读,我发现人们在谈论
final int takeFlags = intent.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(selectedImageUri, takeFlags);
这是一些相当现代的发明,但不幸的是它只是在 S8+ 上造成了这种情况
SecurityException: No persistable permission grants found
在 Galaxy Nexus 上它只是崩溃了
java.lang.NoSuchMethodError
【问题讨论】:
-
请以您使用的意图的代码开始您的帖子。我之前要求您显示您的意图代码,否则我们不知道您在做什么。大多数事情取决于使用的意图。
-
谢谢。我在上面添加了更多细节。
-
使用 ACTION_GET_CONTENT 你不能获得持久权限,因为它们没有提供给你。对于持久权限,您必须使用 ACTION_OPEN_DOCUMENT。检查 getFlags() 中设置了哪些位/标志,您会看到。
-
进步!该应用程序和以前一样具有 getFlags() =
FLAG_GRANT_READ_URI_PERMISSION,如果我更改为ACTION_OPEN_DOCUMENT而不是 getFlags() =ACTION_OPEN_DOCUMENT | FLAG_GRANT_WRITE_URI_PERMISSION | FILL_IN_SELECTOR。我不明白,但它确实有所作为。它现在可以在较新的手机上毫无例外地运行,但在我现在无法选择图像之前工作的旧手机上运行。 -
上面的错字,当然应该是getFlags() =
FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION | FILL_IN_SELECTOR
标签: android persistence android-permissions backwards-compatibility