因爲幫人維護一個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