Android 6.0 (M) 系统特性详解

 一.简介

 

Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,而是更加的注重用户的隐私和体验,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装的事情,也不会再不征求用户授权的情况下,就可以任意的访问用户隐私,而且即使在授权之后也可以及时的更改权限。这就是6.0版本做出的更拥护和注重用户的一大体现。

 

Android6.0系统把权限分为两个级别:

 

一类是Normal Permissions,即普通权限,这类权限不会潜藏有侵害用户隐私和安全的问题,比如,访问网络的权限,访问WIFI的权限等。

 

一类是Dangerous Permissions,即危险权限,这类权限会直接的威胁到用户的安全和隐私问题,比如说访问短信,相册等权限,地理位置权限。

 

 

 

 

 

 

二.权限

 

<1> 普通权限举例

ACCESS_LOCATION_EXTRA_COMMANDS

ACCESS_NETWORK_STATE

ACCESS_NOTIFICATION_POLICY

ACCESS_WIFI_STATE

BLUETOOTH

BLUETOOTH_ADMIN

BROADCAST_STICKY

CHANGE_NETWORK_STATE

CHANGE_WIFI_MULTICAST_STATE

CHANGE_WIFI_STATE

DISABLE_KEYGUARD

EXPAND_STATUS_BAR

GET_PACKAGE_SIZE

INSTALL_SHORTCUT

INTERNET

KILL_BACKGROUND_PROCESSES

MODIFY_AUDIO_SETTINGS

NFC

READ_SYNC_SETTINGS

READ_SYNC_STATS

RECEIVE_BOOT_COMPLETED

REORDER_TASKS

REQUEST_IGNORE_BATTERY_OPTIMIZATIONS

REQUEST_INSTALL_PACKAGES

SET_ALARM

SET_TIME_ZONE

SET_WALLPAPER

SET_WALLPAPER_HINTS

TRANSMIT_IR

UNINSTALL_SHORTCUT

USE_FINGERPRINT

VIBRATE

WAKE_LOCK

WRITE_SYNC_SETTINGS

使用以上权限是不会威胁到用户安全的,所以这类权限是可以直接的在manifest里面直接的使用,而且在安装后也会直接的生效了。

 

 

 

 

<2> 危险权限(敏感权限)举例

SMS(短信)

   SEND_SMS

   RECEIVE_SMS

   READ_SMS

   RECEIVE_WAP_PUSH

   RECEIVE_MMS


<uses-permission android:name="android.permission.SEND_SMS"/>

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

<uses-permission android:name="android.permission.READ_SMS"/>

<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>

<uses-permission android:name="android.permission.RECEIVE_MMS"/>



**********************************************************************



STORAGE(存储卡)

   READ_EXTERNAL_STORAGE

   WRITE_EXTERNAL_STORAGE


<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

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


**********************************************************************



CONTACTS(联系人)
   
   READ_CONTACTS

   WRITE_CONTACTS

   GET_ACCOUNTS


<uses-permission android:name="android.permission.READ_CONTACTS"/>

<uses-permission android:name="android.permission.WRITE_CONTACTS"/>

<uses-permission android:name="android.permission.GET_ACCOUNTS"/

************************************************************************



PHONE(手机)

   READ_PHONE_STATE

   CALL_PHONE

   READ_CALL_LOG

   WRITE_CALL_LOG

   ADD_VOICEMAIL

   USE_SIP

   PROCESS_OUTGOING_CALLS


<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<uses-permission android:name="android.permission.CALL_PHONE"/>

<uses-permission android:name="android.permission.READ_CALL_LOG"/>

<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>

<uses-permission android:name="android.permission.ADD_VOICEMAIL"/>

<uses-permission android:name="android.permission.USE_SIP"/>

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

************************************************************************



CALENDAR(日历)

   READ_CALENDAR

   WRITE_CALENDAR


<uses-permission android:name="android.permission.READ_CALENDAR"/>

<uses-permission android:name="android.permission.WRITE_CALENDAR"/>

*************************************************************************



CAMERA(相机)

   CAMERA


<uses-permission android:name="android.permission.CAMERA"/>

*************************************************************************



LOCATION(位置)
   
   ACCESS_FINE_LOCATION

   ACCESS_COARSE_LOCATION


<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

*************************************************************************



SENSORS(传感器)

   BODY_SENSORS


<uses-permission android:name="android.permission.BODY_SENSORS"/>

**************************************************************************



MICROPHONE(麦克风)

   RECORD_AUDIO

<uses-permission android:name="android.permission.RECORD_AUDIO"/>

 

 

注意:

