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

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

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

カスタム AppWidgetHost の実装に関連する主なクラスとコンセプトの概要は次のとおりです。

  • アプリ ウィジェット ホスト: 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() を使用して、ウィジェットのバンドルを変更できます。どちらのメソッドも、AppWidgetProvider への onAppWidgetOptionsChanged() コールバックをトリガーします。

ウィジェットのバインド

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

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

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

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

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

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

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

ホストの責任

ウィジェットの構成設定は、AppWidgetProviderInfo メタデータを使用して指定できます。これらの構成オプション(詳しくは、以降のセクションで説明します)は、ウィジェット プロバイダに関連付けられた AppWidgetProviderInfo オブジェクトから取得できます。

すべてのホストには次の責任があります。

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

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

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

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

アプローチに関するヒント

前のセクションに記載されている要件に加えて、次のヒントに留意してください。

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

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

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

参考情報

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