Android动态申请权限
动态申请权限
Android的权限机制并不是什么新鲜事物,从系统的第一个版本开始就已经存在了。但其实之前Android的权限机制在保护用户安全和隐私等方面起到的作用比较有限,尤其是一些大家都离不开的常用软件,非常容易“店大欺客”。为此,Android开发团队在Android 6.0系统中引用了运行时权限这个功能,从而更好地保护了用户的安全和隐私。
请求相机和SD卡写入权限的例子
最新在研究camera2时,在首次打开相机时需要动态请求权限,这里以"android.permission.CAMERA" 和"android.permission.WRITE_EXTERNAL_STORAGE" 为例记录下动态申请权限的示例,此示例基于android 11.0验证有效。
- 首先创建一个新项目,在 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.当我们首次启动时,应用会弹框请求,如下为截图示例。
4.当然,并不是所有权限都需要在运行时申请,对于用户来说,不停地授权也很烦琐。Android现在将所有的权限归成了两类,一类是普通权限,一类是危险权限。准确地讲,其实还有第三类特殊权限,不过这种权限使用得很少。
普通权限指的是那些不会直接威胁到用户的安全和隐私的权限,对于这部分权限申请,系统会自动帮我们进行授权,而不需要用户再去手动操作了。危险权限则表示那些可能会触及用户隐私或者对设备安全性造成影响的权限如获取设备联系人信息、定位设备的地理位置等,对于这部分权限申请,必须要由用户手动点击授权才可以,否则程序就无法使用相应的功能。
访问 Android权限列表 可以查看Android统中完整的权限列表。