Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 89 di 97
  • livello avanzato
Indice lezioni

App Widget

Cosa sono e come si implementano gli App Widget, componenti visuali che possono essere utilizzati direttamente sulla home screen di Android.
Cosa sono e come si implementano gli App Widget, componenti visuali che possono essere utilizzati direttamente sulla home screen di Android.
Link copiato negli appunti

A volte, sulla home di un dispositivo Android (la schermata che appare quando non sono aperte app), notiamo piccoli riquadri che forniscono informazioni o contengono comandi che attivano funzionalità: gli App Widget. In questa lezione impareremo a crearli e integrarli in un progetto Android Studio.

Figura 1. App Widgets in Android (click per ingrandire)

App Widgets in Android

Uso degli App Widget

Per chi non fosse avvezzo a questi componenti (da un punto di vista dell'utente), ricordiamo come integrarli nella home. Esercitando una pressione prolungata sullo sfondo, appare un menu con cui si accede alla schermata di gestione dei Widget.

Figura 2. Accesso alla gestione degli App Widget (click per ingrandire)

Accesso alla gestione degli App Widget

Da qui si può scegliere il widget da inserire nella Home del dispositivo.

Figura 3. Scelta di un App Widget (click per ingrandire)

Scelta di un App Widget

La loro creazione in un progetto Android Studio richiede un certo numero di passi, che andiamo ad illustrare nel paragrafo seguente.

Progettare Widget

L'esempio che mostriamo crea un Widget dotato di due pulsanti che lanciano Intent in grado di attivare la fotocamera in modalità video o fotografica.

Figura 4. L'esempio (click per ingrandire)

L'esempio

Il primo passo consiste nel realizzare un layout. Ne creeremo uno con elementi tipici delle Activity, tenendo però presente che verrà trattato come una RemoteViews - classe che offre la visualizzazione di elementi grafici in altri processi - pertanto potremo far uso solo delle seguenti View (e non loro sottoclassi):

    • FrameLayout, LinearLayout, RelativeLayout e GridLayout come layout;
    • tra gli altri controlli, Button e ImageButton, ImageView e TextView, ListView e GridView nonchè AnalogClock, Chronometer, ProgressBar, ViewFlipper, StackView, AdapterViewFlipper.

Questo il layout del nostro esempio (file res/layout/camera_widget.xml):

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:background="#ff8533"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Scatta video o foto da qui"
android:textStyle="bold"
android:padding="8dp"
android:textSize="18sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageButton
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="-"
android:background="#44ff8533"
android:padding="8dp"
android:src="@drawable/ic_movie_creation_black_24dp"
android:id="@+id/btn_video"/>
<ImageButton
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:background="#44ff8533"
android:src="@drawable/ic_add_a_photo_black_24dp"
android:id="@+id/btn_photo"
android:padding="8dp"/>
</LinearLayout>
</LinearLayout>

Successivamente, dobbiamo creare una classe Java che estende AppWidgetProvider, consistente in una sorta di BroadcastReceiver evoluto, che dovremo pertanto registrare nel file ApplicationManifest.xml - all'interno del blocco <application> - in questa maniera:

<receiver android:name=".CameraWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/camera_widget_info" />
</receiver>

dove l'attributo name specifica la classe di implementazione dell'App Widget, il blocco intent-filter sancisce l'evento che lo "sveglierà" in quanto estensione di un BroadcastReceiver, mentre l'altro blocco interno di tipo meta-data specifica il file di configurazione che troveremo tra le risorse di tipo XML.

Il file di configurazione camera_widget_info del nostro esempio è il seguente:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/camera_widget"
android:initialLayout="@layout/camera_widget"
android:minHeight="40dp"
android:minWidth="180dp"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="1800000"
android:previewImage="@drawable/screenshot"
android:widgetCategory="home_screen"/>

In esso, troviamo specificate dimensioni minime, direzioni di espansione manuale del widget nonchè l'immagine di anteprima che apparirà nel gestore degli App Widget. È presente anche l'attributo updatePeriodMillis, che indica ogni quanti millisecondi il widget deve essere aggiornato: la documentazione ufficiale comunque specifica che tale aggiornamento non sarà permesso più di una volta ogni mezz'ora.

Quello che segue è il codice della classe CameraWidget:

public class CameraWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// (1) carica layout nella RemoteViews
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.camera_widget);
// (2.1) gestione click su pulsante che attiva video
Intent videoIntent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0,
videoIntent, 0);
views.setOnClickPendingIntent (R.id.btn_video, pendingIntent);
// (2.2) gestione click su pulsante che attiva foto
Intent photoIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
PendingIntent pendingIntentContact = PendingIntent.getActivity (context, 0,
photoIntent, 0);
views.setOnClickPendingIntent (R.id.btn_photo, pendingIntentContact);
// (3) AppWidgetManager assegna la RemoteViews all'App Widget con id appWidgetId
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}

Il metodo onUpdate viene invocato in risposta ai broadcast ACTION_APPWIDGET_UPDATE e ACTION_APPWIDGET_RESTORED ed è finalizzato all'aggiornamento della View. Si noti che in input riceve, tra l'altro, un riferimento al Context ed un array di interi contenente gli identificativi degli App Widget di tale classe che devono ricevere l'aggiornamento. Al suo interno, non faremo altro che eseguire un ciclo su tutti gli id segnalati e, per ognuno di essi, invocheremo il metodo updateAppWidget.

In updateAppWidget, aggiorneremo fisicamente il layout procedendo in questo modo:

  • caricheremo il layout in una RemoteViews;
  • gestiremo gli eventi legati ai pulsanti utilizzando dei PendingIntent che conterranno Intent e descrizione dell'evento che dovrà essere attivato alla loro pressione;
  • tramite l'AppWidgetManager specificheremo che la RemoteViews così definita e configurata appartiene al widget che possiede uno specifico id.

Conclusioni

In questo esempio, abbiamo visto un semplice App Widget che permette di accedere ad applicazioni di sistema, quindi svincolate dal progetto Android in cui è stato definito. Ciò può essere molto utile ma si possono avere vantaggi ancora maggiori offrendoli come accesso rapido ai contenuti della nostra app: approfondimenti in materia possono essere ottenuti dalla documentazione ufficiale.

Ti consigliamo anche