在网上找到一段代码跑在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.youkuaiyun.com/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,类似这样子的
content://media/external/images/media/379
我们需要先转为图片真实的路径才可以读取。图片真实的路径长什么样?
/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>