技術學習記錄

[Android]Android 6.0的動態權限申請

從Android 6.0開始,權限系統被重新設計,因此分成危險權限和一般權限兩部分,

如果targetSdkVersion >= 23,那麼在AndroidManifest.xml中聲明使用了哪些危險權限也沒用。必須經過使用者動態取得,如下圖所示:

Google此做法是基於使用者的安全性。讓危險權限不再是APP安裝時就被許可,而是讓使用者自己判斷要不要授與權限。

權限分類

一般權限

名稱說明
NFC使用NFC
READ_SYNC_SETTINGS允許APP讀取同步設定
READ_SYNC_STATS允許APP讀取同步狀態
WRITE_SYNC_SETTINGS允許APP寫入同步設定
RECEIVE_BOOT_COMPLETED接收開機完成廣播
REORDER_TASKS重新排序系統正在執行的任務
SET_ALARM設定鬧鐘
SET_TIME_ZONE設定時區
SET_WALLPAPER設定桌布
SET_WALLPAPER_HINTS設定桌布(跳出建議視窗)
TRANSMIT_IR允許APP使用紅外線傳輸
USE_FINGERPRINT允許APP使用指紋辨識
VIBRATE允許APP存取震動
WAKE_LOCK允許APP禁止手機休眠
ACCESS_LOCATION_EXTRA_COMMANDS允許APP存取位置額外的指令
ACCESS_NETWORK_STATE允許APP存取網路狀態
ACCESS_WIFI_STATE允許APP存取WIFI狀態
BLUETOOTH允許APP存取藍芽
BLUETOOTH_ADMIN允許APP管理藍芽

危險權限

名稱說明
READ_CALENDAR允許APP讀取行事曆
WRITE_CALENDAR允許APP寫入行事曆
CAMERA允許APP使用相機
READ_CONTACTS允許APP讀取聯絡資訊
WRITE_CONTACTS允許APP寫入聯絡資訊
GET_ACCOUNTS取得手機帳號
ACCESS_FINE_LOCATION允許APP取得精確位置
ACCESS_COARSE_LOCATION允許APP取得大致位置
RECORD_AUDIO允許APP錄音
READ_PHONE_STATE允許APP讀取電話狀態
CALL_PHONE允許APP打電話
READ_CALL_LOG允許APP讀取通話紀錄
WRITE_CALL_LOG允許APP寫入通話紀錄
BODY_SENSORS允許APP讀取體感sensor
SEND_SMS允許APP傳送簡訊
RECEIVE_SMS允許APP接收簡訊
READ_SMS允許APP讀取簡訊
READ_EXTERNAL_STORAGE讀取外部儲存空間(SD卡)
WRITE_EXTERNAL_STORAGE寫入外部儲存空間(SD卡)

如何動態取得權限

這裡使用取得ACCESS_FINE_LOCATION作為示範,首先依舊在AndroidManifest.xml中聲明使用ACCESS_FINE_LOCATION,如下:

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

接著在需要權限的Activity中,加入動態取得權限的程式碼,如下:

private static final int REQUEST_LOCATION = 0x0;

private void checkLocationPermission() {
    int permission = ActivityCompat.checkSelfPermission(
            this,
            ACCESS_FINE_LOCATION
    );
    if (permission != PackageManager.PERMISSION_GRANTED) {
        // 未取得權限,詢問使用者是否授與
        ActivityCompat.requestPermissions( 
                this,
                new String[]{ACCESS_FINE_LOCATION},
                REQUEST_LOCATION );
    }else{
        // 已取得權限,在此做後續處理
    }
}

再來,覆寫onRequestPermissionsResult()方法,如下所示:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull @NotNull String[] permissions, @NonNull @NotNull int[] grantResults) {
    switch(requestCode) {
        case REQUEST_LOCATION:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 已取得權限,在此做後續處理
                    
            } else {
                // 使用者拒絕,顯示對話框告知
                new AlertDialog.Builder(this)
                        .setMessage("要使用定位功能,必須先允許定位權限")
                        .setPositiveButton("確定", null)
                        .show();
            }
            break;
        default:
            break;
    }
}

總結

Google於Android 6.0開始導入動態權限申請機制,並將權限分為一般權限和危險權限兩大類。

目的是為了防止一些惡意軟體,在背後偷偷竊取使用的的機密資料。

對於一般的開發者來說其實影響不大。基本上也只是多了一道判斷要去處理而已。

我個人其實蠻贊同Google這樣的做法。

畢竟危險權限都是使用者的機密資料,如果被有心人利用拿去做壞事那可是一件非常嚴重的事。

經過這次的安全性提升之後,希望Android能夠越來越安全。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *