クイック設定は、クイック設定パネルに表示されるタイルです。アクションを表し、ユーザーがタップして反復タスクをすばやく完了できます。アプリは TileService
クラスを使用してユーザーにカスタムタイルを提供するとともに、Tile
オブジェクトを使用してタイルの状態を追跡できます。たとえば、アプリで提供される VPN をユーザーがオンまたはオフにできるタイルを作成できます。
タイルを作成するタイミングを決める
ユーザーが頻繁にアクセスする機能や、すばやくアクセスする必要がある機能(またはその両方)のタイルを作成することをおすすめします。最も効果的なタイルは、これらの両方の特性を備え、頻繁に実行されるアクションにすばやくアクセスできるものです。
たとえば、ユーザーがワークアウト セッションをすばやく開始できるように、フィットネス アプリのタイルを作成できます。ただし、ユーザーがワークアウト履歴全体を確認できるタイルを同じアプリに作成することはおすすめしません。
タイルの見つけやすさと使いやすさを向上させるため、次のような方法は避けることをおすすめします。
タイルをアプリの起動に使用しないでください。代わりに、アプリのショートカットまたは標準ランチャーを使用してください。
ユーザーの 1 回限りの操作にタイルは使用しないでください。代わりに、アプリのショートカットまたは通知を使用してください。
タイルを作成しすぎないでください。アプリごとに最大 2 つをおすすめします。代わりにアプリのショートカットを使用してください。
情報を表示するだけで、ユーザーが操作できないタイルは使用しないでください。代わりに通知またはウィジェットを使用してください。
タイルを作成する
タイルを作成するには、まず適切なタイルのアイコンを作成し、次にアプリのマニフェスト ファイルで TileService
を作成して宣言する必要があります。
クイック設定のサンプルでは、タイルの作成と管理方法の例を示しています。
カスタム アイコンを作成する
クイック設定パネルのタイルに表示されるカスタム アイコンを指定する必要があります。(このアイコンは、次のセクションで説明する TileService
を宣言するときに追加します)。アイコンは、背景が透明で白色の単色で、サイズは 24 x 24 dp で、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()
の 4 つのコールバック メソッドが含まれています。これらのメソッドは、サービスが新しいライフサイクル フェーズに入るたびにシステムによって呼び出されます。
TileService のライフサイクルの概要
バインドされたサービスのライフサイクルを制御するコールバックに加えて、TileService
ライフサイクルに固有の他のメソッドを実装する必要があります。Service
ライフサイクル メソッドと TileService
ライフサイクル メソッドは 2 つの個別の非同期スレッドで呼び出されるため、これらのメソッドは onCreate()
と onDestroy()
の外部から呼び出される場合があります。
TileService
ライフサイクルには、TileService
が新しいライフサイクル フェーズに入るたびにシステムによって呼び出される次のメソッドが含まれています。
onTileAdded()
: このメソッドは、ユーザーがタイルを初めて追加したとき、およびユーザーがタイルを削除して再度追加した場合にのみ呼び出されます。1 回限りの初期化を行うには、このタイミングが最適です。ただし、これだけでは必要な初期化がすべて完了しない場合があります。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
は非アクティブ モードです。つまり、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()
へのコールバックを受信するまで、タイルを少なくとも 1 回更新できます。
アクティブ モードでは、onStopListening()
へのコールバックを受け取る前にタイルを 1 回だけ更新できます。非アクティブ モードでは、onStartListening()
と onStopListening()
の間でタイルを何度でも更新できます。
Tile
オブジェクトを取得するには、getQsTile()
を呼び出します。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()
: パネルを閉じながらアクティビティを開始します。アクティビティは、ダイアログ内よりも詳細な情報を表示する場合や、操作が高度なインタラクティブ性を持つ場合に便利です。
アプリでユーザーによる重要な操作が必要な場合は、アクティビティを起動する方法は最後の手段にしてください。代わりに、ダイアログや切り替えボタンの使用を検討してください。
タイルを長押しすると、アプリ情報画面が表示されます。この動作をオーバーライドして、代わりに設定アクティビティを起動するには、ACTION_QS_TILE_PREFERENCES
を使用していずれかのアクティビティに <intent-filter>
を追加します。
Android API 28 以降では、PendingIntent
に Intent.FLAG_ACTIVITY_NEW_TASK
が必要です。
if (Build.VERSION.SDK_INT >= 28) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
または、特定の Activity
セクションの AndroidManifest.xml
にフラグを追加することもできます。
タイルを切り替え可能としてマークする
タイルの主な機能が 2 つの状態の切り替えスイッチである場合は、切り替え可能としてマークすることをおすすめします(これはタイルの最も多い動作です)。これにより、タイルの動作に関する情報をオペレーティング システムに提供し、全体的なユーザー補助を改善できます。
タイルを入れ替え可能としてマークするには、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
から決定されます。これは現在のユーザーと一致している必要があります。