原文《Android11 无Root 访问data目录实现、Android11访问data目录、Android11解除data目录限制、Android11 data空白解决》
参考该大佬的方法稍作修改
添加权限
<!-- 修改或删除您共享存储空间中的内容 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- MANAGE_EXTERNAL_STORAGE -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
请求和保存权限
//Android11 请求某一文件及子文件权限
public static void requestPermission(Activity activity,String path, int requestCode){
Uri uri=UriUtil.pathToUri(path);
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri);
}
activity.startActivityForResult(intent, requestCode);
}
//保存已请求权限
public static void savePermission(Intent data){
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
App.getApp().getContentResolver().takePersistableUriPermission(data.getData(), takeFlags);
}
获取列表
//隐私目录
Uri dirUri=UriUtil.pathToUri2(path);
Uri childrenUri= DocumentsContract.buildChildDocumentsUriUsingTree(dirUri, DocumentsContract.getDocumentId(dirUri));
Cursor cursor=null;
try {
cursor = App.getApp().getContentResolver().query(childrenUri, new String[]{DocumentsContract.Document.COLUMN_DOCUMENT_ID}, null, null, null);
} catch (Exception e) {}
if (cursor != null) {
while (cursor.moveToNext()) {
String documentId = cursor.getString(0);
Uri uri = DocumentsContract.buildDocumentUriUsingTree(dirUri, documentId);
DocumentFile file=DocumentFile.fromSingleUri(App.getApp(), uri);
}
}
获取流
getContentResolver().openInputStream(UriUtil.pathToUri2(path))
getContentResolver().openOutputStream(UriUtil.pathToUri2(path))
Uri工具类
public class UriUtil {
public static Uri pathToUri(String path) {
String root=Environment.getExternalStorageDirectory().getPath();
String str="content://com.android.externalstorage.documents/tree/primary%3A";
String str2="/document/primary%3A";
if (path.endsWith("/")) path.substring(0, path.length() - 1);
if (path.equals(root)) {
path = str + str2;
} else {
path = path.replace(root + "/", "").replace("/", "%2F");
path = str + path + str2 + path;
}
return Uri.parse(path);
}
// Abdroid/data Android/obb
public static Uri pathToUri2(String path) {
path = path.replace(Config.PATH_ROOT + "/", "").replace("/", "%2F");
String[] array=path.split("%2F");
String treestr="content://com.android.externalstorage.documents/tree/primary%3A" + array[0] + "%2F" + array[1] + "/document/primary%3A" + path;
return Uri.parse(treestr);
}
public static String treeToPath(String uri){
//content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata%2F<pkg>%2Ffiles
return Environment.getExternalStorageDirectory()+"/"+uri.replace("content://com.android.externalstorage.documents/tree/primary%3A","").replace("%2F","/");
}
public static String treeToPath2(Uri treeUri) {
//content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3AAndroid%2F%data%2F<pkg>%2Ffiles
String substr="document/primary%3A";
String treeStr=treeUri.toString();
return Config.PATH_ROOT + "/" + treeStr.substring(treeStr.indexOf(substr) + substr.length()).replace("%2F", "/");
}
}