android 11 版本下图片的保存方式改变(建议大家从android 10开始适配,我就遇到了部分android 10手机也出现这个问题)
android 11已经出来了半年的,有的手机已经升级到android 11了,比如小米10等。在android 11下,我们会发现应用有些功能变得不正常了,比如图片的保存。android 11有两个可以保存的地方,第一个是项目的私有目录,一个是公共目录。而项目的私有目前的图片是可以改变的,但公共目录的不可以。
项目私有目录
public static String getDownloadPath(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//android 11
return Constants.SDCardConstants.getDir(context) + File.separator;
}else {
return Environment.getExternalStorageDirectory() + "/winetalk/";
}
}
上面的代码是我在兼容了android 11后写的。Constants.SDCardConstants.getDir(context) + File.separator;是项目的私有目录路径。如果在android 11上还是用Environment.getExternalStorageDirectory()这样的路径,就会报没有访问目录的权限。之前一直以为是因为缺少权限,也确实是缺少该路径的权限,因为android 11已经拒绝我们再访问了。所以后续存放文件位置需要改为新的这个。
把透明网络图替换为白色背景并显示
/**
* 给透明图片添加白色底色,转换为jpg格式保存到本地后并获取本地图片并显示,然后删除本地图片
* @param resource
* @param view
* @param url
*/
public static void saveAndGetImage(Context context,Bitmap resource,View view,String url,String type){
//由于图片有透明背景,但又要求显示时添加白色背景。此处的处理:
//1.复制出一个新的Bitmap,然后给新的Bitmap添加一个白色的背景画布,然后把这个图转换为jpg下载到本地。
//2.从手机本地取出该图片显示即可。
String imgPath = C.getDownloadPath(context)+G.urlToFileName(url);
File jpg = new File(imgPath);
Bitmap outB=resource.copy(Bitmap.Config.ARGB_8888,true); //复制出一个新的Bitmap
Canvas canvas=new Canvas(outB); //给新的Bitmap 添加一个白色的画布
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(resource, 0, 0, null);
try {
FileOutputStream out = new FileOutputStream(jpg); //保存到本地,格式为JPEG
if (outB.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
out.flush();
out.close();
}
} catch (FileNotFoundException e) {
G.look("FileNotFoundException e.toString: "+e.toString());
e.printStackTrace();
} catch (IOException e) {
G.look("IOException e.toString: "+e.toString());
e.printStackTrace();
}
//从本地获取保存的图片并显示
Bitmap bitmap = BitmapFactory.decodeFile(imgPath,null);
G.look("saveAndGetImage Bitmap: "+bitmap);
if (type.equals("PhotoView")) {
photoView = (PhotoView) view;
photoView.setImageBitmap(bitmap);
}
//删除本地图片
File file = new File(imgPath);
// 如果已经存在则不需要下载
if (file != null && file.exists()) {
file.delete();
return;
}
}
调用
Utils.saveAndGetImage(context,resource