You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android解决open failed: EACCES (Permission denied)权限拒绝问题

解决Android分享图片到WhatsApp时的权限拒绝问题

1. 确认并申请对应权限

根据Android版本差异,需申请匹配的存储权限:

  • Android 9及以下:申请READ_EXTERNAL_STORAGE权限
  • Android 10-12:仍需READ_EXTERNAL_STORAGE,同时适配分区存储规则
  • Android 13+:申请READ_MEDIA_IMAGES权限

动态申请权限代码示例

private val REQUEST_STORAGE_PERMISSION = 1001

fun checkAndRequestPermission() {
    val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        arrayOf(Manifest.permission.READ_MEDIA_IMAGES)
    } else {
        arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
    }

    if (ContextCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, permissions, REQUEST_STORAGE_PERMISSION)
    } else {
        shareWallpaperWithUri()
    }
}

// 处理权限申请结果
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_STORAGE_PERMISSION && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        shareWallpaperWithUri()
    } else {
        Toast.makeText(this, "需要存储权限才能分享图片", Toast.LENGTH_SHORT).show()
    }
}

2. 适配Android 10+分区存储规则

Android 10及以上启用分区存储后,直接通过文件路径访问公共目录文件会被限制,需通过MediaStore查询获取图片的Uri替代文件路径。

获取图片Uri的代码示例

fun getImageUriFromPath(context: Context, imagePath: String): Uri? {
    val fileName = imagePath.substringAfterLast("/")
    val projection = arrayOf(MediaStore.Images.Media._ID)
    val selection = "${MediaStore.Images.Media.DISPLAY_NAME} = ?"
    val selectionArgs = arrayOf(fileName)
    val cursor = context.contentResolver.query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        null
    )

    cursor?.use {
        if (it.moveToFirst()) {
            val id = it.getLong(it.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
            return ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
        }
    }
    return null
}

3. 修改分享逻辑,使用Uri替代文件路径

WhatsApp支持通过content://类型的Uri分享图片,需为Intent添加临时读取权限,避免直接访问文件路径引发的权限问题。

修正后的分享方法

fun shareWallpaperWithUri() {
    val imagePath = "/storage/emulated/0/Pictures/JayTN24/mens_shirt_0.jpg"
    val imageUri = getImageUriFromPath(this, imagePath) ?: run {
        Toast.makeText(this, "无法找到目标图片", Toast.LENGTH_SHORT).show()
        return
    }

    val intent = Intent(Intent.ACTION_SEND).apply {
        type = "image/jpeg"
        putExtra(Intent.EXTRA_STREAM, imageUri)
        setPackage("com.whatsapp")
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }

    try {
        startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        Toast.makeText(this, "未安装WhatsApp应用", Toast.LENGTH_SHORT).show()
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

额外注意事项

  • 若图片为你的App生成,建议直接通过MediaStore写入公共目录,后续可直接获取对应Uri,无需手动解析路径。
  • 禁止使用file://类型Uri分享,高版本Android会限制第三方App访问此类Uri,必须使用content://类型Uri并授予临时权限。

内容的提问来源于stack exchange,提问作者Syed Ghouser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:35:53