簡單幾行程式碼申請許可權

SamanLan發表於2017-12-13

眾所周知,在Android6.0以上增加了動態申請許可權這玩意(targetSdkVersion >= 23)。 那麼問題來了,what?when?how?

What:

在targetSdkVersion <23,當使用者安裝App時,App會索要了你手機的那些許可權,並且給用一個列表進行展示,但是這些提示只是在安裝是提示,只要你點選接受或者安裝, 表示你允許這個應用在可以獲取它申明的所有許可權。一般很少有人在安裝時,會因為看到某個應用因為申請了某一個敏感許可權而放棄安裝應用。(實力幫應用寶打廣告)

舊許可權顯示.jpg

那麼當使用者使用過程中,正準備使用某個許可權時,系統能及時的彈出一個提示框是否允許。然後使用者結合當前應用判斷,是否應該授予應用許可權。nice。 這樣對使用者而言,完全是主動的,相比安裝時那種選擇,這樣的做法無疑是對使用者莫大的尊重,同時這也保證了使用者的個人隱私。

許可權彈出申請.png

故谷歌爸爸自然而然就產出了這個動態申請許可權,雖然對於程式設計師來說多了一部分程式碼,但正如一句話所說尊重使用者才會贏得使用者

When:

不用想的好嗎?你要用到許可權的時候申請

How:

用到的API也不多就幾個


#####上面說到對於使用者是友好的,對於程式設計師是多增加了程式碼的,當然程式設計師都是懶惰的,那麼一個良好的對申請封裝是顯得多麼的重要與節省功夫、時間。

  1. 上GitHub搜一搜,大多數的封裝都是直接在BaseActivity進行操作,不是說不可以,當然會存在一點耦合度。
  2. 還看到一個RxPermission,思想就是當下火火的Rx。也是相當不錯。但問題又來了,假如專案中沒有用到Rx呢?又要加入RxJava和RxAndroid兩個庫,顯得有點不值得。
  3. 為了將程式碼從activity中抽離,同時為了在fragment(或者fragment中巢狀fragment)中申請許可權不用進行繁瑣的操作,故本次封裝並沒有選擇在BaseActivity中進行封裝。 程式碼連結,看得歡喜歡迎給個star

簡單使用,一個鏈式讓你調下來(注:內部已進行版本判斷,無需再進行判斷)

PermissionsUtils mPermissionsUtils=new PermissionsUtils();

public void 申請(){
    mPermissionsUtils
                // 設定回撥
                .setPermissionsListener(new PermissionsListener() {
                    // 申請的許可權中有被拒絕的回撥該方法,可以在此進行你的邏輯
                    // 由於某些rom對許可權進行了處理,第一次選擇了拒絕,則不會出現第二次詢問(或者沒有不再詢問勾選),故拒絕就回撥onDenied
                    @Override
                    public void onDenied(String[] deniedPermissions) {
                        // 在deniedPermissions裡面包含了所有被拒絕的許可權名字
                        for (int i = 0; i < deniedPermissions.length; i++) {
                            System.out(deniedPermissions[i] + " 許可權被拒絕");
                        }
                    }

                    // 所有申請的許可權同意了回撥該方法,可以在此進行你的邏輯
                    @Override
                    public void onGranted() {
                        Toast.makeText(MainActivity.this, "所有許可權都被同意", Toast.LENGTH_SHORT).show();
                    }
                })
                // 設定Activity,因為檢查許可權必須要有activity物件
                .withActivity(this)
                // 最後呼叫申請許可權的方法
                // 三個引數分別是Object,int,String[]
                // 第一個引數對應的是activity或者fragment,如果是在activity中申請就傳入activity物件,在fragment申請就傳入該fragment物件,這是用於對返回事件的分發進行處理。
                // 第二個對應的是該次申請許可權的requestCode
                // 第三個就是許可權列表,不定長度
                .getPermissions(MainActivity.this,100, Manifest.permission.READ_CONTACTS);
                // 例如申請多個許可權
                /*.getPermissions(MainActivity.this
                        , 100
                        , Manifest.permission.INTERNET
                        , Manifest.permission.READ_EXTERNAL_STORAGE
                        , Manifest.permission.READ_CALENDAR
                        , Manifest.permission.ACCESS_FINE_LOCATION);*/
}

