Android动态权限申请

9 篇文章 0 订阅
1 篇文章 0 订阅

动态申请权限

Android的权限机制并不是什么新鲜事物,从系统的第一个版本开始就已经存在了。但其实之前Android的权限机制在保护用户安全和隐私等方面起到的作用比较有限,尤其是一些大家都离不开的常用软件,非常容易“店大欺客”。为此,Android开发团队在Android 6.0系统中引用了运行时权限这个功能,从而更好地保护了用户的安全和隐私。

请求相机和SD卡写入权限的例子

最新在研究camera2时,在首次打开相机时需要动态请求权限,这里以"android.permission.CAMERA" 和"android.permission.WRITE_EXTERNAL_STORAGE" 为例记录下动态申请权限的示例,此示例基于android 11.0验证有效。

  1. 首先创建一个新项目,在 AndroidManifest.xml 中加入对应权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.myself.demo">

    ***<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />***

    <uses-feature
        android:name="android.hardware.camera2"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2.其次在MainActivity.java中做动态权限申请


public class MainActivity extends AppCompatActivity {

    private final int mRequestCode=100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //CameraManager cameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);


        //一般情况下在触发某个事件的时候再请求动态权限,比如点击事件!
        if(Build.VERSION.SDK_INT>=23){//6.0才用动态权限
            initPermission();
        }
    }

    //需要申请两个权限,拍照和SD读写
    //1、首先声明一个数组permissions,将需要的权限都放在里面
    String[] permissions=new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                      Manifest.permission.CAMERA};
    //2、创建一个mPermissionList,逐个判断哪些权限未授予,未授予的权限存储到mPerrrmissionList中
    List<String> mPermissionlist=new ArrayList<>();

    //权限判断和申请
    private void initPermission(){
        mPermissionlist.clear();//清空没有通过的权限

        //逐个判断你要的权限是否已经通过
        for(int i=0;i<permissions.length;i++){
            if(ContextCompat.checkSelfPermission(this,permissions[i])!=PackageManager.PERMISSION_GRANTED){
                mPermissionlist.add(permissions[i]);//添加还未授予的权限
            }
        }

        //申请权限
        if(mPermissionlist.size()>0){//有权限没有通过,需要申请
            ActivityCompat.requestPermissions(this,permissions,mRequestCode);
        }

    }

    //请求权限后回调的方法
    //参数: requestCode  是我们自己定义的权限请求码
    //参数: permissions  是我们请求的权限名称数组
    //参数: grantResults 是我们在弹出页面后是否允许权限的标识数组,数组的长度对应的是权限名称数组的长度,数组的数据0表示允许权限,-1表示我们点击了禁止权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean hasPermissionDismiss=false;//有权限没有通过
        if (mRequestCode == requestCode) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] == -1) {
                    hasPermissionDismiss = true;
                }
            }
            //如果有权限没有被允许
            if (hasPermissionDismiss) {
                showPermissionDialog();//跳转到系统设置权限页面,或者直接关闭页面,不让他继续访问
            }
        }
    }

    /**
     * 不再提示权限时的展示对话框
     */
    AlertDialog mPermissionDialog;

    private void showPermissionDialog() {
        if (mPermissionDialog == null) {
            mPermissionDialog = new AlertDialog.Builder(this)
                    .setMessage("已禁用权限,请手动授予")
                    .setCancelable(false)
                    .setPositiveButton("设置", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelPermissionDialog();

                            //跳转到设置权限界面
                            Intent intent = new Intent();
                            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package", MainActivity.this.getPackageName(), null);
                            intent.setData(uri);
                            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                            overridePendingTransition(0,0);
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //关闭页面或者做其他操作
                            finish();
                        }
                    })
                    .create();
        }
        mPermissionDialog.show();
    }

    //关闭对话框
    private void cancelPermissionDialog() {
        mPermissionDialog.cancel();
    }


}

代码中均已做了注释,可结合实际业务场景做修改。

3.当我们首次启动时,应用会弹框请求,如下为截图示例。
申请相机权限
申请SD卡写入权限
有权限未授权时的提示,点击设置会跳转到设置权限管理界面

4.当然,并不是所有权限都需要在运行时申请,对于用户来说,不停地授权也很烦琐。Android现在将所有的权限归成了两类,一类是普通权限,一类是危险权限。准确地讲,其实还有第三类特殊权限,不过这种权限使用得很少。
普通权限指的是那些不会直接威胁到用户的安全和隐私的权限,对于这部分权限申请,系统会自动帮我们进行授权,而不需要用户再去手动操作了。危险权限则表示那些可能会触及用户隐私或者对设备安全性造成影响的权限如获取设备联系人信息、定位设备的地理位置等,对于这部分权限申请,必须要由用户手动点击授权才可以,否则程序就无法使用相应的功能。

访问 Android权限列表 可以查看Android统中完整的权限列表。

  • 10
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android 中,有些权限需要动态申请,例如访问摄像头、存储等权限。以下是动态申请权限的步骤: 1. 在 AndroidManifest.xml 文件中声明需要申请权限。 2. 在 Activity 或 Fragment 中发起权限请求,通过调用 `ActivityCompat.requestPermissions()` 方法发起权限请求,该方法需要传入权限数组和请求码。 3. 在 `onRequestPermissionsResult()` 方法中处理权限请求结果,根据用户授权或拒绝的结果做出相应的处理。 下面是一个示例代码: ```java // 检查权限是否已经被授权 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { // 如果没有授权,则发起权限请求 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA); } else { // 如果已经授权,则执行相关操作 openCamera(); } // 处理权限请求结果 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_CAMERA: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户授权,执行相关操作 openCamera(); } else { // 用户拒绝授权,提示需要权限才能继续使用该功能 Toast.makeText(this, "需要摄像头权限才能使用该功能", Toast.LENGTH_SHORT).show(); } break; } } ``` 在上述示例中,如果用户没有授权访问摄像头,就会发起一个摄像头权限请求,请求码为 `MY_PERMISSIONS_REQUEST_CAMERA`,请求结果将在 `onRequestPermissionsResult()` 方法中处理。如果用户授权,则执行 `openCamera()` 方法打开摄像头,否则提示用户需要该权限才能继续使用该功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值