網站首頁 編程語言 正文
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("寫入文件成功");
}
}
總結
原文鏈接:https://blog.csdn.net/yzwfeng/article/details/124378291
相關推薦
- 2022-05-22 asp.net?Core中同名服務注冊的實現代碼_實用技巧
- 2024-07-15 Spring中的單例模式應用詳解
- 2022-12-05 C語言實現順序表的基本操作的示例詳解_C 語言
- 2022-11-17 Kotlin?StateFlow單數據更新熱流設計與使用介紹_Android
- 2022-12-19 Oracle?Instr函數實例講解_oracle
- 2022-06-24 Python統計序列和文件中元素的頻度_python
- 2022-03-27 基于PyQt5制作Excel數據分組匯總器_python
- 2022-11-22 Kotlin?by關鍵字作用及使用介紹_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支