Zezwalaj użytkownikom na konfigurowanie widżetów aplikacji

Widżety aplikacji można konfigurować. Na przykład widżet zegara może umożliwiać użytkownikom określenie, która strefa czasowa ma być wyświetlana.

Jeśli chcesz umożliwić użytkownikom konfigurowanie ustawień widżetu, utwórz konfigurację widżetu Activity. To działanie jest automatycznie uruchamiane przez host widżetu aplikacji podczas tworzenia widżetu lub później w zależności od określonych przez Ciebie opcji konfiguracji.

Deklarowanie działania związanego z konfiguracją

W pliku manifestu Androida zadeklaruj aktywność związaną z konfiguracją jako normalną aktywność. Host widżetu aplikacji uruchamia go z działaniem ACTION_APPWIDGET_CONFIGURE, dlatego działanie musi zaakceptować tę intencję. Na przykład:

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

Zadeklaruj aktywność w pliku AppWidgetProviderInfo.xml za pomocą atrybutu android:configure. Dowiedz się więcej o deklarowaniu tego pliku. Oto przykład deklaracji aktywności konfiguracji:

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

Aktywność jest zadeklarowana z pełną i jednoznaczną przestrzenią nazw, ponieważ program uruchamiający odwołuje się do niej spoza zakresu pakietu.

To wszystko, czego potrzebujesz, aby rozpocząć konfigurację. Następnie trzeba wdrożyć swoje działanie.

Wdrożenie działania związanego z konfiguracją

Implementując działanie, pamiętaj o 2 ważnych kwestiach:

  • Host widżetu aplikacji wywołuje aktywność związaną z konfiguracją, która zawsze musi zwracać wynik. Wynik musi zawierać identyfikator widżetu aplikacji przekazywany przez intencję, która uruchomiła aktywność – zapisany w plikach intencji jako EXTRA_APPWIDGET_ID.
  • System nie wysyła transmisji ACTION_APPWIDGET_UPDATE po uruchomieniu działania konfiguracji, co oznacza, że nie wywołuje metody onUpdate() podczas tworzenia widżetu. Podczas tworzenia widżetu po raz pierwszy odpowiada działanie konfiguracji, które może zażądać aktualizacji z: AppWidgetManager. Parametr onUpdate() jest jednak wywoływany przy kolejnych aktualizacjach – zostanie pominięty tylko za pierwszym razem.

W poniższej sekcji znajdziesz przykłady zwracania wyniku z konfiguracji i aktualizowania widżetu.

Zaktualizuj widżet z poziomu działania konfiguracji

Jeśli widżet używa działania konfiguracji, jego obowiązkiem jest zaktualizowanie widżetu po zakończeniu konfiguracji. Aby to zrobić, poproś o aktualizację bezpośrednio z AppWidgetManager.

Oto podsumowanie procedury prawidłowej aktualizacji widżetu i zamykania działania konfiguracyjnego:

  1. Pobierz identyfikator widżetu aplikacji z intencji, która uruchomiła aktywność:

    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. Ustaw wynik aktywności na RESULT_CANCELED.

    Dzięki temu, jeśli użytkownik wykona działanie przed zakończeniem działania, system powiadomi host widżetu aplikacji, że konfiguracja została anulowana, a host go nie doda:

    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. Skonfiguruj widżet zgodnie z preferencjami użytkownika.

  4. Po zakończeniu konfiguracji pobierz instancję AppWidgetManager, wywołując metodę getInstance(Context):

    Kotlin

    val appWidgetManager = AppWidgetManager.getInstance(context)
    

    Java

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    
  5. Zaktualizuj widżet o układ RemoteViews, wywołując updateAppWidget(int,RemoteViews):

    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. Utwórz intencję zwrotu, ustaw ją w wyniku działania i zakończ działanie:

    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();
    

Przykład znajdziesz w przykładowej klasie ListWidgetConfigureActivity.kt na GitHubie.

Opcje konfiguracji widżetu

Domyślnie host widżetu aplikacji uruchamia działanie konfiguracji tylko raz, zaraz po dodaniu widżetu do ekranu głównego przez użytkownika. Możesz jednak określić opcje, które pozwolą użytkownikom na zmianę konfiguracji istniejących widżetów lub pominięcie początkowej konfiguracji widżetów przez podanie domyślnej konfiguracji widżetu.

Zezwalaj użytkownikom na zmianę konfiguracji umieszczonych widżetów

Aby umożliwić użytkownikom zmianę konfiguracji istniejących widżetów, określ flagę reconfigurable w atrybucie widgetFeatures elementu appwidget-provider. Więcej informacji znajdziesz w przewodniku deklarowania pliku AppWidgetProviderInfo.xml. Na przykład:

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

Użytkownicy mogą ponownie skonfigurować swój widżet, dotykając go i przytrzymując, a następnie klikając przycisk Ponownie skonfiguruj, który jest oznaczony etykietą 1 na ilustracji 1.

Przycisk jest widoczny w prawym dolnym rogu
Rysunek 1. Przycisk Ponownie skonfiguruj widżetu.

Użyj domyślnej konfiguracji widżetu

Aby usprawnić korzystanie z widżetów, możesz zezwolić użytkownikom na pomijanie etapu konfiguracji początkowej. Aby to zrobić, w polu widgetFeatures podaj zarówno flagi configuration_optional, jak i reconfigurable. Pomija to uruchamianie działania konfiguracji po dodaniu widżetu przez użytkownika. Jak już wspomnieliśmy, użytkownik może później ponownie skonfigurować widżet. Na przykład widżet zegara może pomijać wstępną konfigurację i domyślnie wyświetlać strefę czasową urządzenia.

Oto przykład, jak oznaczyć aktywność związaną z konfiguracją jako zarówno możliwą do ponownego skonfigurowania, jak i opcjonalnego:

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

Umożliwianie użytkownikom przypinania widżetów

Na urządzeniach z Androidem 8.0 (poziom interfejsu API 26) lub nowszym menu z aplikacjami, które umożliwiają użytkownikom tworzenie przypiętych skrótów, pozwalają też przypinać widżety do ekranu głównego. Podobnie jak przypięte skróty, przypięte widżety zapewniają użytkownikom dostęp do określonych zadań w aplikacji i można je dodawać do ekranu głównego bezpośrednio z aplikacji, jak pokazano na poniższym filmie.

Przykład układu elastycznego
Rysunek 2. Przykład przypinania widżetu.

W aplikacji możesz wysłać do systemu żądanie przypięcia widżetu do obsługiwanego programu uruchamiającego, wykonując te czynności:

  1. Pamiętaj, aby zadeklarować widżet w pliku manifestu aplikacji.

  2. Wywołaj metodę requestPinAppWidget(), jak pokazano w tym fragmencie kodu:

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);
}