解决open failed: ENOENT (No such file or directory)/(Operation not permitted)

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());
}


 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值