适用于可折叠设备和跨屏设备的应用
通常情况下,应用不应依赖于静态标识符或基于某些屏幕 ID 的逻辑。在大多数情况下,应用应该能够适应在不同尺寸的屏幕上工作,而系统应控制应用的放置位置。例如,针对可折叠设备打造新颖独特的体验,并且当设备处于折叠状态时,在外部屏幕上启动特定的应用。
在这种情况下,SystemUI(或其他系统组件)应检测设备是否处于折叠状态,确定是否应该执行操作,然后启动目标 activity 并指定一个外部屏幕 ID 作为启动目标。应用不应检测此操作,也不应做出响应,然后在特定屏幕上启动。换句话说,不要假设可在一台设备上执行的操作,也可在其他设备上执行。简而言之,专门针对特定设备的代码会导致碎片化程度增加。
限制对屏幕的访问
如果设备配置要求限制对一个或多个屏幕的访问,建议使用 Display#FLAG_PRIVATE
标志将此类屏幕标记为“不公开”。这样做会限制除所有者之外的所有人向此类屏幕添加内容。除所有者之外的任何人如果尝试启动 activity 或添加窗口,都会导致 SecurityException
。如果该屏幕归系统所有,则系统可以添加窗口并启动 activity。
此外,放置在某个屏幕上的实体将始终可以访问该屏幕。 如果所有者在某个屏幕上启动了一个 activity,则该 activity 可以在此屏幕上启动其他 activity。因此,所有者需要负责限制访问,并仅允许受信任的应用访问。
此外,我们还针对虚拟屏幕增加了更多限制,因为任何应用都可以创建虚拟屏幕,而不让用户看见。如果虚拟屏幕不归系统所有,则只有具备 allowEmbedded
属性的 Activity 才能访问该屏幕,并且其调用者应具有 ACTIVITY_EMBEDDING
权限。
要了解详情,请参阅:
ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()
ActivityDisplay#isUidPresent()
DisplayManagerService#isUidPresentOnDisplay()
要有条件地控制 activity 启动,请使用 LaunchParamsController
,它会拦截所有 activity 启动,并允许系统组件修改在启动时使用的参数。此功能可在 system_server
中找到。
配置屏幕窗口设置和系统装饰
可在 DisplayWindowSettings
中配置每个屏幕的系统装饰。设备实现可以在 /data/system/display_settings.xml
中提供默认配置。
此值决定是否要在屏幕上显示系统装饰(启动器、壁纸、导航栏和其他装饰窗口)和 IME。
如需了解详情,请参阅 DisplayWindowSettings#shouldShowSystemDecorsLocked()
和 DisplayWindowSettings#shouldShowImeLocked()
。
要识别屏幕,请使用唯一 ID(这默认使用 DisplayInfo#uniqueId
)或硬件屏幕的物理端口 ID(请参阅 DisplayInfo#address
)。
例如,下面的屏幕配置示例会在模拟屏幕上启用系统装饰和 IME:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <display-settings> <config identifier="0" /> <display name="overlay:1" shouldShowSystemDecors="true" shouldShowIme="true" /> </display-settings>
在上面的示例中,uniqueId
用于在名称属性中标识屏幕,对于模拟屏幕,此 ID 为 overlay:1
。对于内置屏幕,示例值可以是 "local:45354385242535243453"
。另一种方式是使用硬件端口信息,并设置 identifier="1"
以与 DisplayWindowSettings#IDENTIFIER_PORT
对应,然后更新 name 以使用 "port:<port_id>"
格式:
<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?> <display-settings> <config identifier="1" /> <display name="port:12345" shouldShowSystemDecors="true" shouldShowIme="true" /> </display-settings>
如需了解详情,请参阅静态屏幕标识符。
如需了解详情,请参阅: