Android6.0执行时权限解析,RxPermissions的使用,自己封装一套权限框架
Android6.0執行時權限解析,RxPermissions的使用。自己封裝一套權限框架
在Android6.0中,新添加了一個執行時的權限,我相信非常多人都已經知道了。預計也知道怎么用了,這篇博客非常easy。就是告訴大家怎樣去申請執行時權限和RxPermission這個權限框架的使用。同一時候依據現有的技術封裝思想,去封裝一個自己可用的權限框架,好的,我們繼續往下看
一.Android M 執行時權限介紹
關于Android M的更新變化,我就不啰嗦了,有興趣的能夠看下Android M更新
而我們的這篇文章,也是直接參考的Google api文檔中關于執行時權限這一塊的來對應的解說Google API 執行時權限
先來說一些概念性的東西。從 Android 6.0(API 級別 23)開始,用戶開始在應用執行時向其授予權限,而不是在應用安裝時授予。此方法能夠簡化應用安裝過程。由于用戶在安裝或更新應用時不須要授予權限。
它還讓用戶能夠對應用的功能進行很多其它控制。這句話的意思就是你安裝的時候,Android6.0之前,假設你看到非常多權限,有一兩個權限你不想給他,可是假設你不給他,就無法安裝,可是像QQ。微信這種應用,是你不想安裝就不想安裝的嗎?這是非常流氓的,而執行時權限出來后,正常安裝,可是假設你想使用這個功能。再去申請權限,這就比較合理了。我們接著往下看
系統權限分為兩類:正常權限和危急權限:
正常權限不會直接給用戶隱私權帶來風險。假設您的應用在其清單中列出了正常權限,系統將自己主動授予該權限。
危急權限會授予應用訪問用戶機密數據的權限。假設您的應用在其清單中列出了正常權限。系統將自己主動授予該權限。假設您列出了危急權限,則用戶必須明白批準您的應用使用這些權限。
這里也比較好理解。危急權限我們須要去申請就OK了,假設你搞不清楚這些權限的差別,這里我推薦你去看正常權限和危急權限 ,在這個表中。列舉了全部的權限,你能夠依據自己的需求去搜索
我們說了這些概念,事實上我認為你們都會了,那我們直接進入代碼環節吧
二.申請權限
權限你能夠申請單個,也能夠申請多個。我們一步步看,假設我們以打電話的權限為樣例。我們在清單文件里填寫電話權限
<uses-permission android:name="android.permission.CALL_PHONE"/>正常來講,我們僅僅須要調用這段打電話的代碼就能夠撥打電話了。全部我們寫了一個打電話的方法,可是他卻報錯了,那是由于我們使用的targetSdkVersion是25。大于23。全部他會檢查權限,也就是這樣
他警告我們須要去推斷權限。那我們就依照他的提示一步步來,首先推斷是否允許了該權限
//正常獲取權限private void checkPermissionForNormal() {//推斷是否允許此權限if (ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {//假設應用之前請求過此權限但用戶拒絕了請求,此方法將返回 trueif (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CALL_PHONE)) {Toast.makeText(this, "你之前拒絕過此權限", Toast.LENGTH_SHORT).show();} else {//申請權限ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 100);}} else {callPhone();}}這代碼看起來還是比較正常的,首先他會去檢查你當前的權限是否等于PackageManager.PERMISSION_GRANTED,0為成功,-1為失敗,假設他不等于0,那我就去檢查你之前是否請求過該權限,同一時候你點擊了拒絕。
注:假設用戶在過去拒絕了權限請求。并在權限請求系統對話框中選擇了 不再提醒 選項,此方法將返回 false。
假設設備規范禁止應用具有該權限,此方法也會返回 false。
好的,假設都沒有,那我就通過ActivityCompat的requestPermissions方法去請求權限,里面的幾個參數要注意一下,第一個是上下文,第二個是權限數組。也就是說他支持單個和多個權限的申請,第三個是回調的resultCode,我們來執行一下,看下他是怎樣申請的
好的,那我們如今來處理一下結果吧,實現一下onRequestPermissionsResult方法
//權限的回調@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {switch (requestCode) {case 100: {//返回的結果數組大于0說明有結果if (grantResults.length > 0//由于我們僅僅推斷了一個打電話的權限。全部是數組的0&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "允許了權限", Toast.LENGTH_SHORT).show();callPhone();} else {Toast.makeText(this, "拒絕了權限", Toast.LENGTH_SHORT).show();}return;}}}這段代碼的凝視也非常清楚。我們僅僅要推斷有結果,然后就能夠去做對應的。處理了,這個是單個的權限
我們再來看下多個權限的申請。首先是申請了
//正常獲取權限private void checkPermissionForNormal() {//推斷是否允許此權限if (ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED &&ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED &&ContextCompat.checkSelfPermission(this,Manifest.permission.SYSTEM_ALERT_WINDOW) != PackageManager.PERMISSION_GRANTED) {//申請權限ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.CAMERA, Manifest.permission.SYSTEM_ALERT_WINDOW}, 100);} }我在這里申請了一個電話。一個相機的權限。另一個窗體權限。那我們結果的處理怎樣呢
//權限的回調@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {switch (requestCode) {case 100: {if (grantResults.length > 0) {for (int i = 0; i < grantResults.length; i++) {if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "允許權限", Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "拒絕權限", Toast.LENGTH_SHORT).show();}}} else {Toast.makeText(this, "拒絕了權限", Toast.LENGTH_SHORT).show();}return;}}}相同的我們僅僅須要去推斷我們的返回值0或者-1就能夠了。那我們來看下終于的演示結果
這里要注意一點的就是你計算申請了執行時權限。你的清單文件里,也還是要加入加入對應的權限
<uses-permission android:name="android.permission.CALL_PHONE"/><uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>三.RxPermissions
RxPermissions是一個封裝的權限庫,由于使用比較簡單,全部我也提出來給大伙講講,地址能夠參考RxPermissions GitHub
先來說一下這個RxPermissions庫的集成工作,由于他是跟著RxJava一起的,假設要使用。還得加入RxJava,并且RxJava有兩個版本號,我們這里以RxJava2為樣例
加入依賴
//RxPermissionscompile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar'//RxJava2compile "io.reactivex.rxjava2:rxjava:2.0.0"他的使用假設用正常的RxJava語法。那就是這樣:
RxPermissions rxPermissions = new RxPermissions(MainActivity.this); rxPermissions.request(Manifest.permission.CALL_PHONE).subscribe(new Observer<Boolean>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Boolean value) {if(value){Toast.makeText(MainActivity.this, "允許權限", Toast.LENGTH_SHORT).show();}else {Toast.makeText(MainActivity.this, "拒絕權限", Toast.LENGTH_SHORT).show();}}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});這樣我們能夠申請到權限了。如圖
當然假設你使用lambda表達式,你會更爽的
RxPermissions rxPermissions = new RxPermissions(MainActivity.this); rxPermissions.request(Manifest.permission.CALL_PHONE).subscribe(granted -> {if (granted) {Toast.makeText(MainActivity.this, "允許權限", Toast.LENGTH_SHORT).show();} else {Toast.makeText(MainActivity.this, "拒絕權限", Toast.LENGTH_SHORT).show();}});四.權限封裝
關于權限的封裝事實上還是比較糾結的,我們分析下,首先推斷權限,是沒有什么問題的,申請權限也是沒有什么問題的,可是處理結果就麻煩了。他是在Activity的回調中,事實上在fragment也有這個回調處理。全部如今市面上比較多的就是fragment中處理。而我們上面的RxPermissions也是這樣處理的,我們看一下他的源代碼
private RxPermissionsFragment getRxPermissionsFragment(Activity activity) {RxPermissionsFragment rxPermissionsFragment = findRxPermissionsFragment(activity);boolean isNewInstance = rxPermissionsFragment == null;if (isNewInstance) {rxPermissionsFragment = new RxPermissionsFragment();FragmentManager fragmentManager = activity.getFragmentManager();fragmentManager.beginTransaction().add(rxPermissionsFragment, TAG).commitAllowingStateLoss();fragmentManager.executePendingTransactions();}return rxPermissionsFragment;}他把這個fragment add在這個activity中,然后再fragment中處理,說實話,挺巧妙的,那我們今天就換一種方式來處理。這就是我們的統配Activity中處理。而我如今教大家另一種封裝的方法。那就是實現一個Activity的基類,先看下我們怎樣去使用的
checkPermissions(new String[]{Manifest.permission.CALL_PHONE,Manifest.permission.CAMERA,}, 300, new PermissionsResultListener() {@Overridepublic void onSuccessful(int[] grantResults) {for (int i = 0; i < grantResults.length; i++) {if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {Toast.makeText(MainActivity.this, "允許權限", Toast.LENGTH_SHORT).show();} else {Toast.makeText(MainActivity.this, "拒絕權限", Toast.LENGTH_SHORT).show();}}}@Overridepublic void onFailure() {Toast.makeText(MainActivity.this, "失敗", Toast.LENGTH_SHORT).show();} });能夠發現,這里我們就一行代碼。checkPermissions調用,里面的參數一個是權限數組,一個是返回碼,另一個是回調,那怎樣去做呢。事實上就是實現一個接口
public interface PermissionsResultListener {//成功void onSuccessful(int[] grantResults);//失敗void onFailure(); }以及在PermissionsActivity中完畢它的操作。只是有一個弊端就是須要繼承PermissionsActivity。全部我們要寫我們的checkPermissions方法,就須要繼承這個PermissionsActivity,而這里面的代碼說不上難
public class PermissionsActivity extends AppCompatActivity {private PermissionsResultListener mListener;private int mRequestCode;private List<String> mListPermissions = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}protected void checkPermissions(String[] permissions, int requestCode, PermissionsResultListener listener) {//權限不能為空if (permissions != null || permissions.length != 0) {mListener = listener;mRequestCode = requestCode;for (int i = 0; i < permissions.length; i++) {if (!isHavePermissions(permissions[i])) {mListPermissions.add(permissions[i]);}}//遍歷完后申請applyPermissions();}}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == mRequestCode) {if (grantResults.length > 0) {mListener.onSuccessful(grantResults);} else {mListener.onFailure();}}}//推斷權限是否申請private boolean isHavePermissions(String permissions) {if (ContextCompat.checkSelfPermission(this, permissions) != PackageManager.PERMISSION_GRANTED) {return false;}return true;}//申請權限private void applyPermissions() {if (!mListPermissions.isEmpty()) {int size = mListPermissions.size();ActivityCompat.requestPermissions(this, mListPermissions.toArray(new String[size]), mRequestCode);}} }這就是我們的權限封裝了,到這里你應該明白或者說掌握了執行時權限的絕大部分操作吧,我們執行一下看下
Sample下載
有興趣的加群討論:555974449
付費群
總結
以上是生活随笔為你收集整理的Android6.0执行时权限解析,RxPermissions的使用,自己封装一套权限框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 资源读取配置
- 下一篇: Android推送进阶课程学习笔记