危险权限和普通权限也有区别,普通权限是单条的权限,而危险权限是以组展示的,也就是说,当你接受一个危险权限时,不但但接受的是界面上展示的这一个权限,而是它所在这个组里面的其他所有访问权限也将会被自动获取权限,比如,一旦WRITE_CONTACTS被授权了,App也有READ_CONTACTS和GET_ACCOUNTS的权限了。值得注意的是,这类权限也是需要在manifest中注册的。

 

 

 

 

 

 

 

 

三.Demo

写一个Demo,动态申请 联系人和相机的权限

 

 

清单文件

<!--   手机联系人 读 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--   手机联系人 写 -->
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<!--   手机联系人 获取 -->
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>


<!-- 相机 -->
<uses-permission android:name="android.permission.CAMERA"/>


<!-- 传感器 -->
<uses-permission android:name="android.permission.BODY_SENSORS"/>

 

 

工具类

package com.example.test;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class AndroidPermissionUtils {

    /**
     * 当前系统是否是Android 6.0及以上
     */

    public static boolean isMarshmallow = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;

    /**
     * Android 6.0及以上 检测是否具有某些权限
     */

    public static boolean hasAndroidPermission(Context context, String[] permission) {
        boolean has = true;
        for (String per : permission) {
            if (ContextCompat.checkSelfPermission(context, per) != PackageManager.PERMISSION_GRANTED) {
                has = false;
                break;
            }
        }
        return has;
    }

    /**
     * Android 6.0及以上 申请某些权限
     */

    public static void requestAndroidPermission(Activity activity, int code, String[] permission) {
        ActivityCompat.requestPermissions(activity, permission, code);
    }

}

 

 

Activity

package com.example.test;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;

public class PermissionActivity extends AppCompatActivity {

    //手机联系人
    private String permission1 = "android.permission.READ_CONTACTS";
    private String[] permission11 = new String[]{permission1};//敏感权限
    private int Code1 = 123;

    //相机权限
    private String permission2 = "android.permission.CAMERA";
    private String[] permission22 = new String[]{permission2};//敏感权限
    private int Code2 = 456;

    //传感器
    private String permission3 = "android.permission.BODY_SENSORS";
    private String[] permission33 = new String[]{permission3};//敏感权限
    private int Code3 = 789;

