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

升级targetSdkVersion到30后监听WhatsApp图片的FileObserver不触发怎么办

解决方案

核心原因

targetSdkVersion=30对应Android 11系统,分区存储规则强制生效,原有的FileObserver失效是权限、路径配置、系统规则限制共同导致的。

具体解决步骤

  • 步骤1:正确配置和申请所有文件访问权限

    首先在AndroidManifest.xml中添加以下配置:
    <!-- 兼容低版本 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
    <!-- Android 11+ 所有文件访问权限 -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    
    MANAGE_EXTERNAL_STORAGE属于特殊权限,无法通过普通运行时权限弹框申请,必须引导用户跳转到系统设置页手动开启:
    // 检查是否已获得所有文件访问权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        if (!Environment.isExternalStorageManager()) {
            val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
            intent.data = Uri.parse("package:${packageName}")
            startActivityForResult(intent, REQUEST_CODE_MANAGE_STORAGE)
        }
    } else {
        // 申请普通存储权限即可
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_CODE_NORMAL_STORAGE)
    }
    
  • 步骤2:修正监听路径构造逻辑

    你之前将路径替换为mContext.getExternalFilesDir(null).absolutePath是完全错误的,该路径是你的应用私有存储目录,和WhatsApp的公共存储路径毫无关系,自然无法监听到事件。
    正确的监听路径构造方式:
    val whatsappImgPath = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        "${Environment.getExternalStorageDirectory().absolutePath}/Android/media/${WHATSAPP_PKG_NAME}/WhatsApp/Media/WhatsApp Images/"
    } else {
        // 低版本原有路径
        Constants.whatsapp_images_path11
    }
    val targetDir = File(whatsappImgPath)
    // 必须先验证目录存在且你有读取权限
    if (!targetDir.exists() || !targetDir.canRead()) {
        Log.e("Observer", "目标目录不存在或无读取权限")
        return
    }
    
  • 步骤3:修正FileObserver初始化逻辑

    Android 11+对FileObserver的事件监听做了权限校验,必须确保你对监听目录有读取权限后再初始化Observer。另外注意FileObserver默认只监听当前目录的事件,不会递归监听子目录,如果需要监听子目录需要自行遍历所有子目录分别创建Observer实例。
    修正后的初始化示例:
    class WhatsAppImageObserver11(val notify: (msg: String) -> Unit, targetPath: String) : FileObserver(File(targetPath), ALL_EVENTS) {
        init {
            Log.d("WhatsAppImageObserver11", "监听路径:$targetPath 已启动")
        }
        // 原有onEvent逻辑保持不变即可
    }
    
  • 步骤4:移除无效配置

    android:preserveLegacyExternalStorage="true"仅对targetSdk=29升级到30的存量安装应用生效,新安装的targetSdk=30应用该配置完全无效,可以直接从Manifest中移除。

验证要点

  1. 开启所有文件访问权限后,先手动访问一次目标WhatsApp Images目录,确认可以读取到目录下的文件
  2. 确保你构造的监听路径和实际WhatsApp存储图片的路径完全一致,部分新版本WhatsApp可能会修改存储路径,可以通过系统文件管理器确认路径正确性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:15:07