快速設定是顯示在「快速設定」面板中的資訊方塊,代表動作,使用者只要輕觸該方塊,即可快速完成週期性工作。應用程式可以透過 TileService
類別為使用者提供自訂資訊方塊,並使用 Tile
物件追蹤資訊方塊的狀態。例如,您可以建立資訊方塊,讓使用者開啟或關閉應用程式提供的 VPN。
決定建立資訊方塊的時間
建議您針對使用者會經常存取或需要快速存取 (或兩者) 的特定功能建立資訊方塊。最有效的資訊方塊是同時符合這兩種品質的資訊方塊,可讓您快速存取經常執行的操作。
舉例來說,您可以為健身應用程式建立資訊方塊,讓使用者快速啟動健身工作階段。但是,我們不建議在同一個應用程式建立資訊方塊,方便使用者查看完整的健身記錄。
為了提升資訊方塊的能見度和使用便利性,建議您避免採用下列做法:
請避免使用資訊方塊啟動應用程式,請改用應用程式捷徑或標準啟動器。
請避免將資訊方塊用於一次性使用者動作,請改用應用程式捷徑或通知。
避免建立過多資訊方塊。我們建議每個應用程式最多只能使用兩個。請改用應用程式捷徑。
避免使用會顯示資訊 (但不會對使用者互動) 的資訊方塊。請改用通知或小工具。
建立資訊方塊
如要建立資訊方塊,您必須先建立適當的資訊方塊圖示,然後在應用程式的資訊清單檔案中建立並宣告 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
就會繫結。一般的繫結服務生命週期包含下列四個回呼方法: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()
的回呼。您可以在 onStartListening()
和 onStopListening()
之間隨時更新 Tile
物件,次數不限。
您不需要宣告非活動模式,只要將 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
物件的特定欄位,請呼叫下列方法:
將 Tile
物件的欄位設為正確的值後,您必須呼叫 updateTile()
來更新資訊方塊。這會使系統剖析更新的資訊方塊資料,並更新 UI。
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()
收合「快速設定」面板並顯示對話方塊。
如果動作需要額外輸入內容或徵得使用者同意,請使用對話方塊新增動作背景資訊。
啟動活動
startActivityAndCollapse()
會在收合面板時啟動活動。如果要顯示的資訊比對話方塊內的更多詳細資訊,或者您的動作高度互動,活動就能派上用場。
如果應用程式需要大量的使用者互動,應用程式應該只在萬不得已的情況下啟動活動。建議您改用對話方塊或切換按鈕。
長按資訊方塊則可提示使用者「App Info」畫面。如要覆寫此行為,改為啟動活動以設定偏好設定,請使用 ACTION_QS_TILE_PREFERENCES
將 <intent-filter>
新增至其中一個活動。
將圖塊標示為可切換
如果資訊方塊主要是雙狀態開關 (這是資訊方塊最常見的行為),建議您將資訊方塊標示為可切換。這有助於提供資訊方塊在作業系統中的行為資訊,並改善整體的無障礙功能。
將 TOGGLEABLE_TILE
中繼資料設為 true
,即可將資訊方塊標示為可切換。
<service ...>
<meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>
只在有安全鎖定的裝置上執行安全操作
在已鎖定的裝置上,你的圖塊可能會顯示在螢幕鎖定畫面頂端。如果資訊方塊包含機密資訊,請檢查 isSecure()
的值,判斷裝置是否處於安全狀態,且 TileService
應據此變更其行為。
如果資訊方塊動作在鎖定狀態下可以安全執行,請使用 startActivity()
在螢幕鎖定畫面頂端啟動活動。
如果資訊方塊動作不安全,請使用 unlockAndRun()
提示使用者解鎖裝置。如果成功,系統會執行您傳遞至這個方法的 Runnable
物件。
提示使用者新增資訊方塊
若要手動新增動態磚,使用者必須遵循下列步驟:
- 向下滑動開啟「快速設定」面板。
- 輕觸編輯按鈕。
- 捲動瀏覽裝置的所有動態磚,直到找到您的動態磚。
- 按住您的動態磚,並將其拖曳至有效動態磚清單。
使用者也可以隨時移動或移除您的動態磚。
從 Android 13 開始,您可以使用 requestAddTileService()
方法,讓使用者更容易在裝置上新增資訊方塊。這個方法會提示使用者,要求將資訊方塊直接快速加入他們的「快速設定」面板。提示內容包含應用程式名稱、提供的標籤和圖示。
public void requestAddTileService (
ComponentName tileServiceComponentName,
CharSequence tileLabel,
Icon icon,
Executor resultExecutor,
Consumer<Integer> resultCallback
)
回呼中包含資訊方塊是否已新增、未新增、是否已新增,或是否發生任何錯誤。
請自行斟酌,決定是否提示使用者的時機和頻率。建議您只在使用情境下呼叫 requestAddTileService()
,例如使用者首次與資訊方塊輔助的功能互動時。
如果使用者曾經多次拒絕特定 ComponentName
的要求,系統可以選擇停止處理要求。使用者可以從用於擷取這項服務的 Context
決定,其必須與目前的使用者相符。