Nutzern erlauben, App-Widgets zu konfigurieren

App-Widgets können konfiguriert werden. Mit einem Uhren-Widget können Nutzer beispielsweise konfigurieren, welche Zeitzone angezeigt werden soll.

Wenn Sie zulassen möchten, dass Nutzer die Einstellungen Ihres Widgets konfigurieren können, erstellen Sie eine Widget-Konfiguration Activity. Diese Aktivität wird automatisch vom App-Widget-Host gestartet, je nachdem, welche Konfigurationsoptionen Sie angeben, entweder bei der Erstellung des Widgets oder später.

Konfigurationsaktivität deklarieren

Deklarieren Sie die Konfigurationsaktivität in der Android-Manifestdatei als normale Aktivität. Der Host des App-Widgets startet es mit der Aktion ACTION_APPWIDGET_CONFIGURE, sodass die Aktivität diesen Intent akzeptieren muss. Beispiele:

<activity android:name=".ExampleAppWidgetConfigurationActivity">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
    </intent-filter>
</activity>

Deklarieren Sie die Aktivität in der Datei AppWidgetProviderInfo.xml mit dem Attribut android:configure. Weitere Informationen finden Sie unter Deklaration dieser Datei. Hier ein Beispiel für die Deklaration der Konfigurationsaktivität:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    ... >
</appwidget-provider>

Die Aktivität wird mit einem voll qualifizierten Namespace deklariert, da der Launcher von außerhalb des Paketbereichs darauf verweist.

Das ist alles, was Sie zum Starten einer Konfigurationsaktivität benötigen. Als Nächstes müssen Sie die eigentliche Aktivität implementieren.

Konfigurationsaktivität implementieren

Es gibt zwei wichtige Punkte, die Sie beim Implementieren der Aktivität beachten sollten:

  • Der Host des App-Widgets ruft die Konfigurationsaktivität auf und die Konfigurationsaktivität muss immer ein Ergebnis zurückgeben. Das Ergebnis muss die App-Widget-ID enthalten, die vom Intent übergeben wurde, der die Aktivität gestartet hat, und wird in den Intent-Extras als EXTRA_APPWIDGET_ID gespeichert.
  • Das System sendet die ACTION_APPWIDGET_UPDATE-Broadcast nicht, wenn eine Konfigurationsaktivität gestartet wird. Die Methode onUpdate() wird also nicht aufgerufen, wenn das Widget erstellt wird. Es liegt in der Verantwortung der Konfigurationsaktivität, beim ersten Erstellen des Widgets ein Update von AppWidgetManager anzufordern. onUpdate() wird jedoch nur für nachfolgende Aktualisierungen aufgerufen – nur beim ersten Mal.

In den Code-Snippets im folgenden Abschnitt sehen Sie ein Beispiel dafür, wie Sie ein Ergebnis aus der Konfiguration zurückgeben und das Widget aktualisieren können.

Widget über die Konfigurationsaktivität aktualisieren

Wenn ein Widget eine Konfigurationsaktivität verwendet, liegt es in der Verantwortung der Aktivität, das Widget nach Abschluss der Konfiguration zu aktualisieren. Fordern Sie dazu ein Update direkt in der AppWidgetManager an.

Im Folgenden finden Sie eine Zusammenfassung der Schritte, mit denen Sie das Widget ordnungsgemäß aktualisieren und die Konfigurationsaktivität schließen:

  1. Rufen Sie die ID des App-Widgets vom Intent ab, der die Aktivität gestartet hat:

    Kotlin

    val appWidgetId = intent?.extras?.getInt(
            AppWidgetManager.EXTRA_APPWIDGET_ID,
            AppWidgetManager.INVALID_APPWIDGET_ID
    ) ?: AppWidgetManager.INVALID_APPWIDGET_ID
    

    Java

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    if (extras != null) {
        appWidgetId = extras.getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
    }
    
  2. Lege als Aktivitätsergebnis RESULT_CANCELED fest.

    Wenn der Nutzer die Aktivität beendet, bevor das Ende erreicht ist, benachrichtigt das System den App-Widget-Host, dass die Konfiguration abgebrochen wurde und der Host das Widget nicht hinzufügt:

    Kotlin

    val resultValue = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    setResult(Activity.RESULT_CANCELED, resultValue)
    

    Java

    int resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    setResult(Activity.RESULT_CANCELED, resultValue);
    
  3. Konfigurieren Sie das Widget entsprechend den Nutzereinstellungen.

  4. Wenn die Konfiguration abgeschlossen ist, rufen Sie getInstance(Context) auf, um eine Instanz von AppWidgetManager abzurufen:

    Kotlin

    val appWidgetManager = AppWidgetManager.getInstance(context)
    

    Java

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    
  5. Aktualisieren Sie das Widget mit einem RemoteViews-Layout. Rufen Sie dazu updateAppWidget(int,RemoteViews) auf:

    Kotlin

    val views = RemoteViews(context.packageName, R.layout.example_appwidget)
    appWidgetManager.updateAppWidget(appWidgetId, views)
    

    Java

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
    appWidgetManager.updateAppWidget(appWidgetId, views);
    
  6. Erstellen Sie den Rückgabe-Intent, legen Sie ihn mit dem Aktivitätsergebnis fest und beenden Sie die Aktivität:

    Kotlin

    val resultValue = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    setResult(Activity.RESULT_OK, resultValue)
    finish()
    

    Java

    Intent resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    setResult(RESULT_OK, resultValue);
    finish();
    

