《Android Studio开发实战 从零基础到App上线(第2版)》在书后面的附录中给出了Android8和Android9的主要特性说明,附录表格如下图所示:


不过附录表格只涵盖了常见的功能代码适配,而Android8和Android9的众多新特性还涉及到其它的代码适配,下面就补充列出Android8、Android9、Android10的额外兼容处理说明:

Android8.0

1、属性动画组合AnimatorSet增加了setCurrentPlayTime和reverse方法,从而允许倒过来播放属性动画组合。
setCurrentPlayTime和reverse方法的调用方式示例如下:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {animSet.setCurrentPlayTime(0); // 设置当前播放的时间点animSet.reverse(); // 从动画尾巴开始倒播至setCurrentPlayTime设置的时间点}

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/animation/src/main/java/com/example/animation/ObjectGroupActivity.java

2、普通应用不允许修改系统设置
也就是Android8.0之后无法再调用系统设置的修改方法Settings.System.putInt,像原来在代码里调整屏幕亮度的办法就不再适用了。
完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/device/src/main/java/com/example/device/LightActivity.java

3、悬浮窗要使用类型TYPE_APPLICATION_OVERLAY,原来的类型TYPE_SYSTEM_ALERT从Android8.0开始被舍弃了。
设置悬浮窗类型的兼容代码示例如下:

    WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();// 设置为TYPE_SYSTEM_ALERT类型,才能悬浮在其它页面之上if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {// 注意TYPE_SYSTEM_ALERT从Android8.0开始被舍弃了wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;} else {// 从Android8.0开始悬浮窗要使用TYPE_APPLICATION_OVERLAYwmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;}

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/media/src/main/java/com/example/media/widget/FloatWindow.java

Android9.0

1、获取设备序列号的方式由Build.SERIAL改为Build.getSerial(),同时还需要先获得权限READ_PHONE_STATE
获取设备序列号的兼容代码示例如下:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {et_wifi_name.setText(Build.getSerial());} else {et_wifi_name.setText(Build.SERIAL);}

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/mixture/src/main/java/com/example/mixture/WifiApActivity.java

2、默认禁止访问http地址,只允许访问https地址。如果仍要访问http地址,需要修改配置
Android9开始默认使用加密连接,也就是只能访问https打头的网络地址,不能访问http打头的网络地址(如果访问http地址就会报错“No Network Security Config specified”)。此时要在network模块的res目录下面创建xml目录,并在xml目录下新建文件network_security_config.xml,文件内容如下所示:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config><base-config cleartextTrafficPermitted="true" />
</network-security-config>

然后打开network模块的AndroidManifest.xml,在该文件的application节点下增加android:networkSecurityConfig属性,也就是下面这样:

    <applicationandroid:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme"android:networkSecurityConfig="@xml/network_security_config"android:name=".MainApplication">

配置完毕重新运行network模块,就能访问http打头的地址了。
其它无法访问网络图片、无法打开网页、无法下载APK等问题,均可照此办理。或者直接把http换成https也行。

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/network/src/main/res/xml/network_security_config.xml
https://github.com/aqi00/android2/blob/master/network/src/main/AndroidManifest.xml

Android10

1、Android10默认开启沙箱模式,即使已经动态申请了存储卡读写权限,在外部存储上读写文件仍然失败。
首先确保代码已经添加动态申请存储权限的逻辑,然后给AndroidManifest.xml中的application节点增加以下属性:

        android:requestLegacyExternalStorage="true"

还要补充新的权限配置MANAGE_EXTERNAL_STORAGE,配置样例如下:

    <!-- Android10新增权限MANAGE_EXTERNAL_STORAGE --><uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/storage/src/main/AndroidManifest.xml

2、普通应用无法开启或者关闭WiFi功能
一旦build.gradle的targetSdkVersion设置29或更高数值(表示目标SDK版本为Android11或以上版本),则调用WifiManager实例的setWifiEnabled方法始终返回false,也就是无法成功设置WiFi的启用状态。此时要在代码中添加版本号判断,如果当前系统版本大于等于29,就不再开关WiFi,代码例子如下:

        if (Build.VERSION.SDK_INT >= 29) { // Android10之后,普通应用不能开关WiFick_wlan.setEnabled(false);} else {ck_wlan.setOnCheckedChangeListener(this);}

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/device/src/main/java/com/example/device/LocationSettingActivity.java

3、Android10新增了健身运动权限ACTIVITY_RECOGNITION
使用计步器时需要声明健身运动权限,改动点说明如下:
(1)修改AndroidManifest.xml,增加新的权限配置

    <!-- Android10之后,计步器需要健身运动权限 --><uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/device/src/main/AndroidManifest.xml
(2)打开计步器页面时需要动态申请健身运动权限android.permission.ACTIVITY_RECOGNITION,代码片段如下:

if (Build.VERSION.SDK_INT >= 29) {// Android10.0之后使用计步器需要健身运动权限if (PermissionUtil.checkPermission(this, "android.permission.ACTIVITY_RECOGNITION", (int) v.getId() % 4096)) {startActivity(new Intent(this, StepActivity.class));}
}

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/device/src/main/java/com/example/device/MainActivity.java

Android11

1、打包APK时必须勾选V2
依次选择菜单Build→Generate Signed Bundle/APK,在导出APK安装包的时候,V2复选框也要勾选,该选项可避免Janus漏洞,而且从Android11开始必须勾选V2,否则打出来的APK也无法安装。

2、Android11新增了查询所有应用的权限QUERY_ALL_PACKAGES
通常调用PackageManger的getInstalledApplications方法可以获取已安装的应用列表,获取代码示例如下:

List<ApplicationInfo> allApps = getPackageManager().getInstalledApplications(0);

但从Android11开始,还要修改AndroidManifest.xml,增加新的权限配置,以上代码才能查到所有已安装的应用。

    <!-- 查询所有已安装的应用(Android11新增权限) --><uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/custom/src/main/AndroidManifest.xml

3、Android11默认WebView不能访问存储卡上的网页

build.gradle中采用Android11编译时(targetSdkVersion 30),WebView无法访问存储卡的网页文件,此时要调用WebSettings的setAllowFileAccess方法设置为true。在Android10及以下版本,该值默认为true,但从Android11开始该值默认为false。
设置代码示例如下:

// 设置是否允许访问文件,如WebView访问存储卡的文件。
// 不过assets与res文件不受此限制,仍然可以通过“file:///android_asset”和“file:///android_res”访问
// Android11开始该值默认为false,故Android11必须设置为true才能访问存储卡的网页
wv_content.getSettings().setAllowFileAccess(true);

完整的代码例子见以下github页面
https://github.com/aqi00/android2/blob/master/mixture/src/main/java/com/example/mixture/fragment/HtmlFragment.java

Android8.0、9.0、10.0、11.0的新特性兼容适配代码修改相关推荐

  1. Primavera P6打补丁patch,从19.12.0.0升级到19.12.11.0

    给Primavera P6打补丁patch,从19.12.0.0升级到19.12.11.0,以下是升级过程 Patch Instructions 补丁 Database This database p ...

  2. Redis 5.0 正式版发布了,19 个新特性

    转载自  Redis 5.0 正式版发布了,19 个新特性 Redis 5.0 GA 正式版发布了! 下载地址: download.redis.io/releases/redis-5.0.0.tar. ...

  3. iOS 11新特性与适配

    iOS 11新特性与适配 1. UIView变化 1.1. 更加方便的RTL边距设置 1.2. 安全区域 2. UIViewController变化 2.1. 废除API 2.1.1. `automa ...

  4. C++11/14/17 新特性总结

    C++11/14/17 新特性总结 initializer_list std::vector<int> vctInts({92, 12, 39, 46, 92, 84, -1, 0, -2 ...

  5. 2020.10.20课堂笔记(java8新特性 lambda表达式)

    一.什么是Lambda? 我们知道,对于一个Java变量,我们可以赋给其一个"值". 如果你想把"一块代码"赋给一个Java变量,应该怎么做呢? 比如,我想把右 ...

  6. Java 11 正式发布,新特性解读

    Java 11 正式发布,新特性解读 杨晓峰   2018 年 9 月 26 日 话题:Java语言 & 开发 不知不觉 JDK 11 已经发布了,从 9 开始,JDK 进入了让人学不动的更新 ...

  7. Python 3.10 中的 6 个新特性,你体验了吗?

    作者 | Sara A. Metwalli 译者 | 有数可据 出品 | CSDN(ID:CSDNnews) 新的 Python 版本推出了有趣的新功能. Python 是当今最流行的编程语言之一.它 ...

  8. Flink 1.11.0 发布,有哪些值得关注的新特性?

    简介:7 月 7 日,Flink 1.11.0 正式发布.历时近 4 个月,Flink 在生态.易用性.生产可用性.稳定性等方面都进行了增强和改善.Apache Flink PMC.阿里巴巴高级技术专 ...

  9. [译]C#8.0中一个使接口更加灵活的新特性-默认接口实现

    9月份的时候,微软宣布正式发布C#8.0,作为.NET Core 3.0发行版的一部分.C#8.0的新特性之一就是默认接口实现.在本文中,我们将一起来聊聊默认接口实现. 众所周知,对现有应用程序的接口 ...

最新文章

  1. 用C语言解“支票问题”题
  2. UOJ46. 【清华集训2014】玄学
  3. iOS 12 真机调试 Xcode 9 提示 Could not locate device support files.
  4. C语言中的sizeof解析
  5. python多线程库_Python多线程常用包对比
  6. U-Boot 图形化配置及其原理
  7. DL_C1_week4_2(build a deep neural network 2)
  8. C++输出UNICODE字符集
  9. 免费 web api 接口大全
  10. python 管理windows客户端_Python管理Windows进程
  11. SDM439平台出现部分机型SD卡不能识别mmc1: error -110 whilst initialising SD card【学习笔记】...
  12. VNET原理与实现(1)
  13. supermap制作专题图并发布
  14. xcode 常见错误
  15. 一次因JDK夏令时导致接口输出日期格式的时间与预期时间不一致的bug排查
  16. Gos —— 显示器控制
  17. 什么是MySQL数据空洞?
  18. 监控安装ESXi on Arm的树莓派4b的CPU温度
  19. django-filer中文汉化无效的解决方案
  20. invoke 按钮点击_使用aspectj对app中按钮的快速点击进行处理

热门文章

  1. 3-java学习笔记
  2. Leetcode每日一题:155.min-stack(最小栈)
  3. 微机笔记2——8086/8088指令系统
  4. 蓝桥杯 基础练习 时间转换
  5. PBRNet:Progressive Boundary Refinement Network for Temporal Action Detection (AAAI 2020)
  6. 最少硬币找零系列问题(01背包,完全背包,多重背包动态规划)
  7. [APIO2017]商旅——分数优化+floyd+SPFA判负环+二分答案
  8. 按键精灵post教程_【按键精灵教程】更为强大的HTTP方法
  9. hbuilder能用python_Hbuilder之开发Python
  10. Java Applet 授权命令