android 8.0适配走坑之路

本想着一直将版本设置为targetVersion设置为22就可以不用兼容8.0的权限,也确实如此,但本人还是想入坑,理由如下:

1.用户体验不到8.0带给app的好处

2.谷歌爸爸发脾气说要尽快处理好,否则随时不让你用。

3.最近闲着蛋疼,那就来玩玩吧。


由于手头没有手机,那就先来下载模拟器吧。先确定好版本号,26就是anroid8.0了,现在最新的应该是27,对应android8.1版本,同时还推出了android P版本,这个是为了来处理刘海问题,想当初苹果出刘海,各个厂商争相吐槽,随后又紧跟着模仿,这点就不多做评论了。

下载好8.0之后,开机,说实话,这个开机动画跟logo还是挺清新脱俗的



接下直接运行我手头的项目,由于我手头的项目比较复杂,集合了各种sdk,比如扫码、友盟、环信、图片裁剪库、百度地图等等,所以这个项目能兼容好各种权限,基本你那些小项目不会有什么太大的问题。

首先,我的项目里面targetVersion 是22,先运行在8.0的模拟器上,一切正常,他虽然运行在8.0设备上,实际上是以22的,即将6.0以下的版本去运行的,所以不需要兼容所谓的动态权限。


实验开始了:

把targetVersion改为26,一运行,奔溃了,日志如下:


这个权限我再mainfest已经添加过了,但是没有效果的,需要动态添加,决定用AndPermission开源库来解决问题,我也是第一次用。

这是github的地址:https://github.com/yanzhenjie/AndPermission

直接在gradle添加依赖,

implementation 'com.yanzhenjie:permission:2.0.0-rc4'

然后我编译报了这个错

Error:(36, 0) Gradle DSL method not found: 'implementation()' Possible cause

不要慌。原来使用这个参数需要Android 3.0.0,gradle版本必须在3.4以上 ,要么升级你的工具,要么直接implementation改为compile即可。


下面看代码,参数可以传单个权限、单个权限组、多个权限、多个权限组,具体调用可以自己看链接,他里面有示例代码,下面我摘抄单个权限的调用示例,其实其他调用都差不多。至于要用哪一个,完全根据你的项目实际来调用。

AndPermission.with(this)
                        .permission(Permission.READ_PHONE_STATE)
                        .onGranted(new Action() {
                            @Override
                            public void onAction(List<String> permissions) {
                                // TODO what to do.
                                Log.v("zzz","onGranted onAction");
                                Log.v("zzz", "device id:" + getDeviceId(MainActivity.this));
                            }
                        }).onDenied(new Action() {
                    @Override
                    public void onAction(List<String> permissions) {
                        Log.v("zzz","onDenied onAction");
                        // TODO what to do
                    }
                })
               .start();

代码非常的简洁,将我需要的读取手机状态的权限作为参数传给他,然后下次你执行到这块代码时候系统就会自动弹窗。


逻辑非常简单,如果你点击允许,会回调onGranted onAction,然后下面就可以执行你要做的那些跟权限相关的事情。这里我的getDeviceId方法里面就是做了这样的事情。

如果点拒绝,则会调用onDenied onAction,你可以做相应提示,也可以不处理,就是用户点了没反应而已。

注意:如果你拒绝后,下次执行那段代码还是会再次提示弹窗向你咨询权限,


除非你勾选了不再咨询,则下次就不会弹窗,默认你拒绝了。但onDenied onAction还是会调用。如果你点允许,下次也是默认允许,不会再咨询。


不清楚的可以参考这个用法地址:http://www.yanzhenjie.com/AndPermission/cn/usage.html

最后,由于我的项目里面有混淆,所以需要添加 :-dontwarn com.yanzhenjie.permission.**到你的混淆文件当中

2)app顺利登陆,然后打开拍照页面,又闪退:

  android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/diandong/screenshots/1525336037371.png exposed beyond app through ClipData.Item.getUri()

7.0之后你的app就算有权限,给出一个URI之后手机也认为你没有权限。

不用修改原有代码,在Application的oncreate方法中:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());
}

顺利解决,继续来:

3)继续打开拍照页面,又闪退,不过这次异常不一样了:

java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.android.camera2/com.android.camera.CaptureActivity clip={text/uri-list U:file:///storage/emulated/0/Android/data/diandong/screenshots/1525338674467.png} (has extras) } from ProcessRecord{6bd78e4 3236:com.jkinvest.store/u0a99} (pid=3236, uid=10099) with revoked permission android.permission.CAMERA

注意到最后一句话没有,这是提示我没有相机权限,所以接下来,就来动态申请相机权限了,然后按照之前添加权限的方法,只是把参数改为Permission.CAMERA,果然,这次可以拍照了。

4)拍完照之后呢,就要打开照片,结果又崩溃了,又是权限的问题,但这里没有明确说,但经过反复推敲,得知是没有文件读写权限,因为要打开sdcard,所以需要添加权限:Permission.WRITE_EXTERNAL_STORAGE,添加权限之后果然没问题了。

java.io.FileNotFoundException:/storage/emulated/0/Android/data/diandong/screenshots/1525344009524.png (Permission denied)

猜你喜欢

转载自blog.csdn.net/u014369799/article/details/80162409