Android11及以上文件讀寫權限申請詳細介紹
Android11 讀寫權限申請
Android11系統對應用寫入權限做瞭嚴格的限制。本文介紹如何獲取文件讀寫權限。項目中 build.gradle 的targetSdkVersion >= 29 ,會出現讀寫問題。
當targetSdkVersion = 29,通過設置requestLegacyExternalStorage=“true”,還能解決。
當targetSdkVersion = 30後,需要申請所有文件權限才能獲取到寫入權限。
AndroidManifest添加權限設置
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /><!--add 2022-2-11 Android11--> <application ... android:requestLegacyExternalStorage="true" ... >
代碼申請動態權限
1.Android 6.0之上Android11以下申請權限
if (Build.VERSION.SDK_INT >= 23) {// 6.0 String[] perms = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE}; for (String p : perms) { int f = ContextCompat.checkSelfPermission(SafeKeyToolActivity.this, p); Log.d("---", String.format("%s - %d", p, f)); if (f != PackageManager.PERMISSION_GRANTED) { requestPermissions(perms, 0XCF); break; } } }
Android11申請權限
跳轉系統設置界面,用戶授權獲取權限。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !isRefuse) {// android 11 且 不是已經被拒絕 // 先判斷有沒有權限 if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, 1024); } } // 帶回授權結果 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1024 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // 檢查是否有權限 if (Environment.isExternalStorageManager()) { isRefuse = false; // 授權成功 } else { isRefuse = true; // 授權失敗 } } }
對於部分手機如小米手機,即使獲取瞭所有文件的管理權限,依舊訪問不到Android/data目錄,如圖:
嘗試解決辦法:
隻在外部存儲的應用私有目錄下,用直接路徑讀寫文件。
訪問或者共享媒體文件,使用MediaStore在公共目錄下讀寫文件
訪問或者共享非媒體文件,使用系統的文件選擇器SAF在公共目錄Download下讀寫文件。
根目錄下可以創建自定義文件夾、文件。
補充:Android 11 及以上申請外部存儲權限
升級 targetSdkVersion
android defaultConfig { targetSdkVersion 30 } }
添加清單權限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
代碼動態申請
public final class PermissionActivity extends AppCompatActivity { private static final int REQUEST_CODE = 1024; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestPermission(); } private void requestPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // 先判斷有沒有權限 if (Environment.isExternalStorageManager()) { writeFile(); } else { Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); intent.setData(Uri.parse("package:" + context.getPackageName())); startActivityForResult(intent, REQUEST_CODE); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 先判斷有沒有權限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { writeFile(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); } } else { writeFile(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { writeFile(); } else { ToastUtils.show("存儲權限獲取失敗"); } } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Environment.isExternalStorageManager()) { writeFile(); } else { ToastUtils.show("存儲權限獲取失敗"); } } } /** * 模擬文件寫入 */ private void writeFile() { ToastUtils.show("寫入文件成功"); } }
總結
到此這篇關於Android11及以上文件讀寫權限申請的文章就介紹到這瞭,更多相關Android11文件讀寫權限申請內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Android權限詢問的實例詳解
- Android permission denied原因歸納和解決辦法
- Android開發之permission動態權限獲取詳解
- Android批量修改文件格式/文件名的神操作分享
- Android調用應用安裝界面方法