-
项目地址:Github
-
当我在做 Android 版本适配工作的时候很痛苦,那个时候我在想有没有一个文档,将所有的关于 Android 版本适配资料全部收集起来,这样就不需要在网上东找西找了,这样就能把时间和精力投入适配工作中,每当一个新的 Android 版本发布的时候,这个想法越加强烈,终于在 Android 11 刚发布的时候筹划了这件事情,最终赶在 Android 12 刚发布的时候完成了,整个过程耗时非常漫长,因为我正在不断收集优质的资料,同时我也在不断思考,什么样的适配文档才是大家所需要的,我将适配文档简单划分成了以下几部分:
-
官方文档
-
新特性
-
行为变更
-
-
相关资源
-
适配文章链接
-
适配框架链接
-
-
-
为什么要把这个做成开源项目?因为我会不断更新,同时欢迎大家如果有好的文章也可以通过 issue 推荐给我,我审核通过之后会放上去,做好一个开源项目需要大家的添砖加瓦,开源是一个互帮互助的过程,没有大家的支持我很难做好它。
- 这里以适配
Android 14
为例子,第一步将主模块中的build.gradle
文件中修改targetSdkVersion
和compileSdkVersion
这两个的值
android {
compileSdkVersion 34
defaultConfig {
......
targetSdkVersion 34
}
}
- 接下来在代码中做一些版本的判断,并且做好新版本的适配和旧版本的兼容
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
......
} else {
......
}
if (context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
......
} else {
......
}
-
到这里,大家可能有一个疑问,targetSdkVersion 和 compileSdkVersion 有啥区别?
-
targetSdkVersion:目标适配版本,告知系统 App 适配的情况,如果应用的 targetSdkVersion 比系统版本要低,那么在一些新特性上新系统会做向下兼容性处理,如果我们想要适配某个 Android 版本,必须要将 targetSdkVersion 调整到这个版本等级之上,否则在某些机型上面可能会出现一些适配异常的情况。如果我们只是简单调高了 targetSdkVersion 等级而没有适配新版本的特性,那么应用在新系统上可能会出现功能异常的情况,一般情况表现为应用崩溃或者获取不到数据。
-
compileSdkVersion:编译源码版本,我们可以通过修改这个版本等级来改变我们在代码中所看到的 Android SDK 源码的版本,同时也决定了编译器在进行代码检查时所用的版本。
-
-
最后附上一张 Android 版本信息对应表
Android 版本 | API 等级 | 版本代号 | 市场占有率 | 发布时间 |
---|---|---|---|---|
Android 14 | 34 | UPSIDE_DOWN_CAKE |
暂无数据 | 2023 年 10 月 10 日 |
Android 13 | 33 | TIRAMISU |
30.33% | 2022 年 8 月 16 日 |
Android 12L | 32 | S_V2 |
暂无数据 | 2022 年 3 月 9 日 |
Android 12 | 31 | S |
20.58% | 2021 年 10 月 4 日 |
Android 11 | 30 | R |
19.98% | 2020 年 9 月 9 日 |
Android 10 | 29 | Q |
9.27% | 2019 年 9 月 3 日 |
Android 9.0 | 28 | P |
8.61% | 2018 年 8 月 7 日 |
Android 8.1 | 27 | O_MR1 |
2.78% | 2017 年 12 月 5 日 |
Android 8.0 | 26 | O |
3.21% | 2017 年 8 月 22 日 |
Android 7.1 | 25 | N_MR1 |
0.61% | 2016 年 12 月 5 日 |
Android 7.0 | 24 | N |
1.88% | 2016 年 8 月 22 日 |
Android 6.0 | 23 | M |
1.64% | 2015 年 9 月 29 日 |
Android 5.1 | 22 | LOLLIPOP_MR1 |
0.98% | 2015 年 3 月 10 日 |
Android 5.0 | 21 | LOLLIPOP |
0.53% | 2014 年 10 月 15 日 |
Android 4.4 | 19 | KITKAT |
0.3% | 2013 年 10 月 31 日 |
-
市场占用率数据更新至 2023 年 11 月 5 日,数据统计主要参考以下链接:
-
Mobile Android operating system market share by version worldwide from January 2018 to January 2022
-
每个新的 Android 版本都会引入一些变化,以便改进安全性和性能,并提升 Android 的整体用户体验。每款应用的清单文件中都有一个
targetSdkVersion
参数(也称为目标 API 级别),用以告知系统您的应用在不同的 Android 版本上分别该如何运行。 -
将应用的目标 API 级别配置为新近的 API 级别可确保用户享受到安全性、隐私保护和性能方面的改进,同时仍然允许应用在较低版本的 Android(低至
minSdkVersion
)上运行。 -
为了向 Android 和 Google Play 用户提供安全可靠的使用体验,Google Play 要求所有应用在目标 API 级别方面都必须符合下列要求。
新应用 | 尚未在 Play 商店中发布的应用(例如,全新的应用) |
---|---|
应用更新 | 已在 Play 商店中发布的应用的新版本 |
现有应用 | 没有获得更新的已发布应用 |
Android 操作系统版本 | 新应用 | 应用更新 | 现有应用 |
---|---|---|---|
Android 13(API 级别 33) | 2023 年 8 月 1 日 | 2023 年 11 月 1 日 | 2024 年 11 月 1 日 |
Android 12(API 级别 31) | 2022 年 8 月 1 日 | 2022 年 11 月 1 日 | 2023 年 11 月 1 日 |
Android 11(API 级别 30) | 2021 年 8 月 1 日 | 2021 年 11 月 1 日 | 2022 年 11 月 1 日 |
提示:如需获得技术指导来了解如何更改应用的目标 API 级别以满足上述要求,请参阅迁移指南。
Android 操作系统版本 | 新应用 | 应用更新 | 现有应用 |
---|---|---|---|
Android 11(API 级别 30) | 2022 年 8 月 1 日 | 2022 年 11 月 1 日 | 无要求 |
Android 10(API 级别 29) | 无要求 | 无要求 | 无要求 |
Android 9(API 级别 28) | 2019 年 8 月 1 日 | 2019 年 11 月 1 日 | 无要求 |
- 为帮助开发者轻松完成过渡,相比新应用,我们多给了应用更新几个月时间来满足该要求。
- 您的应用若不符合目标 API 级别要求,可能会受到以下方面的影响:
应用 | 影响 |
---|---|
新应用 | 您将无法在 Play 管理中心发布不符合目标 API 级别要求的 app bundle。 |
应用更新 | 您将无法在 Play 管理中心提交不符合目标 API 级别要求的 app bundle 或 APK。 |
现有应用 | 如果新用户的设备搭载的 Android 操作系统版本高于您的应用的目标 API 级别,那么这类用户将无法在 Google Play 上获取您的应用。也就是说,这类新用户将无法从 Google Play 中发现或安装您的应用。之前从 Google Play 中安装过这款应用的用户仍可以发现、重新安装和使用它。这类现有用户即使换用新的 Android 设备,也仍然可以使用您的应用。 |
- 为帮助开发者轻松完成过渡,相比新应用,我们多给了应用更新几个月时间来满足该要求。
-
适配简介
-
厂商适配指南
-
其他适配
-
适配简介
-
厂商适配指南
-
其他适配
-
适配简介
-
厂商适配指南
-
SplashScreen 适配
-
桌面小组件适配
-
exported 属性适配
-
Android 12 L 适配
-
其他适配
隐私权变更 | 受影响的应用 | 缓解策略 |
---|---|---|
强制执行分区存储机制 以 Android 11 或更高版本为目标平台的应用始终会受分区存储行为的影响 | 以 Android 11 或更高版本为目标平台的应用,以及以 Android 10 为目标平台且未将 requestLegacyExternalStorage 设为 true 以停用分区存储的应用 |
更新您的应用以使用分区存储 详细了解分区存储变更 |
单次授权 使用单次授权功能,用户可以授予对位置信息、麦克风和摄像头的临时访问权限 | 在 Android 11 或更高版本上运行且请求位置信息、麦克风或摄像头权限的应用 | 在尝试访问受某项权限保护的数据之前,检查您的应用是否具有该权限 遵循请求权限方面的最佳做法 |
自动重置权限 如果用户在 Android 11 或更高版本上几个月未与应用互动,系统会自动重置应用的敏感权限 | 以 Android 11 或更高版本为目标平台且在后台执行大部分工作的应用 | 要求用户阻止系统重置应用的权限 详细了解自动重置权限 |
后台位置信息访问权限 Android 11 更改了用户向应用授予后台位置信息权限的方式 | 以 Android 11 或更高版本为目标平台且需要在后台访问位置信息的应用 | 通过对权限请求方法的多次单独调用,逐步请求在前台(粗略或精确)和后台访问位置信息的权限。必要时,说明用户授予该权限所能得到的益处 详细了解 Android 11 中的在后台访问位置信息的权限 |
软件包可见性 Android 11 更改了应用查询同一设备上的其他已安装应用及与之互动的方式 | 以 Android 11 或更高版本为目标平台且与设备上的其他已安装应用交互的应用 | 将 <queries> 元素添加到应用的清单 详细了解软件包可见性 |
前台服务 Android 11 更改了前台服务访问位置信息、摄像头和麦克风相关数据的方式 | 在 Android 11 或更高版本上运行且在前台服务中访问位置信息、摄像头或麦克风的应用 | 分别针对需要访问摄像头和麦克风的前台服务,声明 camera 和 microphone 前台服务类型。但请注意,应用在后台运行时启动的前台服务通常无法访问位置信息、摄像头或麦克风。 详细了解前台服务的变更 |
-
适配简介
-
厂商适配指南
-
Android/data 目录适配
-
其他适配
隐私权变更 | 受影响的应用 | 缓解策略 |
---|---|---|
分区存储 针对外部存储的过滤视图,可提供对特定于应用的文件和媒体集合的访问权限 | 访问和共享外部存储中的文件的应用 | 使用特定于应用的目录和媒体集合目录 了解详情 |
增强了用户对位置权限的控制力 仅限前台权限,可让用户更好地控制应用对设备位置信息的访问权限 | 在后台时请求访问用户位置信息的应用 | 确保在没有后台位置信息更新的情况下优雅降级 使用 Android 10 中引入的权限在后台获取位置信息 了解详情 |
系统执行后台 Activity 针对从后台启动 Activity 实施了限制 | 不需要用户互动就启动 Activity 的应用 | 使用通知触发的 Activity 了解详情 |
不可重置的硬件标识符 针对访问设备序列号和 IMEI 实施了限制 | 访问设备序列号或 IMEI 的应用 | 使用用户可以重置的标识符 了解详情 |
无线扫描权限 访问某些 WLAN、WLAN 感知和蓝牙扫描方法需要获得精确位置权限 | 使用 WLAN API 和蓝牙 API 的应用 | 针对相关使用场景请求 ACCESS_FINE_LOCATION 权限 了解详情 |
-
适配简介
-
厂商适配指南
-
分区存储适配
-
深色主题适配
-
其他适配
-
适配简介
-
厂商适配指南
-
刘海屏适配
-
反射 API 适配
-
WebView 多进程适配
-
适配简介
-
厂商适配指南
-
通知渠道适配
-
透明 Activity 方向适配
-
启动后台 Service 适配
-
画中画适配
-
其他适配
-
适配简介
-
FileProvider适配
-
其他适配
-
安卓技术中台:AndroidProject
-
安卓技术中台 Kt 版:AndroidProject-Kotlin
-
权限框架:XXPermissions
-
吐司框架:Toaster
-
网络框架:EasyHttp
-
标题栏框架:TitleBar
-
悬浮窗框架:EasyWindow
-
ShapeView 框架:ShapeView
-
ShapeDrawable 框架:ShapeDrawable
-
语种切换框架:MultiLanguages
-
Gson 解析容错:GsonFactory
-
日志查看框架:Logcat
-
嵌套滚动布局框架:NestedScrollLayout
-
Android 代码规范:AndroidCodeStandard
-
Android 资源大汇总:AndroidIndex
-
Android 开源排行榜:AndroidGithubBoss
-
Studio 精品插件:StudioPlugins
-
表情包大集合:EmojiPackage
-
AI 资源大汇总:AiIndex
-
省市区 Json 数据:ProvinceJson
-
Markdown 语法文档:MarkdownDoc
Copyright 2021 Huang JinQun
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.