アプリ用のカスタム クイック設定タイルを作成する

クイック設定は、クイック設定パネルに表示されるタイルです。アクションを表し、ユーザーがタップして反復タスクをすばやく完了できます。アプリは TileService クラスを使用してユーザーにカスタムタイルを提供するとともに、Tile オブジェクトを使用してタイルの状態を追跡できます。たとえば アプリが提供する VPN をユーザーが有効にしたり、 オフにします。

VPN タイルのオンとオフを切り替えたクイック設定パネル
図 1. VPN タイルのオンとオフを切り替えたクイック設定パネル。

タイルを作成するタイミングを決定する

ユーザーが頻繁にアクセスする機能や、すばやくアクセスする必要がある機能(またはその両方)のタイルを作成することをおすすめします。最も効果的なタイルは、これらの両方の特性を備え、頻繁に実行されるアクションにすばやくアクセスできるものです。

たとえば、ユーザーがワークアウト セッションをすばやく開始できるように、フィットネス アプリのタイルを作成する場合があります。ただし、タイルを作成し、 ユーザーがワークアウトの全履歴を確認できるようにしました。

フィットネス アプリのタイルのユースケース
図 2. フィットネス アプリで推奨されるタイルと推奨されないタイルの例。

タイルの見つけやすさと使いやすさを向上させるため、次のような方法は避けることをおすすめします。

  • アプリを起動するためにタイルを使用することは避けてください。アプリのショートカットまたは標準のショートカットを使用する ランチャーを使用してください。

  • 1 回限りのユーザー操作にタイルを使用しないでください。代わりに、アプリのショートカットまたは通知を使用してください。

  • タイルを作成しすぎないでください。アプリごとに最大 2 つをおすすめします。代わりにアプリのショートカットを使用してください。

  • 情報を表示するだけで、ユーザーが操作できないタイルは使用しないでください。代わりに通知またはウィジェットを使用してください。

タイルを作成する

タイルを作成するには、まず適切なタイルのアイコンを作成し、次にアプリのマニフェスト ファイルで TileService を作成して宣言する必要があります。

クイック設定のサンプルでは、タイルの作成と管理方法の例を示しています。

カスタム アイコンを作成する

