package com.datarecovery.master.utils.xfile; import android.Manifest; import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.UriPermission; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.storage.StorageVolume; import android.provider.DocumentsContract; import java.util.Arrays; import java.util.List; /** * 这个权限申请写的不好,看怎么根据业务需求优化 */ public class XFilePermission { private static final String[] EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q = new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; private static final int REQUEST_CODE_EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q = 11223; private static final int REQUEST_CODE_SAF_PERMISSIONS = 11224; private static final String documentsuiPkg = "com.google.android.documentsui"; public static boolean hasAndroidDataPermission(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { for (String permission : EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q) { if (context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } PackageManager packageManager = context.getPackageManager(); try { ApplicationInfo applicationInfo = packageManager.getApplicationInfo(documentsuiPkg, PackageManager.MATCH_UNINSTALLED_PACKAGES); if (applicationInfo.targetSdkVersion >= 34) { return false; } } catch (PackageManager.NameNotFoundException ignore) { } List storageVolumes = XStorageManager.getReadableStorageVolumes(context); for (StorageVolume storageVolume : storageVolumes) { Uri treeUri = StorageVolumeUtil.getTreeUri(storageVolume); XSAFFile xFile = new XSAFFile(context, treeUri, Arrays.asList("Android", "data")); if (!hasPermission(context, xFile)) { return false; } } return true; } private static boolean hasPermission(Context context, XSAFFile xFile) { ContentResolver contentResolver = context.getContentResolver(); List persistedUriPermissions = contentResolver.getPersistedUriPermissions(); for (UriPermission persistedUriPermission : persistedUriPermissions) { if (!persistedUriPermission.isReadPermission() || !persistedUriPermission.isWritePermission()) { continue; } Uri uri = persistedUriPermission.getUri(); if (uri == null) { continue; } Uri pathUri = xFile.getPathUri(); if (uri.toString().contains(pathUri.toString())) { return true; } } return false; } public static void requestAndroidDataPermission(Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { activity.requestPermissions(EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q, REQUEST_CODE_EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q); } else { Intent grantIntentSDMOg = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); grantIntentSDMOg.putExtra("android.content.extra.SHOW_ADVANCED", true); List storageVolumes = XStorageManager.getReadableStorageVolumes(activity); for (StorageVolume storageVolume : storageVolumes) { Uri treeUri = StorageVolumeUtil.getTreeUri(storageVolume); XSAFFile xFile = new XSAFFile(activity, treeUri, Arrays.asList("Android", "data")); if (!hasPermission(activity, xFile)) { grantIntentSDMOg.putExtra(DocumentsContract.EXTRA_INITIAL_URI, xFile.getDocumentUri()); activity.startActivityForResult(grantIntentSDMOg, REQUEST_CODE_SAF_PERMISSIONS); } } } } public static boolean onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_SAF_PERMISSIONS) { if (resultCode == Activity.RESULT_OK) { Uri treeUri = data.getData(); if (treeUri == null) { return false; } activity.getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); return true; } return false; } return false; } public static boolean onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_CODE_EXTERNAL_STORAGE_PERMISSIONS_BELOW_Q) { for (int grantResult : grantResults) { if (grantResult != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } return false; } }