由于一直以來公司做的項目一直使用的目標版本是API22【安卓5.0】契沫,但是在API22上面會有很多的功能不能使用苫拍,例如軟件管理權限捕虽,同時目前推薦的目標版本是API25也就是Android7.0,所以在后續(xù)的框架搭建中我決定提升項目的TargetVersion。
簡介
對于6.0以下的權限及在安裝的時候劲够,根據(jù)權限聲明產(chǎn)生一個權限列表洛勉,用戶只有在同意之后才能完成app的安裝,造成了我們想要使用某個app,就要默默忍受其一些不必要的權限(比如是個app都要訪問通訊錄盯捌、短信等)。而在6.0以后蘑秽,我們可以直接安裝饺著,當app需要我們授予不恰當?shù)臋嘞薜臅r候,我們可以予以拒絕(比如:單機的象棋對戰(zhàn)肠牲,請求訪問任何權限幼衰,我都是不同意的)。當然你也可以在設置界面對每個app的權限進行查看缀雳,以及對單個權限進行授權或者解除授權塑顺。
新的權限機制更好的保護了用戶的隱私,Google將權限分為兩類俏险,一類是Normal Permissions严拒,這類權限一般不涉及用戶隱私,是不需要用戶進行授權的竖独,比如手機震動裤唠、訪問網(wǎng)絡等;另一類是Dangerous Permission莹痢,一般是涉及到用戶隱私的种蘸,需要用戶進行授權,比如讀取sdcard竞膳、訪問通訊錄等航瞭。
普通權限
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
危險權限(這部分就是我們在使用的使用需要去處理的部分)
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
新的運行時權限機制做了向下兼容,對于API23以下的版本不用處理危險權限申請坦辟,仍然是按照老方法刊侯,直接注冊,但是對于API23及其以上在需要如上危險權限的時候需要做動態(tài)的權限申請锉走,否則將無法使用滨彻。危險權限是按組分類,這個在權限判斷的時候可以用到挪蹭,但是建議單個權限判斷亭饵,多個權限申請,以確保萬無一失梁厉。
相關的API介紹
1.AndroidManifest文件中添加需要的權限
如果你的權限沒有注冊辜羊,但是在代碼中動態(tài)的申請,將導致程序崩潰。
2.權限檢查
ContextCompat.checkSelfPermission(@NonNull Context context, @NonNull String permission)
- 參數(shù)一:上下文
- 參數(shù)二:需要申請的權限的字符如:Manifest.permission.WRITE_EXTERNAL_STORAGE 可避免出現(xiàn)錯誤八秃。返回值是一個int類型碱妆,0代表已獲取,1代表未獲取喜德,通常和0比較山橄,其中:
0 == PackageManager.PERMISSION_GRANTED:(GRANTED 英譯:準許)
-1 == PackageManager.PERMISSION_DENIED:(DENIED 英譯:拒絕)
3.權限請求
ActivityCompat.requestPermissions(final @NonNull Activity activity,final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode)
- 參數(shù)一:上下文
- 參數(shù)二:需要申請的權限字符串,可多個權限一起申請系統(tǒng)將逐一的詢問
- 參數(shù)三:請求碼舍悯,用于回調(diào)時候使用
4.處理請求后的回調(diào)
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {/* callback - do nothing */}
- 參數(shù)一:請求權限時候的請求碼航棱,多權限分別申請,可以作為分類判斷依據(jù)
- 參數(shù)二:申請的權限名稱如:Manifest.permission.WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"
- 參數(shù)三:申請權限的結果萌衬,例如第一個申請硬盤寫入權限饮醇,第二個申請硬盤讀取權限,通過grantResults[0]==PackageManager.PERMISSION_GRANTED來判斷硬盤寫入權限是否準許秕豫;通過grantResults[1]==PackageManager.PERMISSION_GRANTED來判斷硬盤讀取權限是否準許朴艰。如果權限申請拒絕,但是這個權限非常的重要混移,那么我們可以使用解釋性權限:
// Should we show an explanation?
if(ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,Manifest.permission.READ_CONTACTS)){
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
}
如果再次拒絕祠墅,只好做不使用該權限了,例如天貓你不允許讀取短信權限會退出歌径。//權限判斷(版本號是否大于等于安卓6.0毁嗦,是否獲取權限)完整的寫法如下://沒有獲取權限并且權限被拒絕,最后一次的申請(如果失敗將無法申請)
//沒有獲取權限并且權限被拒絕回铛,最后一次的申請(如果失敗將無法申請)
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
//沒有獲取權限狗准,申請權限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_APN_SETTINGS},
Constant.number.PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
//磁盤寫入權限成功,更新app茵肃,反之失敗退出
case Constant.number.HUNDRED:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
updateApp(updateBean);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
return;
}
break;
// 磁盤讀取權限成功腔长,讀取磁盤是否下載有新的安裝包,若有修改升級按鈕文字
case Constant.number.HUNDRED_AND_ONE:
if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
File file = new File(Constant.string.DOWNLOAD_PATH);
File[] files = file.listFiles();
if (null != files) {
for (int i = 0, count = files.length; i < count; i++) {
String apkName = files[i].getName();
if (TextUtils.equals(apkName, SpUtil.getString(this, Constant.string.UPDATE_APP_NAME, Constant.string.DEFAULT_APP_NAME)) && SpUtil.getLong(this, Constant.string.DOWNLOAD_APK_SIZE + Constant.string.DEFAULT_APP_NAME, Constant.number.ZERO) == files[i].length()) {
mIsUpdateComplete = true;
mBtnUpdate.setText(getResources().getString(R.string.install_now));
}
}
}
}
break;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
最后測試验残,看結果
討論群:6242914819捞附,歡迎入群
微信公眾號:AndroidHoisting(歡迎關注,第一時間推送博文信息)