Android - 询问写入 SD 卡权限对话框
Android - ask write to SD card permission dialog
我无法获得对设备 SD 卡根目录的写入权限。我可以毫无问题地写入 SD 卡中的设备内部存储和应用程序包文件夹。我发现使用 Storage Access Framework 可以访问 SD 卡,所以我查看了其他应用程序以了解它们如何访问 SD 卡,并找到了带有简洁权限对话框的 Total Commander。
找不到例子怎么显示这样的对话框?我的目标是将卸载应用程序后保留的大文件存储在SD卡上。
类似问题:
我找到了开源文件管理器。看了看代码,终于找到解决方法了
仅适用于 Android N (7.0.0) (api 24) 及更高版本。
首先获取SD卡的根路径并显示用户权限对话框。
public void takeCardUriPermission(String sdCardRootPath) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
File sdCard = new File(sdCardRootPath);
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
StorageVolume storageVolume = storageManager.getStorageVolume(sdCard);
Intent intent = storageVolume.createAccessIntent(null);
try {
startActivityForResult(intent, 4010);
} catch (ActivityNotFoundException e) {
}
}
}
当用户接受请求时,onActivityResult() 被触发,我们可以从意图数据中保存 uri
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 4010) {
Uri uri = data.getData();
grantUriPermission(getPackageName(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION);
final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(uri, takeFlags);
}
}
现在我们可以检索 SD 卡根的 uri 并将其与存储访问框架一起使用
public Uri getUri() {
List<UriPermission> persistedUriPermissions = getContentResolver().getPersistedUriPermissions();
if (persistedUriPermissions.size() > 0) {
UriPermission uriPermission = persistedUriPermissions.get(0);
return uriPermission.getUri();
}
return null;
}
不幸的是,Android Q 现在不推荐使用 createAccessIntent,并且 documentation 声明如果您在 Android Q 中使用它,它会立即 return RESULT_CANCELED.
他们建议您使用带有 ACTION_OPEN_DOCUMENT_TREE 的意图。您可以指定它最初打开的目录(仅在 Android O 及更高版本上支持),使用户更容易,但是这仍然不是一个非常用户友好的方法。
我想知道是否还有其他任何人知道的用户友好的解决方案?我不明白为什么 Android 删除了 createAccessIntent,因为它似乎是最用户友好的方式。
我无法获得对设备 SD 卡根目录的写入权限。我可以毫无问题地写入 SD 卡中的设备内部存储和应用程序包文件夹。我发现使用 Storage Access Framework 可以访问 SD 卡,所以我查看了其他应用程序以了解它们如何访问 SD 卡,并找到了带有简洁权限对话框的 Total Commander。
找不到例子怎么显示这样的对话框?我的目标是将卸载应用程序后保留的大文件存储在SD卡上。
类似问题:
我找到了开源文件管理器。看了看代码,终于找到解决方法了
仅适用于 Android N (7.0.0) (api 24) 及更高版本。
首先获取SD卡的根路径并显示用户权限对话框。
public void takeCardUriPermission(String sdCardRootPath) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
File sdCard = new File(sdCardRootPath);
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
StorageVolume storageVolume = storageManager.getStorageVolume(sdCard);
Intent intent = storageVolume.createAccessIntent(null);
try {
startActivityForResult(intent, 4010);
} catch (ActivityNotFoundException e) {
}
}
}
当用户接受请求时,onActivityResult() 被触发,我们可以从意图数据中保存 uri
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 4010) {
Uri uri = data.getData();
grantUriPermission(getPackageName(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION);
final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(uri, takeFlags);
}
}
现在我们可以检索 SD 卡根的 uri 并将其与存储访问框架一起使用
public Uri getUri() {
List<UriPermission> persistedUriPermissions = getContentResolver().getPersistedUriPermissions();
if (persistedUriPermissions.size() > 0) {
UriPermission uriPermission = persistedUriPermissions.get(0);
return uriPermission.getUri();
}
return null;
}
不幸的是,Android Q 现在不推荐使用 createAccessIntent,并且 documentation 声明如果您在 Android Q 中使用它,它会立即 return RESULT_CANCELED.
他们建议您使用带有 ACTION_OPEN_DOCUMENT_TREE 的意图。您可以指定它最初打开的目录(仅在 Android O 及更高版本上支持),使用户更容易,但是这仍然不是一个非常用户友好的方法。
我想知道是否还有其他任何人知道的用户友好的解决方案?我不明白为什么 Android 删除了 createAccessIntent,因为它似乎是最用户友好的方式。