ウィジェット ホストを作成する

ほとんどの Android 搭載デバイスで利用できる Android のホーム画面では、ユーザーが アプリ ウィジェット(またはウィジェット)を埋め込んでコンテンツに すばやくアクセスできるようにすることができます。ホーム画面に代わるアプリやこれに類するアプリを開発する場合も、 を実装することで、ユーザーはウィジェットを埋め込むことができるようになります。AppWidgetHostほとんどのアプリでホストが必要になることはありませんが、独自のホストを作成する場合は、ホストが暗黙的に同意することになる契約上の義務を理解することが重要です。

このページでは、カスタムの AppWidgetHostを実装することに伴う責任に重点を置いて説明します。AppWidgetHostの実装方法を示す具体的な例としては、Android ホーム画面の LauncherAppWidgetHostのソースコードをご覧ください。

カスタムの AppWidgetHost の実装に関連する主なクラスと概念の概要は以下のとおりです。

  • アプリ ウィジェット ホ/1}スト: AppWidgetHost は、UI にウィジェットを埋め込むアプリのために、 AppWidget サービスとのインタラクションを提供します。各 AppWidgetHost は、ホスト自身のパッケージ内で一意の ID を持つ必要があります。この ID は、ホストのすべてのユーザー間で保持されます。ID は通常、アプリ内で 割り当てるハードコードされた値です。

  • アプリ ウィジェット ID: 各ウィジェット インスタンスに、バインド時 に一意の ID が割り当てられます。 bindAppWidgetIdIfAllowed() を参照してください。詳しくは、後述のウィジェットをバインドするをご覧ください。ホストは allocateAppWidgetId()を使用して一意の ID を取得します。 この ID はウィジェットの存続期間中、つまり ホストから削除されるまで保持されます。ホスト固有の状態(ウィジェットのサイズや場所など)は、ホスティング パッケージによって維持され、アプリ ウィジェット ID に関連付けられる必要があります。

  • アプリ ウィジェット ホスト ビュー: AppWidgetHostView は、表示する必要のあるときにウィジェットをラップするフレームと考えることができます。ウィジェットが ホストによってインフレートされるたびにウィジェットが AppWidgetHostView に関連付けられます。

    • デフォルトでは、システムによって AppWidgetHostView が作成されますが、ホストは AppWidgetHostView を拡張して独自のサブクラスを作成できます。
    • Android 12(API レベル 31)以降では、AppWidgetHostView に、動的にオーバーロードされた色を処理するための setColorResources()resetColorResources() メソッドが導入されています。これらのメソッドに色を提供するのはホストの 責任です。
  • オプション バンドル: AppWidgetHost は、オプション バンドルを使用して AppWidgetProviderに、ウィジェットの表示形態(たとえば、 サイズ範囲のリスト、ロック画面またはホーム画面に表示するかどうかなど)に関する情報を 伝達します。この情報によって AppWidgetProvider は、表示の形態や 場所に応じてウィジェットのコンテンツや外観をカスタマイズできるようになります。ウィジェットのバンドルを変更するには updateAppWidgetOptions()updateAppWidgetSize() を使用します。どちらのメソッドも、 onAppWidgetOptionsChanged() コールバックを AppWidgetProvider に起動します。

ウィジェットをバインドする

ユーザーがウィジェットをホストに追加すると、「バインディング」と呼ばれるプロセスが発生します。バインド とは、特定のアプリ ウィジェット ID を特定のホストと 特定の AppWidgetProvider に関連付けることです。

バインド API により、ホストがバインディングのためのカスタム UI を提供することもできます。 このプロセスを使用するには、アプリのマニフェストで BIND_APPWIDGET 権限を宣言する必要があります。

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