// 在activity或者fragment中
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // 在onRequestPermissionsResult這個方法呼叫dealResult就可以了
        mPermissionsUtils.dealResult(requestCode, permissions, grantResults);
    }
複製程式碼
主要方法 作用
getPermissions 進行許可權申請,不帶拒絕彈框提示
getPermissionsWithTips 進行許可權申請,帶拒絕彈框提示
dealResult 對申請許可權返回結果進行處理
setPermissionsListener 設定回撥
getAppDetailSettingIntent 跳轉到本應用的設定介面

上面的getPermissionsWithTips是什麼鬼?其實是對被拒絕許可權後一個彈窗,免得大家重複寫,可用可不用 怎麼用?很簡單,傳入提示陣列即可

mPermissionsUtils.getPermissionsWithTips(MainActivity.this
                        ,100
                        , new String[]{"人家要錄音"
                                ,"我們需要讀取你的資訊,磨磨唧唧的"
                                ,"我要上網"
                                ,"我要讀記憶體卡"
                                ,"我要看日曆"
                                ,"我要定位"}
                        , Manifest.permission.RECORD_AUDIO
                        , Manifest.permission.READ_SMS
                        , Manifest.permission.INTERNET
                        , Manifest.permission.READ_EXTERNAL_STORAGE
                        , Manifest.permission.READ_CALENDAR
                        , Manifest.permission.ACCESS_FINE_LOCATION);
複製程式碼

使用者拒絕許可權後效果圖如下

簡單幾行程式碼申請許可權

我有問題要問

● 在6.0所有許可權都需要申請?

曰:當然不是。只有屬於危險許可權的才需要申請。危險許可權看下表1-2

● 那危險許可權也很多啊,也要一個個申請?

曰:當然不是。你看看下面的表,都分好組了(9組),對於同一組內的許可權,只要有一個被同意,其他的都會被同意。

表1-2危險許可權分組

分組 名字 分割線 分組 名字
CALENDAR READ_CALENDAR PHONE READ_PHONE_STATE
WRITE_CALENDAR CALL_PHONE
CAMERA CAMERA READ_CALL_LOG
CONTACTS READ_CONTACTS WRITE_CALL_LOG
WRITE_CONTACTS ADD_VOICEMAIL
GET_ACCOUNTS USE_SIP
LOCATION ACCESS_FINE_LOCATION PROCESS_OUTGOING_CALLS
ACCESS_COARSE_LOCATION SMS SEND_SMS
MICROPHONE RECORD_AUDIO RECEIVE_SMS
SENSORS BODY_SENSORS READ_SMS
STORAGE READ_EXTERNAL_STORAGE RECEIVE_WAP_PUSH
WRITE_EXTERNAL_STORAGE RECEIVE_MMS

再次奉上九組許可權

<!-- 危險許可權 start -->
<!--PHONE-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.ADD_VOICEMAIL"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<uses-permission android:name="android.permission.USE_SIP"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<!--CALENDAR-->
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<!--CAMERA-->
<uses-permission android:name="android.permission.CAMERA"/>
<!--CONTACTS-->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!--LOCATION-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!--MICROPHONE-->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--SENSORS-->
<uses-permission android:name="android.permission.BODY_SENSORS"/>
<!--SMS-->
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<!--STORAGE-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 危險許可權 Permissions end -->
複製程式碼

程式碼邏輯非常簡單,行數不多,註釋也很全,直接去看原始碼就行 程式碼連結,看得歡喜歡迎給個star

相關文章