Escolar Documentos
Profissional Documentos
Cultura Documentos
Paso 1: La interfaz del widget está compuesta por dos FrameLayout, uno negro exterior y uno blanco interior más
pequeño para simular el marco, y una etiqueta de texto (TextView) que muestra el mensaje. Para este ejemplo se llama
“miwidget.xml“:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dip">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:padding="10dip" >
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF"
android:padding="5dip" >
<TextView android:id="@+id/txtMensaje"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#000000"
android:text="Mi Primer Widget" />
</FrameLayout>
</FrameLayout>
</LinearLayout>
Paso 2: Crear un nuevo XML donde definir la frecuencia de actualización. Este XML se crea en la carpeta \res\xml del
proyecto y que se llama “miwidget_wprovider.xml”:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/miwidget"
android:minWidth="146dip"
android:minHeight="72dip"
android:label="Mi Primer Widget"
android:updatePeriodMillis="3600000"
/>
La pantalla inicial de Android se divide en 4×4 celdas donde se pueden colocar aplicaciones, accesos directos y widgets,
según la orientación de la pantalla. Existe una fórmula sencilla para ajustar las dimensiones del widget para que ocupe
un número determinado de celdas sea cual sea la orientación:
ancho_mínimo = (num_celdas * 74) – 2
alto_mínimo = (num_celdas * 74) – 2
Si se desea que el widget ocupe un tamaño mínimo de 2 celdas de ancho por 1 celda de alto, se deben indicar unas
dimensiones de 146dp x 72dp.
Paso 3: Implantar la funcionalidad del widget en su clase java asociada. Esta clase debe heredar de
AppWidgetProvider, que a su vez no es más que una clase auxiliar derivada de BroadcastReceiver, ya que los
widgets de Android no son más que un caso particular de este tipo de componentes. Se deben implementar los mensajes
a los que vamos a responder desde nuestro widget:
onEnabled(): lanzado cuando se añade al escritorio la primera instancia de un widget.
onUpdate(): lanzado periódicamente cada vez que se debe actualizar un widget.
onDeleted(): lanzado cuando se elimina del escritorio una instancia de un widget.
onDisabled(): lanzado cuando se elimina del escritorio la última instancia de un widget.
Implementar como mínimo el evento onUpdate(). El resto de métodos dependerán de la funcionalidad de nuestro
widget. En nuestro caso particular no nos hará falta ninguno de ellos ya que el widget que estamos creando no contiene
ningún dato actualizable, por lo que crearemos la clase, llamada MiWidget, pero dejaremos vacío por el momento el
método onUpdate(). En el siguiente apartado veremos qué cosas podemos hacer dentro de estos métodos.
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
public class MiWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
//Actualizar el widget
//...
}
}
Paso 4: Declarar el widget dentro del manifest de la aplicación. Editar el AndroidManifest.xml para incluir la siguiente
declaración dentro del elemento <application>:
<application>
...
<receiver android:name=".MiWidget" android:label="Mi Primer Widget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/miwidget_wprovider" />
</receiver>
</application>
Para probarlo, ir a la pantalla principal del emulador y añadir nuestro widget al escritorio tal cómo lo haríamos en nuestro
teléfono (digitación larga sobre el escritorio o tecla Menú, seleccionar la opción Widgets, y por último seleccionar nuestro
Widget).
Android Widgets
Table of Contents
1. Prerequisites
2. Android Widgets
2.1. Overview about AppWidgets
2.2. Steps to create a Widget
2.3. Widget size
3. Creating the Broadcast receiver for the widget
3.1. Create and configure widget
3.2. Available views and layouts
3.3. AppWidgetProvider
3.4. Receiver and asynchronous processing
4. Widget updates
5. Exercise: widget with fixed update interval
5.1. Target
5.2. Create project and widget implementation
5.3. Validate
6. Collection View Widgets
7. Enabling a Widget for the Lock Screen
8. Exercise: Update widget via a service
9. About this website
9.1. Donate to support free tutorials
9.2. Questions and discussion
9.3. License for this tutorial and its code
10. Links and Literature
10.1. Source Code
10.2. Android Widget Resources
10.3. Android Resources
10.4. vogella Resources
1. Prerequisites
The following description assume that you already have experience in building standard Android application.
Please see Android Tutorial. It also partly uses Android services. You find an introduction into Android Services
in Android Service Tutorial.
2. Android Widgets
2.1. Overview about AppWidgets
Widgets are little applications which can be placed on a widget host, typically the home screen or the lock
screen of your Android device.
A widget runs as part of the process of its host. This requires that the widget preserves the permissions of their
application.
Widget use RemoteViews to create their user interface. A RemoteView can be executed by another process
with the same permissions as the original application. This way the widget runs with the permissions of its
defining application.
The user interface for a Widget is defined by a broadcast receiver. This receiver inflates its layout into an object
of type RemoteViews . This object is delivered to Android, which hands it over the home screen application.
2.2. Steps to create a Widget
To create a widget, you:
Define a layout file
Create an XML file ( AppWidgetProviderInfo ) which describes the properties of the widget, e.g. size or
the fixed update frequency.
Create a BroadcastReceiver which is used to build the user interface of the widget.
Enter the Widget configuration in the AndroidManifest.xml file.
Optional you can specify a configuration activity which is called once a new instance of the widget is
added to the widget host.
2.3. Widget size
Before Android 3.1 a widget always took a fixed amount of cells on the home screen. A cell is usually used to
display the icon of one application. As a calculation rule you should define the size of the widget with the
formula: ((Number of columns / rows) * 74) - 2 . These are device independent pixels and the -2 is
used to avoid rounding errors.
As of Android 3.1 a widget can be flexible in size, e.g., the user can make it larger or smaller. To enable this for
widget, you can use the android:resizeMode="horizontal|vertical" attribute in the XML configuration
file for the widget.
3. Creating the Broadcast receiver for the widget
3.1. Create and configure widget
To register a widget, you create a broadcast receiver with an intent filter for
the android.appwidget.action.APPWIDGET_UPDATE action.
<receiver
android:icon="@drawable/icon"
android:label="Example Widget"
android:name="MyWidgetProvider" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
The receiver can get a label and icon assigned. These are used in the list of available widgets in the Android
launcher.
You also specify the meta-data for the widget via
the android:name="android.appwidget.provider attribute. The configuration file referred by this metadata
contains the configuration settings for the widget. It contains, for example, the update interface, the size and the
initial layout of the widget.
</appwidget-provider>
Method Description
onEnabled() Called the first time an instance of your widget is added to the home screen.
onDisabled() Called once the last instance of your widget is removed from the home screen.
onUpdate() Called for every update of the widget. Contains the ids of appWidgetIds for
which an update is needed. Note that this may be all of
the AppWidget instances for this provider, or just a subset of them, as stated in
the method's JavaDoc. For example, if more than one widget is added to the
home screen, only the last one changes (until reinstall).
Create the AppWidgetProvider metadata widget_info.xml file, via File → New → Android→ Android XML
File
Open the AndroidManifest.xml and register your widget similar to the following listing.
This attribute specifies that the AppWidgetProvider accepts the ACTION_APPWIDGET_UPDATE broadcast and
specifies the metadata for the widget.
5.3. Validate
Deploy your application on your Android device. Once your application has been deployed use the Android
launcher to install your new widget on the home screen and test it.
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:widgetCategory="keyguard|home_screen"
...
>
...
</appwidget-provider>
In this example you declare a widget to support both - the home and the lock screens. If you recompile and
launch your application now, you will be able to add the widget to the lock screen already.
You can also detect a widget category at runtime. For this, in the AppWidgetProvider.onUpdate() method,
you can check for the category option of a widget with the following code.
Using this technique you can decide at runtime whether the widgets your application provides, will look
differently, when they are hosted on the lock screen.
Similarly to how you used the android:initialLayout attribute for defining an initial layout for home screen widgets,
you can use a new android:initialKeyguardLayout attribute for the lock screen in
the AppWidgetProviderInfo XML file. This layout will appear immediately after a widget is added and will be
replaced by the real layout once the widget is initialized.
8. Exercise: Update widget via a service
The following will demonstrate the usage of a service to update the widget.
Create the following UpdateWidgetService class in your project.
package de.vogella.android.widget.example;
import java.util.Random;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
public class UpdateWidgetService extends Service {
private static final String LOG = "de.vogella.android.widget.example";
@Override
public void onStart(Intent intent, int startId) {
Log.i(LOG, "Called");
// create some random data
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),
R.layout.widget_layout);
Log.w("WidgetExample", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(R.id.update,
"Random: " + String.valueOf(number));
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),
MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
stopSelf();
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<service android:name=".UpdateWidgetService"></service>
Change MyWidgetProvider to the following. It will now only construct the service and start it.
package de.vogella.android.widget.example;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyWidgetProvider extends AppWidgetProvider {
private static final String LOG = "de.vogella.android.widget.example";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
// Get all ids
ComponentName thisWidget = new ComponentName(context,
MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
}
Once called, this service will update all widgets. You can click on one of the widgets to update all widgets.
http://www.vogella.com/tutorials/AndroidWidgets/article.html