卸载和重新安装后,我们的应用程序无法写入<sdcard>/Android/data/<applicationpackage>/files
外部存储上的应用程序文件夹 ( ),无法与 MediaStore 提供商合作,也无法使用 Storage Access Framework 访问 SD 卡上的其他文件。该问题随机发生,但很常见,并且很容易在许多设备上重现。
它可以在许多带有 SD 卡的 Android 5.x 设备上复制:LG G3 VS985 4G (5.1.1)、LG G Pad V500 (5.0.2)、Alcatel Idol 3、Nvidia SHIELD Tablet K1 (5.1.1)、Verizon SM-G900V (5.0) 和其他 LG、Alcatel、Asus 设备...
重现步骤:
- 安装应用程序
<sdcard>/Android/data/<applicationpackage>/files
在 SD 卡上的应用程序文件夹 ( ) 中创建一些文件。此文件夹的 UID 是例如 10206。应用程序 UID 也是 10206。访问 SD 卡工作正常。我可以通过存储访问框架访问应用程序文件夹或访问其他文件夹- 卸载应用程序 - SD 卡上的应用程序文件夹已正确删除。
- 重新安装应用程序(在重新安装之前必须完全卸载它。通过更新应用程序,您将不会复制它。)
现在可能会发生以下 3 种情况之一:
案例 A) 没有错误:应用程序的 UID 增加到例如 10207,SD 卡上的应用程序文件夹的 UID 相同 - 10207,一切正常。我可以通过存储访问框架访问应用程序文件夹或访问其他文件夹。
CASE B)BUG:SD卡上app和应用程序文件夹的UID没有增加,仍然是10206,但是在内部(在系统中)这个应用程序包的UID显然已经不同了。这会导致以下异常:
Caused by: java.lang.SecurityException: Package <applicationpackage> does not belong to calling UID 10206
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.ActivityManagerProxy.getPersistedUriPermissions(ActivityManagerNative.java:3947)
at android.content.ContentResolver.getPersistedUriPermissions(ContentResolver.java:1715)
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/file from pid=3322, uid=10206 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1540)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:420)
at android.content.ContentResolver.query(ContentResolver.java:502)
at android.content.ContentResolver.query(ContentResolver.java:446)
重复步骤 3. 和 4. 后,情况 C) 总是出现。大多数情况下 C) 立即发生,没有情况 B) 并重复步骤 3. a 4。
案例 C) BUG:应用程序的 UID 增加到例如 10207,但应用程序文件夹 ( <sdcard>/Android/data/<applicationpackage>/files
) 的 UID 仍为 10206,无法从应用程序访问。这会导致以下异常:
Caused by: java.io.FileNotFoundException: /storage/sdcard1/Android/data/<applicationpackage>/files/somefolder/somefile.xml: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:456)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
任何进一步的卸载和重新安装都无济于事。应用程序文件夹的 UID 仍然是 10206!并且每次重新安装后(正确地)更改应用程序的 UID。唯一的解决方法是重新启动设备。重新启动后,应用程序文件夹的 UID 会根据应用程序 UID 进行更新。之后,一切正常,直到下一次卸载。所以现在我必须强制用户重启设备。
笔记:
- 我通过以下方式获取应用程序 UID:
android.os.Process.myUid()
- 我通过以下方式获取应用程序文件夹 UID:
Os.stat("<sdcard>/Android/data/<applicationpackage>/files").st_uid
我在很长一段时间内都面临这个问题,现在我很确定它与不同的 UID 有某种关系。我不知道如何很好地修复或解决它。