I widget delle app sono visualizzazioni in miniatura delle app che puoi incorporare in altre app, ad esempio nella schermata Home, e ricevere aggiornamenti periodici. Nell'interfaccia utente, queste visualizzazioni sono chiamate widget e puoi pubblicarne una con un fornitore di widget per app (o fornitore di widget). Un componente dell'app che contiene altri widget è chiamato host del widget dell'app (o host widget). La Figura 1 mostra un widget musicale di esempio:
Questo documento descrive come pubblicare un widget utilizzando un fornitore di widget. Per maggiori dettagli sulla creazione di AppWidgetHost
per ospitare i widget dell'app, vedi Creare un host del widget.
Per informazioni su come progettare il widget, consulta Panoramica dei widget app.
Componenti widget
Per creare un widget, sono necessari i seguenti componenti di base:
- Oggetto
AppWidgetProviderInfo
- Descrive i metadati per un widget, ad esempio il layout, la frequenza degli aggiornamenti e la classe
AppWidgetProvider
.AppWidgetProviderInfo
è definito in XML, come descritto in questo documento. - Corso
AppWidgetProvider
- Definisce i metodi di base che ti consentono di interfacciarti in modo programmatico con il widget. Grazie a questo strumento, ricevi gli annunci quando il widget viene aggiornato,
attivato, disattivato o eliminato. Devi dichiarare
AppWidgetProvider
nel file manifest e poi implementarlo, come descritto in questo documento. - Visualizza layout
- definisce il layout iniziale per il widget. Il layout è definito in XML, come descritto in questo documento.
La Figura 2 mostra come questi componenti si inseriscono nel flusso di elaborazione complessivo del widget dell'app.
Se il widget richiede la configurazione utente, implementa l'attività di configurazione del widget dell'app. Questa attività consente agli utenti di modificare le impostazioni del widget, ad esempio il fuso orario di un widget dell'orologio.
- A partire da Android 12 (livello API 31), puoi fornire una configurazione predefinita e consentire agli utenti di riconfigurare il widget in un secondo momento. Per ulteriori informazioni, vedi Utilizzare la configurazione predefinita del widget e Consentire agli utenti di riconfigurare i widget posizionati.
- In Android 11 (livello API 30) o versioni precedenti, questa attività viene avviata ogni volta che l'utente aggiunge il widget alla schermata Home.
Consigliamo inoltre i seguenti miglioramenti: layout flessibili dei widget, miglioramenti vari, widget avanzati, widget di raccolta e creazione di un host per i widget.
Dichiara il file XML AppWidgetProviderInfo
L'oggetto AppWidgetProviderInfo
definisce le qualità essenziali di un widget.
Definisci l'oggetto AppWidgetProviderInfo
in un file di risorse XML utilizzando un singolo
elemento <appwidget-provider>
e salvalo nella cartella res/xml/
del progetto.
Ciò è mostrato nell'esempio seguente:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:targetCellWidth="1"
android:targetCellHeight="1"
android:maxResizeWidth="250dp"
android:maxResizeHeight="120dp"
android:updatePeriodMillis="86400000"
android:description="@string/example_appwidget_description"
android:previewLayout="@layout/example_appwidget_preview"
android:initialLayout="@layout/example_loading_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>
Attributi di dimensionamento dei widget
La schermata Home predefinita posiziona i widget all'interno della finestra in base a una griglia di celle con altezza e larghezza definite. La maggior parte delle schermate Home consente ai widget solo di assumere dimensioni che sono multipli interi delle celle della griglia, ad esempio due celle orizzontalmente e tre celle in verticale.
Gli attributi di dimensionamento del widget consentono di specificare una dimensione predefinita per il widget e fornire limiti inferiore e superiore alle dimensioni del widget. In questo contesto, la dimensione predefinita di un widget è quella assunta da quest'ultimo quando viene aggiunto per la prima volta alla schermata Home.
La seguente tabella descrive gli attributi <appwidget-provider>
relativi alle dimensioni del widget:
Attributi e descrizione | |
---|---|
targetCellWidth e
targetCellHeight (Android 12),
minWidth e minHeight |
targetCellWidth e
targetCellHeight e minWidth e
minHeight ) in modo che la tua app possa utilizzare
minWidth e minHeight se il dispositivo dell'utente
non supporta targetCellWidth e
targetCellHeight . Se supportati, gli attributi targetCellWidth e targetCellHeight hanno la precedenza sugli attributi minWidth e minHeight .
|
minResizeWidth e
minResizeHeight |
Specifica la dimensione minima assoluta del widget. Questi valori specificano le dimensioni al di sotto delle quali il widget è illeggibile o comunque inutilizzabile. L'utilizzo di questi attributi consente all'utente di ridimensionare il widget a una dimensione inferiore a quella predefinita. L'attributo minResizeWidth viene ignorato se è maggiore di minWidth o se il ridimensionamento orizzontale non è abilitato. Vedi
resizeMode . Allo stesso modo, l'attributo minResizeHeight viene ignorato se è maggiore di minHeight o se il ridimensionamento verticale non è abilitato. |
maxResizeWidth e
maxResizeHeight |
Specifica la dimensione massima consigliata del widget. Se i valori non sono un multiplo delle dimensioni delle celle della griglia, vengono arrotondati alla dimensione della cella più vicina. L'attributo maxResizeWidth viene ignorato se è inferiore a minWidth o se il ridimensionamento orizzontale non è abilitato. Vedi resizeMode . Allo stesso modo, l'attributo maxResizeHeight viene ignorato se è maggiore di minHeight o se il ridimensionamento verticale non è abilitato.
Introdotta in Android 12. |
resizeMode |
Specifica le regole in base alle quali un widget può essere ridimensionato. Puoi utilizzare questo attributo per rendere i widget della schermata Home ridimensionabili orizzontalmente, verticalmente o su entrambi gli assi. Gli utenti toccano e tieni premuto un widget per visualizzarne i punti di manipolazione di ridimensionamento, quindi trascinano i punti di manipolazione orizzontali o verticali per modificarne le dimensioni nella griglia di layout. I valori dell'attributo resizeMode includono
horizontal , vertical e none . Per dichiarare un widget ridimensionabile orizzontalmente e verticalmente, utilizza horizontal|vertical . |
Esempio
Per illustrare come gli attributi nella tabella precedente influiscono sulle dimensioni del widget, supponiamo che:
- Una cella della griglia ha una larghezza di 30 dp e un'altezza di 50 dp.
- Vengono fornite le seguenti specifiche degli attributi:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="80dp"
android:minHeight="80dp"
android:targetCellWidth="2"
android:targetCellHeight="2"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:maxResizeWidth="120dp"
android:maxResizeHeight="120dp"
android:resizeMode="horizontal|vertical" />
A partire da Android 12:
Utilizza gli attributi targetCellWidth
e targetCellHeight
come dimensioni
predefinite del widget.
Per impostazione predefinita, le dimensioni del widget sono 2 x 2. Il widget può essere ridimensionato fino a 2 x 1 o fino a 4 x 3.
Android 11 e versioni precedenti:
Utilizza gli attributi minWidth
e minHeight
per calcolare la dimensione predefinita del widget.
Larghezza predefinita = Math.ceil(80 / 30)
= 3
Altezza predefinita = Math.ceil(80 / 50)
= 2
Le dimensioni del widget sono 3 x 2 per impostazione predefinita. Il widget può essere ridimensionato a 2 x 1 o a schermo intero.
Attributi aggiuntivi del widget
La seguente tabella descrive gli attributi <appwidget-provider>
relativi a qualità diverse dal dimensionamento del widget.
Attributi e descrizione | |
---|---|
updatePeriodMillis |
Definisce la frequenza con cui il framework del widget richiede un aggiornamento da AppWidgetProvider chiamando il metodo di callback onUpdate() . Non è garantito che l'aggiornamento effettivo venga eseguito esattamente in tempo con questo valore e ti consigliamo di eseguire l'aggiornamento il più raramente possibile (non più di una volta all'ora) per risparmiare batteria.
Per l'elenco completo delle considerazioni sulla scelta di un periodo di aggiornamento appropriato,
consulta
Ottimizzazioni per l'aggiornamento dei contenuti del widget. |
initialLayout |
Punta alla risorsa di layout che definisce il layout del widget. |
configure |
Definisce l'attività che viene avviata quando l'utente aggiunge il widget, consentendo di configurare le proprietà del widget. Vedi Consentire agli utenti di configurare i widget. A partire da Android 12, la tua app può saltare la configurazione iniziale. Per maggiori dettagli, vedi Utilizzare la configurazione predefinita del widget. |
description |
Specifica la descrizione del selettore widget da visualizzare per il widget. Introdotta in Android 12. |
previewLayout (Android 12)
e previewImage (Android 11 e versioni precedenti) |
previewImage
e previewLayout in modo che la tua app possa tornare
all'utilizzo di previewImage se il dispositivo dell'utente non supporta
previewLayout . Per maggiori dettagli, consulta
Compatibilità con le versioni precedenti con le anteprime
scalabili dei widget.
|
autoAdvanceViewId |
Specifica l'ID vista della vista secondaria del widget avanzata automaticamente dall'host del widget. |
widgetCategory |
Dichiara se il widget può essere visualizzato nella schermata Home
(home_screen ), nella schermata di blocco (keyguard ) o
in entrambe. Per Android 5.0 e versioni successive, è valido soltanto home_screen .
|
widgetFeatures |
Dichiara le funzionalità supportate dal widget. Ad esempio, se vuoi che il widget utilizzi la sua configurazione predefinita quando un utente lo aggiunge, specifica entrambi i flag configuration_optional e reconfigurable . In questo modo viene bypassato l'avvio dell'attività di configurazione dopo che un utente
ha aggiunto il widget. L'utente può comunque riconfigurare il widget in seguito. |
Utilizzo della classe AppWidgetProvider per gestire le trasmissioni del widget
La classe AppWidgetProvider
gestisce gli annunci del widget e lo aggiorna in risposta agli eventi del ciclo di vita del widget. Le seguenti sezioni descrivono come
dichiarare AppWidgetProvider
nel file manifest e quindi implementarlo.
Dichiara un widget nel manifest
Innanzitutto, dichiara la classe AppWidgetProvider
nel file AndroidManifest.xml
dell'app, come mostrato nell'esempio seguente:
<receiver android:name="ExampleAppWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
L'elemento <receiver>
richiede l'attributo android:name
, che specifica
il AppWidgetProvider
utilizzato dal widget. Il componente non deve essere esportato
a meno che non sia necessario trasmettere un processo separato al tuo AppWidgetProvider
, cosa che in genere non è così.
L'elemento <intent-filter>
deve includere un elemento <action>
con
l'attributo android:name
. Questo attributo specifica che AppWidgetProvider
accetta la trasmissione di ACTION_APPWIDGET_UPDATE
. Questa è l'unica trasmissione che devi dichiarare esplicitamente. AppWidgetManager
invia automaticamente tutte le altre trasmissioni del widget a AppWidgetProvider
, se necessario.
L'elemento <meta-data>
specifica la risorsa AppWidgetProviderInfo
e
richiede i seguenti attributi:
android:name
: specifica il nome dei metadati. Utilizzaandroid.appwidget.provider
per identificare i dati come descrittoreAppWidgetProviderInfo
.android:resource
: specifica la località della risorsaAppWidgetProviderInfo
.
Implementare la classe AppWidgetProvider
La classe AppWidgetProvider
estende
BroadcastReceiver
come
classe pratica per gestire le trasmissioni tramite widget. Riceve solo le trasmissioni
degli eventi pertinenti per il widget, ad esempio quando il widget viene aggiornato,
eliminato, attivato e disattivato. Quando si verificano questi eventi di trasmissione, vengono chiamati i seguenti
metodi AppWidgetProvider
:
onUpdate()
- Questo viene chiamato per aggiornare il widget a intervalli definiti
dall'attributo
updatePeriodMillis
inAppWidgetProviderInfo
. Per ulteriori informazioni, consulta la tabella che descrive gli attributi aggiuntivi del widget in questa pagina. - Questo metodo è chiamato anche quando l'utente aggiunge il widget, quindi esegue la configurazione essenziale, come la definizione dei gestori di eventi per gli oggetti
View
o l'avvio dei job per caricare i dati da visualizzare nel widget. Tuttavia, se dichiari un'attività di configurazione senza il flagconfiguration_optional
, questo metodo non viene chiamato quando l'utente aggiunge il widget, ma viene richiesto per gli aggiornamenti successivi. È responsabilità dell'attività di configurazione eseguire il primo aggiornamento una volta completata la configurazione. Per ulteriori informazioni, vedi Consentire agli utenti di configurare i widget delle app. - Il callback più importante è
onUpdate()
. Per ulteriori informazioni, vedi Gestire gli eventi con il corsoonUpdate()
in questa pagina. onAppWidgetOptionsChanged()
Questa chiamata viene chiamata quando il widget viene posizionato per la prima volta e ogni volta che viene ridimensionato. Utilizza questo callback per mostrare o nascondere i contenuti in base agli intervalli di dimensioni del widget. Ottieni gli intervalli di dimensioni e, a partire da Android 12, l'elenco delle possibili dimensioni utilizzabili da un'istanza di widget chiamando
getAppWidgetOptions()
, che restituisce un elementoBundle
che include quanto segue:OPTION_APPWIDGET_MIN_WIDTH
: contiene il limite inferiore della larghezza, in unità dp, di un'istanza widget.OPTION_APPWIDGET_MIN_HEIGHT
: contiene il limite inferiore relativo all'altezza, in unità dp, di un'istanza widget.OPTION_APPWIDGET_MAX_WIDTH
: contiene il limite superiore della larghezza, in unità dp, di un'istanza widget.OPTION_APPWIDGET_MAX_HEIGHT
: contiene il limite superiore sull'altezza, in unità dp, di un'istanza di widget.OPTION_APPWIDGET_SIZES
: contiene l'elenco delle possibili dimensioni (List<SizeF>
), in unità dp, che un'istanza widget può assumere. Introdotta in Android 12.
onDeleted(Context, int[])
Questo viene chiamato ogni volta che un widget viene eliminato dall'host del widget.
onEnabled(Context)
Questo viene chiamato quando un'istanza del widget viene creata per la prima volta. Ad esempio, se l'utente aggiunge due istanze del widget, questa viene chiamata solo la prima volta. Se devi aprire un nuovo database o eseguire un'altra configurazione che deve essere eseguita una sola volta per tutte le istanze del widget, questo è un buon posto per farlo.
onDisabled(Context)
Questo viene chiamato quando l'ultima istanza del widget viene eliminata dall'host del widget. È qui che ripulisci qualsiasi lavoro svolto in
onEnabled(Context)
, come l'eliminazione di un database temporaneo.onReceive(Context, Intent)
Viene richiesto per ogni trasmissione e prima di ciascuno dei metodi di callback precedenti. In genere non è necessario implementare questo metodo, perché l'implementazione predefinita di
AppWidgetProvider
filtra tutte le trasmissioni del widget e chiama i metodi precedenti a seconda dei casi.
Devi dichiarare l'implementazione della classe AppWidgetProvider
come ricevitore
di trasmissione utilizzando l'elemento <receiver>
in AndroidManifest
. Per ulteriori informazioni, consulta la sezione Dichiarare un widget nel file manifest in questa pagina.
Gestire gli eventi con la classe onUpdate()
Il callback AppWidgetProvider
più importante è onUpdate()
, perché viene
chiamato quando ciascun widget viene aggiunto a un host, a meno che non utilizzi un'attività di
configurazione senza il flag configuration_optional
. Se il widget accetta eventi di interazione dell'utente, registra i gestori di eventi in questo callback. Se il widget non crea file o database temporanei né esegue altre operazioni che richiedono la pulizia, onUpdate()
potrebbe essere l'unico metodo di callback che devi definire.
Ad esempio, se vuoi un widget con un pulsante che avvia un'attività quando viene toccato, puoi utilizzare la seguente implementazione di AppWidgetProvider
:
Kotlin
class ExampleAppWidgetProvider : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Perform this loop procedure for each widget that belongs to this // provider. appWidgetIds.forEach { appWidgetId -> // Create an Intent to launch ExampleActivity. val pendingIntent: PendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ Intent(context, ExampleActivity::class.java), /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Get the layout for the widget and attach an onClick listener to // the button. val views: RemoteViews = RemoteViews( context.packageName, R.layout.appwidget_provider_layout ).apply { setOnClickPendingIntent(R.id.button, pendingIntent) } // Tell the AppWidgetManager to perform an update on the current // widget. appWidgetManager.updateAppWidget(appWidgetId, views) } } }
Java
public class ExampleAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Perform this loop procedure for each widget that belongs to this // provider. for (int i=0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; // Create an Intent to launch ExampleActivity Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ intent, /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // Get the layout for the widget and attach an onClick listener to // the button. RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app // widget. appWidgetManager.updateAppWidget(appWidgetId, views); } } }
Questo AppWidgetProvider
definisce solo il metodo onUpdate()
, utilizzandolo per
creare una PendingIntent
che avvia
un Activity
e lo allega al pulsante del widget utilizzando setOnClickPendingIntent(int,
PendingIntent)
. Include un loop che ripete ogni voce
in appWidgetIds
, ovvero un array di ID che identifica ogni widget creato da
questo provider. Se l'utente crea più istanze del widget, verranno aggiornati tutti contemporaneamente. Tuttavia, viene gestita una sola pianificazione updatePeriodMillis
per tutte le istanze del widget. Ad esempio, se la pianificazione dell'aggiornamento
è definita ogni due ore e viene aggiunta una seconda istanza del widget
un'ora dopo la prima, entrambe vengono aggiornate nel periodo definito dal
primo e il secondo periodo di aggiornamento viene ignorato. Entrambi si aggiornano ogni due ore, non ogni ora.
Per ulteriori dettagli, consulta la classe di esempio ExampleAppWidgetProvider.java
.
Ricevi intent di trasmissione del widget
AppWidgetProvider
è un corso di convenienza. Se vuoi ricevere le trasmissioni del widget direttamente, puoi implementare il tuo BroadcastReceiver
o eseguire l'override del callback onReceive(Context,Intent)
. Gli intent che ti interessano sono i seguenti:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
Creare il layout del widget
Devi definire un layout iniziale per il widget in XML e salvarlo nella directory res/layout/
del progetto. Fai riferimento alle linee guida
per la progettazione per maggiori dettagli.
Se hai familiarità con i layout, creare il layout del widget è semplice. Tuttavia, tieni presente che i layout dei widget si basano su RemoteViews
, che non supporta tutti i tipi di widget di layout o visualizzazione. Non puoi utilizzare viste personalizzate o sottoclassi delle viste supportate da RemoteViews
.
RemoteViews
supporta anche ViewStub
,
un View
invisibile a dimensione zero che puoi utilizzare per aumentare in modo artificioso le risorse di layout in fase di runtime.
Supporto per il comportamento stateful
Android 12 aggiunge il supporto per il comportamento stateful utilizzando i seguenti componenti esistenti:
Il widget è ancora stateless. L'app deve archiviare lo stato e registrarsi per gli eventi di modifica dello stato.
Il codice di esempio riportato di seguito mostra come implementare questi componenti.
Kotlin
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true) // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2) // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent) )
Java
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true); // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2); // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));
Fornisci due layout: uno ha come target i dispositivi con Android 12 o versioni successive in res/layout-v31
e l'altro ha come target Android 11 o versioni precedenti nella cartella res/layout
predefinita.
Implementa gli angoli arrotondati
Android 12 introduce i seguenti parametri di sistema per impostare i raggi degli angoli arrotondati del widget:
system_app_widget_background_radius
: raggio d'angolo dello sfondo del widget, che non supera mai i 28 dp.system_app_widget_inner_radius
: il raggio degli angoli di qualsiasi vista all'interno del widget. che è esattamente di 8 dp in meno rispetto al raggio dello sfondo, per allinearsi perfettamente quando si utilizza una spaziatura interna di 8 dp.
L'esempio seguente mostra un widget che utilizza
system_app_widget_background_radius
per l'angolo del widget e
system_app_widget_inner_radius
per le viste all'interno del widget.
1 Angolo del widget.
2 Angolo di una visualizzazione all'interno del widget.
Considerazioni importanti per gli angoli arrotondati
- Avvio app di terze parti e produttori di dispositivi possono eseguire l'override del
parametro
system_app_widget_background_radius
in modo che sia inferiore a 28 dp. Il parametrosystem_app_widget_inner_radius
è sempre inferiore di 8 dp rispetto al valore disystem_app_widget_background_radius
. - Se il widget non utilizza
@android:id/background
o non definisce uno sfondo che ritaglia i contenuti in base al contorno, conandroid:clipToOutline
impostato sutrue
, Avvio app identifica automaticamente lo sfondo e ritaglia il widget utilizzando un rettangolo con angoli arrotondati di massimo 16 dp. Vedi Assicurarsi che il widget sia compatibile con Android 12.
Per garantire la compatibilità dei widget con le versioni precedenti di Android, ti consigliamo di definire attributi personalizzati e di utilizzare un tema personalizzato per sostituirli per Android 12, come mostrato nei seguenti file XML di esempio:
/values/attrs.xml
<resources>
<attr name="backgroundRadius" format="dimension" />
</resources>
/values/styles.xml
<resources>
<style name="MyWidgetTheme">
<item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
</style>
</resources>
/values-31/styles.xml
<resources>
<style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
</style>
</resources>
/drawable/my_widget_background.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="?attr/backgroundRadius" />
...
</shape>
/layout/my_widget_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:background="@drawable/my_widget_background" />