天天看點

Android permission 動态申請、授權Android permission 新特性深度學習

原文: 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給出的有,

Android permission 動态申請、授權Android permission 新特性深度學習

權限的賦予

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

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,用來區分是申請哪個權限,該函數會彈出一個對話框,詢問使用者是否授權該權限,

Android permission 動态申請、授權Android permission 新特性深度學習

使用者可以選擇授權或取消,那麼我們如何知道使用者的選擇呢,這就要求我們重載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

繼續閱讀