Android 6.0 (M) 系统特性详解

xiaoxiao2021-02-27  354

 一.简介

 

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

转载请注明原文地址: https://www.6miu.com/read-1466.html

最新回复(0)