1. 程式人生 > >Android 6.0 動態許可權申請注意事項

Android 6.0 動態許可權申請注意事項

<strong><span style="font-size:32px;color:#000099;">許可權區分</span></strong>

Android 6.0 為了保護使用者隱私,將一些許可權的申請放在了應用執行的時候去申請, 比如以往的開發中,開發人員只需要將需要的許可權在清單檔案中配置即可,安裝後用戶可以在設定中的應用資訊中看到:XX應用以獲取****許可權。使用者點選可以選擇給應用相應的許可權。此前的應用許可權使用者可以選擇允許、提醒和拒絕。在安裝的時候使用者是已經知道應用需要的許可權的。但是這樣存在一個問題,就是使用者在安裝的時候,應用需要的許可權十分的多(有些開發者為了省事,會請求一些不必要的許可權或者請求全部的許可權),這個時候使用者在安裝應用的時候也許並沒有發現某些侵犯自己隱私的許可權請求,安裝之後才發現自己的隱私資料被竊取。其實Android6.0 動態許可權一方面是為了廣大使用者考慮,另一方面其實是Google為了避免一些不必要的官司。但是這樣做可實在是苦了程式設計師了。不過還好,許可權不是所有的都需要動態申請,下面就說一下Android6.0對許可權的分割:

一、普通許可權

這類的許可權不需要動態申請,需要這個許可權的時候還是按照以往的做法,在清單檔案中申請相應的許可權即可,在安裝的時候會展示給使用者,使用者同意安裝就獲取相應的許可權。寫法舉例如下:

清單檔案中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.deepai.paipai">

    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" 
/>
........
下面是對許可權的總結:

android.permission.EXPAND_STATUS_BAR 允許一個程式擴充套件收縮在狀態列,android開發網提示應該是一個類似Windows Mobile中的托盤程式

android.permission.FACTORY_TEST 作為一個工廠測試程式,執行在root使用者

android.permission.FLASHLIGHT 訪問閃光燈,android開發網提示HTC Dream不包含閃光燈

android.permission.FORCE_BACK 允許程式強行一個後退操作是否在頂層activities

android.permission.FOTA_UPDATE 暫時不瞭解這是做什麼使用的,android開發網分析可能是一個預留許可權.

android.permission.GET_ACCOUNTS 訪問一個帳戶列表在Accounts Service中

android.permission.GET_PACKAGE_SIZE 允許一個程式獲取任何package佔用空間容量

android.permission.GET_TASKS 允許一個程式獲取資訊有關當前或最近執行的任務,一個縮略的任務狀態,是否活動等等

android.permission.HARDWARE_TEST 允許訪問硬體

android.permission.INJECT_EVENTS 允許一個程式截獲使用者事件如按鍵、觸控、軌跡球等等到一個時間流,android開發網提醒算是hook技術吧

android.permission.INSTALL_PACKAGES 允許一個程式安裝應用

android.permission.INTERNAL_SYSTEM_WINDOW 允許開啟視窗使用系統使用者介面

android.permission.ACCESS_CHECKIN_PROPERTIES 允許讀寫訪問“properties”表在checkin資料庫中,改值可以修改上傳。

android.permission.ACCESS_COARSE_LOCATION 允許一個程式訪問CellID或WiFi熱點來獲取粗略的位置

android.permission.ACCESS_FINE_LOCATION 允許一個程式訪問精良位置(如GPS)

android.permission.WRITE_CONTACTS 允許程式寫入但不讀取使用者聯絡人資料

android.permission.WRITE_GSERVICES 允許程式修改Google服務地圖

android.permission.WRITE_OWNER_DATA 允許一個程式寫入但不讀取所有者資料

android.permission.WRITE_SETTINGS 允許程式讀取或寫入系統設定

android.permission.WRITE_SMS 允許程式寫簡訊

android.permission.WRITE_SYNC_SETTINGS 允許程式寫入同步設定

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 允許應用程式訪問額外的位置提供命令

android.permission.ACCESS_MOCK_LOCATION 允許程式建立模擬位置提供用於測試

android.permission.ACCESS_NETWORK_STATE 允許程式訪問有關GSM網路資訊

android.permission.ACCESS_SURFACE_FLINGER 允許程式使用SurfaceFlinger底層特性

android.permission.ACCESS_WIFI_STATE 允許程式訪問Wi-Fi網路狀態資訊

android.permission.ADD_SYSTEM_SERVICE 允許程式釋出系統級服務

android.permission.BATTERY_STATS 允許程式更新手機電池統計資訊

android.permission.BLUETOOTH 允許程式連線到已配對的藍芽裝置

android.permission.BLUETOOTH_ADMIN 允許程式發現和配對藍芽裝置

android.permission.BROADCAST_PACKAGE_REMOVED 允許程式廣播一個提示訊息在一個應用程式包已經移除後

android.permission.BROADCAST_STICKY 允許一個程式廣播常用intents

android.permission.CALL_PHONE 允許一個程式初始化一個電話撥號不需通過撥號使用者介面需要使用者確認

android.permission.DELETE_CACHE_FILES 允許程式刪除快取檔案

android.permission.DELETE_PACKAGES 允許一個程式刪除包

android.permission.DEVICE_POWER 允許訪問底層電源管理

android.permission.DIAGNOSTIC 允許程式RW診斷資源

android.permission.DISABLE_KEYGUARD 允許程式禁用鍵盤鎖

android.permission.DUMP 允許程式返回狀態抓取資訊從系統服務

android.permission.CALL_PRIVILEGED 允許一個程式撥打任何號碼,包含緊急號碼無需通過撥號使用者介面需要使用者確認

android.permission.CAMERA 請求訪問使用照相裝置

android.permission.CHANGE_COMPONENT_ENABLED_STATE 允許一個程式是否改變一個元件或其他的啟用或禁用

android.permission.CHANGE_CONFIGURATION 允許一個程式修改當前設定,如本地化

android.permission.CHANGE_NETWORK_STATE 允許程式改變網路連線狀態

android.permission.CHANGE_WIFI_STATE 允許程式改變Wi-Fi連線狀態

android.permission.CLEAR_APP_CACHE 允許一個程式清楚快取從所有安裝的程式在裝置中

android.permission.CLEAR_APP_USER_DATA 允許一個程式清除使用者設定

android.permission.CONTROL_LOCATION_UPDATES 允許啟用禁止位置更新提示從無線模組

android.permission.REBOOT 請求能夠重新啟動裝置

android.permission.RECEIVE_BOOT_COMPLETED 允許一個程式接收到ACTION_BOOT_COMPLETED廣播在系統完成啟動

android.permission.RECEIVE_MMS 允許一個程式監控將收到MMS彩信,記錄或處理

android.permission.RECEIVE_SMS 允許程式監控一個將收到簡訊息,記錄或處理

android.permission.RECEIVE_WAP_PUSH 允許程式監控將收到WAP PUSH資訊

android.permission.RECORD_AUDIO 允許程序錄制音訊

android.permission.REORDER_TASKS 允許程式改變Z軸排列任務

android.permission.RESTART_PACKAGES 允許程式重新啟動其他程式

android.permission.SEND_SMS 允許程式傳送SMS簡訊

android.permission.INTERNET 允許程式開啟網路套接字

android.permission.MANAGE_APP_TOKENS 允許程式管理(建立、催後、 z-order預設向z軸推移)程式引用在視窗管理器中

android.permission.MASTER_CLEAR 目前還沒有明確的解釋,android開發網分析可能是清除一切資料,類似硬格機

android.permission.MODIFY_AUDIO_SETTINGS 允許程式修改全域性音訊設定

android.permission.MODIFY_PHONE_STATE 允許修改話機狀態,如電源,人機介面等

android.permission.MOUNT_UNMOUNT_FILESYSTEMS 允許掛載和反掛載檔案系統可移動儲存

android.permission.PERSISTENT_ACTIVITY 允許一個程式設定他的activities顯示

android.permission.PROCESS_OUTGOING_CALLS 允許程式監視、修改有關播出電話

android.permission.READ_CALENDAR 允許程式讀取使用者日曆資料

