Android Permission筆記
Android系統中,當你需要進行某種資源的存取,如GPS、網路、電話簿等等,就需要許可(permission)。
許可分為兩種,一般許可(normal permission)和危險許可(dangerous permission)。兩者差別在於,當你需要許可時,一般許可只要在程式中AndroidManifest的檔案打上你需要許可即可;而危險許可除了要在程式中AndroidManifest打上你需要許可外,還需要使用者給予批准。
危險許可在Android 6.0(API Level 23)之前,給使用者做出批准的時機是在安裝該App時,因此當使用者拒絕該許可,它就不會安裝;反之,若使用者允許,該許可在該App中就被允許直到他被解除安裝。
對於危險許可,在Android 6.0(API Level 23)之後,Android因為可以在設定>應用程式>應用程式權限中,查詢、選擇、刪除你給予任一App的許可,所以就算使用者一開始允許某App的某許可,使用者之後也可在應用程式權限中解除,為解決這個狀況,每次開啟該App時,凡是危險許可都要做許可檢查(permmission check),確定系統是否還允許你的App所要求的許可,給使用者做出批准的時機也從安裝該App變成開啟該App時。另外,當你改變應用程式權限中某App的許可時,就算該App在背景執行,在重新喚回的時候也會重新啟動,因此許可檢查只要在程式啟動時執行一次即可。
● 以GPS為例,在取得位置中常會使用到以下許可:
-android.permission.INTERNET:網路許可,屬於一般許可,為了使用網路定位而開啟的。
-android.permission.ACCESS_COARSE_LOCATION:網路定位許可,屬危險許可,精準度不如GPS定位,但只要有網路,在室內也可使用。
-android.permission.ACCESS_FINE_LOCATION:GPS定位許可,屬危險許可,比網路定位精準,也不需要有網路就可使用,但必須在戶外使用。
● 確認許可的步驟:
Step1. 通常對於需要在手機上額外開啟的功能,例如GPS、藍芽、數據網路,會先確定該功能是否開啟。此和許可無關,只是確認該功能使否以開啟。
Step2. 在AndroidManifest檔案中打上你要求的許可。
Step3. 若是危險許可,在程式碼中,每次開啟App時都要做許可檢查。
● 單一許可範例-開啟GPS定位許可
Step1. 確認你要使用的功能是否已經開啟:
if (locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//手機上的GPS功能已開啟
//進行Step2
}
Step2. 在AndroidManifest檔案中打上你要求的許可:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
Step3. 在程式中做許可檢查:
private void permissionCheck(){
if (ContextCompat.checkSelfPermission(thisActicity,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//ACCESS_FINE_LOCATION已被授權
//接收GPS....
else {
//ACCESS_FINE_LOCATION沒有被授權
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_CONTACTS);
/*此函式會呼叫一個Android提供的對話窗,詢問是否授權許可。
thisActivity為當前的Activity
new String[]{...},其中...為放你要詢問授權的許可,可放多項許可。
MY_PERMISSIONS_REQUEST_READ_CONTACTS為自定義的int常數,回傳函式會以此為識別。
*/
}
}
可覆寫授權許可對話窗的回傳函式,以查看使用者的選擇。當使用者選擇許可對話窗後,會呼叫這個函式:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case MY_PERMISSIONS_REQUEST_READ_CONTACTS:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//代表ACCESS_FINE_LOCATION已被授權
//接收GPS...
}
}
}
● 多重許可範例-開啟GPS定位與CAMERA許可
Android的requestPermission也能接受多項許可,我們以GPS定位與CAMERA這兩個許可為例。
Step1. 確認你要使用的功能是否已經開啟。在手機上我們不需要去特別開啟Camera這項功能,所以和上面一樣,只需要確認GPS的功能已被開啟:
if (locationMgr.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//手機上的GPS功能已開啟
//進行Step2
}
Step2. 在AndroidManifest檔案中打上你要求的許可:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.CAMERA"></uses-permission>
Step3. 在程式中做許可檢查:
private void permissionCheck(){
List<string> permissionStrList = new ArrayList<string>();
//ACCESS_FINE_LOCATION Permission
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionStrList.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
//CAMERA Permission
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
permissionStrList.add(Manifest.permission.CAMERA);
}
if(permissionStrList.isEmpty() == false){
String[] permissionStrs = permissionStrList.toArray(new String[permissionStrList.size()]);
ActivityCompat.requestPermissions(this, permissionStrs, MULTI_PERMISSION_CONTACT);
//此函式同樣會呼叫一個Android提供的對話窗,詢問是否授權許可。
}
}
一樣可覆寫授權許可對話窗的回傳函式,以查看使用者的選擇。當使用者選擇許可對話窗後,會呼叫這個函式:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case MULTI_PERMISSION_CONTACT:
if (grantResults.length < 2) return;
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//代表ACCESS_FINE_LOCATION已被授權
//接收GPS...
}
if (grantResults[1] == PackageManager.PERMISSION_GRANTED) {
//代表CAMERA已被授權
//開啟CAMERA...
}
}
}
留言
張貼留言