动态权限

Android 6.0(API 23)及其以上需要动态申请权限
首先,需要在AndroidManifest.xml静态申请权限,否则无法动态申请权限

注意:如果应用程序请求在AndroidManifest中列出的危险权限,
并且应用程序已经在同一权限组中具有另一个危险权限,
系统会立即授予权限,而不会与用户进行任何交互。
例如,如果一个应用程序先前已经请求并被授予READ_CONTACTS权限,
然后它请求WRITE_CONTACTS(同属于联系人一组),
系统会立即授予该权限,不会再弹出权限授予询问的对话框。

需要用户手动赋予的权限( Dangerous Permissions)

所属权限组 权限
日历 READ_CALENDAR
日历 WRITE_CALENDAR
相机 CAMERA
联系人 READ_CONTACTS
联系人 WRITE_CONTACTS
联系人 GET_ACCOUNTS
位置 ACCESS_FINE_LOCATION
位置 ACCESS_COARSE_LOCATION
麦克风 RECORD_AUDIO
电话 READ_PHONE_STATE
电话 CALL_PHONE
电话 READ_CALL_LOG
电话 WRITE_CALL_LOG
电话 ADD_VOICEMAIL
电话 USE_SIP
电话 PROCESS_OUTGOING_CALLS
传感器 BODY_SENSORS
短信 SEND_SMS
短信 RECEIVE_SMS
短信 READ_SMS
短信 RECEIVE_WAP_PUSH
短信 RECEIVE_MMS
存储 READ_EXTERNAL_STORAGE
存储 WRITE_EXTERNAL_STORAGE

<uses-permission android:name="android.permission.上表的权限字符" |> 放在 <application>标签之上

代码封装

权限检测

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
/**
* 检查权限的工具类
* <p/>
* Created by wangchenlong on 16/1/26.
*/
public class PermissionsChecker {
private final Context mContext;

public PermissionsChecker(Context context) {
mContext = context.getApplicationContext();
}

// 判断权限集合
public boolean lacksPermissions(String... permissions) {
for (String permission : permissions) {
if (lacksPermission(permission)) {
return true;
}
}
return false;
}

// 判断是否缺少权限
private boolean lacksPermission(String permission) {
return ContextCompat.checkSelfPermission(mContext, permission) ==
PackageManager.PERMISSION_DENIED;
}
}

权限获取页面
activity_permissions.xml

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<View
android:id="@+id/image"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:adjustViewBounds="true"
android:background="#88888888"
android:contentDescription="@null"/>

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* 权限获取页面
* <p/>
* Created by threetrees on 16/12/1.
*/
public class PermissionsActivity extends AppCompatActivity {

public static final int PERMISSIONS_GRANTED = 0; // 权限授权
public static final int PERMISSIONS_DENIED = 1; // 权限拒绝

private static final int PERMISSION_REQUEST_CODE = 0; // 系统权限管理页面的参数
private static final String EXTRA_PERMISSIONS = "permission"; // 权限参数
private static final String PACKAGE_URL_SCHEME = "package:"; // 方案

private PermissionsChecker mChecker; // 权限检测器
private boolean isRequireCheck; // 是否需要系统权限检测

// 启动当前权限页面的公开接口
public static void startActivityForResult(Activity activity, int requestCode, String... permissions) {
Intent intent = new Intent(activity, PermissionsActivity.class);
intent.putExtra(EXTRA_PERMISSIONS, permissions);
ActivityCompat.startActivityForResult(activity, intent, requestCode, null);
}

// 启动当前权限页面的公开接口
public static void startActivityForResult(Fragment fragment, int requestCode, String... permissions) {
Intent intent = new Intent(fragment.getActivity(), PermissionsActivity.class);
intent.putExtra(EXTRA_PERMISSIONS, permissions);
fragment.startActivityForResult(intent, requestCode);
}

@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {
throw new RuntimeException("PermissionsActivity需要使用静态startActivityForResult方法启动!");
}
setContentView(R.layout.activity_permissions);

mChecker = new PermissionsChecker(this);
isRequireCheck = true;
}

@Override protected void onResume() {
super.onResume();
if (isRequireCheck) {
String[] permissions = getPermissions();
if (mChecker.lacksPermissions(permissions)) {
requestPermissions(permissions); // 请求权限
} else {
allPermissionsGranted(); // 全部权限都已获取
}
} else {
isRequireCheck = true;
}
}

// 返回传递的权限参数
private String[] getPermissions() {
return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);
}

// 请求权限兼容低版本
private void requestPermissions(String... permissions) {
ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
}

// 全部权限均已获取
private void allPermissionsGranted() {
setResult(PERMISSIONS_GRANTED);
finish();
}

/**
* 用户权限处理,
* 如果全部获取, 则直接过.
* 如果权限缺失, 则提示Dialog.
*
* @param requestCode 请求码
* @param permissions 权限
* @param grantResults 结果
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {
isRequireCheck = true;
allPermissionsGranted();
} else {
isRequireCheck = false;
showMissingPermissionDialog();
}
}

// 含有全部的权限
private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
for (int grantResult : grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
return false;
}
}
return true;
}

// 显示缺失权限提示
private void showMissingPermissionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(PermissionsActivity.this);
builder.setTitle("帮助");
builder.setMessage("当前应用缺少必要权限,请点击'设置'-'权限'-打开所需权限。");

// 拒绝, 退出应用
builder.setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
setResult(PERMISSIONS_DENIED);
finish();
}
});

builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
startAppSettings();
}
});

builder.show();
}

// 启动应用的设置
private void startAppSettings() {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));
startActivity(intent);
}
}

在需要申请权限的页面使用

定义权限参数:

1
2
3
4
5
6
7
8
private static final int REQUEST_CODE = 0; // 请求码
private boolean hasPermissions = true;//权限申请标志,可以在onResume()用此标志来判断是否需要申请权限逻辑
private PermissionsChecker mPermissionsChecker; // 权限检测器
// 所需的全部权限
static final String[] PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
};

在Oncreate()等地方初始化:

1
2
3
4
5
	mPermissionsChecker = new PermissionsChecker(mActivity);
// 缺少权限时, 进入权限配置页面
if (Build.VERSION.SDK_INT >= 23 && mPermissionsChecker.lacksPermissions(PERMISSIONS)) {
PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);
}

处理权限申请结果:

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == PermissionsActivity.PERMISSIONS_DENIED) {
hasPermissions = false;
//没有申请权限,这里做一些逻辑处理,比如退出应用
}else if(requestCode == REQUEST_CODE && resultCode == PermissionsActivity.PERMISSIONS_GRANTED)
{
hasPermissions = true;
}
}

坚持原创分享,您的支持将鼓励我继续创作!