天天看点

PermisssionDispatcher 在MIUI 11 上的坑&解决方案

被小米9的权限弹窗折磨了1天多,总算找到了解决方案,记录下来,以资来者

问题是这样的,由于现在对于个人隐私信息越发的关注,有很多应用市场要求APP在动态请求高危权限时,需要先弹出说明框向用户说明。

乍一看这个问题不难哈。哐哐哐,引入PermissionDispatcher框架,再封装一个弹窗逻辑,这事儿就完了。

很好,当我搞定这些后,在我的小米10青春版(MIUI12)上测了下,完美解决应用市场的权限合规问题。

然而,在小米9(MIUI11)上测试时,却发现在我动态请求权限前,会先弹出一个代倒计时的系统权限弹窗。

这就让我百思不得其解了,打断电发现,第一个系统弹窗不是在应用申请高位权限时弹出的,而是调用

PermissionDispatcher

提供的

PermissionUtils#hasSelfPermissions

时触发的。钻进源码里看一波呗。发现

hasSelfPermissions

会对小米设备进行特殊里,一路跟下去,后面就看不到了。。。

/**
 * Determine context has access to the given permission.
 * <p>
 * This is a workaround for RuntimeException of Parcel#readException.
 * For more detail, check this issue https://github.com/hotchemi/PermissionsDispatcher/issues/107
 *
 * @param context    context
 * @param permission permission
 * @return returns true if context has access to the given permission, false otherwise.
 * @see #hasSelfPermissions(Context, String...)
 */
private static boolean hasSelfPermission(Context context, String permission) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && "Xiaomi".equalsIgnoreCase(Build.MANUFACTURER)) {
        return hasSelfPermissionForXiaomi(context, permission);
    }
    try {
        return checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
    } catch (RuntimeException t) {
        return false;
    }
}
           

既然根因找到了,那我们不用这个接口了好不?用

context#checkSelfPermission

,虽然这个方法每次只能校验一个权限,但为了解决问题,我就多写一个for循环呗。

三行代码搞定,编译。运行。。。请求。翻车。

这次是先弹窗再跳那个倒计时的系统权限窗,不处理这个弹窗,系统会跳到不带倒计时的系统权限窗。

再看代码,发现在Dispatcher的生成类中,

xxxWithPermissionCheck

时会调用

PermissionUtils#hasSelfPermissions

static void getCameraWithPermissionCheck(@NonNull MainActivity target) {
    if (PermissionUtils.hasSelfPermissions(target, PERMISSION_GETCAMERAPERMISSION)) {
      target.getCamera();
    } else {
      ActivityCompat.requestPermissions(target, PERMISSION_GETCAMERAPERMISSION, REQUEST_GETCAMERAPERMISSION);
    }
}
           

完了,这波避不开了,我总不能给他提个commit,把这块调用改了吧。等等,开源库会不会升级?!我用的是3.1.0。

到gitHub上找了找,发现最新release版本是4.8.0,大喜。升级一波。编译不过,各种查找资料(gitee上虽然能把代码copy过来,但是很多迭代记录都没有,网络允许的同学还是看github比较好),原来dispatcher从4.x以后变更了依赖包名。修改后,编译通过,回归测试通过。

// 权限申请库 3.1.0
api "com.github.hotchemi:permissionsdispatcher:3.1.0"
annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:3.1.0"
    
// 权限申请库 4.7.0
api "org.permissionsdispatcher:permissionsdispatcher:4.7.0"
annotationProcessor "org.permissionsdispatcher:permissionsdispatcher-processor:4.7.0"
           

查看dispatcher的提交记录,原来在4.1.0时去除了对小米的特殊处理。

4.1.0

@hotchemi hotchemi released this on 7 Dec 2018 · 141 commits to master since this release

Fix: compile time validation for detecting OnNeverAskAgain with special permissions #549

Update: Drop Xiaomi support #548

Fix: Fix CallNeedsPermissionDetector to scan only annotated classes #536

传送门

PermissionsDispatcher用法及多权限同时请求的处理方案