深入 Google Android 6.0/7.0/8.0/9.0 之权限适配详解

Android6.0

The 6

Android的6.0版本,即盛传已久的Android M已经在Google 2015年的 I/O大会上被正式发布。一个在业内已经被热议的议题是:Android M“为工作升级而生”(Android for Work Update)。有业内人士解释道:“Android M将把Android的强大功能拓展至任何你所能看到的工作领域。”

根据Android系统以往的惯例,每一代新系统往往会根据其字母代号,对应一个关于零食的全名。如2014年在Google I/O大会上发布的Android L,其代号“L”一开始还只是Google为开发者称呼方便而准备的一个代号,但后来逐步演变成了“Lollipop”(棒棒糖Android 5.0)。所以,按照这种命名的传统,Android [字母]这种新模式也将意味着,一款新口味Android“零食”即将出现。

Google I/O 2015大会如约已于2015年5月28日举行。在发布会上代号为“Marshmallow(棉花糖)”的安卓6.0系统正式推出。

6.0较以往的版本(5.1之前) 有了很大的提升和变动 :

5.1之前如果需要某些权限 比如联网/获取WIFI信息/拍照/定位/打电话等 直接在Manifest.xml里面声明 <uses-permission xxx/>

就可以了

但6.0之后有了权限划分  普通和敏感权限  像联网INTERNET 之类的权限是不用去动态申请:

正常权限 不需要动态申请的:

  1. ACCESS_LOCATION_EXTRA_COMMANDS

  2. ACCESS_NETWORK_STATE

  3. ACCESS_NOTIFICATION_POLICY

  4. ACCESS_WIFI_STATE

  5. BLUETOOTH

  6. BLUETOOTH_ADMIN

  7. BROADCAST_STICKY

  8. CHANGE_NETWORK_STATE

  9. CHANGE_WIFI_MULTICAST_STATE

  10. CHANGE_WIFI_STATE

  11. DISABLE_KEYGUARD

  12. EXPAND_STATUS_BAR

  13. GET_PACKAGE_SIZE

  14. INSTALL_SHORTCUT

  15. INTERNET

  16. KILL_BACKGROUND_PROCESSES

  17. MODIFY_AUDIO_SETTINGS

  18. NFC

  19. READ_SYNC_SETTINGS

  20. READ_SYNC_STATS

  21. RECEIVE_BOOT_COMPLETED

  22. REORDER_TASKS

  23. REQUEST_IGNORE_BATTERY_OPTIMIZATIONS

  24. REQUEST_INSTALL_PACKAGES

  25. SET_ALARM

  26. SET_TIME_ZONE

  27. SET_WALLPAPER

  28. SET_WALLPAPER_HINTS

  29. TRANSMIT_IR

  30. UNINSTALL_SHORTCUT

  31. USE_FINGERPRINT

  32. VIBRATE

  33. WAKE_LOCK

  34. WRITE_SYNC_SETTINGS

特殊权限 需要动态申请的:

  1. CALENDAR

  2. CAMERA

  3. CONTACTS

  4. LOCATION

  5. MICROPHONE

  6. PHONE

  7. SENSORS

  8. SMS

  9. STORAGE

 检查和申请权限

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

# 检测是否已经被用户授予该权限

