“快捷设置”是显示在“快捷设置”面板中的图块,
代表操作,用户只需点按这些按钮即可快速完成周期性任务。
应用可以通过 TileService
向用户提供自定义功能块
类,并使用 Tile
对象跟踪功能块的状态。例如:
您可以创建一个功能块
让用户能够开启您的应用提供的 VPN
关闭。
决定何时创建功能块
我们建议您针对您期望用户的特定功能创建功能块 经常访问和/或需要快速访问的用户。最有效 即同时符合这两种特征的图块,方便您快速访问 频繁执行的操作。
例如,您可以为健身应用创建功能块,以便用户执行以下操作: 快速开始锻炼课程。不过,我们不建议您 同一应用,并且允许用户查看其全部锻炼历史记录。
为帮助提高功能块的可检测性和易用性,我们建议您 避免某些做法:
避免使用功能块来启动应用。使用应用快捷方式或标准快捷方式 启动器。
避免将功能块用于一次性用户操作。使用应用快捷方式或 notification。
避免创建过多功能块。我们建议每个应用最多设置 2 个。使用 应用快捷方式。
避免使用显示信息,但对以下内容无互动功能的功能块: 用户。请改用通知或 widget。
创建功能块
如要创建功能块,您需要先创建适当的功能块图标,然后
在应用的清单文件中创建并声明 TileService
。
“快捷设置”示例举例说明了如何创建 以及管理卡片
创建自定义图标
您需要提供一个自定义图标,该图标会显示在 快速启动
设置面板。(您将在声明 TileService
时添加此图标,
具体说明。)该图标必须为纯白色,并带有
透明背景,尺寸为 24 x 24dp,采用
VectorDrawable
。
创建一个在视觉上暗示功能块用途的图标。这有助于用户 轻松识别您的功能块是否符合他们的需求。例如,您可以创建一个 一个健身应用的秒表板块,该板块允许用户启动 锻炼课程。
创建并声明 TileService
为功能块创建一项扩展 TileService
类的服务。
Kotlin
class MyQSTileService: TileService() { // Called when the user adds your tile. override fun onTileAdded() { super.onTileAdded() } // Called when your app can update your tile. override fun onStartListening() { super.onStartListening() } // Called when your app can no longer update your tile. override fun onStopListening() { super.onStopListening() } // Called when the user taps on your tile in an active or inactive state. override fun onClick() { super.onClick() } // Called when the user removes your tile. override fun onTileRemoved() { super.onTileRemoved() } }
Java
public class MyQSTileService extends TileService { // Called when the user adds your tile. @Override public void onTileAdded() { super.onTileAdded(); } // Called when your app can update your tile. @Override public void onStartListening() { super.onStartListening(); } // Called when your app can no longer update your tile. @Override public void onStopListening() { super.onStopListening(); } // Called when the user taps on your tile in an active or inactive state. @Override public void onClick() { super.onClick(); } // Called when the user removes your tile. @Override public void onTileRemoved() { super.onTileRemoved(); } }
在应用的清单文件中声明 TileService
。添加名称和标签
TileService
(您在上一部分中创建的自定义图标)后,
以及适当的权限。
<service
android:name=".MyQSTileService"
android:exported="true"
android:label="@string/my_default_tile_label" // 18-character limit.
android:icon="@drawable/my_default_icon_label"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
管理您的 TileService
在应用清单中创建并声明 TileService
后,
必须管理其状态
TileService
是一项绑定服务。“TileService
”的绑定时间
或者系统需要与应用进行通信典型
bound-serviceLifecycle 包含以下四个回调方法:
onCreate()
、onBind()
、onUnbind()
和
onDestroy()
。系统每次在调用
服务将进入一个新的生命周期阶段。
TileService 生命周期概览
除了控制绑定服务生命周期的回调之外,您还必须
实现特定于 TileService
生命周期的其他方法。这些方法
可能会在 onCreate()
和 onDestroy()
之外调用,因为 Service
生命周期方法和 TileService
生命周期方法在
单独的异步线程
TileService
生命周期包含以下方法,
系统在每次 TileService
进入新的生命周期阶段时被系统更新:
onTileAdded()
:仅当用户添加了您的 该功能,并且如果用户移除并再次添加您的功能块。 此时最适合执行任何一次性初始化。但这可能会 无法满足所有需要的初始化。onStartListening()
和onStopListening()
:这些方法是 每当您的应用更新功能块时都会调用,并且会经常调用。通过 “TileService
”在onStartListening()
到 之间仍绑定onStopListening()
,允许您的应用修改功能块并推送更新。onTileRemoved()
:仅当用户移除您的 功能块。
选择聆听模式
您的 TileService
会在活动模式或非活动模式下收听。我们建议
使用活动模式,您需要在应用清单中声明该模式。否则
TileService
是标准模式,无需声明。
请勿假设您的 TileService
将居住在 onStartListening()
之外,并且
onStopListening()
对方法。
活动模式(推荐)
为 TileService
使用活动模式,该模式会在
自己的进程处于活动模式的 TileService
绑定到 onTileAdded()
,
onTileRemoved()
、点按事件以及应用进程请求时。
如果你在功能块状态提示时TileService
收到通知,建议你选择活动模式
应通过自己的进程进行更新。使用中的图块可以限制
因为您不必在每次打开“快捷设置”面板时都进行绑定
显示给用户
可以调用静态 TileService.requestListeningState()
方法
请求开始监听状态并接收
onStartListening()
。
您可以通过将 META_DATA_ACTIVE_TILE
添加到
应用的清单文件中
<service ...>
<meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
...
</service>
非活动模式
非活动模式是标准模式。如果出现以下情况,TileService
将处于非活动模式
每当您的功能块对用户可见时,它就会绑定。这意味着您的
TileService
可能会在其控制范围之外再次创建和绑定。它
也可能会在用户不查看功能块时解除绑定和销毁。
用户打开应用后,应用会收到对 onStartListening()
的回调
“快捷设置”面板。您可以无限次更新 Tile
对象
所需时间介于 onStartListening()
到 onStopListening()
之间。
您无需声明非活动模式,只需不要添加
META_DATA_ACTIVE_TILE
添加到应用的清单文件中。
图块状态概览
用户添加功能块后,功能块会始终处于以下状态之一。
STATE_ACTIVE
:表示开启或启用状态。用户可以 可在此状态下与您的功能块互动。例如,对于允许用户发起定时锻炼的健身应用功能块 会话,
STATE_ACTIVE
表示用户已发起锻炼 且计时器正在计时。STATE_INACTIVE
:表示关闭或暂停状态。用户可以 可在此状态下与您的功能块互动。再次使用健身应用功能块示例,
STATE_INACTIVE
中的功能块应如下所示: 表示用户没有启动锻炼时段, 实现预期目标STATE_UNAVAILABLE
:表示暂时不可用的状态。通过 在此状态下,用户无法与您的功能块互动。例如,
STATE_UNAVAILABLE
中的功能块表示该功能块不是 由于某种原因向用户提供当前可用的资源。
系统仅设置 Tile
对象的初始状态。您设置了 Tile
对象的状态。
系统可能会调节功能块图标和背景的色调,以反映您的
Tile
对象。设置为 STATE_ACTIVE
的 Tile
对象最暗,
STATE_INACTIVE
和 STATE_UNAVAILABLE
越来越轻。确切色调
因制造商和版本而异
更新您的功能块
收到 onStartListening()
的回调后,您可以更新功能块。
取决于板块的模式,您的板块可以至少更新一次,直到
收到对 onStopListening()
的回调。
在活动模式下,你可以在收到
对 onStopListening()
的回调。在非活动模式下,你可以将板块更新为
您可以在 onStartListening()
到 onStopListening()
之间随意操作。
您可以通过调用 getQsTile()
来检索 Tile
对象。更新
Tile
对象的特定字段,请调用以下方法:
设置完毕后,您必须调用 updateTile()
来更新功能块
Tile
对象的字段更改为正确的值。这样,系统会
解析更新后的功能块数据并更新界面。
Kotlin
data class StateModel(val enabled: Boolean, val label: String, val icon: Icon) override fun onStartListening() { super.onStartListening() val state = getStateFromService() qsTile.label = state.label qsTile.contentDescription = tile.label qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.icon = state.icon qsTile.updateTile() }
Java
public class StateModel { final boolean enabled; final String label; final Icon icon; public StateModel(boolean e, String l, Icon i) { enabled = e; label = l; icon = i; } } @Override public void onStartListening() { super.onStartListening(); StateModel state = getStateFromService(); Tile tile = getQsTile(); tile.setLabel(state.label); tile.setContentDescription(state.label); tile.setState(state.enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); tile.setIcon(state.icon); tile.updateTile(); }
处理点按操作
如果您的功能块位于以下位置,用户只需点按您的功能块即可触发操作
STATE_ACTIVE
或 STATE_INACTIVE
。然后,系统会调用您应用的
onClick()
回调。
应用收到对 onClick()
的回调后,即可启动对话框或
触发后台工作或更改功能块的状态。
Kotlin
var clicks = 0 override fun onClick() { super.onClick() counter++ qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.label = "Clicked $counter times" qsTile.contentDescription = qsTile.label qsTile.updateTile() }
Java
int clicks = 0; @Override public void onClick() { super.onClick(); counter++; Tile tile = getQsTile(); tile.setState((counter % 2 == 0) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); tile.setLabel("Clicked " + counter + " times"); tile.setContentDescription(tile.getLabel()); tile.updateTile(); }
启动对话框
showDialog()
可收起“快捷设置”面板并显示一个对话框。
如果操作需要额外输入,请使用对话框为操作添加上下文
或征得用户同意。
启动 activity
startActivityAndCollapse()
在收起
面板。如果有更详细的信息可以显示,那么 activity 非常有用
还是在对话框内操作
或你的操作互动性很高的话
如果您的应用需要用户互动,则应启动 只作为最后的补救手段。请考虑改用对话框或切换开关。
长按功能块会提示用户进入应用信息界面。覆盖
并改为启动一个 activity 来设置偏好设置,添加一个
<intent-filter>
与你的某个活动进行了互动:
ACTION_QS_TILE_PREFERENCES
。
从 Android API 28 开始,PendingIntent
必须
具有 Intent.FLAG_ACTIVITY_NEW_TASK
:
if (Build.VERSION.SDK_INT >= 28) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
您也可以在特定版本的 AndroidManifest.xml
中添加
Activity
部分。
将功能块标记为可切换
如果功能块主要用作 双状态开关(这是功能块最常见的行为)。这有助于 向操作系统提供有关功能块行为的信息, 改进整体无障碍功能。
将 TOGGLEABLE_TILE
元数据设置为 true
,将功能块标记为可切换。
<service ...>
<meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>
仅在被安全锁定的设备上执行安全操作
在锁定的设备上,您的图块可能会显示在锁定屏幕上。如果图块
包含敏感信息,请检查 isSecure()
的值,
确定设备是否处于安全状态,您的 TileService
应
并相应地更改其行为
如果在锁定时可以安全执行图块操作,请使用 startActivity()
在锁定屏幕上启动 activity。
如果图块操作不安全,请使用 unlockAndRun()
提示用户
解锁设备。如果成功,系统会执行
Runnable
对象,
方法。
提示用户添加功能块
如要手动添加功能块,用户必须按以下步骤操作:
- 向下滑动以打开“快捷设置”面板。
- 点按“修改”按钮。
- 滚动浏览孩子设备上的所有板块,直到他们找到您的板块。
- 按住您的功能块,然后将其拖动到有效功能块列表中。
用户还可以随时移动或移除您的功能块。
从 Android 13 开始,您可以使用 requestAddTileService()
方法
以便用户更轻松地将您的功能块添加到设备。此方法
提示用户请求快速将您的功能块直接添加到他们的“快速”
设置面板。提示信息包括应用名称、所提供的标签
和图标
public void requestAddTileService (
ComponentName tileServiceComponentName,
CharSequence tileLabel,
Icon icon,
Executor resultExecutor,
Consumer<Integer> resultCallback
)
该回调包含有关是否添加了功能块(而非功能块)的信息 或该文件是否已经存在,或者是否发生了任何错误。
您可以自行决定何时以及以何种频率提示用户。周三
建议仅在上下文中调用 requestAddTileService()
,例如
当用户首次与您的功能块提供的功能互动时触发。
对于指定的
ComponentName
(如果用户之前已多次拒绝请求)。通过
由Context
用于检索此
服务 - 它必须与当前用户相匹配。