前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 6.0运行时权限理解

Android 6.0运行时权限理解

作者头像
用户3004328
发布2018-09-06 17:14:51
7950
发布2018-09-06 17:14:51
举报
文章被收录于专栏:增长技术

Android6.0运行时权限 思维导图

如果设备运行在5.1或者以下的设备,或者targetSdkVersion在22或以下,系统会在安装app的时候让用户授权权限。再说一遍,系统只会提示用户app需要的权限组,而不会提示某一个特定的权限。

  1. 检测权限
代码语言:javascript
复制
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M //6.0及以上


//current activity
int checkPermission = ContextCompat
	.checkSelfPermission(activity,Manifest.permission.WRITE_CALENDAR);
  1. 请求权限
代码语言:javascript
复制
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    //判断是否需要 向用户解释,为什么要申请该权限
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // 是否需要弹出一个解释申请该权限的提示给用户,如果为true,则可以弹

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                REQUEST_PERMISSIONS_READ_CONTACTS_CODE);

    }
}
  1. 处理请求权限结果
代码语言:javascript
复制
@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_PERMISSIONS_READ_CONTACTS_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 授权成功
                ...
            } else {
					// 权限拒绝
					...
		 		 }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

SYSTEM_ALERT_WINDOW

代码语言:javascript
复制
if (!Settings.canDrawOverlays(this)) {
     Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
     startActivityForResult(intent,1);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
        if (!Settings.canDrawOverlays(this)) {
            // SYSTEM_ALERT_WINDOW permission not granted...
            Toast.makeText(this,"not granted",Toast.LENGTH_SHORT);
        }
    }
}

WRITE_SETTINGs

代码语言:javascript
复制
if(!Settings.System.canWrite(this)){
     Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
             Uri.parse("package:" + getPackageName()));
     startActivityForResult(intent, REQUEST_CODE);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
       if (Settings.System.canWrite(this)) {
           //检查返回结果
          Toast.makeText(MainActivity.this, "WRITE_SETTINGS permission granted", Toast.LENGTH_SHORT).show();
        } else {
          Toast.makeText(MainActivity.this, "WRITE_SETTINGS permission not granted", Toast.LENGTH_SHORT).show();
        }
    }
}

自定义权限

为了执行自定义权限,你必须在你的manifest中声明一个或多个标签。

比如:

代码语言:javascript
复制
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.app.myapp" >
    <permission android:name="com.app.myapp.permission.DEADLY_ACTIVITY"
        android:label="@string/permlab_deadlyActivity"
        android:description="@string/permdesc_deadlyActivity"
        android:permissionGroup="android.permission-group.COST_MONEY"
        android:protectionLevel="dangerous" />
    ...
</manifest>

<protectionLevel>属性是必须的,告诉系统当app申请该权限的时候,要怎样通知用户。

<permissionGroup>属性是可选的,可以帮助系统显示自定义属性属于哪个权限组,当通知用户弹出框的时候,当然你可以选择某一个自定义权限属于已知的权限组,也可以属于某一个自定义权限组,建议属于已知的权限组。

<android:label>相当于权限组的提示,要简短

<android:description>是某一个特定权限的描述,规则是两句话,第一句描述,第二句警告用户如果授权会发生什么后果。

比如,CALL_PHONE权限

代码语言:javascript
复制
<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the application to call
   phone numbers without your intervention. Malicious applications may
   cause unexpected calls on your phone bill. Note that this does not
   allow the application to call emergency numbers.
</string>
  • targetSdkVersion如果是23以下,调用ActivityCompat.requestPermissions(),会弹出权限选择对话框,但是选择拒绝授权,onRequestPermissionsResult中的返回值却是PERMISSION_GRANTED,但选择同意授权,会把应用关闭重新开启当前activity,而不会调用onRequestPermissionsResult中的方法,所以不要在targetSdkVersion设置为23以下,又把complierSdkversion设置为23,这样会出现上述的问题。最好的方式是把targetSdkVersion也设置为23,就可以解决。一切完美运行。*

即:

  1. targetSdkVersion<23, 不要调用处理权限的代码,走老的权限模式。

代码语言:javascript
复制
1.  如果在targetSdkVersion<23时,调用了处理权限的代码。在Android M运行targetSdkVersion < 23的应用时,调用checkSelfPermission,不管用户是否取消授权,checkSelfPermission的返回值始终为PERMISSION_GRANTED的解决办法
代码语言:javascript
复制
		public boolean selfPermissionGranted(String permission) {
	        // For Android < Android M, self permissions are always granted.
	        boolean result = true;

	        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

	            if (targetSdkVersion >= Build.VERSION_CODES.M) {
	                // targetSdkVersion >= Android M, we can
	                // use Context#checkSelfPermission
	                result = context.checkSelfPermission(permission)
	                        == PackageManager.PERMISSION_GRANTED;
	            } else {
	                // targetSdkVersion < Android M, we have to use PermissionChecker
	                result = PermissionChecker.checkSelfPermission(context, permission)
	                        == PermissionChecker.PERMISSION_GRANTED;
	            }
	        }

	        return result;
	  }

  1. targetSdkVersion>=23,complierSdkVersion>=23, 必须调用处理权限的代码,来处理运行时权限,走新的权限模式。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SYSTEM_ALERT_WINDOW
  • WRITE_SETTINGs
  • 自定义权限
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档