关于Android6.0权限设置问题

  • 虽然说 Google 已经放出了 Android M 预览版的 SDK ,但是根据目前市面上刚刚5.0的普及状况来说,想要适配7.0还有很长的一段路
  • 但是据消息而言,下半年国内厂商的旗舰机型不出意外,都应该会上 Android 6.0

6.0 之前的权限设置是怎么样的?

相信这个大家都不陌生,无非不就是在 AndroidManifest.xml 上添加几行代码么

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Bingo ! 就是这个样子!

那么6.0权限机制有什么改变?

  • 首先 Android 的权限机制,一直是关系着 Android 的安全问题
  • 6.0 以前我们只在安装 Android App 的时候会看到涉及到的权限,但是我们大多都不会注意,而且申请到的权限我们都无法修改禁止
  • 这样子就会给一些坏蛋利用权限来做一些损害用户利益的事情
  • 到 6.0 之后如果我们需要获取一些权限不能仅仅在安装时显示权限了,而是需要通过弹窗来提醒用户,让用户自己来选择
566.png
  • 有一点需要注意的时,权限询问弹窗是需要开发者自己在代码中添加的

如何在代码中添加权限判断?

  1. 首先你的项目需要支持 6.0 的编译环境,即 compileSdkVersion 和 targetSdkVersion 需要支持Api23,即Android 6.0
android {    
          compileSdkVersion 23    
          buildToolsVersion "23.0.2"    
  defaultConfig {        
          .......
          targetSdkVersion 23    
        }    
}   
  1. 接下来就是在代码中添加权限验证
    这里,我们假如要申请打电话的权限,相信这个大家一定不陌生,很多人开始学 Android 的第一个demo,应该就是通过 Intent 实现拨号打电话和发短信了吧?

    • 首先我们同样需要在 AndroidManifest.xml 添加需要的权限
         <uses-permission android:name="android.permission.CALL_PHONE"/>
      
    • 这里就是最重要的一点了,我们需要用到在 Api23 中新加入的方法 checkSelfPermission()requestPermissions()
      直接看代码
      //相当于设置一个标识符,在回调函数中可以对应操作
      

    final private int REQUEST_CODE_ASK_PERMISSIONS = 123;//
    /**

    • 判断当前权限是否允许,弹出提示框来选择
      */
      private void insertDummyContactWrapper() {
      // 需要验证的权限
      int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CALL_PHONE);
      if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
      // 弹窗询问 ,让用户自己判断
      requestPermissions(new String[] {Manifest.permission.CALL_PHONE},
      REQUEST_CODE_ASK_PERMISSIONS);
      return;
      }

      Toast.makeText(this,"危险权限已经申请",Toast.LENGTH_SHORT).show();
      String phone="1388888888";
      Intent intent=new Intent();
      intent.setAction(Intent.ACTION_CALL);
      intent.setData(Uri.parse("tel:" + phone));
      startActivity(intent);

    }

    /**

    • 用户进行权限设置后的回调函数 , 来响应用户的操作,无论用户是否同意权限,Activity都会
    • 执行此回调方法,所以我们可以把具体操作写在这里
    • @param requestCode
    • @param permissions
    • @param grantResults
      */

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch(requestCode) {
    case REQUEST_CODE_ASK_PERMISSIONS :
    if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
    //这里写你需要相关权限的操作
    }else{
    Toast.makeText(MainActivity.this,"权限没有开启",Toash.LENGTH_SHORT).show();
    }
    }
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }


## 不添加权限判断会发生什么?
 一张图告诉你

![无标题.png](http://upload-images.jianshu.io/upload_images/638069-a954ac4aeb9f6a75.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* 项目会崩溃 , 大致的意思就是说,存在权限异常,需要检查权限
* 注意,这里我们只是没有在代码中添加权限验证的代码,但在 AndroidManifest.xml 是申请了的
* 同样,仅仅在代码中添加了权限验证,而没有 AndroidManifest.xml 中申请,同样也是会报错的,二者缺一不可

## 所有的权限都需要判断么?

当然不是啦!如果那样真的会逼疯开发者的,233333

* 权限目前被分成了两种权限,Normal 和 Dangerous 
* 属于Normal的权限直接在AndroidManifest.xml中申请就好
* 属于Dangerous的权限则需要在代码中进行权限验证

下面是 Normal 权限

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT


下面是 Dangerous 权限
![Dangerous.png](http://upload-images.jianshu.io/upload_images/638069-47f8a823cdcaab8e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* 同时,需要注意的是 Dangerous 权限是按组分的,例如上图中 android.permission-group.PHONE 中就包含了 CALL_PHONE ,READ_PHONE_STATE 等一系列相关的权限,分在同一组的权限,任何一个权限被授权了,其他权限也自动被授权

### 特殊权限
Android 中有两个特殊权限,使用上面的方法是不成功的,需要特殊设置
* SYSTEM_ALERT_WINDOW
* WRITE_SETTINGS 

关于这两个权限,需要我们自己手动开启系统设置的Activity界面,如下图这样。
![手动开启.png](http://upload-images.jianshu.io/upload_images/638069-2f17dfc7fde6a98a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

代码设置:
``` java
      //权限申请相关方法
      private static final int REQUEST_CODE = 1;
      private void requestAlertWindowPermission() {    
              Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);  
              intent.setData(Uri.parse("package:" + getPackageName())); 
              startActivityForResult(intent, REQUEST_CODE);             
      }
      //回调
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);    
          if (requestCode == REQUEST_CODE) {        
               if (Settings.canDrawOverlays(this)) {            
                    Toast.makeText(this,"弹窗权限开启!",Toast.LENGTH_SHORT).show();            
                    PrefUtils.setBoolean(MainActivity.this, "isAllowAlert", true);        
                }else {           
                    PrefUtils.setBoolean(MainActivity.this, "isAllowAlert", false);        
                   }    
             }
        }

最后说几句

这里我只是向大家简单的介绍了 Android 6.0 的权限机制 ,以及简单的用法 。
如果想更详细的了解,这里有一篇文章可以推荐给大家 [Android M 新的运行时权限开发者需要知道的一切][1]
[1]: http://www.jianshu.com/p/e1ab1a179fbb

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容