Android 6.0動(dòng)態(tài)權(quán)限申請(qǐng)

概述

Google在 Android 6.0 開始引入了權(quán)限申請(qǐng)機(jī)制,將所有權(quán)限分成了正常權(quán)限和危險(xiǎn)權(quán)限。應(yīng)用的相關(guān)功能每次在使用危險(xiǎn)權(quán)限時(shí)需要?jiǎng)討B(tài)的申請(qǐng)并得到用戶的授權(quán)才能使用。

權(quán)限分類

系統(tǒng)權(quán)限分為兩類:正常權(quán)限和危險(xiǎn)權(quán)限。

  • 正常權(quán)限不會(huì)直接給用戶隱私權(quán)帶來風(fēng)險(xiǎn)。如果您的應(yīng)用在其清單中列出了正常權(quán)限,系統(tǒng)將自動(dòng)授予該權(quán)限。
  • 危險(xiǎn)權(quán)限會(huì)授予應(yīng)用訪問用戶機(jī)密數(shù)據(jù)的權(quán)限。如果您的應(yīng)用在其清單中列出了正常權(quán)限,系統(tǒng)將自動(dòng)授予該權(quán)限。如果您列出了危險(xiǎn)權(quán)限,則用戶必須明確批準(zhǔn)您的應(yīng)用使用這些權(quán)限。
危險(xiǎn)權(quán)限和權(quán)限組

重要方法

  • ContextCompat.checkSelfPermission
    檢查應(yīng)用是否具有某個(gè)危險(xiǎn)權(quán)限。如果應(yīng)用具有此權(quán)限,方法將返回 PackageManager.PERMISSION_GRANTED,并且應(yīng)用可以繼續(xù)操作。如果應(yīng)用不具有此權(quán)限,方法將返回 PackageManager.PERMISSION_DENIED,且應(yīng)用必須明確向用戶要求權(quán)限。

  • ActivityCompat.requestPermissions
    應(yīng)用可以通過這個(gè)方法動(dòng)態(tài)申請(qǐng)權(quán)限,調(diào)用后會(huì)彈出一個(gè)對(duì)話框提示用戶授權(quán)所申請(qǐng)的權(quán)限。

  • ActivityCompat.shouldShowRequestPermissionRationale
    如果應(yīng)用之前請(qǐng)求過此權(quán)限但用戶拒絕了請(qǐng)求,此方法將返回 true。如果用戶在過去拒絕了權(quán)限請(qǐng)求,并在權(quán)限請(qǐng)求系統(tǒng)對(duì)話框中選擇了 Don't ask again 選項(xiàng),此方法將返回 false。如果設(shè)備規(guī)范禁止應(yīng)用具有該權(quán)限,此方法也會(huì)返回 false。

  • onRequestPermissionsResult
    當(dāng)應(yīng)用請(qǐng)求權(quán)限時(shí),系統(tǒng)將向用戶顯示一個(gè)對(duì)話框。當(dāng)用戶響應(yīng)時(shí),系統(tǒng)將調(diào)用應(yīng)用的 onRequestPermissionsResult() 方法,向其傳遞用戶響應(yīng),處理對(duì)應(yīng)的場(chǎng)景。

示例

本示例在Google示例的基礎(chǔ)上做了少許修改,步驟如下:

1、在AndroidManifest.xml中添加所需權(quán)限。

<uses-permission android:name="android.permission.READ_CONTACTS" />

2、封裝了一個(gè)requestPermission方法來動(dòng)態(tài)檢查和申請(qǐng)權(quán)限

    private void requestPermission() {

        Log.i(TAG,"requestPermission");
        // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            Log.i(TAG,"checkSelfPermission");
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.READ_CONTACTS)) {
                Log.i(TAG,"shouldShowRequestPermissionRationale");
                // Show an expanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.READ_CONTACTS},
                        MY_PERMISSIONS_REQUEST_READ_CONTACTS);

            } else {
                Log.i(TAG,"requestPermissions");
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.READ_CONTACTS},
                        MY_PERMISSIONS_REQUEST_READ_CONTACTS);
                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }
    }

3、重寫onRequestPermissionsResult方法根據(jù)用戶的不同選擇做出響應(yīng)。

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.i(TAG,"onRequestPermissionsResult granted");
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.

                } else {
                    Log.i(TAG,"onRequestPermissionsResult denied");
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    showWaringDialog();
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

    private void showWaringDialog() {
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("警告!")
                .setMessage("請(qǐng)前往設(shè)置->應(yīng)用->PermissionDemo->權(quán)限中打開相關(guān)權(quán)限,否則功能無法正常運(yùn)行!")
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 一般情況下如果用戶不授權(quán)的話,功能是無法運(yùn)行的,做退出處理
                finish();
            }
        }).show();
    }

RxPermissions

官方提供的方法在一次申請(qǐng)多個(gè)權(quán)限的時(shí)候代碼邏輯寫起來比較繁瑣,于是有了RxPermissions。RxPermissions是使用Rxjava封裝的第三方的權(quán)限申請(qǐng)庫,他的特點(diǎn)是借助Rxjava的特性簡(jiǎn)化了權(quán)限申請(qǐng)的代碼邏輯,使代碼看起來簡(jiǎn)潔易讀。具體的使用方法可以參看《RxPermissions獲取運(yùn)行時(shí)權(quán)限》,里面寫的比較詳細(xì)。

參考文獻(xiàn)

Google Doc:在運(yùn)行時(shí)請(qǐng)求權(quán)限
Google Doc:正常權(quán)限和危險(xiǎn)權(quán)限
權(quán)限分類:正常權(quán)限和危險(xiǎn)權(quán)限
Android6.0動(dòng)態(tài)權(quán)限申請(qǐng)步驟以及需要注意的一些坑
Android6.0------權(quán)限申請(qǐng)管理(單個(gè)權(quán)限和多個(gè)權(quán)限申請(qǐng))
android6.0運(yùn)行時(shí)權(quán)限詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容