天天看點

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用法及多權限同時請求的處理方案