    private String[] permission = new String[]{permission1, permission2, permission3};//总权限
    private int Code = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_permission);
        initView();
    }

    /**
     * 初始化各种View
     */

    private void initView() {

        initPermissions();

        //手机联系人权限相关
        TextView textView1 = findViewById(R.id.activity_permission_textview1);
        textView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (AndroidPermissionUtils.isMarshmallow) {//6.0及以上
                    if (AndroidPermissionUtils.hasAndroidPermission(PermissionActivity.this, permission11)) {//有权限 直接操作
                        getPhone("6.0及以上有权限 直接操作");
                    } else {//没权限 申请
                        AndroidPermissionUtils.requestAndroidPermission(PermissionActivity.this, Code1, permission11);
                    }
                } else {//6.0以下 直接操作
                    getPhone("6.0以下 直接操作");
                }
            }
        });


        //相机权限相关
        TextView textView2 = findViewById(R.id.activity_permission_textview2);
        textView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (AndroidPermissionUtils.isMarshmallow) {//6.0及以上
                    if (AndroidPermissionUtils.hasAndroidPermission(PermissionActivity.this, permission22)) {//有权限 直接操作
                        getCamera("6.0及以上有权限 直接操作");
                    } else {//没权限 申请
                        AndroidPermissionUtils.requestAndroidPermission(PermissionActivity.this, Code2, permission22);
                    }
                } else {//6.0以下 直接操作
                    getCamera("6.0以下 直接操作");
                }
            }
        });


        //传感器权限相关
        TextView textView3 = findViewById(R.id.activity_permission_textview3);
        textView3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (AndroidPermissionUtils.isMarshmallow) {//6.0及以上
                    if (AndroidPermissionUtils.hasAndroidPermission(PermissionActivity.this, permission33)) {//有权限 直接操作
                        getSensors("6.0及以上有权限 直接操作");
                    } else {//没权限 申请
                        AndroidPermissionUtils.requestAndroidPermission(PermissionActivity.this, Code3, permission33);
                    }
                } else {//6.0以下 直接操作
                    getSensors("6.0以下 直接操作");
                }
            }
        });
    }

    /**
     * 手机联系人
     */

    private void getPhone(String type) {
        Log.d("PermissionActivity", "手机联系人type----:" + type);
        ArrayList<HashMap<String, String>> list = readContact();
        int count = list.size();
        StringBuilder sb = new StringBuilder();
        sb.append("当前设备联系人数:" + count + "\n\n\n");
        for (int i = 0; i < count; i++) {
            HashMap<String, String> map = list.get(i);
            String name = map.get("name");
            String phone = map.get("phone");
            sb.append("姓名:" + name + "     手机号:" + phone + "\n\n\n");
        }
        String result = sb.toString();
        Log.d("PermissionActivity", "手机联系人result----:" + result);
    }

    /**
     * 相机权限
     */

    private void getCamera(String type) {
        Log.d("PermissionActivity", "相机权限type----:" + type);
    }

    /**
     * 传感器权限
     */

    private void getSensors(String type) {
        Log.d("PermissionActivity", "传感器权限type----:" + type);
    }

    /**
     * 初始化时申请三个权限
     */

    private void initPermissions() {
        if (AndroidPermissionUtils.isMarshmallow) {//6.0及以上
            AndroidPermissionUtils.requestAndroidPermission(PermissionActivity.this, Code, permission);
        }
    }

    /**
     * 权限回调
     */

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.d("PermissionActivity", "权限回调requestCode----:" + requestCode);
        Log.d("PermissionActivity", "权限回调permissions.toString()----:" + permissions.toString());
        Log.d("PermissionActivity", "权限回调permissions.length----:" + permissions.length);
        Log.d("PermissionActivity", "权限回调grantResults.toString()----:" + grantResults.toString());
        Log.d("PermissionActivity", "权限回调grantResults.length----:" + grantResults.length);
        if (Code1 == requestCode) {//联系人权限相关
            if (grantResults.length > 0 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {//同意了权限
                getPhone("同意了权限——回调");
            } else {//拒绝了权限
                Log.d("PermissionActivity", "联系人权限相关 拒绝了权限——回调");
            }
        } else if (Code2 == requestCode) {//相机权限相关
            if (grantResults.length > 0 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {//同意了权限
                getCamera("同意了权限——回调");
            } else {//拒绝了权限
                Log.d("PermissionActivity", "相机权限相关 拒绝了权限——回调");
            }
        } else if (Code3 == requestCode) {//传感器权限相关
            if (grantResults.length > 0 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {//同意了权限
                getSensors("同意了权限——回调");
            } else {//拒绝了权限
                Log.d("PermissionActivity", "传感器权限相关 拒绝了权限——回调");
            }
        } else if (Code == requestCode) {//初始化申请的三个权限
            if (grantResults.length == 3) {
                if ((grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    getPhone("初始化——同意了权限——回调");
                } else {
                    Log.d("PermissionActivity", "联系人权限相关 初始化—拒绝了权限——回调");
                }

                if ((grantResults[1] == PackageManager.PERMISSION_GRANTED)) {
                    getCamera("初始化——同意了权限——回调");
                } else {
                    Log.d("PermissionActivity", "相机权限相关 初始化——拒绝了权限——回调");
                }

                if ((grantResults[2] == PackageManager.PERMISSION_GRANTED)) {
                    getSensors("初始化——同意了权限——回调");
                } else {
                    Log.d("PermissionActivity", "传感器权限相关 初始化——拒绝了权限——回调");
                }
            }
        }
    }

    /**
     * 获取当前设备联系人信息
     * 1.从raw_contacts中读取联系人的id("contact_id")
     * 2.根据contact_id从data表中查询出相应的电话号码和联系人名称
     * 3.根据mimetype来区分哪个是联系人,哪个是电话号码
     */

    private ArrayList<HashMap<String, String>> readContact() {
        Uri rawContactsUri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri dataUri = Uri.parse("content://com.android.contacts/data");
        ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
        //从raw_contacts中读取联系人的id("contact_id")
        Cursor rawContactsCursor = getContentResolver().query(rawContactsUri, new String[]{"contact_id"}, null, null, null);
        if (rawContactsCursor != null) {
            while (rawContactsCursor.moveToNext()) {
                String contactId = rawContactsCursor.getString(0);
                //根据contact_id从data表中查询出相应的电话号码和联系人名称, 实际上查询的是视图view_data
                Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"data1", "mimetype"}, "contact_id=?", new String[]{contactId}, null);
                if (dataCursor != null) {
                    HashMap<String, String> map = new HashMap<String, String>();
                    while (dataCursor.moveToNext()) {
                        String data1 = dataCursor.getString(0);
                        String mimetype = dataCursor.getString(1);
                        if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
                            map.put("phone", data1);
                        } else if ("vnd.android.cursor.item/name".equals(mimetype)) {
                            map.put("name", data1);
                        }
                    }
                    list.add(map);
                    dataCursor.close();
                }
            }
            rawContactsCursor.close();
        }
        return list;
    }

}

 

 

注意

<1> 敏感权限动态申请一个分组下只申请一个就好。

 

<2> 权限回调方法中可以根据requestCode判断具体是申请的那个敏感权限,进而判断是同意了还是拒绝了。

 

 

附:官网:https://developer.android.google.cn/about/versions/marshmallow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值