升級Android8.0帶了的第一個SecurityException問題

因爲幫人維護一個APP,該APP在Google Play商店發佈,最近Google Play的修改了規則。
上傳APP報錯:

Your app currently targets API level 25 and must target at least API level 26

第一眼看到,就明白了,上傳的APP的targetSdkVersion 必須升級到 26,也就是說Google強行要求Android 的開發API要升級到Android 8,不然不能在Google Play上線。

好吧,升級吧。果然和想的一樣,APP開啓的時候就Crash了,錯誤如下(包名我隱去了):

 java.lang.SecurityException: Permission Denial: opening provider com.******.provider.SeafileProvider from ProcessRecord{6c7a7ea 18676:com.******.debug/u0a809} (pid=18676, uid=10809) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
        at android.os.Parcel.readException(Parcel.java:1967)
        at android.os.Parcel.readException(Parcel.java:1913)
        at android.content.IContentService$Stub$Proxy.notifyChange(IContentService.java:821)
        at android.content.ContentResolver.notifyChange(ContentResolver.java:2052)
        at android.content.ContentResolver.notifyChange(ContentResolver.java:2003)
        at android.content.ContentResolver.notifyChange(ContentResolver.java:1973)
        at com.******.provider.SeafileProvider$1.onAccountsUpdated(SeafileProvider.java:121)
        at android.accounts.AccountManager$19.run(AccountManager.java:2206)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6938)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

只是第一個問題。
來看下代碼怎麼實現的:

······
public static final Uri NOTIFICATION_URI = DocumentsContract.buildRootsUri(Utils.AUTHORITY);
······
 private OnAccountsUpdateListener accountListener = new OnAccountsUpdateListener() {
        @Override
        public void onAccountsUpdated(android.accounts.Account[] accounts) {
            Context c = SeadroidApplication.getAppContext();
            c.getContentResolver().notifyChange(NOTIFICATION_URI, null);//這裏發生了crash
        }
    };

Utils中的包名是寫死的。

 public static final String AUTHORITY = "com.sea***.***oid2";

並且在build.gradle中做了如下配置

 buildTypes {
        debug {
              ······
             applicationIdSuffix ".debug"  // 在打debug 包時,將APP的包名後面加debug,修改了原有的包名。
              ······
         }
}

不明所以的找了不少博客,文字,官網也說的簡單一句,沒有提供修改的方法。

分析:

翻閱資料,查看源碼得知,Android 8.0 生成URI,在notifyChange 的時候,要有authorities, 這個就是應用的包名,因爲上面代碼的原因,導致在調試模式下的debug包的包名是com.sea***.***oid2.debug,而代碼中寫死的是com.sea***.***oid2,所以奔潰了。(Android 8.0 之前的版本沒事)

修復:

將包名改爲動態生成,不要用Utils中寫死的代碼

  public static final Uri NOTIFICATION_URI = DocumentsContract.buildRootsUri(BuildConfig.APPLICATION_ID);//傳入真正的包名。

問題解決。

該問題最具參考價值的資料:

1、https://blog.csdn.net/weixin_37077539/article/details/80067073

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章