转载请注明出处: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"/>