studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android widget homescreen place

para - manual de programacion android pdf



Comprobar widget se coloca en la pantalla de Android (4)

¿Puede alguien decirme cómo verificar que mi widget se haya colocado en la pantalla de inicio?

Tengo un código en mi aplicación que debería ejecutarse solo si el widget se coloca en la pantalla de inicio.


Necesita almacenar esa información usted mismo. Usualmente uso las preferencias de la aplicación, pero puedes usar cualquier cosa. En general, los widgets usan servicios para comunicarse, por lo que es probable que el código que hace las cosas en un servicio, pero al usar la preferencia, permita que cualquier parte de la aplicación acceda a él.

En su clase de widget que amplía AppWidgetProvider, se llama a onEnabled cuando el widget se coloca en una pantalla de inicio y se llama (generalmente) a onDeleted cuando se elimina. onDisabled se invoca cuando se eliminan todas las copias.

Entonces en el código de tu proveedor de widgets:

@Override public void onEnabled(Context context) { super.onEnabled(context); setWidgetActive(true); context.startService(new Intent(appContext, WidgetUpdateService.class)); } @Override public void onDisabled(Context context) { Context appContext = context.getApplicationContext(); setWidgetActive(false); context.stopService(new Intent(appContext, WidgetUpdateService.class)); super.onDisabled(context); } private void setWidgetActive(boolean active){ Context appContext = context.getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext); SharedPreferences.Editor edit = prefs.edit(); edit.putBoolean(Constants.WIDGET_ACTIVE, active); edit.commit(); }

En otra parte del código, debe verificar si el widget está activo por:

public boolean isWidgetActive(Context context){ Context appContext = context.getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); return prefs.getBoolean(Constants.WIDGET_ACTIVE, false); }


Sé que es una vieja pregunta, pero al ver esto hoy vi que hay un par de problemas con la respuesta aceptada de @ larsona1:

  1. si el usuario borró las preferencias compartidas, todavía hay widget, pero la aplicación no lo sabrá.
  2. si el usuario se arrepiente entre "agregar widget" y antes de presionar "ok" - onEnabled se llamará de todos modos, y un widget se registrará en la pantalla de inicio aunque no haya ningún widget, y no habrá forma de eliminarlo más tarde. (puede ser un error en el iniciador de inicio ADT).

Encontré una solución al primer problema. No se necesitan preferencias compartidas en absoluto, ya que de todos modos no es confiable. Debe ser verificado en tiempo de ejecución.

// in some class you define a static variable, say in S.java static boolean sWidgetMayExist = true;

En tu proveedor de widgets:

// MyAppWidgetProvider.java // to respond to runtime changes, when widgets are added and removed @Override public void onEnabled(Context context) { super.onEnabled(context); S.sWidgetMayExist = true; } @Override public void onDisabled(Context context) { super.onDisabled(context); S.sWidgetMayExist = true; }

Y, en su código de servicio, agregue esto:

AppWidgetManager manager = null; RemoteViews views = null; ComponentName widgetComponent = null; // ..and in your update thread if (!S.sWidgetMayExist) { return; } if (manager == null || widgetComponent == null) { widgetComponent = new ComponentName(c, MyAppWidgetProvider.class); manager = AppWidgetManager.getInstance(c); } if (manager.getAppWidgetIds(widgetComponent) == null) { S.sWidgetMayExist = false; }


Solo digo, pero ...

int ids[] = AppWidgetManager.getInstance(this).getAppWidgetIds(new ComponentName(this,MyAppWidgetProvider.class)); Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();


@Waza_Be tiene razón cuando mira la lista "AppWidgetIds" para saber la cantidad de widgets activos (los que están instalados en su pantalla de inicio) es la forma correcta de conocer esta información.

Sin embargo, tenga en cuenta que NO DEBERÍA tener que mirar esto usted mismo.

Consulte la documentación oficial de Android para conocer las mejores prácticas sobre widgets: https://developer.android.com/guide/topics/appwidgets/index.html#AppWidgetProvider

El enfoque correcto es anular solo el método onUpdate () e iterar a través de la lista de widgets "activos":

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); } } }

Y como su propio proveedor de widgets anula AppWidgetProvider, NO ingresará al método onUpdate () si no tiene widgets activos en la pantalla de inicio.

Vea el código onReceive () de Android AppWidgetProvider que ya verifica para usted que "appWidgetIds.length> 0":

public void onReceive(Context context, Intent intent) { // Protect against rogue update broadcasts (not really a security issue, // just filter bad broacasts out so subclasses are less likely to crash). String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { Bundle extras = intent.getExtras(); if (extras != null) { int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); if (appWidgetIds != null && appWidgetIds.length > 0) { this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds); } } } (...) }