Android 15下检测其他应用Android/data/包名目录存在性的兼容性问题求助
兄弟,这个适配问题我上个月做Android15兼容的时候刚踩过坑,太懂这种明明代码逻辑没问题,换个系统版本就失效的抓狂感了😅
问题根源
本质是Android15对应用外部私有目录(也就是你说的Android/data/包名路径)的访问策略又收紧了——之前Android14及以下,即使目标应用没在运行,其他应用还能直接检测到这个目录的存在;但Android15里,只要目标应用处于未运行状态,系统就会直接限制其他应用对该目录的访问,导致你用FileSystem API检测的时候返回不存在,但实际上这个目录是真实存在的。
可行的解决方案
优先推荐:结合PackageManager判断应用安装状态 + 路径检测
既然Android15不让我们直接读未运行应用的私有目录,那我们可以换个思路:先确认目标应用是不是已经安装了——因为只要应用正常安装,系统就会自动在Android/data下创建对应的私有目录(除非用户手动删除了这个目录,这种情况其实很少见)。然后再结合路径检测的结果,做兼容处理。给你调整了下代码,你可以直接试试:
fun Context.isOtherAppExternalDataDirExists(packageName: String): Boolean { val pm = this.packageManager // 第一步:判断目标应用是否已安装 val isAppInstalled = try { pm.getApplicationInfo(packageName, 0) true } catch (e: PackageManager.NameNotFoundException) { false } if (!isAppInstalled) { return false } // 构造外部私有目录路径 val externalDataDir = Environment.getExternalStorageDirectory() .resolve("Android/data") .resolve(packageName) val fileSystem = FileSystem.SYSTEM return try { // 尝试直接检测目录状态 fileSystem.exists(externalDataDir) && fileSystem.metadata(externalDataDir).isDirectory } catch (e: IOException) { // 抛出异常说明是权限限制导致无法访问,结合应用已安装的状态,默认认为目录存在 true } }这里的逻辑是:如果应用已经安装,但路径检测因为权限限制失败(抛出IO异常或者返回false),我们就默认目录存在——毕竟正常情况下应用安装后这个目录肯定会被系统创建,只有极端场景下才会被用户手动删除。
不推荐的方案:申请
MANAGE_EXTERNAL_STORAGE权限
这个权限是用来获取全外部存储访问权限的,但属于Google严格管控的敏感权限,只有真正的文件管理器、专业备份类等核心功能必须全存储访问的应用,才能通过Google Play的审核。如果你的应用只是单纯要检测目录存在性,完全没必要走这条路,反而会给自己的上架带来不必要的麻烦。体验较差的备选方案:通过SAF让用户选择目录
就是用Storage Access Framework唤起系统文件选择器,让用户手动选中目标应用的Android/data目录,但这种方式完全依赖用户操作,体验非常差,一般只作为所有方案都走不通时的最后备选。
我当时就是用第一种方案解决的,基本覆盖了大部分业务场景,你可以先试试这个思路。
内容来源于stack exchange

