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

Android中无法获取特定WhatsApp状态文件夹权限问题求助

获取WhatsApp状态文件夹权限时遇到“无法使用此文件夹以保护隐私”问题

我尝试获取WhatsApp状态文件夹的权限,编写了如下代码,但在模拟器中操作时出现报错提示:“无法使用此文件夹以保护隐私”。

相关代码

获取权限的方法

@RequiresApi(Build.VERSION_CODES.Q)
private fun getFolderPermission() {
    val storageManager = application.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val intent = storageManager.primaryStorageVolume.createOpenDocumentTreeIntent()
    val targetDirectory = "%3AAndroid%2Fmedia%2Fcom.whatsapp%2F"
    var uri = intent.getParcelableExtra<Uri>("android.provider.extra.INITIAL_URI") as Uri
    var scheme = uri.toString()
    scheme = scheme.replace("/root/", "/tree/")
    scheme += "%3A$targetDirectory"
    Toast.makeText(applicationContext,scheme,Toast.LENGTH_LONG).show()
    uri = Uri.parse(scheme)
    intent.putExtra("android.provider.extra.INITIAL_URI", "content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses")
    intent.putExtra("android.content.extra.SHOW_ADVANCED", true)
    startActivityForResult(intent, 1234)//content //com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2F
}

权限回调处理

@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK) {
        val treeUri = data?.data

        val sharedPreferences = getSharedPreferences("DATA_PATH", MODE_PRIVATE)
        val myEdit = sharedPreferences.edit()
        myEdit.putString("PATH", treeUri.toString())
        myEdit.apply()
        if (treeUri != null) {
            contentResolver.takePersistableUriPermission(
                treeUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION
            )
            val fileDoc = DocumentFile.fromTreeUri(applicationContext, treeUri)
            for (file: DocumentFile in fileDoc!!.listFiles()) {
                if (file.name!!.endsWith(".nomedia")) {

                }
            }
        }
    }
}

报错截图

报错截图:无法使用此文件夹以保护隐私

问题原因

Android 10及以上版本的**分区存储(Scoped Storage)**机制会保护应用的私有媒体目录。WhatsApp的Statuses文件夹属于com.whatsapp应用的私有目录(路径Android/media/com.whatsapp/WhatsApp/Media/.Statuses),直接通过OpenDocumentTreeIntent跳转到该目录会触发系统的隐私保护拦截,禁止直接访问。

解决方案

不要直接指定跳转到Statuses子目录,先引导用户授权访问Android/media/com.whatsapp目录,之后再在代码中导航到Statuses子目录:

修正后的权限获取方法

@RequiresApi(Build.VERSION_CODES.Q)
private fun getFolderPermission() {
    val storageManager = application.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val intent = storageManager.primaryStorageVolume.createOpenDocumentTreeIntent()

    // 构造初始URI,定位到Android/media/com.whatsapp目录
    val initialUri = intent.getParcelableExtra<Uri>("android.provider.extra.INITIAL_URI") as Uri
    var uriString = initialUri.toString()
    // 替换root为tree,适配文档树URI格式
    uriString = uriString.replace("/root/", "/tree/")
    // 添加目标路径:Android/media/com.whatsapp
    uriString += "%3AAndroid%2Fmedia%2Fcom.whatsapp"
    val targetUri = Uri.parse(uriString)

    intent.putExtra("android.provider.extra.INITIAL_URI", targetUri)
    intent.putExtra("android.content.extra.SHOW_ADVANCED", true)
    startActivityForResult(intent, 1234)
}

修正后的回调处理(自动导航到Statuses子目录)

@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK && requestCode == 1234) {
        val treeUri = data?.data ?: return

        // 持久化权限
        contentResolver.takePersistableUriPermission(
            treeUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION
        )

        // 导航到Statuses子目录
        var statusesDir = DocumentFile.fromTreeUri(applicationContext, treeUri)
        // 依次进入WhatsApp -> Media -> .Statuses
        statusesDir = statusesDir?.findFile("WhatsApp") ?: return
        statusesDir = statusesDir.findFile("Media") ?: return
        statusesDir = statusesDir.findFile(".Statuses") ?: return

        // 持久化Statuses目录的URI(可选)
        val sharedPreferences = getSharedPreferences("DATA_PATH", MODE_PRIVATE)
        sharedPreferences.edit().putString("PATH", statusesDir.uri.toString()).apply()

        // 现在可以遍历Statuses目录下的文件
        for (file in statusesDir.listFiles()) {
            if (!file.name.orEmpty().endsWith(".nomedia")) {
                // 处理状态文件
            }
        }
    }
}

说明

  1. 先让用户授权com.whatsapp的媒体目录,这是系统允许的操作,不会触发隐私拦截。
  2. 授权完成后,通过DocumentFile逐级导航到.Statuses子目录,即可正常访问其中的状态文件。
  3. 持久化Statuses目录的URI后,后续可以直接使用该URI访问,无需重复授权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:04:55