クイックアイコンのタイルに表示されるカスタムアイコンを用意する必要があります。 設定パネル。(このアイコンは、TileService を宣言するときに追加します。 (次のセクションで説明します)。アイコンは白色で点灯し、 透明な背景、24 x 24 dp、 VectorDrawable

ベクター型ドローアブルの例
図 3. ベクター型ドローアブルの例。

タイルの目的を視覚的に示唆するアイコンを作成します。これにより、 タイルがニーズに合っているかどうかを簡単に確認できます。たとえば、ユーザーがワークアウト セッションを開始できるように、フィットネス アプリのタイルにストップウォッチのアイコンを作成できます。

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 には、次の 4 つのコールバック メソッドが含まれています。 onCreate()onBind()onUnbind()onDestroy()これらのメソッドは、 ライフサイクル フェーズに入ります。

TileService のライフサイクルの概要

バインドされたサービスのライフサイクルを制御するコールバックに加えて、TileService ライフサイクルに固有の他のメソッドを実装する必要があります。これらのメソッドは、 onCreate()onDestroy() の外部で呼び出される場合があります。これは、Service が ライフサイクル メソッドと TileService ライフサイクル メソッドは、2 つの 非同期スレッドを分離できます

TileService ライフサイクルには、呼び出される次のメソッドが含まれます。 TileService が新しいライフサイクル フェーズに入るたびに、システムにより次のように処理されます。

  • onTileAdded(): このメソッドは、ユーザーが ユーザーがタイルを削除して再度追加した場合などです。 これが 1 回限りの初期化を行うのに最適なタイミングです。ただし、 初期化の条件をすべて満たしているとは言えません。

  • onStartListening()onStopListening(): これらのメソッドは、アプリがタイルを更新するたびに呼び出され、頻繁に呼び出されます。TileServiceonStartListening()onStopListening() の間にバインドされたままであるため、アプリはタイルを変更して更新をプッシュできます。

  • onTileRemoved(): このメソッドは、ユーザーがタイルを削除した場合にのみ呼び出されます。

で確認できます。

リスニング モードを選択する

TileService は、アクティブ モードまたは非アクティブ モードでリッスンします。アクティブ モードを使用することをおすすめします。このモードはアプリ マニフェストで宣言する必要があります。それ以外の場合、TileService は標準モードであり、宣言する必要はありません。

TileServiceonStartListening() メソッドと 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_INACTIVESTATE_UNAVAILABLE が徐々に明るくなります。正確な色相 メーカーとバージョンに固有です

オブジェクトの状態を反映するように色付けされた VPN タイル
図 4. タイルの状態(アクティブ、非アクティブ、利用不可)を反映して色付けされたタイルの例。

タイルを更新する

onStartListening() へのコールバックを受け取ったら、タイルを更新できます。 タイルのモードに応じて、次の期限まで少なくとも 1 回はタイルを更新できます。 onStopListening() へのコールバックを受信したとき。

アクティブ モードでは、onStopListening() へのコールバックを受け取る前にタイルを 1 回だけ更新できます。非アクティブ モードでは、onStartListening()onStopListening() の間でタイルを何度でも更新できます。

Tile オブジェクトを取得するには、getQsTile() を呼び出します。Tile オブジェクトの特定のフィールドを更新するには、次のメソッドを呼び出します。

で確認できます。

タイルの設定が完了したら、updateTile() を呼び出してタイルを更新する必要があります。 Tile オブジェクトのフィールドに正しい値を設定します。これにより、システムは更新されたタイルデータを解析し、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 以降では、PendingIntentIntent.FLAG_ACTIVITY_NEW_TASK がある。

if (Build.VERSION.SDK_INT >= 28) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

また、特定の Terraform 構成ファイルの AndroidManifest.xml にフラグを追加することもできます。 Activity セクション。

タイルを切り替え可能としてマークする

タイルの主な機能が 2 つの状態の切り替えスイッチである場合は、切り替え可能としてマークすることをおすすめします(これはタイルの最も多い動作です)。これにより、タイルの動作に関する情報をオペレーティング システムに提供し、全体的なユーザー補助を改善できます。

タイルを入れ替え可能としてマークするには、TOGGLEABLE_TILE メタデータを true に設定します。

<service ...>
  <meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
    android:value="true" />
</service>

安全にロックされたデバイスで安全な操作のみを実行します

ロックされたデバイスでは、ロック画面の上部にタイルが表示されることがあります。もしタイルが 含まれている場合は、isSecure() の値を確認して、 デバイスが安全な状態かどうかを判別し、TileService が それに応じて動作を変更します。

ロックされた状態でタイルのアクションを安全に実行できる場合は、startActivity() を使用してロック画面の上にアクティビティを起動します。

タイルのアクションが安全でない場合は、unlockAndRun() を使用して、デバイスのロックを解除するようユーザーに促します。成功すると、システムによって これに渡す Runnable オブジェクト メソッドを呼び出します。

タイルを追加するようユーザーに促す

タイルを手動で追加するには、ユーザーが以下の操作を行う必要があります。

  1. 下にスワイプしてクイック設定パネルを開きます。
  2. 編集ボタンをタップします。
  3. デバイス上のすべてのタイルをスクロールして、目的のタイルを探します。
  4. タイルを長押しして、アクティブなタイルのリストにドラッグします。

ユーザーはいつでもタイルを移動または削除できます。

Android 13 以降では、requestAddTileService() メソッドを使用して、ユーザーがデバイスにタイルを簡単に追加できるようにできます。この方法は タイルをクイックビューに直接追加するよう、ユーザーに求めるメッセージが表示されます 設定パネル。プロンプトには、アプリケーション名、指定されたラベル、 追加できます

Quick Settings Placement API プロンプト
図 5. Quick Settings Placement API プロンプト。
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

コールバックには、タイルが追加されたかどうか、追加されなかったかどうか、すでに存在していたかどうか、エラーが発生したかどうかに関する情報が含まれます。

ユーザーにプロンプトを表示するタイミングと頻度は、状況に応じて判断してください。水 requestAddTileService() は、次のような状況でのみ呼び出すことをおすすめします。 タイルで実現されている機能をユーザーが初めて操作したとき。

システムは、特定のサービスに対するリクエストの処理を ComponentName: ユーザーが以前に十分な回数リクエストを拒否した場合。ユーザーは、このサービスの取得に使用された Context から決定されます。これは現在のユーザーと一致している必要があります。