Android permission 動態申請、授權

Android permission 新特性深度學習

本篇文章介紹android permission系統,並介紹android 6.0 permission的新特性,包括權限動態申請和授權等。

permission system

Android開發者都知道,我們開發的應用默認是沒有任何權限的,我們沒有辦法聯網,沒有辦法進行外部空間存儲(內部空間是可以的),除非我們申請了相應的權限(permission)。

比如,我們在Manifest文件中,加入以下語句,我們就可以在我們的應用中連接到網絡。

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

那麼,android爲什麼要這麼設計呢?筆者認爲,這樣的設計的最大好處是,由於手機上存儲了用戶的大量隱祕信息,對於Android的用戶來說,每次安裝App時,都會提示用戶該App擁有什麼權限,這樣用戶對該App就有了大概的認識,該App可能會進行什麼操作,會不會竊取我的隱私等(當然,普通的Android用戶是沒有這個意識的)。

Android將所有的權限分爲了兩種,一種是Normal,另一種是Dangerous. 關於兩者,Developer是這麼介紹的,

Normal permissions cover areas where your app needs to access data or resources outside the app’s sandbox, but where there’s very little risk to the user’s privacy or the operation of other apps. For example, permission to set the time zone is a normal permission. If an app declares that it needs a normal permission, the system automatically grants the permission to the app.

總的來說,normal類型的權限會泄露用戶的風險會很少,所以Android會默認賦予這些權限。

Dangerous permissions cover areas where the app wants data or resources that involve the user’s private information, or could potentially affect the user’s stored data or the operation of other apps. For example, the ability to read the user’s contacts is a dangerous permission. If an app declares that it needs a dangerous permission, the user has to explicitly grant the permission to the app.

而Dangerous權限是怎樣的呢?該類型的權限泄露用戶隱私的風險會很大,例如,讀取用戶的通訊錄。
關於Dangerous類的權限,Developer給出的有,
這裏寫圖片描述

權限的賦予

上邊介紹了危險權限是要用戶的允許才能使用的,

before 6.0

在Android 6.0之前,這些權限的賦予是在用戶安裝App的時候,用戶可以選擇賦予該權限,然後安裝App,但是如果用戶不賦予的話,那麼該App就無法安裝,這就是所謂的All or Nothing。當然,這是原生系統的特性,據我所知,小米、魅族定製的系統已經可以動態賦予權限。

after 6.0

Android 6.0對該特性進行了修改,畢竟All or Nothing的機制存在較大的弊端,很多用戶爲了使用該App,就同意了所有權限,並且無法對其進行控制,這樣就顯得權限的作用並沒有顯現出來。所以Android 6.0 允許了動態賦予權限。

Developer對其的說明如下,

If the device is running Android 6.0 (API level 23) or higher, and the app’s targetSdkVersion is 23 or higher, the app requests permissions from the user at run-time. The user can revoke the permissions at any time, so the app needs to check whether it has the permissions every time it runs

如果你的設備的Android版本在6.0之上,並且App的目標sdk版本在23之上,那麼用戶就可以對其權限進行動態賦予。而其他情況下,用戶無法動態賦予權限,還是All or Nothing。要不全部賦予,要不就不安裝。

那麼如何使用該新特性呢?

Check For Permissions

Develper的解釋如下,

If your app needs a dangerous permission, you must check whether you have that permission every time you perform an operation that requires that permission. The user is always free to revoke the permission, so even if the app used the camera yesterday, it can’t assume it still has that permission today.

如果我們的應用包括危險權限,那麼我們在每次執行對應的操作的時候,就應該檢查是否被授予該權限。因爲用戶可以隨時取消App的某個權限,所以我們應該每次都要檢查用戶是否賦予了該權限。否則,就會崩潰。

該函數的用法如下,

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.WRITE_CALENDAR);

如果用戶賦予了該權限,那麼該方法會返回PackageManager.PERMISSION_GRANTED,然後我們就可以繼續我們的操作;否則會返回PERMISSION_DENIED。如果返回PERMISSION_DENIED,我們就無法直接進行我們的操作,因爲我們沒有權限。那麼應該怎麼辦呢?此時,我們應該顯式的申請權限。

那麼怎麼顯示的申請權限呢?這就用到下面的函數,

requestPermissions

當我們發現,我們的應用沒有被授予某個權限的時候,我們就可以顯示的申請。
一個例子如下,

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

其中MY_PERMISSIONS_REQUEST_READ_CONTACTS是設置的requestCode,用來區分是申請哪個權限,該函數會彈出一個對話框,詢問用戶是否授權該權限,
這裏寫圖片描述

用戶可以選擇授權或取消,那麼我們如何知道用戶的選擇呢,這就要求我們重載Acitivity的一個接口,

    @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.
                    System.out.println("User granted permission");

                } else {
                    System.out.println("User didn't grante permission");

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

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

我們根據requestCode來區分申請的權限。當用戶選擇後,就會回調該接口,我們就可以知道用戶的選擇,進而執行下一步操作。

文中的例子,可以通過以下方式獲得,
https://github.com/KingPaul/DynamicPermissionDemo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章