if (ContextCompat.checkSelfPermission(LaunchActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=           PackageManager.PERMISSION_GRANTED) {

# 没有被授予权限

# 判断如果已经被用户拒绝过一次(非永久拒绝),则显示用户此权限的一些说明,这里可以用toast,当然也可以用自定义界面来显示给用户,如果是采用自定义界面来显示给用户,在有“确定”,“取消”等按钮的情况下,下面的“请求权限”步骤要酌情调用

if (ActivityCompat.shouldShowRequestPermissionRationale(LaunchActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {

Toast.makeText(LaunchActivity.this, "request read external storage", Toast.LENGTH_LONG).show();

}

# 请求权限,数组传入多个值,可以一次请求多个权限

ActivityCompat.requestPermissions(LaunchActivity.this,

new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},

PERMISSIONS_REQUEST_EXTERNAL_STORAGE);

}

} else {

# 6.0以下版本,直接使用权限

// 做一些权限对应的操作

}

如果是在6.0及6.0以上版本时,执行 ActivityCompat.requestPermissions()方法请求权限后,如果用户同意或者拒绝后,会回调onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法,该方法的几个参数,我们做一下解释:

  1. requestCode 对应的是ActivityCompat.requestPermissions请求时的requestCode,这个与Activity中常用的onActivityResult方法中的requestCode类似,用来标识某一次或者某一个请求的回调对应关系

  2. permissions 对应ActivityCompat.requestPermissions()方法中请求的权限列表

  3. grantResults 对应2中permissions的每个权限的用户应答结果

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

switch (requestCode) {

case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {

// If request is cancelled, the result arrays are empty.

if (grantResults.length > 0

&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the

// contacts-related task you need to do.

} else {

// permission denied, boo! Disable the

// functionality that depends on this permission.

}

return;

}

}

}

权限申请的状态:

PackageManager.PERMISSION_DENIED:拒绝

PackageManager.PERMISSION_GRANTED:授权

Android 7.0

The 7

Android 7.0是Google推出的智能手机操作系统,最终官方代号,定名为“Nougat”(牛轧糖)。2016年的Google I/O开发者大会在美国西部时间2016年5月18-20日召开,地点为山景城的Shoreline Ampitheatre圆形剧场。在这里,新版的Android N系统正式发布。 

2016年8月22日,Google正式推送Android 7.0 Nougat正式版。

2016年12月5日,Google为Android 7.0发布了重要的维护性更新,也就是Android 7.1。  Android 7.1的一个小版本更新——安卓7.1.2已于2017年4月3日推送。

2017年5月5日,Google正式向开发者发出通知,宣布Andrdoid 7.0的Beta项目正式停止,最终版本止步在Android 7.1.2,让位于Android O。

继6.0依赖 每一年的版本对权限要求越来越严格,6.0的动态权限,7.0+又加入了临时环境缓存权限/7.0之前  比如拍照/打开文件等直接是

Intent intent = new Intent("android.intent.action.VIEW");  
intent.addCategory("android.intent.category.DEFAULT");  
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);  
Uri uri = Uri.fromFile(new File(picPath));  

String type = getMIMEType(picPath);
if ((null!=type) && (!TextUtils.isEmpty(type))) {
   intent.setDataAndType (uri, type);  
   context.startActivity(intent);  
}

直接通过隐式Intent去打开

但是在7.0之后是不可以了 需要加入以下方式:

在Manifest里面加入

<!--
适配7.0+
-->
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="apk的包名.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

然后再res/下新建xml文件夹/然后新建:

然后在代码里的:

Uri uri = Uri.fromFile(new File(picPath)); 

更改为:

Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
   uri =  FileProvider.getUriForFile(context, "com.luxiaofeng-你的应用包名 和mainfest声明的一致",newFile(picPath));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}else{
   uri = Uri.fromFile(new File(picPath));
}
intent.setDataAndType (uri, type);
context.startActivity(intent);

但是这里有一个隐形的BUG/也就是阿里巴巴安卓开发规范提出的:

所以写代码得要考虑使用环境 设备的不同  版本的不同等 

if (null != type && !TextUtils.isEmpty(type)) {
    intent.setDataAndType(uri, type);
    if (context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
        context.startActivity(intent);
    } else {
        //没有匹配到相关组件 
    }
}

Android 8.0

The 8

安装apk的权限也是需要动态申请,

Manifest:

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

Code:

int permission = ActivityCompat.checkSelfPermission(activity,
        Manifest.permission.REQUEST_INSTALL_PACKAGES);
if (permission != PackageManager.PERMISSION_GRANTED) {
    // We don't have permission so prompt the user
    ActivityCompat.requestPermissions(activity, PERMISSONS,
            REQUEST_EXTERNAL_STORAGE);
}
private static String[] PERMISSONS= {
   Manifest.permission.REQUEST_INSTALL_PACKAGES
};
发布了42 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_29769851/article/details/105663758