Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> app在android 6.0或以上平台版本運行過程中請求權限

app在android 6.0或以上平台版本運行過程中請求權限

編輯:關於Android編程

前言


從android 6.0(API 23)開始,安裝app時不需要對app的權限申請進行授權,而是在app運行的時候,用戶才需要對app進行授權。這種流程精簡了app的安裝過程,用戶不需要在安裝或者升級app的時候進行授權操作。這同樣也給了用戶更多對app功能的控制能力;例如,用戶可以選擇給一個照相app訪問攝像頭的權限,但不給它訪問設備地理位置的權限。用戶也可以通過app的設置界面,隨時撤銷對app授予的權限。

系統權限可以被分為兩大類,普通權限和危險權限:

普通權限不會引起用戶隱私洩露的風險。如果你的app在manifest文件中列舉了一個普通權限,系統會自動對申請的普通權限直接授權。 危險權限允許app訪問用戶的機密信息。如果的你app在它的manifest中列舉了一個普通權限,系統會自動授權。但如果你列舉的是一個危險權限,用戶就必須明確處理是否授權給你的app。

更多相關信息,請參考普通權限和危險權限。

無論是哪個android版本,你的app都必須在它的manifest文件上聲明它需要的所有普通權限和危險權限,詳情請參考聲明權限。只不過,聲明權限的結果因系統版本和app的target SDK不同而不同:

如果設備運行在android 5.1或者更低版本的系統上,或者app的target SDK是22或者更低:如果你的app在它的manifest文件中聲明了一個危險權限,那麼用戶在安裝app的時候就必須授權這個危險權限給你的app;如果用戶不同意授予這個權限,系統就拒絕安裝這個app。 如果設備運行在android 6.0或者更高的系統版本上,並且app的target SDK是23或者更高:app必須在manifest文件中聲明所有需要的權限,並且在app運行的過程中必須請求用戶對每個使用到的危險權限進行授權。用戶可以選擇授權或者拒絕每一個權限,如果用戶拒絕了授權,app同樣可以繼續運行,只是對應的功能無法使用。

注意: 從android 6.0(API 23)開始,不管app的target SDK是不是低版本的SDK,用戶都可以隨時取消任意app已經授權過的權限。不管你的app是什麼target SDK版本,當你的app缺少一個需要的權限時,你都應該測試的app功能是否正常。

本章節內容將探討如何使用android support library來檢查和請求權限。android的framework在android 6.0(API 23)版本上提供了類似的方法。不過,相對來說使用support library的方法會比較簡單,因為這樣你的app在調用這些方法之前就不需要檢查當前運行的android系統版本是多少。

 

檢查權限


如果你的app需要一個危險權限,那麼你每次執行需要這個危險權限的操作時,你都必須檢查是否已經申請到這個權限。用戶隨時都可以撤銷授予過的權限,因此,盡管一個app昨天可以正常使用攝像頭,但不代表今天仍然擁有使用攝像頭的權限。

檢查你的app是否擁有過一個權限,需要調用ContextCompat.checkSelfPermission()方法。例如,下面的代碼片段檢查了activity是否擁有寫日歷的權限:

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

如果app擁有這個權限,方法會返回PackageManager.PERMISSION_GRANTED,app可以繼續執行相關操作。如果app不具備該權限,方法會返回PERMISSION_DENIED,app需要明確請求用戶授予該權限。

 

申請權限


如果你的app需要使用一個在它的manifest文件中聲明的危險權限,那麼在使用之前它必須請求用戶授予該權限。android提供了一系列方法供你申請權限。請求這些方法會喚起一個標准的android對話框,這個對話框你不能自定義。

解釋app為什麼需要權限

在一些情況下,你可能想要幫助用戶理解為什麼你的app需要一個權限。例如,如果用戶啟動一個攝影app,用戶應該對app請求使用攝像頭的權限不會感到驚訝,但是用戶可能無法理解為什麼app還要求訪問設備的地理位置和通訊錄。在你申請一個權限之前,你應該考慮給用戶提供一個解釋。但是要注意不要用解釋過多騷擾用戶;如果你提供了太多的解釋,用戶可能會厭煩你的app並且卸載掉。

