我已授予编写外部和可移动存储的权限。但我仍然无法在Android 7上的SD卡上随处写。
Intent intent = storageVolume.createAccessIntent(null);
startActivityForResult(intent, 989);
RxPermissions.getInstance(getActivity())
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(granted -> {
if (!granted) return;
showAlternativeDirectoryChooser();//success
}, throwable -> {
});
以下是文件夹创建的代码:
DocumentFile documentFile = DocumentFile.fromFile(dir);
DocumentFile test = documentFile.createDirectory("test_folder");
test == null
答案 0 :(得分:0)
Android提供您需要在SWAP
中使用的Uri。 Uri根本不一定与您尝试访问的路径相关。你不能猜到它。你必须实际使用你给予的Uri。
如果您致电onActivityResult
或DocumentFile.fromFile
,那么您错了。
答案 1 :(得分:0)
您不能使用:
DocumentFile documentFile = DocumentFile.fromFile(dir);
因为它不是SAF有效的Uri。
如果您不想使用ACTION_OPEN_DOCUMENT_TREE或ACTION_OPEN_DOCUMENT来获取Uri ,则可以使用以下方法将FILE转换为Uri(SAF):从API19(Android4.4-Kitkat)到API28( Android8-Oreo)。如果您要访问应用程序外部的外部可移动存储,则返回的Uri与返回对话框及其对API 28安全限制(SAF权限)的有效性相同。
/**
* Ing.N.Nyerges 2019 V2.0
*
* Storage Access Framework(SAF) Uri's creator from File (java.IO),
* for removable external storages
*
* @param context Application Context
* @param file File path + file name
* @return Uri[]:
* uri[0] = SAF TREE Uri
* uri[1] = SAF DOCUMENT Uri
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static Uri[] getSafUris (Context context, File file) {
Uri[] uri = new Uri[2];
String scheme = "content";
String authority = "com.android.externalstorage.documents";
// Separate each element of the File path
// File format: "/storage/XXXX-XXXX/sub-folder1/sub-folder2..../filename"
// (XXXX-XXXX is external removable number
String[] ele = file.getPath().split(File.separator);
// ele[0] = not used (empty)
// ele[1] = not used (storage name)
// ele[2] = storage number
// ele[3 to (n-1)] = folders
// ele[n] = file name
// Construct folders strings using SAF format
StringBuilder folders = new StringBuilder();
if (ele.length > 4) {
folders.append(ele[3]);
for (int i = 4; i < ele.length - 1; ++i) folders.append("%2F").append(ele[i]);
}
String common = ele[2] + "%3A" + folders.toString();
// Construct TREE Uri
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme);
builder.authority(authority);
builder.encodedPath("/tree/" + common);
uri[0] = builder.build();
// Construct DOCUMENT Uri
builder = new Uri.Builder();
builder.scheme(scheme);
builder.authority(authority);
if (ele.length > 4) common = common + "%2F";
builder.encodedPath("/document/" + common + file.getName());
uri[1] = builder.build();
return uri;
}
然后,您可以使用以下方式调用权限:
context.grantUriPermission(context.getPackageName(), uri, Intent
.FLAG_GRANT_READ_URI_PERMISSION | Intent
.FLAG_GRANT_WRITE_URI_PERMISSION);
context.getContentResolver().takePersistableUriPermission(uri, Intent
.FLAG_GRANT_READ_URI_PERMISSION | Intent
.FLAG_GRANT_WRITE_URI_PERMISSION);