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