ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # Android 10重要变更 ## 1、对不可重置的设备标识符实施了限制 > 自 Android 10(API 级别 29)起,您的应用必须是[设备或个人资料所有者应用](https://source.android.com/devices/tech/admin/managed-profiles?hl=zh-cn#device_administration),具有[特殊运营商许可](https://source.android.com/devices/tech/config/uicc?hl=zh-cn),或具有`READ_PRIVILEGED_PHONE_STATE`特权,才能访问不可重置的设备标识符(包含 IMEI 和序列号)。 > 受影响的方法包括: > * `Build` * [`getSerial()`](https://developer.android.com/reference/android/os/Build#getSerial()) > * `TelephonyManager` * [`getImei()`](https://developer.android.com/reference/android/telephony/TelephonyManager#getImei(int)) * [`getDeviceId()`](https://developer.android.com/reference/android/telephony/TelephonyManager#getDeviceId(int)) * [`getMeid()`](https://developer.android.com/reference/android/telephony/TelephonyManager#getMeid(int)) * [`getSimSerialNumber()`](https://developer.android.com/reference/android/telephony/TelephonyManager#getSimSerialNumber()) * [`getSubscriberId()`](https://developer.android.com/reference/android/telephony/TelephonyManager#getSubscriberId()) **即:** Android 10开始,普通应用无法再获取到设备的IMEI。 > 如果您的应用没有该权限,但您仍尝试查询不可重置标识符的相关信息,则平台的响应会因目标 SDK 版本而异: > * 如果应用以 Android 10 或更高版本为目标平台,则会发生[`SecurityException`](https://developer.android.com/reference/java/lang/SecurityException)。 > * 如果应用以 Android 9(API 级别 28)或更低版本为目标平台,则相应方法会返回`null`或占位符数据(如果应用具有[`READ_PHONE_STATE`](https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE)权限)。否则,会发生`SecurityException`。 **即:** targetSdkVersion<=28时,获取IMEI为空;targetSdkVersion>=29时,会发生SecurityException异常 ## 2、在后台运行时访问设备位置信息需要权限 > 为了让用户更好地控制应用对位置信息的访问权限,Android 10 引入了 ACCESS_BACKGROUND_LOCATION 权限。与 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 权限不同,ACCESS_BACKGROUND_LOCATION 权限仅会影响应用在后台运行时对位置信息的访问权限。 当targetSdkVersion<=28时,应用请求了`ACCESS_FINE_LOCATION`或`ACCESS_COARSE_LOCATION`权限时,系统会自动将`ACCESS_BACKGROUND_LOCATION`添加到请求中。 ## 3、外部存储访问权限范围限定为应用文件和媒体(target 29+) > 默认情况下,对于以 Android 10 及更高版本为目标平台的应用,其[访问权限范围限定为外部存储](https://developer.android.com/training/data-storage/files/external-scoped),即分区存储。此类应用可以查看外部存储设备内以下类型的文件,无需请求任何与存储相关的用户权限: * 特定于应用的目录中的文件(使用[`getExternalFilesDir()`](https://developer.android.com/reference/android/content/Context#getExternalFilesDir(java.lang.String))访问)。 * 应用创建的照片、视频和音频片段(通过[媒体库](https://developer.android.com/training/data-storage/files/media)访问)。 **即:** 当targetSdkVersion>=29时,应用不需要请求权限,就可以访问本应用目录中的文件(getExternalFilesDir())和本应用创建的照片、视频、音频片段(通过媒体库访问)。 ## 4、对启用和停用 WLAN 实施了限制(target 29+) > 以 Android 10 或更高版本为目标平台的应用无法启用或停用 WLAN。[`WifiManager.setWifiEnabled()`](https://developer.android.com/reference/android/net/wifi/WifiManager#setWifiEnabled(boolean))方法始终返回`false`。 > 如果您需要提示用户启用或停用 WLAN,请使用[设置面板](https://developer.android.com/about/versions/10/features#settings-panels)。 # Android 9重要变更 ## 1、强制执行 FLAG_ACTIVITY_NEW_TASK 要求 > 在 Android 9 中,您不能从非 Activity 环境中启动 Activity,除非您传递 Intent 标志[`FLAG_ACTIVITY_NEW_TASK`](https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_NEW_TASK)。 如果您尝试在不传递此标志的情况下启动 Activity,则该 Activity 不会启动,系统会在日志中输出一则消息。 ## 2、构建序列号弃用(target 28+) > 在 Android 9 中,[`Build.SERIAL`](https://developer.android.com/reference/android/os/Build#SERIAL)始终设为`"UNKNOWN"`,以保护用户隐私。 > 如果您的应用需要访问设备的硬件序列号,您应改为请求[`READ_PHONE_STATE`](https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE)权限,然后调用[`getSerial()`](https://developer.android.com/reference/android/os/Build#getSerial())。 ## 3、默认启用网络传输层安全协议 (TLS) > 如果您的应用以 Android 9 或更高版本为目标平台,则[`isCleartextTrafficPermitted()`](https://developer.android.com/reference/android/security/NetworkSecurityPolicy#isCleartextTrafficPermitted())方法默认返回`false`。如果您的应用需要针对特定网域启用明文,则您必须在应用的[网络安全配置](https://developer.android.com/training/articles/security-config)中,针对这些网域明确将`cleartextTrafficPermitted`设置为`true`。 ## 4、异形屏适配 参考:[https://blog.csdn.net/guolin\_blog/article/details/103112795](https://blog.csdn.net/guolin_blog/article/details/103112795) # Android 8重要变更 ## 1、Android ID > 对于安装在运行 Android 8.0 的设备上的应用,ANDROID_ID的值现在将根据应用签署密钥和用户确定作用域。应用签署密钥、用户和设备的每个组合都具有唯一的ANDROID_ID值。因此,在相同设备上运行但具有不同签署密钥的应用将不会再看到相同的 Android ID(即使对于同一用户来说,也是如此)。 **即:** 在一台手机上,对于不同的应用来说,获取到的Android ID值是不一样的。 > 只要签署密钥相同,`ANDROID_ID`的值在软件包卸载或重新安装时就不会发生变化。 ## 2、权限组问题 > 在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。 > 对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。 > 例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE。应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。 **即:** targetSdkVersion<=24时,用户申请一个权限,系统会同时授予用户该权限组的其他权限。targetSdkVersion>=26时,用户申请一个权限,系统会仅仅授予其该权限,后面再请求该权限组其他权限时,系统会自动授予,而不再提示用户。 ## 3、通知渠道 参考[http://www.androidwiki.site/1569138](http://www.androidwiki.site/1569138) ## 4、应用图标 参考[http://www.androidwiki.site/1569138](http://www.androidwiki.site/1569138) ## 5、允许安装未知来源应用(target 26+) 针对 8.0 的应用需要在 AndroidManifest.xml 中声明 REQUEST\_INSTALL\_PACKAGES 权限,否则将无法进行应用内升级。 # 参考 Android 10 中的隐私权变更:[https://developer.android.com/about/versions/10/privacy/changes](https://developer.android.com/about/versions/10/privacy/changes) Android Q 适配指南 让你少走一堆弯路:[https://juejin.im/post/5cad5b7ce51d456e5a0728b0#comment](https://juejin.im/post/5cad5b7ce51d456e5a0728b0#comment) Android O 适配详细指南:[https://juejin.im/post/5baa1c606fb9a05d396f16ea](https://juejin.im/post/5baa1c606fb9a05d396f16ea)