解决万恶的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());
}

参考:https://blog.csdn.net/dongxianfei/article/details/115449709
https://zhuanlan.zhihu.com/p/477539888

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"open failed: ENOENT (No such file or directory)" 错误通常表示尝试打开或访问一个不存在的文件或目录。这可能由以下原因导致: 1. 文件或目录不存在:您尝试打开的文件或目录路径可能是错误的,或者确实在指定的位置上不存在。请确保路径和文件名的正确性,并验证所需的文件或目录是否存在。 2. 权限问题:您可能没有足够的权限来访问指定的文件或目录。请确保您的应用程序具有适当的文件读取权限,以便能够打开和访问所需的文件。 3. 文件或目录被移动或删除:在尝试访问文件或目录之前,可能已经发生了文件或目录的移动、重命名或删除操作。在访问之前,请确保文件或目录尚未被其他操作修改或删除。 4. 文件路径格式错误:如果文件路径包含非法字符、不正确的分隔符或其他格式问题,也可能导致无法找到文件或目录。请确保路径格式正确,并使用正确的分隔符(例如斜杠“/”)。 5. 外部存储问题:如果您尝试访问外部存储设备上的文件,并且设备未正确挂载或不可用,也可能导致此错误。请确保外部存储设备已正确挂载,并且您的应用程序具有适当的存储权限。 要解决此问题,您可以执行以下操作: - 检查文件路径和文件名的正确性,并确保文件或目录存在。 - 检查应用程序的文件读取权限,并确保您具有适当的权限。 - 在访问文件或目录之前,确保它尚未被移动、重命名或删除。 - 确保文件路径格式正确,并使用正确的分隔符。 - 如果涉及外部存储,确保设备已正确挂载,并且您的应用程序具有适当的存储权限。 通过仔细检查和排除上述问题,您应该能够解决 "open failed: ENOENT (No such file or directory)" 错误。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值