一、Android 11上传下载资源失败:open failed: ENOENT (No such file or directory)
前提:发现Android 11 上传图片及下载文件都失败,报错日志:open failed: ENOENT (No such file or directory)
原来是Android 11访问文件资源管理器需要加上特殊权限: MANAGE_EXTERNAL_STORAGE 文件管理权限
之前申请权限是通过Dialog展现给用户,而Android 11以后通过 Activity 展现给用户看(Intent跳转)。
1)目标sdk修改为30:targetSdkVersion 30
2)清单文件注册:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3)当系统在11及以上申请此权限
public void checkPermissions() {
//申请危险权限
....
//申请Android11特殊权限
requestManagerPermission();
}
private void requestManagerPermission() {
//当系统在11及以上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// 没文件管理权限时申请权限
if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + mContext.getPackageName()));
startActivityForResult(intent, REQUEST_MANAGER_PERMISSION);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_MANAGER_PERMISSION && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//用户拒绝权限,重新申请
if (!Environment.isExternalStorageManager()) {
requestManagerPermission();
}
}
}
二、保存截图失败:open failed: EPERM (Operation not permitted)
前提:发现Android 11 保存截图失败,报错日志:open failed: ENOENT (Operation not permitted)
解决:根据版本,将文件保存在不同的路径下。
默认获取外部存储目录,sdk>29获取外部SD卡缓存目录。
String path = Environment.getExternalStorageDirectory().getPath();
if (Build.VERSION.SDK_INT > 29) {
path = activity.getExternalFilesDir(null).getAbsolutePath() ;
}
File file = new File(path, fileName);
//截图流程...请忽略
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
// 截屏-将view作为原图绘制出来
View v = activity.getWindow().getDecorView();
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(),Bitmap.Config.RGB_565);
Canvas c = new Canvas(bitmap);
c.translate(-v.getScrollX(), -v.getScrollY());
v.draw(c);
// 压缩Bitmap,不支持png图片的压缩
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
// 把文件插入到系统图库
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri =activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
// 通知图库更新
activity.sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
ToastUtils.showMessage("保存成功");
} catch (IOException e) {
e.printStackTrace();
ToastUtils.showMessage(e.getMessage());
}
参考:https://blog.youkuaiyun.com/dongxianfei/article/details/115449709
https://zhuanlan.zhihu.com/p/477539888