Android开发之运行时权限申请和自定义权限

转载请注明出处:http://blog.csdn.net/li0978/article/details/52168827


运行时权限申请

Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,又新增了运行时权限动态检测,以下权限都需要在运行时判断(不判断则会报错):

身体传感器
日历
摄像头
通讯录
地理位置
麦克风
电话
短信
存储空间
申请过程如下:

首先触发权限申请:

public void onCameraClick(View view) {
        //判断权限是否已经同意
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            //1.还未同意
            requestCameraPermission();
        } else {
            //2.已同意
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivity(intent);
        }
    }
开始请求权限:

private void requestCameraPermission() {
        //判断“不在提醒”复选框是否展示
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
            //3.复选框显示时的请求
            ActivityCompat.requestPermissions(GooglePermissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
        } else {
            //4.复选框不显示时的请求
            ActivityCompat.requestPermissions(GooglePermissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
        }

        //如果需要针对“不在提醒”复选框显示时做一些处理用上边的方式,否者干脆直接请求权限(个人推荐后者)
//        ActivityCompat.requestPermissions(GooglePermissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
    }
这一步可以不仅仅可以请求一个权限也可以请求一组权限,另外也将会根据权限申请的过程展示不同的权限说明界面(都是系统给的),第一次请求是没有复选框的,第一次拒绝后第二次请求会多出一个复选框出来。

                

权限请求结果:

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CAMERA) {
            if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //5.回调权限申请成功
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivity(intent);
            } else {
                //6.回调权限申请拒绝
                Toast.makeText(this, "相机开启被拒绝,请到系统设置中开启相机权限。", Toast.LENGTH_LONG).show();
            }
        }
    }
这一步和Activity中执行startActivityForResult方法进行回调的onActivityResult()方法类似,这里可以根据当前请求某个权限的申请结果进行不同的处理。

根据上边三段代码中注释部分的编号,整个请求过程如下图所示:


在fragment中权限处理:

1.在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的onRequestPermissionsResult。

2.如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方法,onRequestPermissionsResult不会回调回来,建议使用getParentFragment().requestPermissions方法,这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调后传到子Fragment:

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        List<Fragment> fragments = getChildFragmentManager().getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                if (fragment != null) {
                    fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
                }
            }
        }
    }

自定义权限

在android系统的安全模型中,应用程序在默认的情况下不可以执行任何对其他应用程序,系统或者用户带来负面影响的操作。如果应用需要执行某些操作,就需要声明使用这个操作对应的权限。

一般情况下我们都是注册系统权限来满足对系统相关组件的操作,我们还可以自定义属于我们自己app的权限来满足来自其他程序安全的交互通信。

1.声明自定义权限:

<permission
        android:name="com.bigrun.permissionforandroidm.customerpermission1"
        android:description="@string/hello_world"
        android:label="@string/app_name"
        android:protectionLevel="normal" />

 
 自定义权限中标示说明: 
 

android:name :权限的唯一标识,一般都是使用 包名加权限名 。(必写)

android:label: 对权限的一个简短描述。

android:description :对权限的描述,一般是两句话,第一句话描述这个权限所针对的操作,第二句话告诉用户授予app这个权限会带来的后果 。

android:permissionGroup: 权限所属权限组的名称 。

android:protectionLevel: 权限的等级。(必写)

权限的等级分为如下四个:

normal 是最低的等级,声明此权限的app,系统会默认授予次权限,不会提示用户 。 dangerous  权限对应的操作有安全风险,系统在安装声明此类权限的app时会提示用户 ,在android6.0以上会出现运行时提示权限申请对话框。 signature  此权限的申请若想正常使用必须保证两个应用的签名一致。

signatureOrSystem  与signature类似,只是增加了rom中自带的app的声明 。

2.指定某个组件启动时使用此权限:

这里我们指定程序的主程序拥有此权限。

<activity android:name=".TestActivity" android:permission="com.bigrun.permissionforandroidm.customerpermission1">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
        </intent-filter>
</activity>
一定要有一个过滤器设置其启动方式为主界面启动。

3.在另一个应用中去启动此界面。

注册上一个应用程序的自定义权限:

<uses-permission android:name="com.example.customerpermission1"/>

启动上一个应用程序:

Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.bigrun.permissionforandroidm","com.bigrun.permissionforandroidm.TestActivity");
intent.setComponent(componentName);
startActivity(intent);

上边也可以设定一个权限组:

<permission-group
        android:name="com.bigrun.permissionforandroidm.customerpermissiongroup"
        android:description="@string/hello_world"
        android:label="@string/app_name" />

    <permission
        android:name="com.bigrun.permissionforandroidm.customerpermission1"
        android:description="@string/hello_world"
        android:label="@string/app_name"
        android:permissionGroup="com.bigrun.permissionforandroidm.customerpermissiongroup"
        android:protectionLevel="normal" />

在另外一个app中同样要注册这个权限组:

<uses-permission android:name="com.bigrun.permissionforandroidm.customerpermission1"/>
<permission-tree android:name="com.kifile.test.permission"/>














猜你喜欢

转载自blog.csdn.net/li0978/article/details/52168827