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

Android 11/13访问其他应用media文件夹所需权限及代码示例

Android 11/13 访问其他应用Android/media/包名目录的权限说明及代码示例

权限要求

Android 11(API 30)

  • 无需申请READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限,但禁止直接通过文件路径访问其他应用的该目录。必须通过**存储访问框架(SAF)**让用户手动选择目标目录,或借助MediaStore API访问目录内的媒体文件。

Android 13(API 33)

  • 访问媒体文件时,需申请细分权限:READ_MEDIA_IMAGES(图片)、READ_MEDIA_VIDEO(视频)、READ_MEDIA_AUDIO(音频),替代了旧版的READ_EXTERNAL_STORAGE。
  • 直接路径访问其他应用的Android/media/包名目录仍受系统限制,需通过SAF或MediaStore操作;访问自身应用的该目录则无需额外权限(属于应用私有媒体目录)。

代码示例

1. 使用SAF选择其他应用的Android/media目录

private const val REQUEST_CODE_OPEN_DIR = 1001

// 启动SAF选择目标目录
fun openOtherAppMediaDir() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
        // 可选:设置初始打开位置为Android/media目录
        val androidMediaUri = DocumentsContract.buildTreeDocumentUri(
            "com.android.externalstorage.documents",
            "primary:Android/media"
        )
        putExtra(DocumentsContract.EXTRA_INITIAL_URI, androidMediaUri)
    }
    startActivityForResult(intent, REQUEST_CODE_OPEN_DIR)
}

// 处理SAF返回的目录结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CODE_OPEN_DIR && resultCode == Activity.RESULT_OK) {
        data?.data?.let { treeUri ->
            // 获取持久化访问权限,避免应用重启后权限失效
            contentResolver.takePersistableUriPermission(
                treeUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
            )
            // 通过DocumentFile操作目录内文件
            val targetDir = DocumentFile.fromTreeUri(this, treeUri)
            targetDir?.listFiles()?.forEach { file ->
                Log.d("SAF_TEST", "文件:${file.name}")
            }
        }
    }
}

2. 通过MediaStore查询其他应用目录下的图片

private const val REQUEST_CODE_READ_MEDIA = 1002

fun queryOtherAppMediaImages() {
    // Android 13+先检查权限
    if (ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.READ_MEDIA_IMAGES
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.READ_MEDIA_IMAGES),
            REQUEST_CODE_READ_MEDIA
        )
        return
    }

    // 查询路径包含目标应用包名的图片文件
    val projection = arrayOf(
        MediaStore.Images.Media._ID,
        MediaStore.Images.Media.DISPLAY_NAME,
        MediaStore.Images.Media.RELATIVE_PATH
    )
    val selection = "${MediaStore.Images.Media.RELATIVE_PATH} LIKE ?"
    val selectionArgs = arrayOf("%Android/media/com.example.targetapp%") // 替换为目标应用包名

    contentResolver.query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        null
    )?.use { cursor ->
        while (cursor.moveToNext()) {
            val fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
            Log.d("MEDIA_STORE", "找到图片:$fileName")
        }
    }
}

// 处理权限申请结果
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_CODE_READ_MEDIA && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        queryOtherAppMediaImages()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:05:18