Android6.0 權限管理學習

1、前言

Android M 開始,App不會在安裝的時候授予權限,而是在運行時一個一個的詢問用戶授予權限。html

1. 運行時權限僅當咱們設置targetSdkVersion >= 23才起做用,固然還要是M系統的手機。app在6.0以前的設備依然使用舊的權限系統。java

2. 若是app的targetSdkVersion < 23,或者手機版本  < 6.0 ,那將被認爲app沒有用23新權限測試過,那將被繼續使用舊有規則:用戶在安裝的時候不得不接受全部權限,安裝後app就有了那些權限咯!android

注意,此時用戶依然能夠取消已經贊成的受權!用戶取消受權時,android 6.0系統會警告,但這不妨礙用戶取消受權。app

當咱們在targetSdkVersion 低於23的App調用一個須要權限的函數時,這個權限若是被用戶取消受權了的話,不拋出異常。可是他將啥都不幹,結果致使函數返回值是null或者0。ide

2、官網流程翻譯函數

官網:https://developer.android.com/training/permissions/index.html測試

1. Declaring Permissions 聲明權限

 在AndroidManifest.xml中聲明this

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.snazzyapp">

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

    <application ...>
        ...
    </application>
</manifest>

權限分正常和危險兩種,正常的權限和之前同樣,只須要在Manifest.xml中聲明便可,在App安裝時,自動分配權限,且用戶也不能夠在設置中取消權限;危險權限須要運行時申請。spa

權限組,將危險權限分組,同一個組裏的任何一個權限被受權了,其餘權限也自動被受權。翻譯

下面是權限表格

Permission Group Permissions
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE

 

2. Requesting Permissions at Run Time 運行時申請權限

(1)  檢測是否已經受權

/**
  * Determine whether <em>you</em> have been granted a particular permission.
  *
  * @param permission The name of the permission being checked.
  *
  * @return {@link PackageManager#PERMISSION_GRANTED} if you have the
  * permission, or {@link PackageManager#PERMISSION_DENIED} if not.
  *
  * @see PackageManager#checkPermission(String, String)
  * @see #checkCallingPermission(String)
  */
checkSelfPermission(String)

(2) 請求權限

shouldShowRequestPermissionRationale() 判斷是否須要爲權限申請向用戶友好提示

返回true,上次申請權限,用戶選擇拒絕。

返回false

第一次申請,或上次申請權限,用戶選擇拒絕,並選擇了「不在提醒」的選項;

設備的策略禁止當前應用獲取這個權限的受權。

注意:第二次請求權限時,纔會有「不在提醒」的選項,若是用戶一直拒絕,並無選擇「不在提醒」的選項,下次請求權限時,會繼續有「不在提醒」的選項。

顯示權限說明:是根據你的應用中使用的權限分類來的:

1.用戶容易知道應用須要獲取的權限:如一個拍照應用,須要攝像頭的權限,是很正常,不用提示。

2.一些用戶感受困惑的一些權限:如:分享圖片,還須要獲取位置的權限,這個須要提示用戶:爲何須要這個權限。

處理 「再也不提醒」

若是用戶拒絕某受權。下一次彈框,用戶會有一個「再也不提醒」的選項的來防止app之後繼續請求受權。

若是這個選項在拒絕受權前被用戶勾選了。下次爲這個權限請求requestPermissions時,對話框就不彈出來了,結果就是,app啥都不幹。
這將是不好的用戶體驗,用戶作了操做卻得不到響應。這種狀況須要好好處理一下。

final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
 
private void insertDummyContactWrapper() {
    int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
    if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
            if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
                showMessageOKCancel("You need to allow access to Contacts",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(new String[] 
{Manifest.permission.WRITE_CONTACTS},
                                        REQUEST_CODE_ASK_PERMISSIONS);
                            }
                        });
                return;
            }
        requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
                REQUEST_CODE_ASK_PERMISSIONS);
        return;
    }
    insertDummyContact();
}

(3) 處理請求返回結果

@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) {

                // permission was granted, yay! 
                // Do the contacts-related task you need to do.

            } else {

                // permission denied, boo! 
                // Disable the functionality that depends on this permission.
            }
            return;
        }

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

3. Permissions Best Practices 權限申請最佳實踐

1. 若是不須要對數據有特別的控制權的話,能夠採起用Intent呼起系統應用的方式來避免申請權限,好比Camera、contacts、phone call,都是能夠直接調用系統app的。

注意打電話操做雖然是用的Intent方式,若是是這樣的寫法context.startActivity(new Intent("android.intent.action.CALL", Uri.parse(formatter.format(tel)))); 也要申請權限;若是是用的 android.intent.action.DIAL來調起的話,就不須要。

2. 只申請須要的權限,且只在須要的時候申請。

相關文章
相關標籤/搜索