只有在用戶已經拒絕了權限請求的情況下,你才有可能需要向用戶提供一個解釋。如果用戶繼續嘗試使用需要申請權限的功能,但是這個權限之前已經被用戶拒絕,這就說明用戶可能不清楚為什麼app的這個功能需要申請權限。類似這樣的情況,那麼顯示一個權限申請解釋就是一種很好的解決方法。

為了幫助判斷用戶在什麼情況下需要一個權限解釋,android提供了一個工具方法,ActivityCompat.shouldShowRequestPermissionRationale()。如果app之前申請過一個權限,但這個權限被用戶拒絕了,這個方法就會返回true。

注意: 如果用戶在過去拒絕權限申請的同時還勾選了系統權限申請對話框中的不再詢問選項,這個方法也會返回false。如果是在設備權限設置中禁止了app使用的權限,用這個方法判斷這些權限同樣也會返回false。

申請你需要的權限

如果你的app目前不具備它所需要的權限,app必須調用requestPermissions()多個重載方法中的一個來申請適當的權限。這些方法中,你的app除了將所需要的權限作為參數傳遞進去之外,還需要傳遞一個整型值作為本次權限請求的標識碼。這些方法都是異步的:方法會直接返回,等到用戶響應對話框之後,系統才會回調app的回調方法把結果傳遞回來,結果中包括app調用requestPermissions()方法時傳遞進來的請求碼。

下面的代碼檢查app是否擁有讀取用戶聯系人的權限,如果沒有,在需要的時候會申請權限:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // 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.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                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.
    }
}

注意: 當你的app調用requestPermissions()方法時,系統會彈出一個標准的對話框給用戶。你的app無法配置或者修改這個對話框。如果你需要向用戶提供一些的信息或者解釋,你應該在調用requestPermissions()方法之前進行這些操作,請參考上面小節解釋app為什麼需要權限

處理權限請求的響應

當你的app申請權限之後,系統會顯示一個對話框給用戶。當用戶響應之後,系統會回調你的app的onRequestPermissionsResulet()方法,將響應結果傳遞過來。你的app必須重寫這個方法來判斷申請的權限是否被授予了。回調方法會接收到與你傳遞到requestPermissions()方法中相同的請求碼。例如,如果一個app請求READ_CONTACTS訪問權限,它可能需要以下的響應代碼:

@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
    }
}

這個系統顯示的對話框會描述你的app需要訪問的權限組,它不會列舉具體使用到的哪一個權限。例如,如果你請求READ_CONTACTS權限,系統對話框只會描述你的app需要訪問設備的通訊錄。用戶只需要對每一個權限組授權一次。一旦對一個權限組授權之後,如果你的app請求同一個權限組中的其它權限(同樣也要在app的manifest文件聲明),系統會自動授予這些權限。當你請求這些同個權限組中的其它權限時,系統也會回調你的onRequestPermissionsResult()方法並傳遞PERMISSION_GRANTED參數,回調的結果就跟用戶已經通過系統對話框明確同意你的權限申請一樣。

注意: 你的app仍然需要明確請求每一個它需要的權限,不過用戶是否已經同意授權同個權限組中的其它權限。此外,每個權限組包含的權限在未來android的發布版中也有可能會變化。你的代碼邏輯不應該建立在使用到的幾個權限是否被包含在同一個權限組中的假設之上。

例如,假設你在app的manifest中聲明了READ_CONTACTS和WRITE_CONTACTS權限。如果你已經請求過READ_CONTACTS權限並且用戶通過授權申請,當你再請求WRITE_CONTACTS權限時,系統會立即把這個權限也授權給app,不需要再與用戶進行授權交互。

如果用戶拒絕了你的權限申請,你的app應該采取適當的響應操作。例如,你的app可能需要顯示一個對話框來解釋為什麼你的app無法繼續執行下去的原因是需要被用戶拒絕的權限。

當系統請求用戶授權時,用戶可以選擇告訴系統需要再次請求這個權限。在這種情況下,無論app調用多少次requestPermissions()方法來申請權限,系統都會直接決絕申請。系統會回調你的onRequestPermissionsResult()回調方法並且傳遞PERMISSION_DENIED參數值,整個回調過程就跟用戶已經直接明確拒絕你的權限申請一樣。這意味著當你調用requestPermissions()方法時,你不能假設與用戶直接交互的操作一定會發生。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved