Los widgets son vistas de apps en miniatura que puedes incorporar en otras apps (como la pantalla principal) y recibir actualizaciones periódicas. Estas vistas se denominan widgets en la interfaz de usuario, y puedes publicar una con un proveedor de widgets de apps (o proveedor de widgets). Un componente de la app que contiene otros widgets se denomina host de widgets de la app (o host de widgets). En la figura 1, se muestra un ejemplo de widget de música:

En este documento, se describe cómo publicar un widget con un proveedor de widgets. Si deseas obtener detalles para crear tu propio AppWidgetHost
para alojar widgets de apps, consulta Cómo crear un host de widgets.
Para obtener información sobre cómo diseñar tu widget, consulta Descripción general de los widgets de apps.
Componentes de widgets
Para crear un widget, necesitas los siguientes componentes básicos:
- Objeto
AppWidgetProviderInfo
- Describe los metadatos de un widget, como el diseño, la frecuencia de actualización y la clase
AppWidgetProvider
.AppWidgetProviderInfo
se define en XML, como se describe en este documento. - Clase
AppWidgetProvider
- Define los métodos básicos que te permiten interactuar de manera programática con el widget. De esta manera, recibirás emisiones cuando se actualice, se habilite, se inhabilite o se borre el widget. Declaras
AppWidgetProvider
en el manifiesto y, luego, lo implementas, como se describe en este documento. - Diseño de la vista
- Define el diseño inicial del widget. El diseño se define en XML, como se describe en este documento.
En la figura 2, se muestra cómo estos componentes se ajustan al flujo general de procesamiento de widgets de la app.

Si tu widget necesita configuración del usuario, implementa la actividad de configuración del widget de la app. Esta actividad permite a los usuarios modificar la configuración de los widgets, por ejemplo, la zona horaria de un widget de reloj.
- A partir de Android 12 (nivel de API 31), puedes proporcionar una configuración predeterminada y permitir que los usuarios reconfiguren el widget más adelante. Consulta Cómo usar la configuración predeterminada del widget y Cómo permitir que los usuarios reconfiguren los widgets colocados para obtener más detalles.
- En Android 11 (nivel de API 30) o versiones anteriores, esta actividad se inicia cada vez que el usuario agrega el widget a su pantalla principal.
También recomendamos las siguientes mejoras: diseños de widgets flexibles, mejoras varias, widgets avanzados, widgets de colección y cómo compilar un host de widgets.
Declara el XML de AppWidgetProviderInfo
El objeto AppWidgetProviderInfo
define las cualidades esenciales de un widget.
Define el objeto AppWidgetProviderInfo
en un archivo de recursos XML con un solo elemento <appwidget-provider>
y guárdalo en la carpeta res/xml/
del proyecto.
Esto se muestra en el siguiente ejemplo:
<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>
Atributos de tamaño del widget
En la pantalla principal predeterminada, se colocan los widgets en la ventana según una cuadrícula de celdas que tienen una altura y un ancho definidos. La mayoría de las pantallas principales solo permiten que los widgets adopten tamaños que sean múltiplos enteros de las celdas de la cuadrícula, por ejemplo, dos celdas horizontales por tres celdas verticales.
Los atributos de tamaño del widget te permiten especificar un tamaño predeterminado para tu widget y proporcionar límites inferior y superior para su tamaño. En este contexto, el tamaño predeterminado de un widget es el tamaño que adopta el widget cuando se agrega por primera vez a la pantalla principal.
En la siguiente tabla, se describen los atributos de <appwidget-provider>
relacionados con el tamaño del widget:
Atributos y descripción | |
---|---|
targetCellWidth y
targetCellHeight (Android 12),
minWidth y minHeight |
targetCellWidth y targetCellHeight , y minWidth y minHeight , de modo que tu app pueda recurrir al uso de minWidth y minHeight si el dispositivo del usuario no admite targetCellWidth y targetCellHeight . Si se admiten, los atributos
targetCellWidth y targetCellHeight tienen prioridad
sobre los atributos minWidth y minHeight .
|
minResizeWidth y
minResizeHeight |
Especifica el tamaño mínimo absoluto del widget. Estos valores especifican el tamaño por debajo del cual el widget es ilegible o inutilizable. El uso de estos atributos permite al usuario cambiar el tamaño del widget por un tamaño que es menor que el predeterminado. El atributo minResizeWidth se ignora si es mayor que minWidth o si el cambio de tamaño horizontal no está habilitado. Consulta
resizeMode . Del mismo modo, el atributo minResizeHeight se ignora si es mayor que minHeight o si el cambio de tamaño vertical no está habilitado. |
maxResizeWidth y
maxResizeHeight |
Especifica el tamaño máximo recomendado del widget. Si los valores no son múltiplos de las dimensiones de la celda de la cuadrícula, se redondean hacia arriba al tamaño de celda más cercano. El atributo maxResizeWidth se ignora si es menor que minWidth o si el cambio de tamaño horizontal no está habilitado. Consulta resizeMode . Del mismo modo, el atributo maxResizeHeight se ignora si es mayor que minHeight o si el cambio de tamaño vertical no está habilitado.
Se introdujo en Android 12. |
resizeMode |
Especifica las reglas por las que se puede cambiar el tamaño de un widget. Puedes usar este atributo para hacer que se pueda cambiar el tamaño de los widgets de la pantalla principal de forma horizontal o vertical, o en ambos ejes. Los usuarios deben mantener presionado un widget para mostrar los controladores de cambio de tamaño y, luego, arrastrar los controladores horizontales o verticales para cambiar su tamaño en la cuadrícula de diseño. Los valores del atributo resizeMode incluyen horizontal , vertical y none . Para declarar un widget como horizontal y vertical, usa horizontal|vertical . |
Ejemplo
Para ilustrar cómo los atributos de la tabla anterior afectan el tamaño del widget, supón las siguientes especificaciones:
- Una celda de la cuadrícula tiene 30 dp de ancho y 50 dp de alto.
- Se proporciona la siguiente especificación de atributos:
<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 partir de Android 12:
Usa los atributos targetCellWidth
y targetCellHeight
como el tamaño predeterminado del widget.
El tamaño predeterminado del widget es de 2 x 2. El widget se puede reducir hasta 2x1 o aumentar hasta 4x3.
Android 11 y versiones anteriores:
Usa los atributos minWidth
y minHeight
para calcular el tamaño predeterminado del widget.
El ancho predeterminado = Math.ceil(80 / 30)
= 3
La altura predeterminada = Math.ceil(80 / 50)
= 2
El tamaño predeterminado del widget es de 3 x 2. El widget se puede redimensionar hasta 2 × 1 o hasta pantalla completa.
Atributos adicionales del widget
En la siguiente tabla, se describen los atributos de <appwidget-provider>
relacionados con cualidades que no son el tamaño del widget.
Atributos y descripción | |
---|---|
updatePeriodMillis |
Define la frecuencia con la que el marco de trabajo del widget solicita una actualización desde el AppWidgetProvider llamando al método de devolución de llamada onUpdate() . Con este valor, no se garantiza que la actualización real ocurra exactamente a tiempo, y sugerimos realizarla con la menor frecuencia posible (tal vez no más de una por hora) para conservar la batería.
Para obtener la lista completa de consideraciones para elegir un período de actualización adecuado, consulta Optimizaciones para actualizar el contenido de los widgets. |
initialLayout |
Apunta al recurso de diseño que define el diseño del widget. |
configure |
Define la actividad que se inicia cuando el usuario agrega el widget, lo que le permite configurar las propiedades del widget. Consulta Cómo permitir que los usuarios configuren widgets. A partir de Android 12, tu app puede omitir la configuración inicial. Consulta Cómo usar la configuración predeterminada del widget para obtener más detalles. |
description |
Especifica la descripción que se mostrará en el selector de widgets para tu widget. Se introdujo en Android 12. |
previewLayout (Android 12)
y previewImage (Android 11 y versiones anteriores) |
previewImage y previewLayout para que tu app pueda recurrir a previewImage si el dispositivo del usuario no admite previewLayout . Para obtener más detalles, consulta Retrocompatibilidad con vistas previas escalables de widgets.
|
autoAdvanceViewId |
Especifica el ID de vista de la subvista del widget que el host del widget hace avanzar automáticamente. |
widgetCategory |
Declara si el widget se puede mostrar en la pantalla principal (home_screen ), la pantalla de bloqueo (keyguard ) o ambas. Para Android 5.0 y versiones posteriores, solo es válido home_screen .
|
widgetFeatures |
Declara las funciones que admite el widget. Por ejemplo, si deseas que el widget use su configuración predeterminada cuando un usuario lo agregue, especifica las marcas configuration_optional y reconfigurable . De esta manera, se evita iniciar la actividad de configuración después de que un usuario
agrega el widget. El usuario aún puede reconfigurar el widget más adelante. |
Usa la clase AppWidgetProvider para controlar las transmisiones de widgets
La clase AppWidgetProvider
controla las transmisiones de widgets y actualiza el widget en respuesta a los eventos del ciclo de vida del widget. En las siguientes secciones, se describe cómo declarar AppWidgetProvider
en el manifiesto y, luego, implementarlo.
Cómo declarar un widget en el manifiesto
Primero, declara la clase AppWidgetProvider
en el archivo AndroidManifest.xml
de tu app, como se muestra en el siguiente ejemplo:
<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>
El elemento <receiver>
requiere el atributo android:name
, que especifica el AppWidgetProvider
que utiliza el widget. El componente no se debe exportar, a menos que un proceso independiente necesite transmitir a tu AppWidgetProvider
, lo que no suele ser el caso.
El elemento <intent-filter>
debe incluir un elemento <action>
con el atributo android:name
. Este atributo especifica que el AppWidgetProvider
acepta la emisión de ACTION_APPWIDGET_UPDATE
. Esta es la única emisión que debes declarar de manera explícita. El AppWidgetManager
envía automáticamente todas las demás emisiones del widget al AppWidgetProvider
según sea necesario.
El elemento <meta-data>
especifica el recurso AppWidgetProviderInfo
y requiere los siguientes atributos:
android:name
: Especifica el nombre de los metadatos. Usaandroid.appwidget.provider
para identificar los datos como el descriptorAppWidgetProviderInfo
.android:resource
: Especifica la ubicación del recursoAppWidgetProviderInfo
.
Implementa la clase AppWidgetProvider
La clase AppWidgetProvider
extiende BroadcastReceiver
como una clase de conveniencia para controlar las emisiones de widgets. Recibe solo las emisiones de eventos que son relevantes para el widget, como cuando este se actualiza, se borra, se habilita o se inhabilita. Cuando se producen estos eventos de emisión, se llaman a los siguientes métodos de AppWidgetProvider
:
onUpdate()
- Se llama a este método para actualizar el widget a intervalos definidos por el atributo
updatePeriodMillis
enAppWidgetProviderInfo
. Consulta la tabla que describe los atributos adicionales del widget en esta página para obtener más información. - También se llama a este método cuando el usuario agrega el widget, por lo que realiza la configuración esencial, como definir controladores de eventos para objetos
View
o iniciar trabajos para cargar datos que se mostrarán en el widget. Sin embargo, si declaras una actividad de configuración sin la marcaconfiguration_optional
, no se llama a este método cuando el usuario agrega el widget, pero sí se llama para las actualizaciones posteriores. Es responsabilidad de la actividad de configuración realizar la primera actualización cuando se completa la configuración. Consulta Permite que los usuarios configuren widgets de apps para obtener más información. - La devolución de llamada más importante es
onUpdate()
. Consulta Cómo controlar eventos con la claseonUpdate()
en esta página para obtener más información. onAppWidgetOptionsChanged()
Se llama a este método cuando se coloca por primera vez el widget y cada vez que se le cambia el tamaño. Usa esta devolución de llamada para mostrar u ocultar contenido en función de los rangos de tamaño del widget. Para obtener los rangos de tamaño y, a partir de Android 12, la lista de tamaños posibles que puede tener una instancia de widget, llama a
getAppWidgetOptions()
, que devuelve unBundle
que incluye lo siguiente:OPTION_APPWIDGET_MIN_WIDTH
: Contiene el límite inferior del ancho, en unidades dp, de una instancia de widget.OPTION_APPWIDGET_MIN_HEIGHT
: Contiene el límite inferior de la altura, en unidades dp, de una instancia de widget.OPTION_APPWIDGET_MAX_WIDTH
: Contiene el límite superior del ancho, en unidades dp, de una instancia de widget.OPTION_APPWIDGET_MAX_HEIGHT
: Contiene el límite superior de la altura, en unidades dp, de una instancia de widget.OPTION_APPWIDGET_SIZES
: Contiene la lista de tamaños posibles (List<SizeF>
), en unidades de dp, que puede adoptar una instancia de widget. Se introdujo en Android 12.
onDeleted(Context, int[])
Se llama a este método cada vez que se borra un widget del host de widgets.
onEnabled(Context)
Se llama a este método cuando se crea una instancia del widget por primera vez. Por ejemplo, si el usuario agrega dos instancias de tu widget, solo se lo llama la primera vez. Si necesitas abrir una nueva base de datos o realizar otra configuración que solo debe ocurrir una vez para todas las instancias del widget, este es un buen lugar para hacerlo.
onDisabled(Context)
Se llama a este método cuando se borra la última instancia del widget del host de widgets. Aquí debes limpiar los trabajos realizados en
onEnabled(Context)
, como borrar una base de datos temporal.onReceive(Context, Intent)
Se llama a este método para cada emisión y antes de cada uno de los métodos de devolución de llamada anteriores. Por lo general, no es necesario implementar este método, ya que la implementación predeterminada de
AppWidgetProvider
filtra todas las transmisiones de widgets y llama a los métodos anteriores según corresponda.
Debes declarar tu implementación de la clase AppWidgetProvider
como un receptor de emisión con el elemento <receiver>
en AndroidManifest
. Consulta Cómo declarar un widget en el manifiesto en esta página para obtener más información.
Cómo controlar eventos con la clase onUpdate()
La devolución de llamada AppWidgetProvider
más importante es onUpdate()
, ya que se la llama cuando se agrega cada widget a un host, a menos que uses una actividad de configuración sin la marca configuration_optional
. Si el widget acepta eventos de interacción con el usuario, registra los controladores de eventos en esta devolución de llamada. Si tu widget no crea archivos o bases de datos temporales, ni realiza otro trabajo que requiera limpieza, onUpdate()
podría ser el único método de devolución de llamada que debas definir.
Por ejemplo, si quieres un widget con un botón que inicie una actividad cuando se presione, puedes usar la siguiente implementación de 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); } } }
Este AppWidgetProvider
solo define el método onUpdate()
, que se usa para crear un PendingIntent
que inicia un Activity
y lo adjunta al botón del widget con setOnClickPendingIntent(int,
PendingIntent)
. Incluye un bucle que se repite en cada entrada en appWidgetIds
, que es un arreglo de IDs que identifica cada widget creado por este proveedor. Si el usuario crea más de una instancia del widget, todas se actualizan de forma simultánea. Sin embargo, solo se administra una programación de updatePeriodMillis
para todas las instancias del widget. Por ejemplo, si el programa de actualización se define para que se ejecute cada dos horas y se agrega una segunda instancia del widget una hora después de la primera, ambas se actualizan en el período definido por la primera, y se ignora el segundo período de actualización. Ambos se actualizan cada dos horas, no cada hora.
Consulta la clase de ejemplo ExampleAppWidgetProvider.java
para obtener más detalles.
Cómo recibir intents de emisión del widget
AppWidgetProvider
es una clase de conveniencia. Si deseas recibir directamente las emisiones del widget, puedes implementar tu propio BroadcastReceiver
o anular la devolución de llamada onReceive(Context,Intent)
. Los intents a los que debes prestar atención son los siguientes:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
Crea el diseño del widget
Debes definir un diseño inicial para el widget en formato XML y guardarlo en el directorio res/layout/
del proyecto. Consulta los Lineamientos de diseño para obtener más detalles.
Crear el diseño del widget es sencillo si tienes conocimientos sobre los diseños. Sin embargo, ten en cuenta que los diseños de los widgets se basan en RemoteViews
, que no admite todo tipo de diseño o widget de vista. No puedes usar vistas personalizadas ni subclases de las vistas que admite RemoteViews
.
RemoteViews
también admite ViewStub
, que es un View
invisible de tamaño cero que puedes usar para aumentar de forma diferida los recursos de diseño durante el tiempo de ejecución.
Compatibilidad con comportamientos con estado
Android 12 agrega compatibilidad para comportamientos con estados a través de los siguientes componentes existentes:
El widget todavía no tiene un estado. La app debe almacenar el estado y registrarse para los eventos de cambio de estado.

En el siguiente ejemplo de código, se muestra cómo implementar estos componentes.
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));
Proporciona dos diseños: uno para dispositivos que ejecutan Android 12 o versiones posteriores en res/layout-v31
, y el otro para versiones anteriores de Android 11 o versiones anteriores en la carpeta res/layout
predeterminada.
Cómo implementar esquinas redondeadas
En Android 12, se introducen los siguientes parámetros del sistema para establecer los radios de las esquinas redondeadas del widget:
system_app_widget_background_radius
: El radio de la esquina del fondo del widget, que nunca es superior a 28 dp.Radio interior, que se puede calcular a partir del radio exterior y el padding. Observa el siguiente fragmento:
/** * Applies corner radius for views that are visually positioned [widgetPadding]dp inside of the * widget background. */ @Composable fun GlanceModifier.appWidgetInnerCornerRadius(widgetPadding: Dp): GlanceModifier { if (Build.VERSION.SDK_INT < 31) { return this } val resources = LocalContext.current.resources // get dimension in float (without rounding). val px = resources.getDimension(android.R.dimen.system_app_widget_background_radius) val widgetBackgroundRadiusDpValue = px / resources.displayMetrics.density if (widgetBackgroundRadiusDpValue < widgetPadding.value) { return this } return this.cornerRadius(Dp(widgetBackgroundRadiusDpValue - widgetPadding.value)) }
Para calcular un radio adecuado para el contenido interno de tu widget, usa la siguiente fórmula: systemRadiusValue - widgetPadding
Los widgets que recortan su contenido en formas no rectangulares deben usar @android:id/background
como el ID de vista de la vista de fondo que tiene android:clipToOutline
establecido en true
.
Consideraciones importantes para las esquinas redondeadas
- Los launchers de terceros y los fabricantes de dispositivos pueden anular el parámetro
system_app_widget_background_radius
para que sea inferior a 28 dp. Si tu widget no usa
@android:id/background
o no define un fondo que recorte su contenido según el contorno (conandroid:clipToOutline
establecido entrue
), el launcher identifica automáticamente el fondo y recorta el widget con un rectángulo con esquinas redondeadas establecido en el radio del sistema.Las formas no rectangulares deben estar dentro de su contenedor de cambio de tamaño rectangular redondeado para que no se recorten.
A partir de Android 16, el valor del sistema AOSP para
system_app_widget_background_radius
es24dp
. Los launchers y los fabricantes de dispositivos pueden recortar el widget en elsystem_app_widget_background_radius
.El contenido interno de un widget debe tener suficiente relleno para admitir valores de radio de
system_app_widget_background_radius
hasta28dp
y evitar que las esquinas redondeadas recorten el contenido.
Para garantizar la compatibilidad del widget con versiones anteriores de Android, te recomendamos que definas atributos personalizados y uses un tema personalizado para anularlos en Android 12, como se muestra en los siguientes archivos XML de ejemplo:
/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" />