关于Android6.0权限设置问题

作者: wanbo_ | 来源:发表于2016-04-01 13:44 被阅读3399次
    • 虽然说 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:https://img.haomeiwen.com/i638069/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:https://img.haomeiwen.com/i638069/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:https://img.haomeiwen.com/i638069/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

    相关文章

      网友评论

        本文标题:关于Android6.0权限设置问题

        本文链接:https://www.haomeiwen.com/subject/lvtylttx.html