Widgets en los que se puede hacer clic en Android

5 minutos de lectura

Widgets en los que se puede hacer clic en Android
leif andersen

La documentación del desarrollador parece haberme fallado aquí. Puedo crear un widget estático sin pensar, incluso puedo crear un widget como el widget de reloj analógico que se actualizará solo, sin embargo, no puedo por mi vida descubrir cómo crear un widget que reaccione cuando un usuario hace clic en eso. Esta es la mejor muestra de código que la documentación del desarrollador brinda sobre lo que debe contener una actividad de widget (la única pista adicional son las demostraciones de API, que solo crean un widget estático):

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;

        // Perform this loop procedure for each App Widget that belongs to this provider
        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];

            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

            // Get the layout for the App Widget and attach an on-click listener to the button
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current App Widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

desde: La página de widgets de la documentación para desarrolladores de Android

Por lo tanto, parece que se llama a la intención pendiente cuando se hace clic en el widget, que se basa en una intención (no estoy muy seguro de cuál es la diferencia entre una intención y una intención pendiente), y la intención es para la clase ExampleActivity . Así que hice de mi clase de actividad de muestra una actividad simple que, cuando se creaba, creaba un objeto de reproductor multimedia y lo iniciaba (nunca liberaba el objeto, por lo que eventualmente fallaba, aquí está su código:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.sound);
    mp.start();
}

Sin embargo, cuando agregué el widget a la pantalla de inicio e hice clic en él, no se reprodujo nada, de hecho, no se reprodujo nada cuando configuré el temporizador de actualización en unos pocos cientos de milisegundos (en el archivo xml del proveedor del widget de aplicación). Además, establecí puntos de interrupción y descubrí que no solo nunca alcanzaba la actividad, sino que nunca se activaría ningún punto de interrupción que estableciera. (Todavía no he descubierto por qué es así), sin embargo, logcat parecía indicar que se estaba ejecutando el archivo de clase de actividad.

Entonces, ¿hay algo que pueda hacer para que un widget de aplicación responda a un clic? como el onClickPendingIntent() método es el más cercano que he encontrado a un onClick tipo de método.

  • Hai Leif, ¿resuelve este problema con Methode de Brain515? Tengo un problema similar, pero la solución de Brain no funciona para mí. ¿Pueden ayudarme por favor?

    – Ajmal MA

    06 jun.

Widgets en los que se puede hacer clic en Android
quark extraño

Primero, agregue una variable estática con una constante.

public static String YOUR_AWESOME_ACTION = "YourAwesomeAction";

Luego, debe agregar la acción a la intención antes de agregar la intención a la intención pendiente:

Intent intent = new Intent(context, widget.class);
intent.setAction(YOUR_AWESOME_ACTION);

(Donde widget.class es la clase de su AppWidgetProvider, su clase actual)

Luego debe crear un PendingIntent con getBroadcast

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

Establezca onClickPendingIntent para la vista en la que se puede hacer clic en su widget

remoteView.setOnClickPendingIntent(R.id.widgetFrameLayout, pendingIntent);

Luego, reemplaza el método onReceive en la misma clase:

@Override
public void onReceive(Context context, Intent intent) {
 super.onReceive(context, intent);

Y luego responda a las pulsaciones de sus botones consultando la intención devuelta para su acción dentro del método onReceive:

if (intent.getAction().equals(YOUR_AWESOME_ACTION)) {
   //do some really cool stuff here
}

¡Y eso debería hacerlo!

  • ¿Dónde se ubica esta línea ( Intent Intent = new Intent(context, ExampleActivity.class);)? ¿Qué contiene widget.class? Supongo que ExampleActivity es lo que queremos lanzar.

    – Sólo curioso

    01 feb.

  • Editó la respuesta a un método con algunos pasos adicionales que se necesitan para que esto funcione. getBroadcast es importante para que se transmita PendingIntent, en lugar de getActivity del ejemplo.

    – Guykun

    20 jun.

  • .getActivity se usa para abrir una actividad, por ejemplo, cuando hace clic en un objeto en el widget

    – erdomester

    13 oct.

  • Use un LocalBroadcastManager en lugar de transmisiones genéricas

    – Vikram Bodicherla

    05 ene.

  • AFAIK no hay forma de usar PendingIntent con LocalBroadcastManager

    – bóveda

    04 abr.

Widgets en los que se puede hacer clic en Android
Miguel

Deja el onActualizar método tal como era y copiar y pegar la lógica para actualizarAppWidget.

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                            int appWidgetId) {

    // Create an Intent to launch ExampleActivity when clicked
    Intent intent = new Intent(context, ExampleActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
    // Construct the RemoteViews object
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
    // Widgets allow click handlers to only launch pending intents
    views.setOnClickPendingIntent(R.id.button, pendingIntent);
    // Instruct the widget manager to update the widget
    appWidgetManager.updateAppWidget(appWidgetId, views);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    // There may be multiple widgets active, so update all of them
    for (int appWidgetId : appWidgetIds) {
        updateAppWidget(context, appWidgetManager, appWidgetId);
    }
}

PD. Intención pendiente es solo una “caja” para un Intent, que permite otras aplicaciones para tener acceso y ejecutar ese Intent en su aplicación.

  • ¿Por qué haces esto para cada actualización de widget? ¿Seguro que solo hay que hacerlo una vez?

    -Richard Barraclough

    25 jun.

.

¿Ha sido útil esta solución?