动态权限申请:
Google在 Android 6.0 开始引入了权限申请机制,将所有权限分成了正常权限和危险权限。应用的相关功能每次在使用危险权限时需要动态的申请并得到用户的授权才能使用。
正常权限:不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。
危险权限:会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。如果您列出了危险权限,则用户必须明确批准您的应用使用这些权限。
重要方法
1.ContextCompat.checkSelfPermission()
检查应用是否具有某个危险权限。如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回 PackageManager.PERMISSION_DENIED,且应用必须明确向用户要求权限。
2.ActivityCompat.requestPermissions()
应用可以通过这个方法动态申请权限,调用后会弹出一个对话框提示用户授权所申请的权限。
3.ActivityCompat.shouldShowRequestPermissionRationale()
如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false。
4.onRequestPermissionsResult()
当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的 onRequestPermissionsResult() 方法,向其传递用户响应,处理对应的场景。
实例:
写一个申请权限的工具类:
package com.example.jiaho.baidumapproject;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
//申请权限的工具类
public class PermissionUtils {
private Activity mActivity;
private int mReqCode;
private CallBack mCallBack;
//定义一个回调接口
public static interface CallBack{
//接受
void grantAll();
//拒绝
void denied();
}
//定义一个构造函数
public PermissionUtils(Activity activity) {
this.mActivity = activity;
}
//定义请求权限的方法
@RequiresApi(api = Build.VERSION_CODES.M)
public void request(List<String> needPermissions, int reqCode, CallBack callBack){
mReqCode=reqCode;
mCallBack=callBack;
//因为6.0之后才需要动态权限申请
if (Build.VERSION.SDK_INT < 23){
//6.0之前是默认获取全部权限
callBack.grantAll();
return;
}
//判空,并抛出异常
if (mActivity==null){
throw new IllegalArgumentException("activity is null.");
}
//将需要申请的权限,因为有些权限已经赋予
List<String> reqPermission =new ArrayList<>();
for (String permission:needPermissions){
if (mActivity.checkSelfPermission(permission)!= PackageManager.PERMISSION_GRANTED){
reqPermission.add(permission);
}
}
//如果没有要授予的权限,则直接返回
if (reqPermission.isEmpty()){
callBack.grantAll();
return;
}
//真正开始申请
mActivity.requestPermissions(reqPermission.toArray(new String[]{}),reqCode);
}
//处理权限返回的回调
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode==mReqCode){
boolean grantAll = true;
//遍历每一个授权结果
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i]!=PackageManager.PERMISSION_GRANTED){
grantAll=false;
Toast.makeText(mActivity,permissions[i]+"未授权",Toast.LENGTH_SHORT).show();
break;
}
}
if (grantAll){
mCallBack.grantAll();
}else {
mCallBack.denied();
}
}
}
}
在Activity中的应用:
package com.example.jiaho.baidumapproject;
import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class SplashActivity extends AppCompatActivity {
private static List<String> sNeedPermissions=new ArrayList<>();
private PermissionUtils permissionUtils= null;
//静态块中初始化所需要的权限
static {
sNeedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
sNeedPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
sNeedPermissions.add(Manifest.permission.ACCESS_NETWORK_STATE);
sNeedPermissions.add(Manifest.permission.INTERNET);
sNeedPermissions.add(Manifest.permission.READ_PHONE_STATE);
sNeedPermissions.add(Manifest.permission.READ_SYNC_SETTINGS);
sNeedPermissions.add(Manifest.permission.ACCESS_WIFI_STATE);
sNeedPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
sNeedPermissions.add(Manifest.permission.CAMERA);
sNeedPermissions.add(Manifest.permission.CHANGE_WIFI_STATE);
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
permissionUtils=new PermissionUtils(this);
permissionUtils.request(sNeedPermissions, 100, new PermissionUtils.CallBack() {
@Override
public void grantAll() {
toMainActivity();
finish();
}
@Override
public void denied() {
fileList();
}
});
}
public void toMainActivity(){
//进入主Activity
startActivity(new Intent(SplashActivity.this,MainActivity.class));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
permissionUtils.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}