计划概览
Android 12 中提供的功能
官方地址:https://developer.android.google.cn/preview
新功能:
用于接收内容的统一 API
Android 12 引入了全新的统一 API,您可以从任何可用来源(剪贴板、键盘或拖放操作)接收富媒体内容。
您可以向界面组件附加新接口 OnReceiveContentListener
,并在通过任何机制插入内容时获得回调。此回调会成为您的代码处理接收所有内容(从纯文本和样式文本到标记、图片、视频、音频文件等)的唯一位置。
为了向后兼容以前的 Android 版本,我们还向 AndroidX 添加了新的 API(可在 Core 1.5.0-beta1 和 Appcompat 1.3.0-beta-01 中获得),我们建议您在实现此功能时使用该 API。
统一 API 会通过创建一个要实现的单一 API 来整合这些不同的代码路径,这样您就可以专注于应用特定的逻辑,而让平台处理其余的工作:
public class MyReceiver implements OnReceiveContentListener {
public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
@Override
public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
Pair<ContentInfoCompat, ContentInfoCompat> split = contentInfo.partition(
item -> item.getUri() != null);
ContentInfo uriContent = split.first;
ContentInfo remaining = split.second;
if (uriContent != null) {
ClipData clip = uriContent.getClip();
for (int i = 0; i < clip.getItemCount(); i++) {
Uri uri = clip.getItemAt(i).getUri();
// App-specific logic to handle the URI ...
}
}
// Return anything that your app didn't handle. This preserves the default platform
// behavior for text and anything else that you aren't implementing custom handling for.
return remaining;
}
}
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
AppCompatEditText myInput = findViewById(R.id.my_input);
ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
}
}
兼容的媒体转码
Android 12 可以自动将设备上录制的 HEVC(H.265) 和 HDR(HDR10 和 HDR10+)视频转码为 AVC (H.264),AVC (H.264) 是与标准播放器广泛兼容的格式。因此,当现代编解码器可用且不会影响与旧应用的兼容性时,便会利用现代编解码器。
如果视频被不支持 HEVC 格式的应用打开,Android 会自动将以 HEVC (H.265) 等格式录制的视频转码为 AVC (H.264) 格式。
Android 假定应用可以支持播放所有媒体格式,因此兼容的媒体转码在默认情况下是关闭的。如果应用请求将媒体转码为更兼容的格式,则应声明其媒体功能。有两种声明这些功能的方法:在资源中声明,或在代码中内嵌声明。
在资源中声明功能
<?xml version="1.0" encoding="utf-8"?>
<media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
<format android:name="HEVC" supported="true"/>
<format android:name="HDR10" supported="false"/>
<format android:name="HDR10Plus" supported="false"/>
</media-capabilities>
在此示例中,设备上录制的 HDR 视频被无缝转码为 AVC SDR(标准动态范围)视频,而 HEVC 视频则无法转码。
在 application
标记中使用 property
标记来添加对媒体功能文件的引用。
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
在代码中声明功能
通过 ContentResolver#openTypedAssetFileDescriptor()
等方法访问媒体内容时,请使用此对象:
ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder()
.addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
.addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
.addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
.build();
Bundle providerOptions = new Bundle();
providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities);
try (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {
// Content will be transcoded based on values defined in the
// ApplicationMediaCapabilities provided.
}
此方法优先于应用的 AndroidManifest.xml
中关联的功能,允许针对特定代码路径进行更精细的控制,例如执行 A/B 测试。
AVIF 图片支持
Android 12 引入了对使用 AV1 图片文件格式 (AVIF) 的图片的支持。AVIF 是一种使用 AV1 编码的图片和图片序列的容器格式。它利用了视频压缩的帧内编码内容。与以前的图片格式(例如 JPEG)相比,这种格式可显著提升相同文件大小下的图片质量。
从音频产生触感反馈效果
Android 12 应用可使用手机的振动器从音频会话产生触感反馈。这可让您获得更身临其境的游戏和音频体验。例如,触感反馈效果增强的铃声有助于识别来电者,或者赛车游戏可以模拟在崎岖地形驾驶的感觉。
如需了解详情,请参阅 HapticGenerator 参考文档。
动画 GIF 和 WebP 的原生 ImageDecoder 支持
在 Android 12 中,NDK ImageDecoder
API 已进行了扩展,可以对使用以下文件格式的图片的所有帧和时间数据进行解码:动画 GIF 和动画 WebP 文件格式。在 Android 11 中引入该 API 时,该 API 仅从这些格式的动画中解码第一张图片。
使用 ImageDecoder
(而非第三方库)可进一步缩减 APK 大小,并从未来与安全性和性能相关的更新中受益。
如需详细了解该 API,请参阅 API 参考文档和 GitHub 上的示例。
Drawable drawable = ImageDecoder.decodeDrawable(source);
if (drawable instanceof AnimatedImageDrawable) {
((AnimatedImageDrawable) drawable).start();
}
安全性
在非 DPC (设备策略Controller )应用中提供设备属性验证
Android 12 扩展了一组应用,当这些应用生成新密钥时,可以验证认证证书中的设备属性。
自 Android 9(API 级别 28)起,使用 Keymaster 4.0 或更高版本的设备政策所有者 (DPO) 可以验证这些认证证书中的设备属性。从 Android 12 开始,任何以 Android 12 为目标平台的应用都可以使用 setDevicePropertiesAttestationIncluded()
方法执行此验证。
生成的设备属性包含以下 Build
字段:
BRAND
DEVICE
MANUFACTURER
MODEL
PRODUCT
企业功能新变化
工作资料的安全和隐私权增强功能
对于具有工作资料的个人设备,Android 12 提供了以下功能:
密码复杂度功能以预定义复杂存储分区(高、中、低和无)的形式设定设备级密码要求。如有必要,可对工作资料安全验证应用严格的密码要求。
工作资料安全验证新手入门流程已简化。现在,设置会考虑设备密码是否符合管理员要求,让用户可以轻松选择是增强设备密码的强度还是使用工作资料安全验证。
注册特定 ID 提供了一个唯一 ID,用于标识特定组织的工作资料注册,并且可在恢复出厂设置后保持稳定。在 Android 12 中,对于具有工作资料的个人设备,系统会移除对该设备的其他硬件标识符(IMEI、MEID、序列号)的访问权限。
公司自有设备(无论是否具有工作资料)可以选择是否保留上述列表项中列出的功能,但不需要在 Android 12 中采用。
非受管设备证书管理
没有管理功能的设备现在可以利用 Android 的设备密钥生成功能管理证书:
用户可以授予证书管理应用管理其凭据(不包括 CA 证书)的权限。
证书管理应用可以使用 Android 的设备密钥生成功能。
证书管理应用可以声明支持使用凭据进行身份验证的应用和 URI 的列表。
新 API 可提供新功能:
检查现有的设备级密码是否符合明确设备密码要求。
检查给定别名下是否安装了证书和私钥。
弃用
Android 12 弃用了以下 API,值得引起注意:
不再使用
setPasswordQuality()
和getPasswordQuality()
在具有工作资料的个人设备而非公司自有设备上设置设备级密码。DPC 应改用setRequiredPasswordComplexity()
。setOrganizationColor()
和getOrganizationColor()
在 Android 12 中已完全弃用。
连接性
Wi-Fi 感知 (NAN) 增强功能
Android 12 增强了 Wi-Fi 感知功能:
在搭载 Android 12 及更高版本的设备上,您可以使用
onServiceLost()
回调,以便在应用因服务停止或超出范围而导致已发现的服务丢失时收到提醒。设置多个数据路径(NAN 数据路径)的方式将发生变化以提高效率。较低的版本使用 L2 消息功能来交换发起方的对等信息,由此导致了延迟。在搭载 Android 12 及更高版本的设备上,可以将响应方(服务器)配置为接受任何对等方,也就是说,它不需要预先知道发起方信息。这可加快数据路径启动,并只需一个网络请求即可实现多个点对点链接。
为了防止框架因资源不足而拒绝发现请求或连接请求,在搭载 Android 12 及更高版本的设备上,您可以调用
WifiAwareManager.getAvailableAwareResources()
。通过此方法的返回值,您可以获得可用数据路径的数量、可用发布会话的数量以及可用的订阅会话数量。
行为变更:所有应用
Android 12 平台包含一些行为变更,这些变更可能会影响您的应用。以下行为变更将影响在 Android 12 上运行的所有应用,无论采用哪种 targetSdkVersion
都不例外。您应该测试您的应用,然后根据需要进行修改,以适当地支持这些变更。
用户体验
沉浸模式下的手势导航改进(弱相关)
Android 12 简化了沉浸模式,使手势导航更易于操作且与其他活动体验(例如观看视频和阅读图书)更加一致。应用仍然可以在全屏游戏体验中防止意外手势,以免用户在玩游戏时意外退出游戏;所有其他全屏或沉浸式体验现在都允许用户通过滑动手势进行导航。
为了实现这一点,从 Android 12 开始,我们已弃用非粘性沉浸式体验(
BEHAVIOR_SHOW_BARS_BY_TOUCH
、BEHAVIOR_SHOW_BARS_BY_SWIPE
)的现有行为。它们已被默认行为 (BEHAVIOR_DEFAULT
) 取代,即在隐藏系统栏后,允许使用滑动手势。此标志会根据模式显示不同的视觉和功能行为:在“三按钮”模式下,视觉和功能行为与 Android 12 之前的版本中的沉浸模式相同。
-
在手势导航模式下,行为如下:
- 在视觉上,它与 Android 11 及更低版本中的沉浸模式相同。
从功能上讲,即使系统栏被隐藏,也允许使用手势;只需滑动屏幕一次便可调用系统返回操作,而 Android 11 需要滑动两次。下拉通知栏或转到主屏幕无需另外滑动屏幕。
Android 12 的粘性沉浸模式 (
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
) 没有任何变化。请注意此功能的以下向后兼容性:-
如果应用以 Android 11 及更低版本为目标平台,则在 Android 12 上运行时:
-
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
展示出的功能和呈现出的视觉效果相同。
-
默认值会映射到
BEHAVIOR_SHOW_BARS_BY_SWIPE
。-
如果应用以 Android 12 为目标平台,则在 Android 11(API 级别 30)及更低版本上运行时:
- 展示出的功能和呈现出的视觉效果应该是相同的,但
BEHAVIOR_SHOW_BARS_BY_TOUCH
映射到BEHAVIOR_SHOW_BARS_BY_SWIPE
的情况除外。
- 展示出的功能和呈现出的视觉效果应该是相同的,但
请务必更新您的 SDK 级别,以获得新的默认值 (
BEHAVIOR_SHOW_BARS_BY_SWIPE
)。否则,BEHAVIOR_SHOW_BARS_BY_TOUCH
的默认值会保持不变。
前台服务通知延迟
为了在 Android 12 上提供针对短时间运行的前台服务的流畅体验,系统可以为某些前台服务延迟 10 秒显示前台服务通知。此更改使某些短期任务在显示通知之前完成。
如果某项前台服务至少具有以下特征之一,则系统会在服务启动后立即显示相关通知:
该服务与包含操作按钮的通知相关联。
该服务的
foregroundServiceType
为connectedDevice
、mediaPlayback
、mediaProjection
或phoneCall
。该服务根据通知的类别属性中的定义,提供与通话、导航或媒体播放相关的用例。
注意:在未来的 Android 12 开发者预览版中,这些用例可能会发生变化。
- 该服务通过在设置通知时调用
setShowForegroundImmediately()
,以停用行为变更。
隐私设置
对 Netlink MAC 地址的限制(强相关)
Android 12 进一步限制了所有非系统应用对设备的 MAC 地址(不可重置的标识符)的访问,无论目标 API 级别如何都是如此。
相关 API 会返回空值或占位值,具体取决于应用的目标 SDK 版本:
如果应用以 Android 12 为目标平台,则该 API 会返回 null。
如果应用以 Android 11 或更低版本为目标平台,则该 API 将返回硬编码占位值:
02:00:00:00:00:00
开发者应使用 ConnectivityManager
,而不是较低级别的 API(例如 NetworkInterface
、getifaddrs()
)或 Netlink 套接字。开发者在其代码中调用 NetworkInterface.getHardwareAddress()
时,logcat 输出会显示:CompatibilityChangeReporter: Compat change id reported: 170188668;
开发者可以使用名为 RETURN_NULL_HARDWARE_ADDRESS
的兼容性标志切换 NetworkInterface.getHardwareAddress()
的行为:在启用时返回 null,或在停用时返回 02:00:00:00:00:00
。
安全性
不受信任的触摸事件被屏蔽
为了维持系统安全并保持良好的用户体验,Android 12 会阻止应用使用触摸事件,使用触摸事件时叠加层会以不安全的方式遮掩应用。 换言之,系统会屏蔽穿透某些窗口的触摸操作,但有一些例外情况。
受影响的应用
此变更会影响选择让触摸操作穿透其窗口的应用,例如使用 FLAG_NOT_TOUCHABLE
标志。包括但不限于以下示例:
需要
SYSTEM_ALERT_WINDOW
权限并使用FLAG_NOT_TOUCHABLE
标志的叠加层,例如使用TYPE_APPLICATION_OVERLAY
的窗口。使用
FLAG_NOT_TOUCHABLE
标志的 activity 窗口。消息框消息。
例外情况
在以下情况下,允许执行“穿透”触摸操作:
应用中的互动。您的应用会显示叠加层,并且只有当用户与您的应用进行互动时才会显示叠加层。
-
可信窗口
。包括但不限于以下窗口:
- 无障碍窗口
输入法 (IME) 窗口
Google 助理窗口
注意:类型为 TYPE_APPLICATION_OVERLAY
的窗口不受信任。
不可见窗口。窗口的根视图是
GONE
或INVISIBLE
。全透明窗口。窗口的
alpha
属性为 0.0。足够半透明的系统警报窗口。当组合后的不透明度小于或等于系统针对触摸的最大遮掩不透明度时,系统会将一组系统警报窗口视为足够半透明。 在开发者预览版 1 中,此最大不透明度是 0.8,但在今后的开发者预览版中此值可能会发生变化。
应用无法关闭系统对话框
为了加强用户与应用和系统互动时的控制,从 Android 12 开始,弃用了 ACTION_CLOSE_SYSTEM_DIALOGS
intent 操作。除了一些特殊情况之外,当应用尝试调用包含此操作的 intent 时,系统会基于应用的目标 SDK 版本执行以下操作之一:
如果应用以 Android 12 为目标平台,则会发生
SecurityException
。如果应用以 Android 11(API 级别 30)或更低版本为目标平台,则系统不会执行 intent,并且 Logcat 中会显示以下消息:
例外情况
在以下情况下,应用仍然可以在 Android 12 上关闭系统对话框:
您的应用运行的是插桩测试。
您的应用以 Android 11 或更低版本为目标平台,并在抽屉式通知栏顶部显示一个窗口。
注意:如果您的应用以 Android 12 为目标平台,在这种情况下您无需使用 ACTION_CLOSE_SYSTEM_DIALOGS
。这是因为,如果在窗口位于抽屉式通知栏的顶部时您的应用调用 startActivity()
,系统会自动关闭抽屉式通知栏。
- 您的应用以 Android 11 或更低版本为目标平台。此外,用户已与通知互动,可能使用了通知的操作按钮,您的应用正在处理服务或广播接收器来响应该用户操作。
限制非 SDK 接口(强相关)
Android 12 包含更新后的受限制非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测试)。在限制使用非 SDK 接口之前,我们会尽可能确保有可用的公开替代方案。
如果您的应用并非以 Android 12 为目标平台,其中一些变更可能不会立即对您产生影响。然而,虽然您目前仍可以使用一些非 SDK 接口(具体取决于应用的目标 API 级别),但只要您使用任何非 SDK 方法或字段,终归存在导致应用出问题的显著风险。
如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试该应用来进行确认。如果您的应用依赖于非 SDK 接口,您应该开始计划迁移到 SDK 替代方案。然而,我们知道某些应用具有使用非 SDK 接口的有效用例。如果您无法为应用中的某项功能找到使用非 SDK 接口的替代方案,应请求新的公共 API。
如需详细了解此 Android 版本中的变更,请参阅 Android 12 中有关限制非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,请参阅对非 SDK 接口的限制。
行为变更:以 Android 12 为目标平台的应用
以下行为变更仅影响以 Android 12 或更高版本为目标平台的应用。如果您的应用以 Android 12 为目标平台,您应该修改自己的应用以适当地支持这些行为(如果适用)。
无法复制加载中的内容
隐私设置
WebView 中的现代 SameSite Cookie 行为(弱相关)
Android 的 WebView 组件基于为 Google 的 Chrome 浏览器提供支持的开源项目 Chromium。在过去一年中,Chromium 变更了对第三方 Cookie 的处理方式,目的是为了更好地保护用户的安全和隐私,并赋予用户更高的透明度和控制权。这些变更已面向很多 Chrome 用户发布,从 Android 12 开始,这些变更将应用于 WebView 中。
Cookie 的 SameSite
属性决定了它是可以与任何请求一起发送,还是只能与同站点请求一起发送。Android 12 中的 WebView 基础版本(版本 89.0.4385.0)包含以下隐私保护方面的变更,旨在改善对第三方 Cookie 的默认处理方式,并帮助防止意外跨站点共享:
没有
SameSite
属性的 Cookie 被视为SameSite=Lax
。带有
SameSite=None
的 Cookie 还必须指定Secure
属性,这意味着它们需要安全的上下文,并应通过 HTTPS 发送。站点的 HTTP 版本和 HTTPS 版本之间的链接现在被视为跨站点请求,因此除非将 Cookie 正确标记为
SameSite=None; Secure
,否则 Cookie 不会被发送。
对于开发者而言,一般指导意见是识别关键用户流中的跨站点 Cookie 依赖项,并确保在需要时使用适当的值显式设置 SameSite
属性。您必须显式指定允许在不同网站上运行的 Cookie,或适用于从 HTTP 切换到 HTTPS 进行同站点导航的 Cookie。
如需了解有关这些变更的网站开发者完整指南,请参阅 SameSite Cookie 说明和 Schemeful SameSite。
在您的应用中测试 SameSite 行为
如果您的应用使用 WebView,或者您需要管理使用 Cookie 的网站或服务,我们建议您在 Android 12 WebView 上测试您的数据流。 如果发现问题,您可能需要更新 Cookie 以支持新的 SameSite 行为。
留意登录和嵌入式内容中存在的问题,以及用户从不安全的页面启动并转到安全页面的登录流、购买和其他身份验证流。
如需使用 WebView 测试应用,您必须完成以下任一步骤,为需要测试的应用启用新的 SameSite 行为:
- 在 WebView devtools 中切换界面标志 webview-enable-modern-cookie-same-site,在测试设备上手动启用 SameSite 行为。
此方法允许您在任何运行 Android 5.0(API 级别 21)或更高版本(包括 Android 12)和 WebView 版本 89.0.4385.0 或更高版本的设备上进行测试。
- 通过
targetSdkVersion
编译您的应用,使其以 Android 12 为目标平台。
如果您使用此方法,则必须使用运行 Android 12 和 WebView 版本 89.0.4385.0 或更高版本的设备。
注意:由于 Android 12 开发者预览版 1 中存在一个已知会影响 WebView 的问题,您目前无法在 Android 12 上启用或测试 Schemeful Same-Site 变更。 我们已在内部解决这个问题,并将在未来的开发者预览版中添加此解决措施。在此期间,您仍可以针对其他 SameSite 变更在 Android 12 上测试您的应用(请参阅默认 SameSite=Lax 和 SameSite=None 必须是安全的)。如需了解有关 Android 上的 WebView 远程调试的信息,请参阅 Android 设备的远程调试入门。
adb 备份限制
为了保护私有应用数据,Android 12 变更了 adb backup
命令的默认行为。对于以 Android 12 为目标平台的应用,用户运行 adb backup
命令时,从设备导出的任何其他系统数据都不包含应用数据。
如果您的测试或开发工作流程依赖于使用 adb backup
的应用数据,现在您可以选择通过在应用的清单文件中将 android:debuggable
设置为 true
来导出应用数据。
注意:为了帮助保护应用数据,请务必在发布应用前将 android:debuggable
设置为 false
。
安全性
更安全地导出组件(强相关)
如果您的应用以 Android 12 为目标平台,且包含使用 intent 过滤器的 activity、服务或广播接收器,您必须为这些应用组件显式声明 android:exported
属性。
警告:如果 activity、服务或广播接收器使用 intent 过滤器,并且未显式声明 android:exported
的值,则您的应用将无法在搭载 Android 12 的设备上进行安装。
以下代码段显示了一个服务示例,该服务包含 intent 过滤器并针对 Android 12 进行了正确配置:
<service android:name="com.example.app.backgroundService"
android:exported="false">
<intent-filter>
<action android:name="com.example.app.START_BACKGROUND" />
</intent-filter>
</service>
待处理 intent 必须声明可变性
如果您的应用以 Android 12 为目标平台,您必须为您的应用创建的每个 PendingIntent
对象指定可变性。这项额外的要求可提高应用的安全性。
如需声明特定 PendingIntent
对象是否可变,请分别使用 PendingIntent.FLAG_MUTABLE
或 PendingIntent.FLAG_IMMUTABLE
标志。如果您的应用试图在不设置任何可变标志的情况下创建 PendingIntent
对象,系统会抛出 IllegalArgumentException
尽可能创建不可变的待处理 intent
在大多数情况下,您的应用应创建不可变的 PendingIntent
对象,如以下代码段所示。如果 PendingIntent
对象不可变,则应用无法修改 intent 来调整调用 intent 的结果。
然而,某些应用需要创建可变的 PendingIntent
对象:
通知中的直接回复操作需要变更与回复关联的
PendingIntent
对象中的剪辑数据。通常,您可以通过将FILL_IN_CLIP_DATA
作为标志传递给fillIn()
的方法请求此变更。如果您的应用使用
PendingIntent
将对话放在气泡中,则 intent 应该可变,以便系统可以应用正确的标志,例如FLAG_ACTIVITY_MULTIPLE_TASK
和FLAG_ACTIVITY_NEW_DOCUMENT
。
如果您的应用创建了可变的 PendingIntent
对象,强烈建议您使用显式 intent 并填写 ComponentName
。如此一来,每当另一个应用调用 PendingIntent
并将控制权传回您的应用时,应用中的相同组件都会启动。
注:目前的S版本,即使声明了PendingIntent.FLAG_IMMUTABLE
,依旧会报错
以不安全的方式启动嵌套 intent
为了提高平台安全性,Android 12 提供了一种调试功能,如果您的应用以不安全的方式启动嵌套 intent,此功能便会发出警告。嵌套 intent 是在其他 intent 中作为 extra 传递的 intent。如果您的应用同时执行以下两项操作,就会发生 StrictMode 违规行为。
- 您的应用从已传递的 intent 的 extra 中解封嵌套 intent。
- 您的应用立即使用该嵌套 intent 启动应用组件,例如将 intent 传递给
startActivity()
、startService()
或bindService()
。
配置应用以检测嵌套 intent 的不安全启动
如需检查您的应用中是否会以不安全的方式启动嵌套 intent,请在配置 VmPolicy
时调用 detectUnsafeIntentLaunch()
,如以下代码段所示。如果您的应用检测到 StrictMode 违规行为,您可能需要停止应用的执行以保护潜在的敏感信息。
protected void onCreate() {
StrictMode.setVmPolicy(new VmPolicy.Builder()
// Other StrictMode checks that you've previously added.
// ...
.detectUnsafeIntentLaunch()
.penaltyLog()
// Consider also adding penaltyDeath()
.build());
}
更负责地使用 intent
您的应用可能会启动嵌套 intent,以便在应用的各个组件之间导航,或代表其他应用执行操作。如需在这两种情况下最大限度地降低出现 StrictMode 违规行为的可能性,请执行以下操作:
嵌套 intent 的内部启动:确保这些组件不会被导出。
嵌套 intent 的跨应用启动:使用
PendingIntent
代替嵌套 intent。如此一来,当PendingIntent
从包含它的Intent
中解封时,应用组件可以使用调用进程的身份启动PendingIntent
。该配置允许提供程序应用向调用应用的任何组件(包括未导出的组件)发送回调。
性能
前台服务启动限制
以 Android 12 为目标平台的应用再也无法在后台运行时启动前台服务,但一些特殊情况除外。如果应用尝试在后台运行时启动前台服务,则会引发异常(少数特殊情况除外)。当您的应用在后台运行时,请考虑使用 WorkManager 来计划和启动工作。
前台服务的推荐替代方案:WorkManager(值得尝试)
如果您的应用受到此变更的影响,建议您转向使用 WorkManager。Android 12 Beta 版发布时,WorkManager 将成为启动高优先级后台任务的推荐解决方案。
Work Manager 2.7.0-alpha01 支持加急作业,后者是 Android 12 中的一种新作业。在 Android 11 及更低版本中,此版本的 WorkManager 使用前台服务提供向后兼容性。
加急作业
Android 12 新推出的加急作业允许应用执行重要任务,同时使系统能够更好地控制对资源的访问权限。 加急作业在前台服务和 JobScheduler
作业之间具有一组特征:
它们不受某些系统电源管理限制(包括省电模式和低电耗模式)的影响。
只要系统的当前工作负载允许,系统就会立即运行这些作业。
加急作业可能会延迟
系统会尝试在调用指定的加急作业后,尽快执行该作业。但与其他类型的作业一样,如果正在运行的作业过多或系统资源不足,系统可能会延迟启动新的加急作业。
具体而言,当至少发生以下任一情况时,系统就会推迟执行加急作业:
系统负载过高。
已超出加急作业配额限制。加急作业使用基于应用待机存储分区的配额系统,并限制滚动时间窗口中的最大执行时间。用于加急作业的配额比用于其他类型的后台作业的配额限制更大。
允许从后台启动前台服务的情况
在以下情况下,即使您的应用在后台运行,也可以启动前台服务:
您的应用从某种用户可见的状态,例如某种 activity,过渡至其他状态。
您的应用使用 Firebase Cloud Messaging 接收一条高优先级消息。
用户对与应用相关的界面元素执行操作。例如,他们可能与气泡、通知、微件或 activity 互动。
您的应用收到与地理围栏或运动状态识别相关的事件。
设备重新启动并在广播接收器中接收了
ACTION_BOOT_COMPLETED
intent 操作之后。应用包含特定系统角色或权限,例如设备所有者和配置文件所有者。
您的应用使用 Companion Device Manager。
您的应用已请求
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
权限,并将用户导向至用户已在其中停用该应用的电池优化功能的设置页面。
如需将用户引导至系统设置中的电池优化页面,请调用包含 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
intent 操作的 intent。
- 应用满足限制从后台启动 activity 的例外情况中所述的任何条件,但应用在现有任务的返回堆栈中具有 activity 的情况除外。
无法通过服务或广播接收器创建通知 trampoline
当用户与通知互动时,某些应用会启动应用组件来响应通知点按操作,此应用组件最终会启动用户最终看到并与之互动的 activity。此应用组件被称为通知 trampoline。
为了改进应用性能和用户体验,以 Android 12 为目标平台的应用无法从用作通知 trampoline 的服务或广播接收器中启动 activity。换言之,当用户点按通知或通知中的操作按钮时,您的应用无法在服务或广播接收器内调用 startActivity()
。
当您的应用尝试从充当通知 trampoline 的服务或广播接收器启动 activity 时,系统会阻止启动该 activity 启动
如果您的应用从充当通知 trampoline 的服务或广播接收器启动 activity,请完成以下迁移步骤:
- 创建与一个下列 activity 关联的
PendingIntent
对象:
用户点按通知后会看到的 activity(首选)。
Trampoline activity 或用于启动用户在点按通知后可以看到的 activity 的 activity。
- 在构建通知的过程中,请使用您在上一步中创建的
PendingIntent
对象。
限制非 SDK 接口(强相关)
Android 12 包含更新后的受限制非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测试)。在限制使用非 SDK 接口之前,我们会尽可能确保有可用的公开替代方案。
如果您的应用并非以 Android 12 为目标平台,其中一些变更可能不会立即对您产生影响。然而,虽然您目前仍可以使用一些非 SDK 接口(具体取决于应用的目标 API 级别),但只要您使用任何非 SDK 方法或字段,终归存在导致应用出问题的显著风险。
如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试您的应用来进行确认。如果您的应用依赖于非 SDK 接口,您应该开始计划迁移到 SDK 替代方案。然而,我们知道某些应用具有使用非 SDK 接口的有效用例。如果您无法为应用中的某项功能找到使用非 SDK 接口的替代方案,应请求新的公共 API。
如需详细了解此 Android 版本中的变更,请参阅 Android 12 中有关限制非 SDK 接口的更新。如需全面了解有关非 SDK 接口的详细信息,请参阅对非 SDK 接口的限制。
自定义通知变更(弱相关)
Android 12 改变了完全自定义通知的外观。 以前,自定义通知能够使用整个通知区域并提供自己的布局和样式。由此产生的反模式可能会令用户困惑,或在不同设备上引发布局兼容性问题。
对于以 Android 12 为目标平台的应用,包含自定义内容视图的通知将不再使用完整通知区域;相反,系统会应用标准模板。此模板可确保自定义通知在所有状态下都与其他通知相同,例如,在收起状态下的通知图标和展开功能,以及在展开状态下的通知图标、应用名称和收起功能。此行为与 Notification.DecoratedCustomViewStyle
的行为几乎完全相同。
通过这种方式,Android 12 通过为用户提供可看到且熟悉的通知展开功能,使所有通知保持外观一致且易于浏览。
下图显示了标准模板中的自定义通知:
Android 12 中的变更会影响某些定义 Notification.Style
的自定义子类的应用,或使用 Notification.Builder
的方法 setCustomContentView(RemoteViews)
、setCustomBigContentView(RemoteViews)
和 setCustomHeadsUpContentView(RemoteViews)
的应用。
- 请注意自定义视图规格。一般来说,提供给自定义通知的高度比之前小。在收起状态下,自定义内容的最大高度已从 106dp 减少到 48dp。此外,水平空间也减小了。
- 为了确保“浮动通知”状态看起来符合您的预期,请勿忘记将通知渠道的重要性提升至“高”(在屏幕中弹出)。
连接性
以 Android 12 及更高版本为目标平台的设备在具有硬件支持的设备上运行时,在与对等设备建立连接时,使用点对点连接不会断开与现有 Wi-Fi 的连接。如需检查是否支持此功能,请使用 WifiManager.isMultiStaConcurrencySupported()
。
补充:
华为鸿蒙初接触:
官方地址:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/start-overview-0000000000029602
鸿蒙系统已经适配了市面上主流游戏和应用,并且没有提供任何关于Android应用在鸿蒙系统上的适配方案。
鸿蒙系统采用IDE开发工具DevEco-Studio,基于IntelliJ IDEA,所以整体开发和Android十分相似,包括目录结构
缺点:
鸿蒙应用仅能运行在搭载鸿蒙系统的设备,而今数量很少
需要注册华为开发者,需提供身份证、银行卡等,门槛较高
IDE小问题较多
常用的迁移文件夹在2.0beta版本会有问题
目前previewer预览不支持随写随见,也没有支持拖拽控件布局功能
优点:
鸿蒙应用可以支持手机、平板、电视、穿戴设备、汽车等,一次开发,多点展示
支持Java、Js等多语言,Java提供UI元素更丰富,开发更灵活,Js提供轻量化,开发更简便
对Android开发者而言,学习成本较低,不仅是在IDE的操作习惯,且整体的Framwork和Android很相似,如AbilityPackage对应Application,Ability对应Activity,AbilitySlice对应Fragment,UI也是基于xml或者代码Api实现