Android:由于UID无效,应用程序无法在重新安装后访问外部存储

时间:2016-01-13 02:04:17

标签: android android-5.0-lollipop android-sdcard storage-access-framework

卸载和重新安装后,我们的应用程序无法写入外部存储上的应用程序文件夹(<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设备...

重现的步骤:

  1. 安装应用程序
  2. 在SD卡上的应用程序文件夹(<sdcard>/Android/data/<applicationpackage>/files)中创建一些文件。该文件夹的UID例如是10206.应用程序UID也是10206.访问SD卡工作正常。我可以通过Storage Access Framework访问应用程序文件夹或访问其他文件夹
  3. 卸载应用程序 - 正确删除SD卡上的应用程序文件夹。
  4. 重新安装应用程序(必须在重新安装之前完全卸载。通过更新应用程序,您将无法重现它。)
  5. 现在可以发生以下三种情况之一:

    案例A)没有错误:申请的UID增加到例如10207,SD卡上的应用程序文件夹的UID是相同的 - 10207,一切正常。我可以通过Storage Access Framework访问应用程序文件夹或访问其他文件夹。

    案例B)BUG:SD卡上的应用程序和应用程序文件夹的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:app的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有关。我不太清楚如何修复或解决它。

0 个答案:

没有答案