转载请注明出处:http://blog.csdn.net/smartbetter/article/details/52778023
尽管Android正在被不断开发,但Android 6.0是完全不同的,对于Android 6.0的几个主要的变化,查看查看官网的这篇文章:
http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-changes.html
其中当然包含Runtime Permissions。
本篇文章目的就是让开发者能轻松解决一些运行时权限的问题。
新的权限获取方式除了要求像之前版本一样在AndroidManifest文件中静态申请之外,应用还需根据需要请求权限,方式采用向用户显示一个请求权限的对话框。这些被动态申请的权限可以在系统设置中被手动关闭。另外,对于类别为NORMAL(正常)的权限,仍然只需要在AndroidManifest文件中静态申请,系统安装时会直接获取,对于Dangerous(危险)权限则需要在Java代码中作处理。
Normal Permissions如下:
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
Dangerous Permissions如下(权限组的形式):
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
注:如果你申请某个Dangerous Permissions,假设你的app早已被用户授权了同一组的某个危险权限,那么系统会立即授权,而不需要用户去点击授权。开发的时候不要对权限组有过多依赖,尽可能对每个危险权限都进行正常的权限申请。
下面我们来进行Android 6.0的适配工作:
(1)在AndroidManifest文件中添加需要的权限(我们假设权限xx);
<uses-permission android:name="android.permission.xx" />
(2)在Java代码中进行动态授权:
private static final int REQUEST_XX_PERMISSION=10;
/** * 这个方法在需要进行授权的地方调用 */
private void requestXxPermission(){
//判断系统版本
if (Build.VERSION.SDK_INT >= 23) {
//检测当前app是否拥有某个权限
int checkCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.xx);
//判断这个权限是否已经授权过
if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){
//判断是否需要 向用户解释,为什么要申请该权限,该方法只有在用户在上一次已经拒绝过你的这个权限申请才会调用。
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.xx))
Toast.makeText(this,"Need xx permission.",Toast.LENGTH_SHORT).show();
/** * 参数1 Context * 参数2 需要申请权限的字符串数组,支持一次性申请多个权限,对话框逐一询问 * 参数3 requestCode 主要用于回调的时候检测 */
ActivityCompat.requestPermissions(this ,new String[]{Manifest.permission.xx},REQUEST_BLUETOOTH_PERMISSION);
return;
}else{
}
} else {
}
}
(3)授权回调处理
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case REQUEST_XX_PERMISSION:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//授权成功
} else {
//授权拒绝
}
break;
}
}
对于权限的申请结果,首先验证requestCode定位到你的申请,然后验证grantResults对应于申请的结果,这里的数组对应于申请时的第二个权限字符串数组。如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。如果申请成功,就可以做你的事情了。
(1)在AndroidManifest文件中添加需要的权限;
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
(2)在Java代码中进行动态授权(这里以蓝牙权限为例):
private static final int REQUEST_BLUETOOTH_PERMISSION=10;
private void requestBluetoothPermission(){
//判断系统版本
if (Build.VERSION.SDK_INT >= 23) {
//检测当前app是否拥有某个权限
int checkCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
//判断这个权限是否已经授权过
if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){
//判断是否需要 向用户解释,为什么要申请该权限
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION))
Toast.makeText(this,"Need bluetooth permission.",Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this ,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_BLUETOOTH_PERMISSION);
return;
}else{
}
} else {
}
}
(3)此处为简化处理就不作授权回调处理了。