從Android動態許可權到Rxpermissions實現
搞Android開發的同學可能都知道,Android 6.0最重要的新特性就是動態許可權申請。
使用者可直接在執行時管理應用許可權,這種模式讓使用者能夠更好地瞭解和控制權限。動態許可權對於使用者來說肯定是非常好的一個新特性,但對於開發者來說可能不是很友好。不過想想也挺好的,畢竟使用者為大,保護使用者的隱私最重要了。
唉,做Android真累。

讓我們先來看看6.0以上的許可權怎麼申請吧~
動態許可權申請步驟
步驟一
先在AndroidManifest中填寫你要申請的許可權。
我們只需要在對應的位置寫入申請許可權程式碼即可,例如我現在申請相機許可權。
<uses-permission android:name="android.permission.CAMERA" />
步驟二
然後我們需要在開啟相機的位置新增下面的程式碼。
public void requestPower() { // checkSelfPermission 判斷是否已經申請了此許可權 if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { //如果應用之前請求過此許可權但使用者拒絕了請求,shouldShowRequestPermissionRationale將返回 true。 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { } else { ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA,}, 1); } } }
步驟三
然後還需要在 onRequestPermissionsResult 回撥方法中去進行處理。程式碼如下
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { for (int i = 0; i < permissions.length; i++) { if (grantResults[i] == PERMISSION_GRANTED) { Toast.makeText(this, "" + "許可權" + permissions[i] + "申請成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "" + "許可權" + permissions[i] + "申請失敗", Toast.LENGTH_SHORT).show(); } } } }
這些好了之後我們來看一看效果吧。

動態申請許可權基本上就這樣子了。 下面進入本文重點內容,講解RxPermissions實現原理。
RxPermissions
RxPermissions是什麼?
Android runtime permissions powered by RxJava2 ——官方解釋 ,也就是說它是基於Rxjava的動態許可權框架。
RxPermissions怎麼用?
首先去gradle中引入依賴
implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
然後新增如下程式碼即可。
private void rxPermissionTest() { RxPermissions rxPermissions = new RxPermissions(this); rxPermissions.request(Manifest.permission.CAMERA).subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean granted) throws Exception { if (granted) { // 開啟相機 } else { // 許可權被拒絕 } } }); }
實現效果與上面一樣。我就不重複貼圖了,大家可以自己試試看看。
RxPermissions實現原理。
上面寫了這麼多東西,相必大家早就想看最後部分了吧。 沒錯,這就是最後部分。

9648fc14eb1146b8839470cbe852be56.jpeg
這裡為大家獻上我最喜歡的一句話, Talk is cheap, Show me the code.
意思就是,別叨叨了,有種上程式碼~~
我們先從RxPermissions的構造方法看起。

構造方法挺容易理解的,就是初始化RxPermissionsFragment,我們所有的許可權申請、回撥都是在這個Fragment中實現的,這也是RxPermissions框架最主要的部分,一切都是圍繞這個展開的。
在getRxPermissionsFragment方法中將這個無介面的Fragment新增到FragmentManager。

接下來我們需要翻閱大概瞭解一下RxPermissionsFragment這個類。首先看處理許可權返回的程式碼。

在上面我們講過onRequestPermissionsResult這個方法是處理許可權返回時候具體邏輯的,在這裡我們就見到了吧。
該框架向外部暴露了一個onRequestPermissionsResult的過載方法,在這個方法中定義了一個PublishSubject,它將每個許可權封裝為Permission實體類,然後將它發出給訂閱它的觀察者進行處理。本篇暫時不講Rxjava的用法。 我暫且認為大家都會Rxjava了。
讓我們繼續看,isGranted方法。在這個方法中我們看到了一個熟悉的方法 checkSelfPermission ,說明它是在這個方法中開始的許可權申請。

RxPermissionsFragment主要的幾個方法已經說完了,下面我們繼續看 RxPermissions類 。
剛才在RxPermissions用法中已經寫過,這個框架是呼叫request方法,所以我們看request方法是如何實現的。

看起來此方法通過compose進行了一個轉換,具體實現在ensure中,我們繼續點進去看ensure方法。

在這個方法中,我們還需要看一下request(o,permission)內部又實現了一些什麼操作。

這個方法中是將 Object 轉為了 Observable Permission 具體轉的實現還需要看 requestImplementation 方法的實現。

主要邏輯就是通過RxPermissionsFragment的isGranted方法進行判斷,如果同意權限,返回Permission物件為true,否則返回false。
讓我們再回到ensure方法

很明顯,ensure中flatMap方法內,是將Object物件轉為Boolean物件,如果permission物件同意授權返回true,反之返回false。
所以我們就可以將最終申請結果通過訂閱關係返回給觀察者,然後在Activity中進行處理。
看完這個框架,我決定還要繼續學習Rxjava,因為有好多操作符使用我也不會。。。。
本人才疏學淺,如果有寫錯的地方,還希望大家指出來。

Stay hungry Stay foolish。
Bye~