彻底解决Android6.0权限管理问题
16lz
2022-05-11
随着Android版本的不断更新,Google的Android开发人员也想到了Android应用在权限管理方面的各种问题,让好多用户摸不着头脑就使用了用户的隐私数据。 为了在权限这方面加强管理,安卓平台权限一直有被流氓应用随便利用诟病,Android M的发布彻底解决了这一问题,取而代之的是, app不得不在运行时一个一个询问用户授予权限。Android 6.0(api23)M系统中,做了一些限制, 开发者在使用到每条权限时必须自己调用相关代码请求。 如果没有获得某项权限,直接使用相关功能,则会导致自己程序crash.。为了解决这方面的问题,我们每次请求某一个权限要写好多代码解决这个问题,非常的麻烦。 下面是我做的一个轻量级的封装,可以减少很多重复的工作。
效果图 请求权限
用户禁止了权限
一.Android6.0M对权限的划分
Android6.0M中对用户的权限分为了一般权限和危险权限,这些危险权限除了在AndroidManifest.xml中注册以外,还需要在使用的时候对用户进行请求权限弹窗提醒,才可以使用。 这些危险权限如下:
二.封装一个MPermissionsActivity的思路和步骤
- 第一步:检测所有的权限是否都已授权
/** * 检测所有的权限是否都已授权 * * @param permissions * @return */ private boolean checkPermissions(String[] permissions) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; }
- 第二步:获取权限集中需要申请权限的列表
/** * 获取权限集中需要申请权限的列表 * * @param permissions * @return */ private List getDeniedPermissions(String[] permissions) { List needRequestPermissionList = new ArrayList<>(); for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED || ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { needRequestPermissionList.add(permission); } } return needRequestPermissionList; }
- 第三步:请求权限
/** * 请求权限 * * @param permissions 请求的权限 * @param requestCode 请求权限的请求码 */ public void requestPermission(String[] permissions, int requestCode) { this.REQUEST_CODE_PERMISSION = requestCode; if (checkPermissions(permissions)) { permissionSuccess(REQUEST_CODE_PERMISSION); } else { List needPermissions = getDeniedPermissions(permissions); ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_CODE_PERMISSION); } }
- 第四步:处理权限请求回调
/** * 系统请求权限回调 * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_PERMISSION) { if (verifyPermissions(grantResults)) { permissionSuccess(REQUEST_CODE_PERMISSION); } else { permissionFail(REQUEST_CODE_PERMISSION); showTipsDialog(); } } }
- 第五步:查看处理权限请求回调用户是否已经授权
/** * 确认所有的权限是否都已授权 * * @param grantResults * @return */ private boolean verifyPermissions(int[] grantResults) { for (int grantResult : grantResults) { if (grantResult != PackageManager.PERMISSION_GRANTED) { return false; } } return true; }
- 第六步:授权成功处理函数
/** * 获取权限成功 * * @param requestCode */ public void permissionSuccess(int requestCode) { Log.d(TAG, "获取权限成功=" + requestCode); }
- 第七步:授权失败处理函数与弹出用户提示
/** * 权限获取失败 * @param requestCode */ public void permissionFail(int requestCode) { Log.d(TAG, "获取权限失败=" + requestCode); } /** * 显示提示对话框 */ private void showTipsDialog() { 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) { startAppSettings(); } }).show(); }
- 第八步:授权失败给用户提示后想再次开启跳到设置app权限界面
/** * 启动当前应用设置页面 */ private void startAppSettings() { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); }
三.完整的MPermissionsActivity代码
import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Build;import android.provider.Settings;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.util.Log;import java.util.ArrayList;import java.util.List;/** * Created by hyczlf on 2017-02-19. */public class MPermissionsActivity extends AppCompatActivity { private final String TAG = "MPermissions"; private int REQUEST_CODE_PERMISSION = 0x00099; /** * 请求权限 * * @param permissions 请求的权限 * @param requestCode 请求权限的请求码 */ public void requestPermission(String[] permissions, int requestCode) { this.REQUEST_CODE_PERMISSION = requestCode; if (checkPermissions(permissions)) { permissionSuccess(REQUEST_CODE_PERMISSION); } else { List needPermissions = getDeniedPermissions(permissions); ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_CODE_PERMISSION); } } /** * 检测所有的权限是否都已授权 * * @param permissions * @return */ private boolean checkPermissions(String[] permissions) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } /** * 获取权限集中需要申请权限的列表 * * @param permissions * @return */ private List getDeniedPermissions(String[] permissions) { List needRequestPermissionList = new ArrayList<>(); for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED || ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { needRequestPermissionList.add(permission); } } return needRequestPermissionList; } /** * 系统请求权限回调 * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_PERMISSION) { if (verifyPermissions(grantResults)) { permissionSuccess(REQUEST_CODE_PERMISSION); } else { permissionFail(REQUEST_CODE_PERMISSION); showTipsDialog(); } } } /** * 确认所有的权限是否都已授权 * * @param grantResults * @return */ private boolean verifyPermissions(int[] grantResults) { for (int grantResult : grantResults) { if (grantResult != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } /** * 显示提示对话框 */ private void showTipsDialog() { 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) { startAppSettings(); } }).show(); } /** * 启动当前应用设置页面 */ private void startAppSettings() { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); } /** * 获取权限成功 * * @param requestCode */ public void permissionSuccess(int requestCode) { Log.d(TAG, "获取权限成功=" + requestCode); } /** * 权限获取失败 * @param requestCode */ public void permissionFail(int requestCode) { Log.d(TAG, "获取权限失败=" + requestCode); }}
四.用法
- 布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
- MainActivity中使用:继承MPermissionsActivity即可
import android.Manifest;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.view.View;public class MainActivity extends MPermissionsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 打电话 * * @param view */ public void onClick1(View view) { requestPermission(new String[]{Manifest.permission.CALL_PHONE}, 0x0001); } /** * 写SD卡 * * @param view */ public void onClick2(View view) { requestPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0x0002); } /** * 拍照 * * @param view */ public void onClick3(View view) { requestPermission(new String[]{Manifest.permission.CAMERA}, 0x0003); } /** * 权限成功回调函数 * * @param requestCode */ @Override public void permissionSuccess(int requestCode) { super.permissionSuccess(requestCode); switch (requestCode) { case 0x0001: Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:13468857714")); startActivity(intent); break; } }}
更多相关文章
- Android(安卓)开发的常用工具类(一)——ScreenUtils 可用于获取屏
- Android(安卓)上下文菜单:给ListView注册ContextMenu后获取被长按
- Android获取屏幕分辨率及DisplayMetrics简介
- android以后台service的方式获取GPRS数据
- Android(安卓)各大网络请求库的比较及实战
- Android悬浮窗使用小结
- androidManifest.xml之uses-permission(权限-安全控制)
- Android(安卓)root原理
- Android多媒体学习一:Android中Image的简单实例。