Android 7.1.1 及更高版本可为演示模式提供系统级支持,以便用户可以轻松检测运行中的设备。Android 8.1 对这项支持进行了修订,以通过设备政策管理器创建演示用户。这有利于对标准演示模式进行更灵活的 OEM 自定义。
Android 8.1 及更高版本
Android 8.1 支持通过设备政策管理器向零售店用户展示设备功能。尽管设备政策管理器的 API 可以在 8.1 之前的版本上使用,但是对于 8.1 之前的版本,无法使用 createAndManageUser 创建演示类型的用户。
实现
配置
在配置前将 Settings.Global.DEVICE_DEMO_MODE
设置为 1,以表示设备应进入演示模式。系统服务器将使用此标志来管理演示模式的各个方面,例如电源配置文件。此外,零售员工必须向演示应用授予设备所有权。完成消费者设置后,将无法设置设备所有者。
创建演示应用
设备所有者应用无需在系统映像上进行提权或预安装。一般来说,这类应用的实现方式与传统应用是一样的;以下是它们之间的差异:
- 所有的设备所有者应用都必须扩展
DeviceAdminReceiver
组件,该组件可作为所有设备政策管理器 API 的授权令牌。该组件必须具有android.permission.BIND_DEVICE_ADMIN
权限,包含请求的特殊政策(作为元数据),并过滤android.app.action.PROFILE_PROVISIONING_COMPLETE
和android.app.action.DEVICE_ADMIN_ENABLED
Intent。 DevicePolicyManager#MAKE_USER_DEMO
是一个隐藏 API。设置此标志可以创建特殊的演示类型用户。此标志是一个常量 0x4。- 设备所有权只能通过托管配置进行分配。
设备政策管理器
设备政策管理器 API 会授予所有的设备所有者 (DO) 和配置文件所有者 (PO) 权限(软件包安装权限除外,因为系统会自动授予这项权限)。与 DO 关联的 PO 可以使用 AIDL 接口来访问仅向 DO 授予的权限。可用的功能包括:
- 创建用户。通过 DevicePolicyManager 创建的用户将自动设置为 PO。
- 切换用户。
- 将权限政策设置为
PERMISSION_POLICY_AUTO_GRANT
,这样可以自动授予所有运行时权限。权限的授予范围也可以缩小:单项权限授予单一应用。这不适用于 Appops 权限(用户仍必须基于每个用户、每个应用授予权限)。 - 添加用户限制。与演示模式相关的限制可能包括但不限于:
DISALLOW_MODIFY_ACCOUNTS
DISALLOW_USB_FILE_TRANSFER
DISALLOW_DEBUGGING_FEATURES
DISALLOW_CONFIG_WIFI
DISALLOW_CONFIG_BLUETOOTH
DISALLOW_INSTALL_UNKNOWN_SOURCES
DISALLOW_CONFIG_MOBILE_NETWORKS
- 启用自动系统更新。设备将自动下载并应用 OTA 更新。
- 设置 LockTask 允许的软件包。
- 将设备恢复出厂设置。
- 停用锁屏功能。
- 阻止设置密码/指纹。
- 控制 Wi-Fi 网络更改。与用户限制
DISALLOW_CONFIG_WIFI
一起使用时,设备所有者应用可以控制对 WLAN 网络选择设置的访问权限。 - 重新启动设备。
- 通过 PackageInstaller 安装软件包。
- 设置一组已加入白名单的 Settings.Global、Settings.Secure 和 Settings.System 设置。
- 阻止卸载软件包。
示例和其他资源
- 用户、配置文件和帐号的 Android 开发者定义
- 设备政策管理器 API 文档
- 示例设备所有者应用
验证
CTS 不涵盖零售演示模式,因为该模式是一项可选功能。测试应手动进行,或对演示应用进行单元测试。
Android 8.0 及更早版本
Android 7.1.1 引入了零售演示模式,并提供了一个简单 API 来播放演示视频。该实现已在 Android 8.1 中移除。
生命周期

图 1. 语言选择中的零售演示模式选项
设置向导 (SUW)
零售员工可以从任何设置向导的首屏直接启用演示模式,具体方法是选择列表底部的语言零售演示。此选项适用于全新出厂的设备。一旦消费者完成设置,演示模式将不再可用。选择后,设备将完成具有简短流程的 SUW。

