Android在API 23之后开启了危险权限动态申请的机制,具体有哪些权限这里不做赘述,只拿笔者在手机和TV端开发中用到的权限例举,示例Demo并没有依赖任何的第三方库,纯Android代码,大约130行左右。
Android运行时权限,6.0—9.0多版本,多终端(手机,TV盒子)130行代码一劳永逸_第1张图片

1.新建一个用于检查权限的Activity,定义申请权限数组和请求码,在onCreate中进行权限检查,将没有授权的权限添加到待申请列表。

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        ArrayList<String> needGetList = null;        for (String permission : mPermissions) {//            检查是否已经授权            if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED) {                if (needGetList == null){                    needGetList = new ArrayList<>();                }                //没有授权,添加到待申请列表                needGetList.add(permission);            }        }                // 进行申请动作        actionPermission(needGetList, needGetList == null ? true : false);    }

2.根据待申请集合和结果进行申请动作

    private void actionPermission(ArrayList<String> needGetList, boolean result){        //  有需要申请的权限        if (needGetList != null && needGetList.size() > 0){            System.out.println(needGetList.toString());            String[] arrays = new String[needGetList.size()];            for (int i = 0; i < needGetList.size(); i++) {                arrays[i] = needGetList.get(i);            }            ActivityCompat.requestPermissions(this, arrays, MY_PERMISSIONS_REQUEST_READ_CONTACTS);        }else {            if (result){                // 授权成功                Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();            }else {                Toast.makeText(this, "授权失败,您可之后到系统应用管理页面进行手动授权", Toast.LENGTH_SHORT).show();            }            startActivity(new Intent(this, HomeActivity.class));            finish();        }    }

3.重写onRequestPermissionsResult方法获取申请的结果

返回的permissions是所有发起申请的权限,grantResults是对应的申请结果,下标是一一对应的。判断grantResults的结果是不是PackageManager.PERMISSION_DENIED(被拒绝),如果有被拒绝的权限弹出对话框提示,如果没有则关闭页面。

    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        switch (requestCode) {            case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {                ArrayList<String> denied = new ArrayList<>();                for (int i = 0; i < grantResults.length; i++) {                    if (grantResults[i] == PackageManager.PERMISSION_DENIED){                        denied.add(permissions[i]);                    }                }                if (denied.size() > 0 ){                // 有未申请到得权限 需要弹框提醒                    showRationaleDialog(denied);                }else {//                    申请到所有权限  跳转页面                    actionPermission(null, true);                }            }        }    }

4.弹出对话框提示用户是否继续授权

点击继续授权跳转到系统应用管理中本应用的详情页面进行开启,点击取消提示用户授权失败并关闭页面(如遇必须权限可以提示用户不授权无法使用)
注:手机端打开详情页面没有问题,但部分TV盒子将应用详情给砍掉了,会打开失败。

    /**     * 弹出提示语     *     */    private void showRationaleDialog(final ArrayList<String> denied) {        AlertDialog.Builder builder = new AlertDialog.Builder(this);        builder.setTitle("提示");        TextView mMsg = new TextView(this);        mMsg.setText("您还有权限未授权完毕,将导致应用无法正常使用,是否跳转到系统设置界面继续授权?");        mMsg.setGravity(Gravity.CENTER_HORIZONTAL);        mMsg.setTextSize(18);        builder.setView(mMsg);        builder.setCancelable(false);        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                dialog.dismiss();                try{//                    打开系统 本应用的详情页面                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);                    intent.setData(Uri.fromParts("package", BeforeActivity.this.getPackageName(), null));                    BeforeActivity.this.startActivity(intent);                }catch (Exception e){                    Log.e(TAG, "打开当前本应用设置界面失败: " + e.getMessage());                    try{//                        打开系统已安装应用页面                        BeforeActivity.this.startActivity(new Intent(Settings.ACTION_APPLICATION_SETTINGS));                    }catch (Exception e2){                        Log.e(TAG, "打开应用设置界面失败: " + e.getMessage());                        Toast.makeText(BeforeActivity.this, "打开应用设置界面失败", Toast.LENGTH_SHORT).show();//                        如果都打开失败  提示用户手动之后手动开启权限  并关闭页面                        actionPermission(null, false);                    }                }                toAppDetail = true;            }        });        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                dialog.dismiss();                actionPermission(null, false);            }        });        Dialog tipDialog = builder.create();        tipDialog.setCanceledOnTouchOutside(false);        tipDialog.show();    }

5.从系统的应用详情页返回后

这里用的是重写onStart方法根据标志位来做的判断,页面重新可见后再次检查权限是否已经都可用,权限都可用就关闭页面,如果依然有未开启的权限则提示用户。

    @Override    protected void onStart() {        super.onStart();        if (toAppDetail){            toAppDetail = false;            for (String permission : mPermissions) {//            检查是否已经授权                if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED) {                    actionPermission(null, false);                    return;                }            }            actionPermission(null, true);        }    }

整体流程就是这样,经过测试目前在华为、荣耀、小米、vivo手机上都可以实现权限的动态申请,另外TV端在小米、天猫、当贝部分盒子上也可以实现动态获取。
Demo详情地址:https://github.com/TheTangEmperor/permissiondemo.git

更多相关文章

  1. Android 开发者从0到1发布一个微信小程序的采坑过程——使用帮助
  2. 【5年Android从零复盘系列之五】关于页面布局控件开发总结
  3. Android之权限管理
  4. Android 为【apk】文件签名,增加修改系统时间等权限
  5. Android AutoCompleteTextView控件实现类似百度搜索提示,限制输入
  6. Android兼容android7.0、及Android8.0以上apk安装权限问题(二)
  7. Android API 28 访问服务器失败 提示CLEARTEXT
  8. android页面全屏及状态栏和导航栏的(沉浸式)
  9. android studio中xml文件代码提示问题

随机推荐

  1. android 获得监听某一广播的所有程序
  2. Android手机中紧急号码的定制
  3. Android调用系统分享功能以及createChoos
  4. Android(安卓)Studio 简单功能介绍
  5. Android 动画1--View控件的显示和隐藏效
  6. android设置隐藏软键盘
  7. Android camera调用出现错误解决方法
  8. Android根据电话号码取得联系人姓名及头
  9. android:taskAffinity属性的简单测试
  10. 分享一段Android基于https协议POST数据的