Google2月按时发布了第一个开发者预览版本,正式版会在8-9月份发布。
按照惯例,Android更新了可以刷机的手机型号,Pixel 4仅支持4a(5G)版本:
Pixel 4a (5G)
Pixel 5 and 5a
Pixel 6 and 6 Pro
Pixel 6a
Pixel 7 and 7 Pro
开发者可以参考Android官网(/about/versions/14/get)进行刷机,普通用户刷机请慎重。
Behavior changes: all apps:
a. 核心功能-SCHEDULE_EXACT_ALARM 权限将默认关闭
为了减少耗电,以Android 13或更高版本为目标开发的应用,将会默认关闭SCHEDULE_EXACT_ALARM 权限。该权限用于精确闹钟,从Android 12开始引入,主要影响新安装的应用(会有权限弹窗,需要用户手动选择),旧系统上已经安装并授权过该权限的应用,系统升级后,将继续保持允许状态,用户可以进设置中手动关闭。
受影响的主要是下面三个接口,如果授权前调用,会抛出SecurityException崩溃信息
-
setExact()
-
setExactAndAllowWhileIdle()
-
setAlarmClock()
日历和闹钟类应用虽然不受该改动影响,但是最好使用USE_EXACT_ALARM( /reference/android/#USE_EXACT_ALARM )(不需要弹窗)来替换。
b. 核心功能-Context 注册的广播将会放入队列
当应用进入缓存状态后(比如退到后台),系统会将context注册的广播统一放到队列,等应用退出缓存状态后,系统会发送队列里的广播,可能会出现多个广播合并为一个广播的情况。
c. 安全和隐私—最低SDK版本限制
从Android 14开始,目标sdk版本小于23(Android 6.0)的应用,将不能安装。这项比较好理解,Android 6.0之后引入了运行时权限,需要弹窗让用户选择是否允许权限。大部分长期维护的应用,早已经做过这方面的适配,一些老旧应用,会受一些影响。当然,已经安装在系统中的应用,在升级完成后,还是可以继续使用的。
d. 辅助功能
从Android 14开始,系统支持字号放大200%,以方便低视力人群更好的使用,字号使用sp作单位,将不受影响,否则界面可能会比较凌乱,没有按规范开发的应用,赶紧着手改进吧。
Behavior changes: Apps targeting Android 14 or higher:
a. 核心功能-前台service必须设置type
可以在manifest中使用android:foregroundServiceType 设置前台service类型:
<manifest ...>
<uses-permission android:name=".FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK" />
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback" <---here
android:exported="false">
</service>
</application>
</manifest>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
也可以在代码中设置:
(0, notification, FOREGROUND_SERVICE_TYPE_LOCATION)
- 1
Android 14后,不设置Type的话,调用startForeground()会抛出MissingForegroundServiceTypeException异常
使用相应的Type,需要申请对应的权限,没有权限的话,调用startForeground()会抛出SecurityException异常,下面是所有的service类型,以及对应的权限:
Foreground service type declared | Permission that must be declared |
---|---|
camera | FOREGROUND_SERVICE_CAMERA |
connectedDevice | FOREGROUND_SERVICE_CONNECTED_DEVICES |
dataSync | FOREGROUND_SERVICE_DATA_SYNC |
health(Android 14 support) | FOREGROUND_SERVICE_HEALTH |
location | FOREGROUND_SERVICE_LOCATION |
mediaPlayback | FOREGROUND_SERVICE_MEDIA_PLAYBACK |
mediaProjection | FOREGROUND_SERVICE_MEDIA_PROJECTION |
microphone | FOREGROUND_SERVICE_MICROPHONE |
phoneCall | FOREGROUND_SERVICE_PHONE_CALL |
remoteMessaging(Android 14 support) | FOREGROUND_SERVICE_REMOTE_MESSAGING |
shortService(Android 14 support) | No additional permission requirements |
specialUse(Android 14 support) | FOREGROUND_SERVICE_SPECIAL_USE |
systemExempted(Android 14 support) | FOREGROUND_SERVICE_SYSTEM_EXEMPTED |
b. 安全性 – implicit and pending intents 限制
只有exported=true的组件,才能使用隐性intent调用:
- Implicit intents are only delivered to exported components. Apps must either use an explicit intent to deliver to unexported components, or mark the component as exported.
- If an app creates a mutable pending intent with an intent that doesn’t specify a component or package, the system now throws an exception.
以下面的manifest定义为例:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name=".APP_ACTION" />
<category android:name="" />
</intent-filter>
</activity>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
定义了action(.APP_ACTION)并且定义android:exported=“false”,如果执行下面的代码,会抛出异常:
// Throws an exception when targeting Android 14.
(Intent(".APP_ACTION"))
- 1
- 2
上面代码只能在android:exported=**“true”**时正常执行
或者使用显示调用(指定package或component):
// This makes the intent explicit.
val explicitIntent = Intent(".APP_ACTION")
{
package =
}
(explicitIntent)
- 1
- 2
- 3
- 4
- 5
- 6
安全性 – 运行时注册的广播接收器,必须指定RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED
动态注册的Receiver,需要通过RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED指明是否对外部应用可见:
//类似exported true
(sharedBroadcastReceiver, intentFilter,RECEIVER_EXPORTED)
//类似exported false
(privateBroadcastReceiver, intentFilter, RECEIVER_NOT_EXPORTED)
- 1
- 2
- 3
- 4
如果receiver只是用来接收系统广播,则不用指定
安全性 – 更安全的动态加载代码(Dynamic Code Loading)
虽然Android 不建议动态加载外部资源(DEX, JAR, or APK),但鉴于某些使用场景,目前还没有禁止使用,Andoid 14上面,所有动态加载的代码,必须设置为只读的,以降低代码注入风险:
val jar = File("DYNAMICALLY_LOADED_FILE.jar")
val os = FileOutputStream(jar)
{
// Set the file to read-only first to prevent race conditions
()
// Then write the actual file content
}
val cl = PathClassLoader(jar, parentClassLoader)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
不设置的话,系统会抛出异常
对于已经存在的file,建议先删除,再重新创建(或下载)
c. non-SDK interface restrictions
Android 14 继续更新api限制,详见文件
更多原创文章,欢迎关注
头条号 程序员明哥
微信公众号 程序员明哥