图 2. 语言选择中的零售演示模式选项
访客会话
设备进入演示模式后,会切换到新的演示用户,并自动启动覆盖层资源中指定的自定义启动器(如“实现”部分所述)。默认情况下,此自定义启动器会重复播放演示视频,直至用户触摸屏幕开始访客会话。这时,自定义启动器会在启动系统启动器后退出。原始设备制造商 (OEM) 可以更改自定义启动器,使其在退出时额外启动其他服务或活动。如需了解详情,请参阅“实现”部分。
为了保持演示模式的完整性,键盘锁会被停用,且某些可能会对演示模式产生不利影响的“快捷设置”操作也会被禁用,其中包括:
- 飞行模式切换
- 移除或修改 WLAN 接入点(设置)
- 更改运营商(设置)
- 配置热点(设置)
- 用户切换
此外,还对某些会影响零售模式的全局设置进行了停用,以便阻止对这些设置的访问:
- Wi-Fi 设置
- 移动网络配置选项,尤其是热点
- 蓝牙配置
- 备份和重置、日期和时间以及移动网络(这些选项根本不会显示)
如果用户一段时间(默认为 90 秒)没有操作,演示模式会显示系统对话框,提示用户是退出会话还是继续。如果用户选择退出或在 5 秒内没有任何响应,演示模式将终止/擦除当前演示用户,然后切换到新的演示用户,并再次循环播放原始视频。如果有人使用电源按钮关闭屏幕,几秒钟后屏幕又会自动打开。
设备退出演示会话后,会自动静音并重置一些全局设置,其中包括:
- 亮度
- 自动旋转
- 手电筒
- 语言
- 无障碍
退出演示模式
如需退出演示模式,零售员工必须从引导加载程序将设备恢复出厂设置。
示例和源代码
从以下位置查找循环播放视频的自定义启动器:
/packages/apps/RetailDemo
实现
启用 RetailDemoModeService
设置向导将设置全局设置 Global.DEVICE_DEMO_MODE=true
,以表示设备已进入演示模式。一遇到此设置,RetailDemoModeService
便会在用户 0 已启动时创建并切换至演示用户,启用覆盖层资源中指定的自定义启动器,并停用 SUW。系统服务器和 SystemUI 也会使用此标志来管理演示模式的各个方面。
设置自定义启动器或视频播放器
OEM 可以通过覆盖 /frameworks/base/core/res/res/config.xml
中指定的框架资源 config_demoModeLauncherComponent
来指定自定义启动器
例如,使用以下代码:
<!-- Component that is the default launcher when Retail Mode is enabled. --> <string name="config_demoModeLauncherComponent">com.android.retaildemo/.DemoPlayer</string>
位于 /packages/apps/RetailDemo
的零售演示 DemoPlayer 应用是 Android 开放源代码项目 (AOSP) 中的默认自定义启动器。该应用会在 /data/preloads/demo/retail_demo.mp4
中查找视频并进行循环播放。当用户触摸屏幕时,自定义启动器会停用其活动组件,然后默认的系统启动器便会启动。
自定义启动器必须将其自定义组件标记为默认停用,从而避免该组件在非演示情境下出现。在演示情境下,系统服务器会在启动新的演示会话时启用指定的 config_demoModeLauncherComponent
。
设置向导也会查找上述视频作为素材,以提供给演示模式进行播放。如果视频不是演示的一部分,可以修改 SUW 以查找其他表明支持演示模式的 OEM 特定标志。
如果有 A/B 两个系统分区,B 系统分区的 /preloads/demo
中必须包含演示视频。在首次启动时,系统会将该视频复制到 /data/preloads/demo
。
如需设置特定于演示模式的设置,请使用:Settings.Global.retail_demo_mode_constants
。例如:user_inactivity_timeout_ms=90000,warning_dialog_timeout_ms=10000
注意:目前的超时默认值为 90000 毫秒,但可对其进行配置。
查找示例图片
此功能可将示例照片放在对任何图库应用均可见的特殊文件夹中。这些照片仅在演示模式下可用,并且由于处在受保护的目录中,所以演示用户无法对其进行修改。
阻止 Google 帐号
访客用户中设置了一些限制,类似于通过托管设备/资料策略防止应用和用户执行某些操作。其中一项限制是 DISALLOW_MODIFY_ACCOUNTS
。在此限制之下,AccountManager 和“设置”不允许添加帐号。某些 Google 应用会对此限制做出反应并显示一条错误消息,其他应用则不提示登录帐号(如 YouTube 和 Google 相册)。
OEM 应用也应检查是否已设置 DISALLOW_MODIFY_ACCOUNTS
。但这是一个一般问题,并非演示模式所独有。企业用例很可能已解决此问题。
自定义系统启动器
OEM 可以自由选择布局,但应该在主屏幕和底部区域包含正常运行的应用。
针对零售演示模式自定义内置应用
内置应用可调用 API UserManager.isDemoUser()
来查看应用是否在演示环境中启动,以此针对零售演示模式自定义应用体验。
遵循演示视频指南
演示视频应采用纵向布局(如果是平板电脑,则为设备的自然方向),且时长在 5 秒以上。由于视频将在展示期间全天候播放,因此视频内容不能导致烧机。
维护
使设备退出演示模式
只能通过从引导加载程序恢复出厂设置来实现。
系统软件的自动 OTA
默认情况下,启用演示模式时,设备政策将自动设置为无线下载 (OTA) 更新。零售设备将不经过确认,自动下载、重新启动并安装更新(考虑电池阈值),即使更新被标记为可选亦如此。
注意:如果针对 OTA 使用 A/B 系统分区,则接收 OTA 更新后,设备将无法在 B 系统分区中找到原始的演示模式资源。因此,之后的任何恢复出厂设置操作都会导致设备无法返回演示模式。
通过网络更新演示视频
只要有网络连接,/packages/apps/RetailDemo
中的 RetailDemo 应用便可以更新演示视频。通过在 RetailDemo 应用中替换以下字符串值,可配置下载视频的网址:
<!-- URL where the retail demo video can be downloaded from. --> <string name="retail_demo_video_download_url"></string>
如果需要在不同的区域使用不同的视频,可以通过使用特定于语言区域的字符串资源 res/values-*/strings.xml.
配置不同的下载网址。例如,如果需要在美国和英国使用不同的视频,可以将相应的下载网址分别放在 res/values-en-rUS/strings.xml
和 res/values-en-rGB/strings.xml
中。
在 res/values-en-rUS/strings.xml
中:
<string name="retail_demo_video_download_url">download URL for US video goes here</string>
同样,在 res/values-en-rGB/strings.xml
中:
<string name="retail_demo_video_download_url">download URL for UK video goes here</string>
每次设备重新启动时,此视频最多只能下载一次。视频在设备上播放时,RetailDemo 应用会在后台检查是否提供了下载网址以及网址中的视频是否比正在播放的视频新。
如果是,RetailDemo 应用就会下载该视频并开始播放。视频下载完成后,下载的视频将用于在之后的演示会话中播放。在下次重新启动之前,将不再执行任何此类检查。