android.permission.READ_CONTACTS 允許程式讀取使用者聯絡人資料

android.permission.READ_FRAME_BUFFER 允許程式螢幕波或和更多常規的訪問幀緩衝資料

android.permission.READ_INPUT_STATE 允許程式返回當前按鍵狀態

android.permission.READ_LOGS 允許程式讀取底層系統日誌檔案

android.permission.READ_OWNER_DATA 允許程式讀取所有者資料

android.permission.READ_SMS 允許程式讀取簡訊息

android.permission.READ_SYNC_SETTINGS 允許程式讀取同步設定

android.permission.READ_SYNC_STATS 允許程式讀取同步狀態

android.permission.SET_ACTIVITY_WATCHER 允許程式監控或控制activities已經啟動全域性系統中

android.permission.SET_ALWAYS_FINISH 允許程式控制是否活動間接完成在處於後臺時

android.permission.SET_ANIMATION_SCALE 修改全域性資訊比例

android.permission.SET_DEBUG_APP 配置一個程式用於除錯

android.permission.SET_ORIENTATION 允許底層訪問設定螢幕方向和實際旋轉

android.permission.SET_PREFERRED_APPLICATIONS 允許一個程式修改列表引數PackageManager.addPackageToPreferred()和PackageManager.removePackageFromPreferred()方法

android.permission.SET_PROCESS_FOREGROUND 允許程式當前執行程式強行到前臺

android.permission.SET_PROCESS_LIMIT 允許設定最大的執行程序數量

android.permission.SET_TIME_ZONE 允許程式設定時間區域

android.permission.SET_WALLPAPER 允許程式設定桌布

android.permission.SET_WALLPAPER_HINTS 允許程式設定桌布hits

android.permission.SIGNAL_PERSISTENT_PROCESSES 允許程式請求傳送訊號到所有顯示的程序中

android.permission.STATUS_BAR 允許程式開啟、關閉或禁用狀態列及圖示Allows an application toopen, close, or disable the status bar and its icons.

android.permission.SUBSCRIBED_FEEDS_READ 允許一個程式訪問訂閱RSS Feed內容提供

android.permission.SUBSCRIBED_FEEDS_WRITE 系統暫時保留改設定,android開發網認為未來版本會加入該功能。

android.permission.SYSTEM_ALERT_WINDOW 允許一個程式開啟視窗使用TYPE_SYSTEM_ALERT,顯示在其他所有程式的頂層

android.permission.VIBRATE 允許訪問振動裝置

android.permission.WAKE_LOCK 允許使用PowerManager的 WakeLocks保持程序在休眠時從螢幕消失

android.permission.WRITE_APN_SETTINGS 允許程式寫入API設定

android.permission.WRITE_CALENDAR 允許一個程式寫入但不讀取使用者日曆資料

可以看出Android中對資源以及服務的訪問都非常嚴格,另外,在程式打包成APK的時候也需要對軟體進行簽名。

獲取精確位置 android.permission.ACCESS_FINE_LOCATION 通過GPS晶片接收衛星的定位資訊,定位精度達10米以內

訪問定位額外命令 android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 允許程式訪問額外的定位提供者指令

獲取模擬定位資訊 android.permission.ACCESS_MOCK_LOCATION 獲取模擬定位資訊,一般用於幫助開發者除錯應用

獲取網路狀態 android.permission.ACCESS_NETWORK_STATE 獲取網路資訊狀態,如當前的網路連線是否有效

訪問Surface Flinger android.permission.ACCESS_SURFACE_FLINGER Android平臺上底層的圖形顯示支援,一般用於遊戲或照相機預覽介面和底層模式的螢幕截圖

獲取WiFi狀態 android.permission.ACCESS_WIFI_STATE 獲取當前WiFi接入的狀態以及WLAN熱點的資訊

賬戶管理 android.permission.ACCOUNT_MANAGER 獲取賬戶驗證資訊,主要為GMail賬戶資訊,只有系統級程序才能訪問的許可權

驗證賬戶 android.permission.AUTHENTICATE_ACCOUNTS 允許一個程式通過賬戶驗證方式訪問賬戶管理ACCOUNT_MANAGER相關資訊

電量統計 android.permission.BATTERY_STATS 獲取電池電量統計資訊

繫結小外掛 android.permission.BIND_APPWIDGET 允許一個程式告訴appWidget服務需要訪問小外掛的資料庫,只有非常少的應用才用到此許可權

繫結裝置管理 android.permission.BIND_DEVICE_ADMIN 請求系統管理員接收者receiver,只有系統才能使用

繫結輸入法 android.permission.BIND_INPUT_METHOD 請求InputMethodService服務,只有系統才能使用

繫結RemoteView android.permission.BIND_REMOTEVIEWS 必須通過RemoteViewsService服務來請求,只有系統才能用

繫結桌布 android.permission.BIND_WALLPAPER 必須通過WallpaperService服務來請求,只有系統才能用

使用藍芽 android.permission.BLUETOOTH 允許程式連線配對過的藍芽裝置

藍芽管理 android.permission.BLUETOOTH_ADMIN 允許程式進行發現和配對新的藍芽裝置

變成磚頭 android.permission.BRICK 能夠禁用手機,非常危險,顧名思義就是讓手機變成磚頭

應用刪除時廣播 android.permission.BROADCAST_PACKAGE_REMOVED 當一個應用在刪除時觸發一個廣播

收到簡訊時廣播 android.permission.BROADCAST_SMS 當收到簡訊時觸發一個廣播

連續廣播 android.permission.BROADCAST_STICKY 允許一個程式收到廣播後快速收到下一個廣播

WAP PUSH廣播 android.permission.BROADCAST_WAP_PUSH WAPPUSH服務收到後觸發一個廣播

撥打電話 android.permission.CALL_PHONE 允許程式從非系統撥號器裡輸入電話號碼

通話許可權 android.permission.CALL_PRIVILEGED 允許程式撥打電話,替換系統的撥號器介面

拍照許可權 android.permission.CAMERA 允許訪問攝像頭進行拍照

改變元件狀態 android.permission.CHANGE_COMPONENT_ENABLED_STATE 改變元件是否啟用狀態

改變配置 android.permission.CHANGE_CONFIGURATION 允許當前應用改變配置,如定位

改變網路狀態 android.permission.CHANGE_NETWORK_STATE 改變網路狀態如是否能聯網

改變WiFi多播狀態 android.permission.CHANGE_WIFI_MULTICAST_STATE 改變WiFi多播狀態

改變WiFi狀態 android.permission.CHANGE_WIFI_STATE 改變WiFi狀態

清除應用快取 android.permission.CLEAR_APP_CACHE 清除應用快取

清除使用者資料 android.permission.CLEAR_APP_USER_DATA 清除應用的使用者資料

底層訪問許可權 android.permission.CWJ_GROUP 允許CWJ賬戶組訪問底層資訊

手機優化大師擴充套件許可權 android.permission.CELL_PHONE_MASTER_EX 手機優化大師擴充套件許可權

控制定位更新 android.permission.CONTROL_LOCATION_UPDATES 允許獲得行動網路定位資訊改變

刪除快取檔案 android.permission.DELETE_CACHE_FILES 允許應用刪除快取檔案

刪除應用 android.permission.DELETE_PACKAGES 允許程式刪除應用

電源管理 android.permission.DEVICE_POWER 允許訪問底層電源管理

應用診斷 android.permission.DIAGNOSTIC 允許程式到RW到診斷資源

禁用鍵盤鎖 android.permission.DISABLE_KEYGUARD 允許程式禁用鍵盤鎖

轉存系統資訊 android.permission.DUMP 允許程式獲取系統dump資訊從系統服務

狀態列控制 android.permission.EXPAND_STATUS_BAR 允許程式擴充套件或收縮狀態列

工廠測試模式 android.permission.FACTORY_TEST 允許程式執行工廠測試模式

使用閃光燈 android.permission.FLASHLIGHT 允許訪問閃光燈

強制後退 android.permission.FORCE_BACK 允許程式強制使用back後退按鍵,無論Activity是否在頂層

訪問賬戶Gmail列表 android.permission.GET_ACCOUNTS 訪問GMail賬戶列表

獲取應用大小 android.permission.GET_PACKAGE_SIZE 獲取應用的檔案大小

獲取任務資訊 android.permission.GET_TASKS 允許程式獲取當前或最近執行的應用

允許全域性搜尋 android.permission.GLOBAL_SEARCH 允許程式使用全域性搜尋功能

硬體測試 android.permission.HARDWARE_TEST 訪問硬體輔助裝置,用於硬體測試

注射事件 android.permission.INJECT_EVENTS 允許訪問本程式的底層事件,獲取按鍵、軌跡球的事件流

安裝定位提供 android.permission.INSTALL_LOCATION_PROVIDER 安裝定位提供

安裝應用程式 android.permission.INSTALL_PACKAGES 允許程式安裝應用

內部系統視窗 android.permission.INTERNAL_SYSTEM_WINDOW 允許程式開啟內部視窗,不對第三方應用程式開放此許可權

訪問網路 android.permission.INTERNET 訪問網路連線,可能產生GPRS流量

結束後臺程序 android.permission.KILL_BACKGROUND_PROCESSES 允許程式呼叫killBackgroundProcesses(String).方法結束後臺程序

管理賬戶 android.permission.MANAGE_ACCOUNTS 允許程式管理AccountManager中的賬戶列表

 普通許可權的總結:

ACCESS_LOCATION_EXTRA_COMMANDS 定位許可權

ACCESS_NETWORK_STATE 網路狀態許可權

ACCESS_NOTIFICATION_POLICY 通知 APP通知顯示在狀態列

ACCESS_WIFI_STATE WiFi狀態許可權

BLUETOOTH 使用藍芽許可權

BLUETOOTH_ADMIN 控制藍芽開關

BROADCAST_STICKY 粘性廣播

CHANGE_NETWORK_STATE 改變網路狀態

CHANGE_WIFI_MULTICAST_STATE 改變WiFi多播狀態,應該是控制手機熱點(猜測)

CHANGE_WIFI_STATE 控制WiFi開關,改變WiFi狀態

DISABLE_KEYGUARD 改變鍵盤為不可用

EXPAND_STATUS_BAR 擴充套件bar的狀態

GET_PACKAGE_SIZE 獲取應用安裝包大小

INTERNET 網路許可權

KILL_BACKGROUND_PROCESSES 殺死後臺程序

MODIFY_AUDIO_SETTINGS 改變音訊輸出設定

NFC 支付

READ_SYNC_SETTINGS 獲取手機設定資訊

READ_SYNC_STATS 資料統計

RECEIVE_BOOT_COMPLETED 監聽啟動廣播

REORDER_TASKS 建立新棧

REQUEST_INSTALL_PACKAGES 安裝應用程式

SET_TIME_ZONE 允許應用程式設定系統時間區域

SET_WALLPAPER 設定桌布

SET_WALLPAPER_HINTS 設定桌布上的提示資訊,個性化語言

TRANSMIT_IR 紅外發射

USE_FINGERPRINT 指紋識別

VIBRATE 震動

WAKE_LOCK 鎖屏

WRITE_SYNC_SETTINGS 改變設定

SET_ALARM 設定警告提示

INSTALL_SHORTCUT 建立快捷方式

UNINSTALL_SHORTCUT 刪除快捷方式

以上這些只是普通許可權,我們開發的時候,正常使用就行了,需要的許可權在清單檔案配置即可。

危險許可權

這類許可權需要在需要的時候,需要我們動態申請,比如:當我們需要開啟相機拍攝照片的時候需要我們通過程式碼的方式在需要的地方去申請許可權。Android6.0中許可權問題中我們需要注意的是:

1:由於許可權API的問題,我們的Actiivty最好是AppCompatActivity型別的,也就是說在你的BaseActivity需要繼承AppCompatActivity

2:許可權是分組的,同一組的許可權申請其中一個,同組的許可權就全部都申請了

特殊許可權 組:

CALENDAR 日曆

CAMERA 相機

CONTACTS 聯絡人

LOCATION 定位

MICROPHONE 麥克相關,比如錄音

PHONE 手機狀態

SENSORS 感測器

SMS 簡訊

STORAGE 儲存許可權

具體的許可權分組情況如下表:

請求許可權實現:

使用的API:

6.0的執行時許可權,我們最終都是要支援的,通常我們需要使用如下的API

  • int checkSelfPermission(String permission) 用來檢測應用是否已經具有許可權,這個方法是在API23中才有的,為了相容低版本,建議使用v4包中的ContextCompat.checkSelfPermission,在下面的注意事項中有解釋,這裡就不在贅述了

  • void requestPermissions(String[] permissions, int requestCode) 進行請求單個或多個許可權,第一個引數是請求的許可權集合,第二個引數是請求碼,在回撥監聽中可以用來判斷是哪個許可權請求的結果

  • void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 使用者對請求作出響應後的回撥,請求成功或者失敗的監聽

  • shouldShowRequestPermissionRationale這個API可以幫我們判斷接下來的對話方塊是否包含”不再詢問“選擇框。在6.0之前的版本永遠返回的是fasle

比如我們請求CAMERA許可權:

@Override
public void onClick(View v) {
	if (!(checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)) {
  		if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
      			Toast.makeText(this, "Please grant the permission this time", Toast.LENGTH_LONG).show();
    		}
    	requestReadContactsPermission();
	} else {
  		Log.i(LOGTAG, "onClick granted");
	}
}
 
private static final int REQUEST_PERMISSION_CAMERA_CODE = 1;
private void requestCameraPermission() {
    requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA_CODE);
}
 
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSION_CAMERA_CODE) {
        int grantResult = grantResults[0];
        boolean granted = grantResult == PackageManager.PERMISSION_GRANTED;
        Log.i(LOGTAG, "onRequestPermissionsResult granted=" + granted);
    }
}


以上是申請一個許可權時的方式。如果我們想同時申請多個許可權就應該寫為如下方式:

private static final int REQUEST_CODE = 1;
private void requestMultiplePermissions() {
    String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE};
    requestPermissions(permissions, REQUEST_CODE);
}

注意事項

API問題

由於checkSelfPermission和requestPermissions從API 23才加入,低於23版本,需要在執行時判斷 或者使用Support Library v4中提供的方法

  • ContextCompat.checkSelfPermission

  • ActivityCompat.requestPermissions

  • ActivityCompat.shouldShowRequestPermissionRationale

多系統問題

當我們支援了6.0必須也要支援4.4,5.0這些系統,所以需要在很多情況下,需要有兩套處理。比如Camera許可權

if (isMarshmallow()) {
    requestPermission();//然後在回撥中處理
} else {
    useCamera();//低於6.0直接使用Camera
}

兩個特殊許可權

特殊許可權,顧名思義,就是一些特別敏感的許可權,在Android系統中,主要由兩個

  • SYSTEM_ALERT_WINDOW,設定懸浮窗,進行一些黑科技

  • WRITE_SETTINGS 修改系統設定

關於上面兩個特殊許可權的授權,做法是使用startActivityForResult啟動授權介面來完成。

請求SYSTEM_ALERT_WINDOW

private static final int REQUEST_CODE = 1;
private  void requestAlertWindowPermission() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE) {
        if (Settings.canDrawOverlays(this)) {
          Log.i(LOGTAG, "onActivityResult granted");
        }
    }
}

上述程式碼需要注意的是

  • 使用Action Settings.ACTION_MANAGE_OVERLAY_PERMISSION啟動隱式Intent

  • 使用"package:" + getPackageName()攜帶App的包名資訊

  • 使用Settings.canDrawOverlays方法判斷授權結果

請求WRITE_SETTINGS

private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
        if (Settings.System.canWrite(this)) {
            Log.i(LOGTAG, "onActivityResult write settings granted" );
        }
    }
}

上述程式碼需要注意的是

  • 使用Action Settings.ACTION_MANAGE_WRITE_SETTINGS 啟動隱式Intent

  • 使用"package:" + getPackageName()攜帶App的包名資訊

  • 使用Settings.System.canWrite方法檢測授權結果

注意:關於這兩個特殊許可權,一般不建議應用申請。