半栈工程师程序员

升级Android8.0带了的第一个SecurityExcept

2018-12-10  本文已影响45人  小追兵

因为帮人维护一个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

上一篇下一篇

猜你喜欢

热点阅读