对于权限来说,有普通权限,危险权限等,对于普通权限,只需要在AndroidManifest.xml中添加一下权限声明就可以了。但是对于危险权限就需要进行运行时权限处理。
这是安卓开发时会用到的权限,需要用到时查找即可
还有危险权限
危险权限在Android6.0就要进行运行时权限处理
我们举一个的危险权限例子:我们申请了打电话和照相两个危险权限
首先在activity_main.xml添加一个按钮:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/make_call"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Make call"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/make_camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="make camera"/>
</LinearLayout>
在AndroidManifest.xml中添加:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CAMERA"/>
然后修改MainActivity代码:
package com.example.runtimepermissiontest;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//打电话
Button button=findViewById(R.id.make_call);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//判断是否授权
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)!= PackageManager.PERMISSION_GRANTED){
//未授权则调用ActivityCompat.requestPermissions()方法
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},1);
}else{
call();
}
}
});
//相机
Button button1 = findViewById(R.id.make_camera);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 2);
} else {
camera();
}
}
});
}
public void call(){
try{
Intent intent=new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}catch (SecurityException e){
e.printStackTrace();
}
}
public void camera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
}
//ActivityCompat.requestPermissions()方法调用后的结果返回onRequestPermissionsResult()方法
@Override
//这三个参数,首先第一个是个请求码,动态处理权限时,每一种权限会有不同的请求码,我们可以根据请求码在以下的方法中处理需要处理的权限
//代码注释的部分则是根据何种请求来处理权限 例如:ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 2);第二个参数就是个permission,也就是下面代码的第二个参数
//它是根据你要申请的权限请求来分类处理的。
//以下两种方法都可以,只是处理的参数不同,但目的都一样。
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//判断申请码
switch (requestCode){
//申请码为1代表打电话
case 1:
/* switch (permissions[0]){
case Manifest.permission.CALL_PHONE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
call();
} else {
Toast.makeText(this, "没有电话权限", Toast.LENGTH_SHORT).show();
}
break;
case Manifest.permission.CAMERA:
if(grantResults.length>0&&grantResults[1]==PackageManager.PERMISSION_GRANTED){
camera();
}else {
Toast.makeText(this, "没有相机权限", Toast.LENGTH_SHORT).show();
}
break;
}*/
//判断授权结果grantResults中的内容是否为我们申请的权限
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
call();
}else{
Toast.makeText(this,"没有电话权限",Toast.LENGTH_SHORT).show();
}
break;
//申请码为2代表相机
case 2:
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
camera();
}else {
Toast.makeText(this, "没有相机权限", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
运行时权限核心就是在程序运行时由用户授权执行某些危险操作。
- 首先我们要判断用户是不是已经给我们授权过了。借助ContextCompat.checkSelfPermission()方法。checkSelfPermission()方法接受两个参数,第一个参数是Context,第二个参数是具体的权限名(比如打电话的就是Manifest.permission.CALL_PHONE,相机就是Manifest.permission.CAMERA)。
- 然后我们使用方法的返回值和PackageManager.PERMISSION_GRANTED作比较,相等就表明已经授权,不相等就没有授权。
- 如果已经授权,就简单了,直接执行你想用的权限逻辑就可以(比如代码中的打电话封装在call()方法中),如果没有授权,就需要调用ActivityCompat.requestPermission()方法来向用户申请授权,requestPermission()方法接收3个参数,第一个是Activity实例,第二个参数是String数组,我们把要申请的权限名放在数组即可。第三个是请求码,只要是个唯一值就行。(本代码打电话请求码为1,相机请求码为2)
- 调用完requestPermission()方法之后,系统会弹出一个权限申请的对话框,然后用户可以选择同意或拒绝我们的权限申请,不论哪种结果,都会回调到onRequestPermissionResult()方法中,而授权的结果则会封装在grantResults参数中。这里我们只需要判断一下最后的授权结果,用户同意就调用申请的权限逻辑(打电话),不同意就失败提示即可。