在android 6.0以後,權限不止是在AndroidManifest.xml文件裏面聲明,而且需要在代碼中動態獲取,這一點大部分人應該都很清楚了,如果不清楚,可以看下面代碼(這裏以讀寫文件和相機權限爲例):
// 準備申請的權限
private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA};
private static final int REQUEST_CODE = 10001;
// 版本判斷。當手機系統大於 23 時,纔有必要去判斷權限是否獲取
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 檢查該權限是否已經獲取
for (String permission : permissions) {
// GRANTED---授權 DINIED---拒絕
if (ContextCompat.checkSelfPermission(getApplicationContext(), permission) == PackageManager.DINIED) {
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE);
}
}
}
用以上代碼去申請權限。
在最近的開發過程中,發現在華爲P30等手機上,調用系統獲取圖片或者是拍照獲取圖片時候獲取不到,通過以下方法獲得圖片的Bitmap時爲空:
Bitmap bitmap1 = BitmapFactory.decodeFile(outputFile.getAbsolutePath());
然後通過另外方式獲取Bitmap
byte[] bytes = new byte[(int) outputFile.length() + 1];
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(outputFile.getAbsoluteFile());
inputStream.read(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
LogUtils.e("test", " FileNotFoundException e " + e.toString());
} catch (IOException e) {
LogUtils.e("test", " IOException e " + e.toString());
}
bitmap1 = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
結果Catch 到 FileNotFoundException e java.io.FileNotFoundException: /storage/emulated/0/Pictures/xxxxx.jpg: open failed: EACCES (Permission denied)
沒有權限,但上面明明已經申請權限,且已經手動賦予權限。在手機設置裏面的App權限管理裏面找到對應App,發現確實是有存儲權限的,實在是不放心,又在代碼裏打印出來,確認App有讀寫存儲權限:
boolean permission_readStorage = (PackageManager.PERMISSION_GRANTED ==
activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
boolean permission_writeStorage = (PackageManager.PERMISSION_GRANTED ==
activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
打印出來,都有權限,更百思不得其解,繼續找相關資料,發現在android 10系統中
需要在文件下AndroidManifest.xml 加上android:requestLegacyExternalStorage = “true” 這個屬性
<application android:requestLegacyExternalStorage = “true”>
然後試驗,發現可以成功讀取文件了,問題解決。
關於android 10 (Android Q) 版本具體的系統分區權限及適配,可以參考下面文章: