白天在做SDK23版本的適配,遇到了不少坑,現在抽空記下來,以此為戒。 首先要知道哪些坑,就得先瞭解一些定義和基本使用方式。 那麼先介紹一下動態申請的許可權分組情況。 下麵的許可權組是由谷歌官方定義的,目的是在申請許可權時,只要用戶允許同一許可權組的任意一條許可權,那麼該組的其他許可權也就預設是允許的。不過據高 ...
白天在做SDK23版本的適配,遇到了不少坑,現在抽空記下來,以此為戒。
首先要知道哪些坑,就得先瞭解一些定義和基本使用方式。
那麼先介紹一下動態申請的許可權分組情況。
下麵的許可權組是由谷歌官方定義的,目的是在申請許可權時,只要用戶允許同一許可權組的任意一條許可權,那麼該組的其他許可權也就預設是允許的。不過據高人介紹,在使用時最好是用到哪個許可權就具體的請求該許可權,因為保不齊哪天谷歌一高興就把許可權組換了甚至刪了、
group:android.permission-group.CONTACTS permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTS group:android.permission-group.PHONE permission:android.permission.READ_CALL_LOG permission:android.permission.READ_PHONE_STATE permission:android.permission.CALL_PHONE permission:android.permission.WRITE_CALL_LOG permission:android.permission.USE_SIP permission:android.permission.PROCESS_OUTGOING_CALLS permission:com.android.voicemail.permission.ADD_VOICEMAIL group:android.permission-group.CALENDAR permission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDAR group:android.permission-group.CAMERA permission:android.permission.CAMERA group:android.permission-group.SENSORS permission:android.permission.BODY_SENSORS group:android.permission-group.LOCATION permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATION group:android.permission-group.STORAGE permission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGE group:android.permission-group.MICROPHONE permission:android.permission.RECORD_AUDIO group:android.permission-group.SMS permission:android.permission.READ_SMS permission:android.permission.RECEIVE_WAP_PUSH permission:android.permission.RECEIVE_MMS permission:android.permission.RECEIVE_SMS permission:android.permission.SEND_SMS permission:android.permission.READ_CELL_BROADCASTS
其實許可權組的定義很簡單,下麵簡單介紹下動態申請許可權的步驟。
第一步,檢查app擁有的許可權。
1 if(ContextCompat.checkSelfPermission( 2 mActivity,Manifest.permisson.READ_CONTACTS) 3 != PackageManager.PERMISSION_GRANTED) { 4 //當前Activity沒有獲得READ_CONTACTS許可權時 5 }else{ 6 //否則已允許 7 }
第二步,申請許可權。
1 ActivityCompat.requestPermissions( 2 mActivity, 3 new String[]{Manifest.permission.READ_CONTACTS}, 4 REQUEST_CODE_PERMISSION_CONTACTS);
第三步,許可權申請回調方法。
1 @Override 2 public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 3 switch (requestCode) { 4 case REQUEST_CODE_PERMISSION_CONTACTS: { 5 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 6 //用戶已授權 7 } else { 8 //用戶拒絕許可權 9 } 10 return; 11 } 12 } 13 }
如此三步,看上去很簡單,可真要用起來可就沒有那麼簡單了。下麵就說說這裡邊的坑吧。
坑一、許可權申請只能在Activity或者Fragment的上下文中,不能用getApplicationContext()。
由於我們項目在應用初始化時要獲取記憶體的存儲路徑並創建一系列文件緩存,這些操作都是寫在Application的onCreate()中調用不同的Util工具類進行的,所以在Android6.0以上這麼寫就有點不太靠譜了。目前我的解決措施是在應用程式初始化時,先判斷SDK版本,只對版本號小於23的app創建緩存文件,高於23的則在進入Activity之後再初始化。
坑二、許可權申請時使用的請求碼必須小於16。
至於什麼原因不太清楚,可能谷歌公司認為許可權本來就不多,沒必要將請求碼弄得很大占用多餘的記憶體吧。說到請求碼,也就是上面代碼中未定義的常量值REQUEST_CODE_PERMISSION_CONTACTS,如果你定義的這個值超過了15,運行時就會報安全異常,提示請求碼必須小於16。
目前來說這兩個坑就夠我忙活一天的了,看來還是經驗不足啊,以後還要多多吸取經驗。