ただしこれで終わりではありません。ランタイムにユーザーがアプリに対してウィジェットを追加する権限を明示的に許可する必要があります。アプリにウィジェットを追加する権限があるかどうかを確認するには、 bindAppWidgetIdIfAllowed() メソッドを使用します。bindAppWidgetIdIfAllowed()false が返される場合、アプリでユーザーに権限を許可することを求めるダイアログを表示する必要があります(現在のウィジェット追加に適用する場合は「許可」、今後のウィジェット追加すべてに適用する場合は「常に許可」)。

以下のスニペットは、このダイアログの表示方法に関する例です。

Kotlin

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)
    // This is the options bundle described in the preceding section.
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)
}
startActivityForResult(intent, REQUEST_BIND_APPWIDGET)

Java

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle described in the preceding section.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);

ホストは、ユーザーが追加するウィジェットに設定が必要かどうかを確認する必要があります。詳しくは、ユーザーがアプリ ウィジェットを設定できるようにするをご覧ください。

ホストの責任

AppWidgetProviderInfo メタデータを使用して、ウィジェットのさまざまな設定項目を指定できます。 こうした設定項目について詳しくは以下で説明しますが、ホストはこれを ウィジェットプロバイダに関連付けられた AppWidgetProviderInfo オブジェクトから取得できます。

対象とする Android のバージョンに関係なく、すべてのホストに以下の 責任があります。

  • ウィジェットを追加する際に、前述のようにウィジェット ID を割り当てます。ウィジェットがホストから削除されたときには、 deleteAppWidgetId() を呼び出してウィジェット ID の割り当てを解除します。

  • ウィジェットを追加する際に、設定アクティビティを起動する必要があるかどうかを 確認します。通常、ホストは、ウィジェットの設定 アクティビティが存在し、 configuration_optional フラグと reconfigurable フラグの両方を指定してオプションとしてマークされていない場合は、そのアクティビティを起動する必要があります。詳しくは、 設定アクティビティからウィジェットを更新する をご覧ください。これは、多くのウィジェットで表示のために必要なステップです。

  • ウィジェットは、デフォルトの幅と高さを AppWidgetProviderInfo メタデータで指定します。これらの値はセル単位で定義されます。 Android 12 以降では、targetCellWidthtargetCellHeight が 指定されている場合はセル単位、minWidthminHeight のみが指定されている場合は dp 単位で定義されます。ウィジェットのサイズ設定属性をご覧ください。

    ウィジェットが少なくともこの dp 数でレイアウトされていることを確認してください。たとえば、多くのホストでは、アイコンやウィジェットをグリッド形式で配置します。この場合、デフォルトではホストは `minWidth` と `minHeight` の制約を満たす最小の数のセルを使用してウィジェットを追加します。minWidthminHeight

前述のセクションの要件に加えて、特定の プラットフォーム バージョンでホストに新しい責任を課す機能が導入されています。

ターゲットとする Android のバージョンに基づいてアプローチを決定する

Android 12

Android 12(API レベル 31)では、ウィジェット インスタンスがオプション バンドルで取得できる可能性のあるサイズのリスト(dp 単位)を含む追加の List<SizeF> がバンドルされています。 提供されるサイズ数はホストの実装によって異なります。通常、ホストはスマートフォン用に 2 つのサイズ(縦向きと横向き)、折りたたみ式デバイス用に 4 つのサイズ を提供します。

AppWidgetProviderRemoteViews に提供できる異なる RemoteViews の数には MAX_INIT_VIEW_COUNT(16)の上限があります。 AppWidgetProvider オブジェクトは RemoteViews オブジェクトを List<SizeF> の各サイズにマッピングするため、MAX_INIT_VIEW_COUNT を超えるサイズは指定しないでください。

Android 12 では、 maxResizeWidth 属性と maxResizeHeight 属性(dp 単位)も導入されています。これらの属性の少なくとも 1 つを使用するウィジェットは、属性で指定されたサイズを超えないようにすることをおすすめします。

参考情報

  • Glance のリファレンス ドキュメントをご覧ください。