Ein Beispiel hierfür ist die Beispielklasse ListWidgetConfigureActivity.kt auf GitHub (in englischer Sprache).

Konfigurationsoptionen für Widgets

Standardmäßig startet der App-Widget-Host die Konfigurationsaktivität nur einmal, unmittelbar nachdem der Nutzer das Widget seinem Startbildschirm hinzugefügt hat. Sie können jedoch Optionen angeben, mit denen sich Nutzer vorhandene Widgets neu konfigurieren oder die anfängliche Widget-Konfiguration überspringen können, indem Sie eine Standard-Widget-Konfiguration angeben.

Nutzern erlauben, platzierte Widgets neu zu konfigurieren

Damit Nutzer vorhandene Widgets neu konfigurieren können, geben Sie das Flag reconfigurable im Attribut widgetFeatures von appwidget-provider an. Weitere Informationen finden Sie im Leitfaden zum Erklären der Datei AppWidgetProviderInfo.xml. Beispiele:

<appwidget-provider
    android:configure="com.myapp.ExampleAppWidgetConfigurationActivity"
    android:widgetFeatures="reconfigurable">
</appwidget-provider>

Nutzer können ihr Widget neu konfigurieren, indem sie es gedrückt halten und auf die Schaltfläche Neu konfigurieren tippen, die in Abbildung 1 mit 1 beschriftet ist.

Schaltfläche wird unten rechts angezeigt
Abbildung 1. Widget-Schaltfläche Neu konfigurieren.

Standardkonfiguration des Widgets verwenden

Du kannst die Widget-Nutzung noch reibungsloser gestalten, indem du Nutzern erlaubst, den ersten Konfigurationsschritt zu überspringen. Geben Sie dazu sowohl das Flag configuration_optional als auch das Flag reconfigurable im Feld widgetFeatures an. Dadurch muss die Konfigurationsaktivität nicht gestartet werden, nachdem ein Nutzer das Widget hinzugefügt hat. Wie bereits erwähnt, kann der Nutzer das Widget danach immer noch neu konfigurieren. Ein Uhren-Widget kann beispielsweise die Anfangskonfiguration umgehen und standardmäßig die Zeitzone des Geräts anzeigen.

Hier ist ein Beispiel dafür, wie Sie Ihre Konfigurationsaktivität als rekonfigurierbar und optional markieren können:

<appwidget-provider
    android:configure="com.myapp.ExampleAppWidgetConfigurationActivity"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

Nutzer können Widgets anpinnen

Auf Geräten mit Android 8.0 (API-Level 26) und höher können Nutzer über Launcher, mit denen Nutzer angeheftete Verknüpfungen erstellen können, auch Widgets an ihren Startbildschirm anpinnen können. Ähnlich wie angepinnte Verknüpfungen bieten diese angepinnten Widgets Nutzern Zugriff auf bestimmte Aufgaben in Ihrer App. Sie können dem Startbildschirm direkt aus der App hinzugefügt werden, wie im folgenden Video gezeigt.

Beispiel für ein responsives Layout
Abbildung 2. Beispiel für das Anpinnen eines Widgets

So kannst du in deiner App eine Anfrage an das System zum Anheften eines Widgets an einen unterstützten Launcher erstellen:

  1. Sie müssen in der Manifestdatei Ihrer App ein Widget deklarieren.

  2. Rufen Sie die Methode requestPinAppWidget() auf, wie im folgenden Code-Snippet gezeigt:

Kotlin

val appWidgetManager = AppWidgetManager.getInstance(context)
val myProvider = ComponentName(context, ExampleAppWidgetProvider::class.java)

if (appWidgetManager.isRequestPinAppWidgetSupported()) {
    // Create the PendingIntent object only if your app needs to be notified
    // when the user chooses to pin the widget. Note that if the pinning
    // operation fails, your app isn't notified. This callback receives the ID
    // of the newly pinned widget (EXTRA_APPWIDGET_ID).
    val successCallback = PendingIntent.getBroadcast(
            /* context = */ context,
            /* requestCode = */ 0,
            /* intent = */ Intent(...),
            /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT)

    appWidgetManager.requestPinAppWidget(myProvider, null, successCallback)
}

Java

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName myProvider = new ComponentName(context, ExampleAppWidgetProvider.class);

if (appWidgetManager.isRequestPinAppWidgetSupported()) {
    // Create the PendingIntent object only if your app needs to be notified
    // when the user chooses to pin the widget. Note that if the pinning
    // operation fails, your app isn't notified. This callback receives the ID
    // of the newly pinned widget (EXTRA_APPWIDGET_ID).
    PendingIntent successCallback = PendingIntent.getBroadcast(
            /* context = */ context,
            /* requestCode = */ 0,
            /* intent = */ new Intent(...),
            /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT);

    appWidgetManager.requestPinAppWidget(myProvider, null, successCallback);
}