クイック設定は、クイック設定パネルに表示されるタイルで、アクションを表し、ユーザーはタップして繰り返しタスクをすばやく完了できます。アプリでは、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
は、アプリからリクエストされた場合、またはシステムがそれと通信する必要がある場合にバインドされます。一般的な bound-service のライフサイクルには、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
が作成され、制御不能なタイミングで再度バインドされる可能性があります。ユーザーがタイルを表示していないときは、バインドを解除して破棄することもできます。
ユーザーがクイック設定パネルを開くと、アプリは 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
を使用してアクティビティの 1 つに <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
から決定されます。これは現在のユーザーと一致する必要があります。