Android 6.0 发布以来,在权限机制上发布了新的API,已经抛弃了之前只需要在manifest上设置就可以获得权限的方式。6.0的权限机制更加注重隐私与体验,动态申请权限的方式更加灵活,把权限管理交给用户,即使授权之后也可以及时更改权限。
Google 将权限分为两类:
动态申请权限步骤:一类是Normal Permissions,这类权限一般不涉及用户隐私,不需要手机授权的,比如说访问网络。二是Dangerous Permissions,涉及用户隐私,需要授权。
* 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
1,你的手机系统版本是6.0以上并且targetSdkVersion设置为>=23,这是动态申请权限的基本条件。
2,在AndroidManifest.xml中申请你需要的权限,包括普通权限和需要申请的特殊权限(不可省)。
3,开始申请权限,这里有三个主要的API:
(1),ContextCompat.checkSelfPermission()检查权限
(2),ActivityCompat.requestPermissions()申请授权
(3),onRequestPermissionsResult()授权回调
(4),ActivityCompat.shouldShowRequestPermissionRationale()拒绝说明(可选)
下面在BaseActivity 封装申请权限
判断一组权限,如果没有就去申请
/**
* 判断权限
* @param permissions
* @return
*/
public boolean checkPermission(String... permissions)
{
for(String permisssion : permissions)
{
if(ContextCompat.checkSelfPermission(this,permisssion)!= PackageManager.PERMISSION_GRANTED)
{
return false ;
}
}
return true ;
}
申请权限:
/**
* 申请权限
* @param code
* @param permissions
*/
public void requestPermissions(int code,String... permissions)
{
ActivityCompat.requestPermissions(this,permissions,code);
}
测试用例,判断有没有相机权限:
public class MainActivity extends BaseActivity {
private String[] permissions = null ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permissions = new String[]{permission.CAMERA} ;
if(checkPermission(permissions))
{
startCamera();
}else
{
/**如果app之前请求过该权限,被用户拒绝, 这个方法就会返回true.
如果用户之前拒绝权限的时候勾选了对话框中”Don’t ask again”的选项,那么这个方法会返回false.
如果设备策略禁止应用拥有这条权限, 这个方法也返回false.
*/
//可选
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA))
{
Toast.makeText(this,"你之前拒绝过该权限",Toast.LENGTH_LONG).show();
}
requestPermissions(0,permissions);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 0:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//拿到权限
startCamera();
}else
{
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
permission.CAMERA)) {
//权限设置页面
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 3);
}
}break ;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode)
{
case 3:
if(checkPermission(permissions))
{
//doSometh
// Log.e("permisson","==================="+ActivityCompat.shouldShowRequestPermissionRationale(this,
// permission.CAMERA));
startCamera();
}else
{
Log.e("permisson","==================="+ActivityCompat.shouldShowRequestPermissionRationale(this,
permission.CAMERA));
requestPermissions(0,permissions);
}
break;
}
}
/**
* 启动相机
*/
private void startCamera()
{
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 1);
}
}
把权限检测和申请放到Activity基类里,统一管理。