Android 6.0 運行時許可權處理,android6.0
在運行時請求許可權
從Android 6.0(API層級23)開始,使用者權限授予應用程式在應用程式運行時,當他們安裝程式。這種方法簡化了應用程式的安裝過程,因為使用者不需要安裝或更新應用程式時授予許可權。這也給了使用者更多的控制應用程式的功能;例如,一個使用者可以選擇給相機應用程式訪問相機而不是裝置的位置。使用者可以隨時撤銷許可權,通過將應用程式的設定螢幕。
系統許可權分為兩類,普通和危險:
- 正常的許可權不直接使用者的隱私風險。如果你的應用程式資訊清單列出了一個正常的許可權,系統自動授予許可。
- 危險的許可權可以給應用程式訪問使用者的機密資料。如果你的應用程式資訊清單列出了一個正常的許可權,系統自動授予許可。如果你列出一個危險的許可,使用者必須顯式地給應用程式審批。
在所有版本的Android系統,您的應用程式需要申報的正常和危險的許可權需要在其應用程式資訊清單,如聲明中所述的許可權。然而,宣言的影響是不同的根據系統版本和SDK應用程式的目標水平:
- 如果裝置運行Android 5.1或更低,或應用程式的目標SDK是22或更低:如果你在清單列表一個危險的許可,使用者授予許可權安裝應用程式時,如果他們不授予許可權,系統沒有安裝應用程式。
- 如果裝置運行Android 6.0或更高版本,和你的應用程式的目標SDK是23或更高:應用列表的許可權清單,它必須要求每個危險的許可權需要在應用程式運行時。使用者可以授予或拒絕每一個許可權,應用程式可以繼續運行能力有限,即使使用者拒絕許可權請求。
注意:從Android 6.0(API層級23),使用者可以在任何時候從任何應用程式撤銷許可權,即使應用程式API層級較低的目標。你應該測試你的應用程式,以確認它正確行為的時候丟失了一個需要許可,無論什麼API層級應用程式的目標。
這節課描述了如何使用Android支援庫檢查,和請求,許可權。Android 6.0的Android架構提供了類似的方法(API層級23)。然而,使用支援庫比較簡單,因為應用程式不需要檢查哪個版本的Android上運行之前調用的方法。
檢查許可權
如果你的應用需要一個危險的許可,你必須檢查你是否有許可權每次執行一個操作,要求許可。使用者總是可以撤銷許可,所以即使相機昨天使用的應用程式,它不能假設它今天仍有該許可權。
檢查如果你有許可權,調用ContextCompat.checkSelfPermission()方法。例如,這個程式碼片段展示了如何檢查活動日曆上寫入權限:
// Assume thisActivity is the current activityint permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR);
如果應用程式許可,該方法返回PackageManager。PERMISSION_GRANTED,應用程式可以繼續運行。如果應用程式沒有許可,方法返回PERMISSION_DENIED,應用程式必須顯式地要求使用者許可。
請求的許可權
如果你的應用需要一個應用程式資訊清單中列出的危險的許可,它必須要求使用者授予許可權。Android提供了幾種方法可用於請求許可。調用這些方法提出一個標準的Android對話方塊中,您不能定製。
解釋為什麼這個應用程式需要的許可權
在某些情況下,您可能想要協助使用者理解為什麼你的應用需要一個許可。攝影為例,如果一個使用者啟動一個應用程式,使用者可能不會感到驚訝,允許應用程式要求使用相機,但是使用者可能不理解為什麼這個應用程式要訪問使用者的位置或連絡人。在請求許可之前,你應該考慮為使用者提供一個解釋。記住,你不想淹沒使用者提供解釋,如果你提供太多的解釋,使用者可能會發現應用令人沮喪和刪除它。
您可以使用的一種方法是提供一個解釋只有在使用者已經拒絕了該許可權的請求。如果使用者一直試圖使用功能需要一個許可,但一直拒絕許可的要求,這可能表明使用者不理解為什麼允許應用程式需要提供該功能。在這樣的情況下,它可能是一個好主意給一個解釋。
協助找到的情況下,使用者可能需要一個解釋,Android提供了一種utiltity方法,shouldShowRequestPermissionRationale()。這個方法返回true,如果應用程式要求這個許可之前,使用者拒絕請求。
注意:如果使用者拒絕許可請求過去,再次選擇了不要問選項允許請求系統對話方塊中,這個方法返回false。該方法還返回false如果裝置政策禁止應用程式擁有該許可權。
請求所需要的許可權
如果應用程式已經不允許它的需求,應用程式必須調用一個requestPermissions()方法來請求適當的許可權。應用程式通過它想要的許可權,以及一個整數要求您指定識別這個許可請求的代碼。這種方法非同步函數:它返回,使用者響應對話方塊之後,系統調用應用程式的回調方法對結果的影響,通過相同的請求代碼,應用程式傳遞給requestPermissions()。
下面的代碼檢查應用程式允許讀取使用者的聯絡,必要時請求許可:
// Here, thisActivity is the current activityif (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. }}
注意:當您的應用程式調用requestPermissions(),系統顯示一個標準對話方塊給使用者。應用程式不能配置或改變對話方塊。如果需要提供任何資訊或向使用者解釋,你應該這樣做之前你叫requestPermissions(),解釋為什麼所述應用程式需要的許可權。
處理許可權請求響應
當應用程式請求許可權,系統向使用者提供了一個對話方塊。當使用者響應,系統調用應用程式的onRequestPermissionsResult()方法,傳遞使用者響應。你的應用必須覆蓋那個方法來找出是否被授予許可。回調傳遞相同的請求代碼傳遞給requestPermissions()。例如,如果一個應用程式請求READ_CONTACTS訪問它可能回調方法如下:
@Overridepublic 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 }}
所示的對話方塊,系統描述了允許組織你的應用程式需要訪問;它不特定的許可權列表。舉個例子,如果你請求READ_CONTACTS許可,該系統對話方塊只是說你的應用程式需要訪問裝置的連絡人。一旦為每個使用者只需要許可許可權組。如果你的應用程式請求的任何其他許可權組(應用程式資訊清單中列出),系統自動賦予他們。請求許可時,系統調用你onRequestPermissionsResult()回調方法和通過PERMISSION_GRANTED,以同樣的方式將如果使用者有明確授予你的要求通過系統對話方塊。
注意:應用程式仍然需要每個許可需要顯式地請求,即使使用者已經允許另一個在同一組。此外,許可權分組的分組可能改變未來的Android版本。你的代碼不應該依賴於假設特定的許可權或不在同一組。
例如,假設您在應用程式列表READ_CONTACTS和WRITE_CONTACTS清單。如果你請求READ_CONTACTS和使用者授予許可權,然後你請求WRITE_CONTACTS,系統立即授予許可沒有與使用者互動。
如果使用者拒絕許可權請求,應用程式應該採取適當的措施。例如,您的應用程式可能會顯示一個對話方塊解釋為什麼它不能執行使用者所請求的操作,需要許可。
當系統要求使用者授予許可權,使用者可以選擇告訴系統不要求許可了。在這種情況下,任何時候一個應用程式使用requestPermissions()要求許可權,系統立即否認了這一請求。系統調用你onRequestPermissionsResult()回調方法和通過PERMISSION_DENIED,以同樣的方式將如果使用者已經明確拒絕了你的請求。這意味著當你叫requestPermissions(),你不能假設任何直接與使用者互動。