需求分析:
自从Android系统增加了动态申请权限的机制后为写代码的程序员们带来了不少的工作量。
Android 开发中需要动态申请权限是因为 Android 操作系统为了保障用户隐私和安全而设计的一项重要功能。通过动态请求权限,应用程序只有在需要时才会请求获取特定权限,而不是在安装时就默认获取所有权限。这样可以减少应用对用户隐私的侵入,并防止恶意应用滥用权限。 这样可以让用户更加明确地知道应用程序需要哪些权限,并且可以提高用户对应用程序的信任感。
本文我们将分析Android开发中动态申请权限的相关内容,包括动态判断权限状态,动态申请权限和分析申请结果的方法,并封装一个通用工具类,为自己的后续的开发中复用,减少编重复代码的场景。
公 众 号:木木与代码
本文作者: @MuMu
编写日期:2024年06月11日
本文字数:1231个字符
关注可了解更多的教程。问题或建议,请公众号留言;
效果演示
本示例测试尝试申请摄像头权限,如果第一次申请或者用户还未点击“拒绝并不再询问”权限的选项可以调用系统的权限允许提示,如果用户选择了拒绝则需要跳转到app详细页设置权限。
判断权限
public boolean permissionOk(Context context, String permission){
return (PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(context, permission));
}
其中context
是上下文,permission
是要判断的权限名称,permission
是字符串String类型,一般使用Manifest.permission
下以常量定义,如摄像头权限为Manifest.permission.CAMERA
。
申请权限
public void requestPermission(Activity activity, String[] permission, int requestCode)
ActivityCompat.requestPermissions(activity, permission, requestCode);
}
其中activity
是上下文,permission
是要申请的权限名称,permission
是字符串String类型的数组,一般使用Manifest.permission
下以常量定义,如摄像头权限为Manifest.permission.CAMERA
。requestCode
s是请求结果处理时使用的标志。
结果处理
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 200) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授予了权限
Toast.makeText(this, "同意了, 有权限", Toast.LENGTH_SHORT).show();
} else {
// 如果权限被拒绝,检查用户是否选择了不再询问
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
// 用户选择了不再询问,需要引导用户前往设置界面开启权限
Toast.makeText(this, "请在app详细页设置权限", Toast.LENGTH_SHORT).show();
} else {
// 用户拒绝了权限请求
// 提示用户权限对于应用的重要性,并再次请求权限
Toast.makeText(this, "请同意权限", Toast.LENGTH_SHORT).show();
}
}
}
}
要处理用户是否选择了同意使用权限,需要在activity的onRequestPermissionsResult
方法中判断用户用户的操作,可以根据申请权限时的requestCode和系统回调返回的值来判断用户是否同意了我们的申请权限的请求。
封装工具类
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import androidx.core.app.ActivityCompat;
/**
* @Author: MuMu
* @Date: 2024/5/9 14:31
*/
public class MuPermission {
private final Activity mActivity;
public MuPermission(Activity activity) {
this.mActivity = activity;
}
// 判断权限
public boolean permissionOk(String permission){
return (PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(mActivity, permission));
}
// 申请权限
public void requestPermission(String permission, int requestCode, OnPermissionListener listener) {
if (listener==null) return;
this.mListener = listener;
if (permissionOk(permission)) {
mListener.onPermissionGranted();
} else {
ActivityCompat.requestPermissions(mActivity, new String[]{permission}, requestCode);
}
}
// 处理申请结果
public void onRequestPermissionsResult(String permissions, int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mListener.onPermissionGranted();
} else {
mListener.onPermissionDenied();
}
}
// 打开app的详细页面
public void toAppDetail(int requestCode){
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", mActivity.getPackageName(), null);
intent.setData(uri);
mActivity.startActivityForResult(intent, requestCode);
}
}
事件接口
/**
* @Author: MuMu
* @Date: 2024/6/11 10:51
*/
public interface OnPermissionListener {
void onPermissionGranted();
void onPermissionDenied();
}
示例测试代码
import android.Manifest;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mumu.mulib.android.boot.permission.MuPermission;
import com.mumu.mulib.android.boot.permission.OnPermissionListener;
import com.mumu.mulib.android.window.MuDialog;
/**
* @Author: MuMu
* @Date: 2024/6/12 11:03
*/
public class TestActivity extends BaseActivity{
// 界面上的按钮
private Button button;
// 权限工具类
private MuPermission muPermission;
// 回调处理时的标志代码
private final int requestCode = 1001;
// 要申请的权限
private final String permission = Manifest.permission.CAMERA;
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setContentView(R.layout.activity_test);
// 初始化变量
button = findViewById(R.id.requestBtn);
muPermission = new MuPermission(this);
// 按钮事件
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 申请权限
muPermission.requestPermission(permission, requestCode, new OnPermissionListener() {
@Override
public void onPermissionGranted() {
// 已经获得权限
Toast.makeText(this, "同意了, 有权限", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied() {
// 没有权限,提示用户设置权限
showPermissionSettingDialog(); // 自定义的对话框
}
});
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 处理用户的操作结果
muPermission.onRequestPermissionsResult(permission, grantResults);
}
// 自定义的对话框,引导用户
private void showPermissionSettingDialog() {
MuDialog muDialog = new MuDialog(this);
muDialog.setMessage("请设置摄像头使用权限\n\n在跳转的页面中选择“应用权限”,再选择麦克风设置权限");
muDialog.setBtnClose("关闭", view1 -> {
muDialog.dismiss();
});
muDialog.setBtnOk("设置", view1 -> {
// 跳转app的详细页
muPermission.toAppDetail(requestCode);
muDialog.dismiss();
});
muDialog.show();
}
}
创建一个activity测试我们封装的权限申请工具类的功能,测试效果和上面的测试效果图一致。
到此本节文章内容已结束,谢谢您的阅读!
如有问题欢迎一起讨论!