Android6.0+动态权限管理

Android

封装Android依赖库,方便Android6.0+环境下动态申请权限。

Android6.0以后,一些权限不只是通过AndroidManifest申明,还需要在代码申请,系统弹出权限申请弹框,让用户确认授权,才能使用这些权限,如:WRITE_EXTERNAL_STORAGE。

Android权限

  • 需要申请权限
    需要申请的权限分为9组,每组只要有一个权限申请成功,就默认整组权限都可以使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    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
  • 普通权限,在AndroidManifest.xml中申明即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
    android.permission.ACCESS_NETWORK_STATE
    android.permission.ACCESS_NOTIFICATION_POLICY
    android.permission.ACCESS_WIFI_STATE
    android.permission.ACCESS_WIMAX_STATE
    android.permission.BLUETOOTH
    android.permission.BLUETOOTH_ADMIN
    android.permission.BROADCAST_STICKY
    android.permission.CHANGE_NETWORK_STATE
    android.permission.CHANGE_WIFI_MULTICAST_STATE
    android.permission.CHANGE_WIFI_STATE
    android.permission.CHANGE_WIMAX_STATE
    android.permission.DISABLE_KEYGUARD
    android.permission.EXPAND_STATUS_BAR
    android.permission.FLASHLIGHT
    android.permission.GET_ACCOUNTS
    android.permission.GET_PACKAGE_SIZE
    android.permission.INTERNET
    android.permission.KILL_BACKGROUND_PROCESSES
    android.permission.MODIFY_AUDIO_SETTINGS
    android.permission.NFC
    android.permission.READ_SYNC_SETTINGS
    android.permission.READ_SYNC_STATS
    android.permission.RECEIVE_BOOT_COMPLETED
    android.permission.REORDER_TASKS
    android.permission.REQUEST_INSTALL_PACKAGES
    android.permission.SET_TIME_ZONE
    android.permission.SET_WALLPAPER
    android.permission.SET_WALLPAPER_HINTS
    android.permission.SUBSCRIBED_FEEDS_READ
    android.permission.TRANSMIT_IR
    android.permission.USE_FINGERPRINT
    android.permission.VIBRATE
    android.permission.WAKE_LOCK
    android.permission.WRITE_SYNC_SETTINGS
    com.android.alarm.permission.SET_ALARM
    com.android.launcher.permission.INSTALL_SHORTCUT
    com.android.launcher.permission.UNINSTALL_SHORTCUT

动态申请

  • 设置targetSdkVersion为23以上

  • 在AndroidManifest.xml中申明需要的权限,包括普通权限和需要申请的权限

  • 对于申请的权限,需要在代码中申请

    1. 检测权限,使用ContextCompat可以在任意地方使用该方式

      1
      2
      // 检测权限是否被授权
      if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
    2. 如果未授权,则必须在Activity中申请

      1
      Activity.requestPermissions()

      icon_permission_request

    3. 如果用户拒绝,并且点击了“不再询问”,当再次使用步骤2申请时,界面上不会有任何反应,因此需要判断用户是否点击“不再询问”,在Activity中使用shouldShowRequestPermissionRationale方法判断。然后自定义弹框给用户,让用户进入Setting应用去开启权限。
      icon_permission_denied

      icon_permission_no_remind

      icon_permission_setting

      注意:对于“不再询问”的理解:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      在6.0时代,需要在程序运行时获取相关权限,展开一个对话框询问是否授予该程序相应权限。
      从第二次开始运行的时候,会增加一个选项框,“以后不再询问”,如果选择了这个选项,那么以后程序不会再询问是否授予权限了。
      这时候选择了确认倒还好,之后倒方便了。
      如果选择了拒绝,那之后也不会显示对话框,但是权限一直是拒绝的。这样是非常不好的体验,不知道的还以为程序崩溃了。
      所以,我们需要在这个时候也显示相应对话框[自定义的对话框]来告诉用户

      第一次请求时,返回false
      如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true
      注:如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false
      如果设备规范禁止应用具有该权限,此方法也会返回 false

      如果想判断是否拒绝权限,需要在请求一次之后的Failure回调里,再次执行shouldShowRequestPermissionRationale方法,返回 false为拒绝

权限申请封装依赖库

Permission,欢迎start!!!

将动态申请权限的步骤封装起来,方便使用:

  • 链式申请和回调
  • 可在任何地方调用,不限于Activity
  • 自定义进入Setting应用的提示

引入

1
compile 'com.excellence:permission:1.0.0'

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
* 申请单个权限
*/
private void singleRequest()
{
PermissionRequest.with(this).permission(WRITE_EXTERNAL_STORAGE).request(new IPermissionListener()
{

@Override
public void onPermissionsGranted()
{
Toast.makeText(MainActivity.this, "申请单个权限成功", Toast.LENGTH_SHORT).show();
}

@Override
public void onPermissionsDenied()
{
Toast.makeText(MainActivity.this, "申请单个权限失败", Toast.LENGTH_SHORT).show();
}
});
}

/**
* 选中“不在询问”情况下,拒绝时默认情况显示SettingDialog的弹框;
*
* 可以自定义弹框,提示用户进入Setting应用,在rationale监听中提示
* 注意:请使用PermissionActivity的引用,因为我将回调全部在PermissionActivity处理了
*/
private void singleRequest()
{
PermissionRequest.with(this).rationale(new IRationaleListener()
{
@Override
public void OnRationale(final PermissionActivity activity)
{
new SettingDialog(activity).setTitle("Warning").setOnCancelListener(new SettingDialog.OnCancelListener()
{
@Override
public void onCancel()
{
/**
* 点击取消时,认为请求失败
*/
activity.permissionsDenied();
}
}).show();
}
}).permission(WRITE_EXTERNAL_STORAGE).request(new IPermissionListener()
{

@Override
public void onPermissionsGranted()
{
Toast.makeText(MainActivity.this, "申请单个权限成功", Toast.LENGTH_SHORT).show();
}

@Override
public void onPermissionsDenied()
{
Toast.makeText(MainActivity.this, "申请单个权限失败", Toast.LENGTH_SHORT).show();
}
});
}

/**
* 申请多个权限
*/
private void multiRequest()
{
PermissionRequest.with(this).permission(READ_CONTACTS, CAMERA).request(new IPermissionListener()
{
@Override
public void onPermissionsGranted()
{
Toast.makeText(MainActivity.this, "申请多个权限成功", Toast.LENGTH_SHORT).show();
}

@Override
public void onPermissionsDenied()
{
Toast.makeText(MainActivity.this, "申请多个权限失败", Toast.LENGTH_SHORT).show();
}
});
}

感谢

谢谢老板,请尽情用红包来蹂躏我吧!!!
0%