AndPermission 算是一個不錯的 權限庫了,鏈式調用,還可以使用 content 上下文去請求權限,這樣我們可以寫到 application 的 oncreate 中去了
官方文檔中說 AndPermission 還可以處理國內不同廠商的 5.X 系統上的權限管理,手頭沒有5.X 的機器,這個得碰到再試了。
先來看下 AndPermission 的鏈式調用
private void requestPermission() {
AndPermission.with(this)
.permission(Manifest.permission.CAMERA)
// 準備方法,和 okhttp 的攔截器一樣,在請求權限之前先運行改方法,已經擁有權限不會觸發該方法
.rationale((context, permissions, executor) -> {
// 此處可以選擇顯示提示彈窗
executor.execute();
})
// 用戶給權限了
.onGranted(permissions -> show("用戶給權限啦"))
// 用戶拒絕權限,包括不再顯示權限彈窗也在此列
.onDenied(permissions -> {
// 判斷用戶是不是不再顯示權限彈窗了,若不再顯示的話進入權限設置頁
if (AndPermission.hasAlwaysDeniedPermission(MainActivity.this, permissions)) {
// 打開權限設置頁
AndPermission.permissionSetting(MainActivity.this).execute();
return;
}
show("用戶拒絕權限");
})
.start();
}
然后我錄了一段大家有個感性認識
添加依賴
implementation 'com.yanzhenjie:permission:2.0.0-rc4'
API 說明
再開頭我們都看到了 AndPermission 的基本 API,我們主要看權限申請回調情況
- rationale
rationale 這是攔截器,當用戶不給權限時優先執行,用戶給權限就不會執行,AndPermission 給大家提供這個方法就是考慮有的 app 的體驗上,這里他推薦大家 toast 一個 diaolg 出來,用戶提示用戶為啥,需要哪些權限,然后我們用這個 executor 執行器去決定是終止請求還是繼續執行權限請求 - onGranted
用戶同意給權限 - onDenied
用戶不給權限,包括用戶選擇拒絕和用戶點了不再提示2種情況- AndPermission.hasAlwaysDeniedPermission
針對用戶點了不再提示這種情況,可以使用這個 api 去判斷,然后我們啟動權限設置頁 - AndPermission.permissionSetting
AndPermission 提供的動權限設置頁的 API ,可惜的是不能監聽返回結果,大家從上面的演示可以看到,這里需要考慮如何處理
- AndPermission.hasAlwaysDeniedPermission
AndPermission 用的哪種方式去攔截的權限結果
我們知道權限結果我們需要去 onRequestPermissionsResult 中去判斷,這樣給我們的代碼造成很大的問題,我要是在 persenter 或是工具類中申請權限,還要通過 callback 傳遞回 UI 頁面,這樣太過麻煩,類結構也不好何設計,我們傳這個 callback 可能需要傳2-3層才能傳遞給 UI 對象,太坑爹了,我最討厭動態權限的這點了。
動態權限的基礎知識點可以看我的文章:android 6.0動態權限
那么 我們看到 AndPermission 不用我們去監聽 onRequestPermissionsResult 了,如何做的呢,這我們就得翻翻源碼了
AndPermission 的源碼不少,但是思路不難,我偷個懶截圖了
不用特意去解釋了,大家看圖看注解文字就都看的明白,最終就是啟動了一個專門的 activity,用于攔截權限結果,在啟動頁面時把 lisenter 一起傳過去了,就是這個思路。
從源碼結構也能看出來,封裝了不同的權限請求來源,但是最終只啟動了 一個 activity
權限寫在 application 的問題
試了下 AndPermission 可以把權限請求寫在 application 里,大家看下結果
可以運行,因為是啟動一個專門請求權限的 Activity ,所以不會中斷 app 啟動流程,例子中我們可以看到2個問題:
- app 走自己的,權限請求彈窗顯示在那
- 用 AndPermission 啟動的權限設置頁,我們監聽不到返回結果,這樣會影響我們的判斷
恩,其實用 AndPermission 在 application 中申請權限是不恰當的,AndPermission 不會中斷 app 的啟動流程,這樣我們是無法控制的,而且系統的權限設置頁監聽不到返回結果也是影響我們的邏輯流程的
app 啟動時的權限判斷一般都是不給權限就不能再愉快玩耍的,這樣看我們的需求在 application 中去實現滿足不了
那 app 啟動 我們應該在哪里去判斷權限
既然我們在 application 寫不恰當,那么我們瞬移到閃屏頁好了,我們在閃屏頁判斷權限邏輯,我們自己去啟動系統的權限設置頁,這樣我們也能監聽的到,或者我們修改 AndPermission 的源碼。
啟動權限設置頁代碼:
private void startAppSettingActivity(Activity activity) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + activity.getPackageName()));
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
activity.startActivityForResult(intent, 200);
}
注意不要加這個 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) ,要不從系統權限設置頁回來時會出現閃屏的問題。