如果說5.0是android上的里程碑,那么6.0就是對它的完善與升級。6.0從UI上與5.0沒有任何區(qū)別,依舊堅(jiān)持了好評的md風(fēng)格,但不僅僅只是內(nèi)核的升級而已。
6.0首先是刪除了apache的httpclient包,讓一些網(wǎng)絡(luò)請求框架需要對6.0進(jìn)行適配,雖然有補(bǔ)救的方法,但官方刪除了,也讓okhttp更深入人心。然后就是今天我們重點(diǎn)討論的權(quán)限管理。
6.0以前的app安裝時(shí),會(huì)默認(rèn)授予清單文件manifest中的權(quán)限,雖然安裝時(shí)會(huì)告知用戶有哪些權(quán)限,但一般很少有人會(huì)在意這一點(diǎn)。于是各種居心叵測的廠家或者開發(fā)者往往都是列一堆的權(quán)限,做著用戶所不知道的事情。從6.0開始,情況就不一樣了,一些危險(xiǎn)的權(quán)限我們不但在寫在manifest中,還需要用戶授予同意才能使用。可以說扼殺了一部分廠家的利益。
那么這些危險(xiǎn)的權(quán)限有哪些呢?
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
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
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
permission:android.permission.CAMERA
permission:android.permission.BODY_SENSORS
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
permission:android.permission.RECORD_AUDIO
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
至于如何適配6.0之后的手機(jī),主要有2種方式
1.app的build.gradle中 targetSdkVersion <23
這種方式簡單粗暴,安裝時(shí)依然會(huì)默認(rèn)授予全部的權(quán)限,但是用戶可以在app的權(quán)限管理中關(guān)閉某些權(quán)限,可能導(dǎo)致app無法運(yùn)行。
2.如果targetSdkVersion>=23則需要寫相應(yīng)的適配代碼
public static boolean hasPermission(@NonNull Context context, @NonNull String... permissions) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true;
for (String permission : permissions) {
boolean hasPermission = (ContextCompat.checkSelfPermission(context, permission) == PackageManager
.PERMISSION_GRANTED);
if (!hasPermission) return false;
}
return true;
}
我們先判斷android版本,有沒有權(quán)限,然后若沒有權(quán)限就申請
public static void requestPermission(@NonNull Activity activity, int requestCode, @NonNull String... permissions) {
String [] ps=new String[permissions.length];
for (int i=0;i<permissions.length;i++){
ps[i]=permissions[i];
}
ActivityCompat.requestPermissions(activity, ps, requestCode);
}
然后就是權(quán)限授予的回調(diào)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
//這里就可以處理了
}
如果用戶拒絕了授予,則可以使用如下方法給用戶解釋為什么需要該權(quán)限,返回true我們就彈出解釋對話框,
public static boolean shouldShowRationalePermissions(Object o, String... permissions) {
for (String permission : permissions) {
if (o instanceof Activity) {
return ActivityCompat.shouldShowRequestPermissionRationale((Activity) o, permission);
} else if (o instanceof android.support.v4.app.Fragment) {
return ((android.support.v4.app.Fragment) o).shouldShowRequestPermissionRationale(permission);
}
}
return false;
}
如果用戶不但拒絕,還點(diǎn)擊了不再提醒,就比較麻煩了,因?yàn)椴粫?huì)再有授權(quán)框了,我們只能檢測如果權(quán)限拒絕了,彈出提示框,要用戶到權(quán)限管理中心去開啟權(quán)限。
public static boolean hasAlwaysDeniedPermissio(Object o, @NonNull List<String>
deniedPermissions) {
for (String deniedPermission : deniedPermissions) {
if(!shouldShowRationalePermissions(o,deniedPermission))
return true;
}
return false;
}
以上就是處理6.0以上的權(quán)限問題,但不一定適配國產(chǎn)等機(jī)型,畢竟國內(nèi)各大Rom修改源碼比較嚴(yán)重,有自家的權(quán)限管理,需要特殊處理。
目前github上開源的權(quán)限管理也有不少
- lovedise的PermissionGen
- PermissionGen的升級版 yanzhenjie的AndPermission
- hotchemi的PermissionsDispatcher,插件地址permissions-dispatcher-plugin
- k0shk0sh的PermissionHelper
- ParkSangGwon的TedPermission
- Google官方googlesamples的easypermissions
- anthonycrd的Grant
- 基于Rx的RxPermissions
- Karumi的Dexter
- 張鴻洋的MPermissions
各有優(yōu)劣,不過對于國產(chǎn)手機(jī),自帶權(quán)限管理可能需要自行適配了哦。