Android工具箱之Android 6.0權限管理

這是一個系列,咱們將其命名爲工具箱,若是你尚未看以前的文章:android

Android工具箱之Context解析segmentfault

Android工具箱之文件目錄網絡

Android工具箱之組織你的代碼文件app

Android工具箱之理解app資源文件async

Android工具箱之Activity生命週期ide

Android工具箱之遷移到AppCompat工具

概述

默認狀況下,一個Android app是不會獲取任何權限的。當你的app須要使用任何被設備保護起來的特性的時候(好比發送網絡請求,訪問照相機,發送短信等),其必須從用戶那兒獲取到相關的權限。ui

Android 6.0以前的權限管理

在Android6.0以前,開發者獲取設備權限很是的簡單,全部的權限會在安裝的時候處理。好比一個用戶想要安裝一個app,那麼在安裝以前,Android系統會彈出一個對話框,讓你可以瀏覽該應用獲取你設備的哪些權限,好比Dropbox:this

圖片描述

對於開發者而言,若是你想獲取權限,只須要在AndroidManifest.xml文件中申明。舉個栗子,獲取聯繫人權限:spa

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.app.myapp" >
    
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    ...
</manifest>

用戶在安裝完之後沒有任何更改權限的機會。雖然讓開發者更方便的處理權限,可是對於用戶來講,是個很差的體驗。

Android 6.0的權限管理

最顯著的改變是Android 6.0支持用戶隨時的更改app權限,隨時的含義包括app正在運行。6.0的設備會分兩種權限。

常規權限

何爲常規權限,即你只須要在xml中申明,用戶不會彈出任何讓其選擇是否開啓權限的彈窗,即靜默權限。這些權限包括:網絡訪問,獲取網絡狀態等。注意:常規的權限,你必需要在xml中申明。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.app.myapp" >
    
    <uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>

運行時權限

若是你想獲取的權限不在常規權限列表中,你須要進行運行時權限處理。即你須要在代碼中動態的獲取權限,系統會彈出對話框供用戶選擇:

圖片描述

那麼如何定義運行權限呢?其實和常規權限是同樣的,你須要首先在xml中申明:

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

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

接下來,你須要申請權限,而後處理結果。下面的代碼將會爲你展現這些步驟:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // In an actual app, you'd want to request a permission when the user performs an action
        // that requires that permission.
        getPermissionToReadUserContacts();
    }

    // Identifier for the permission request
    private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1;

    // Called when the user is performing an action which requires the app to read the
    // user's contacts
    public void getPermissionToReadUserContacts() {
        // 1) Use the support library version ContextCompat.checkSelfPermission(...) to avoid
        // checking the build version since Context.checkSelfPermission(...) is only available
        // in Marshmallow
        // 2) Always check for permission (even if permission has already been granted)
        // since the user can revoke permissions at any time through Settings
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {

            // The permission is NOT already granted.
            // Check if the user has been asked about this permission already and denied
            // it. If so, we want to give more explanation about why the permission is needed.
            if (shouldShowRequestPermissionRationale(
                    Manifest.permission.READ_CONTACTS)) {
                // Show our own UI to explain to the user why we need to read the contacts
                // before actually requesting the permission and showing the default UI
            }

            // Fire off an async request to actually get the permission
            // This will show the standard permission request dialog UI
            requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
                    READ_CONTACTS_PERMISSIONS_REQUEST);
        }
    }

    // Callback with the request from calling requestPermissions(...)
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        // Make sure it's our original READ_CONTACTS request
        if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
            if (grantResults.length == 1 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Read Contacts permission granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

權限Groups

當一個app須要大量的權限的時候,若是讓開發者每次須要使用權限而彈出對話框,顯示是權限的濫用。而權限羣容許app在某一時間點同時申請多個權限。可是注意,大多數狀況下,你仍是應該單獨的去獲取單一的權限,可是好比下面這個栗子:當你須要獲取聯繫人讀的權限,你向用戶申請,而當你讀完以後,你須要寫的權限,那麼你又要向用戶申請,這樣你能夠爲它們設置權限羣,當你申明讀權限的同時,申請寫的權限,這樣以後你就不用再次申請寫的權限了。

相關文章
相關標籤/搜索