在網上找到一段代碼跑在android 10上,加載相冊圖檔失敗該怎麼解決?
1、首先确認已經給了相應權限
2、跟蹤加載圖檔的代碼
Cursor cursor = getApplicationContext().getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
null, null, MediaStore.Images.Media.DATE_ADDED);
列印日志發現這個寫法正确、可以擷取6張圖檔,既然讀取圖檔沒有問題,那就繼續往下
3、看顯示圖檔的代碼
Glide.with(context)
.load(arrayList.get(position).cover)
.placeholder(R.drawable.image_placeholder).centerCrop().into(viewHolder.imageView);
原來用的是Glide加載,那為什麼不行呢?網絡搜尋下 Android 10 Glide,找到結果如下
https://github.com/bumptech/glide/issues/3896 核心内容如下
issue:
on Android 10 , Glide failed to load image from local storage.
fix for above issue
android:requestLegacyExternalStorage="true"
就是說在application加入android:requestLegacyExternalStorage="true"就可以解決
4、requestLegacyExternalStorage
進一步查詢這個requestLegacyExternalStorage的作用,你就會知道更底層一些的知識。
#######################################
再說一個錯誤
FileNotFoundException: /content:/media/external/images
參考文章
https://blog.csdn.net/dickyqie/article/details/105120866
https://stackoverflow.com/questions/6935497/android-get-gallery-image-uri-path
https://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore
https://zhuanlan.zhihu.com/p/128558892
簡單分析下
高版本采用MediaStore來管理檔案、增删改查都可以用這個。說一個常見的應用場景,那就是讀取手機相冊裡面的圖檔。我們調用相冊讀取的圖檔路徑是一個uri,類似這樣子的
我們需要先轉為圖檔真實的路徑才可以讀取。圖檔真實的路徑長什麼樣?
/storage/emulated/0/DCIM/Camera/394210ccb4c70757ee9e74da852f6c65.jpg
那怎麼轉換呢,這時候就要用到MediaStore幫助我們。簡單說,MediaStore就是一個檔案資料庫,手機上的檔案都記錄在這個庫裡。我們看轉換代碼
public static String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}catch (Exception e){
e.printStackTrace();
return null;
}
finally {
if (cursor != null) {
cursor.close();
}
}
}
網上其他資料一般到這裡就完了,但是我這麼寫了,還是取不到。進一步研究發現,MediaStore在擷取檔案的時候需要用到provider,在application需要添加如下代碼
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>