介绍
Android 系统 6.0 版本之前,安装 App 时会提示用户此 App 都需要使用哪些权限,如图 7.1所示。但是用户不可以单独对某项权限进行授权或者是拒绝,如果用户安装了该 App,就表示用户已经接受了该 App 对这些权限的使用。从 Android 系统 6.0 版本开始,Android 使用了新的权限管理机制,将 App 可以使用的权限分成了两类,一类是普通权限,例如,设置手机振动或者是访问网络等。另一类是危险权限,例如,开启摄像头或者是获取地理位置等。对于普通权限,仍然和以前一样,开发者只需要在 AndroidManifest 配置文件中添加所需的权限即可,用户只要同意安装就表示已经接受该 App 使用这些权限。对于危险权限来说,因为涉及到个人的隐私,所以不仅需要在AndroidManifest 配置文件中添加权限,还需要在运行时请求用户授权此类权限,如图 7.2 所示。此时用户可以选择允许或拒绝,如果拒绝某项权限,该 App 将无法使用该权限的功能。
用法
运行 App 时权限的申请步骤如下:
(1)判断当前手机系统版本是否大于或等于 6.0 版本。可以使用以下代码:
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
Toast.makeText(this, "大于等于6.0", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "小于6.0", Toast.LENGTH_SHORT).show();
}
(2)检查是否授权了某个权限,这里以读取联系人权限为例。可以使用以下代码:
//Manifest.permission.READ_CONTACTS为查询的读取联系人权限
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
//没有权限,可以在这里申请权限。
}else{
//权限已经申请。
}
(3)申请一组需要的权限可以是 1 个或者多个以数组的形式添加。可以使用以下代码:
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS} ,1);
(4)用户处理完授权操作后,查看申请结果的回调。可以使用以下代码:
- int requestCode 申请权限的请求代码,会在回调onRequestPermissionsResult() 方法时返回,用来判断是哪个授权申请的回调
- String permissions[] 申请需要权限的数组
- int[] grantResults 授权结果数组,对应 permissions,通过 PackageManager 判断是否已经授权
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: { //判断授权码为1的申请权限数组
//判断授权结果是否已经授权
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//用户已同意权限
} else {
//用户已拒绝权限
}
return;
}
}
}
例子
模拟申请定位权限
编写布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--申请定位权限按钮-->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:onClick="onPermission"
android:text="申请定位权限" />
</RelativeLayout>
编写ApplyForPermission
打开 manifests 目录中的 AndroidManifest.xml 文件,在该文件中的 application 节点上面添加定位权限的代码。关键代码如下:
<!--定位权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
调用 onRequestPermissionsResult() 申请权限的回调方法,在该方法中首先判断用户是否同意了授权定位的权限,如果同意了将通过 Toast 进行提示,否则通过对话框的方式提示用户该权限的重要性,并提醒用户可以在设置中心进行权限的授权操作。
public class ApplyForPermission extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_apply_for_permission);
}
//创建申请定位权限按钮的单击事件
public void onPermission(View view){
//M=23,对应Android6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//判断是否没有授权定位权限
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//申请定位权限
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
Toast.makeText(this, "定位权限已经授权!", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: { //判断授权码为1的申请权限数组
//判断授权结果是否已经授权
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "用户已经同意授权定位的权限!",
Toast.LENGTH_SHORT).show();
} else {
new AlertDialog.Builder(this)
.setTitle("提示信息")
.setMessage("当前应用缺少必要权限,该功能暂时无法使用。" +
"如若需要,请单击[确定]按钮前往设置中心进行权限授权。")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//通过Intent跳转设置中心界面
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
}).show();
}
return;
}
}
}
}
效果