升级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中移除。
验证要点
- 开启所有文件访问权限后,先手动访问一次目标WhatsApp Images目录,确认可以读取到目录下的文件
- 确保你构造的监听路径和实际WhatsApp存储图片的路径完全一致,部分新版本WhatsApp可能会修改存储路径,可以通过系统文件管理器确认路径正确性
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

