Pregunta

¿Alguien puede decirme cómo verificar que mi widget haya sido colocado en la pantalla de inicio?

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

¿Fue útil?

Solución

Necesitas almacenar esa información tú mismo. Por lo general, uso las preferencias de aplicación, pero podría usar cualquier cosa. En general, los widgets usan servicios para comunicarse, por lo que su código que hace cosas está en un servicio, pero el uso de la preferencia permite que cualquier parte de su aplicación acceda a esto.

En su clase de widgets que extiende AppWidgetProvider, el OnEnable se llama cuando el widget se coloca en una pantalla de inicio y el OnDeleted se llama (generalmente) cuando se elimina. OnDisable se llama cuando se eliminan todas las copias.

Entonces, en el código de su proveedor de widget:

@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, verificaría 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);
}

Otros consejos

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

Sé que es una pregunta antigua, pero al mirar esto hoy vi que hay un par de problemas con la respuesta aceptada de @Larsona1:

  1. Si el usuario borra 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", se llamará a OnEnabled de todos modos, y un widget se registrará en la pantalla de inicio a pesar de que no hay widget, y no hay forma de eliminarlo más tarde. (Puede ser un error en ADT Home Launcher).

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

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

En su proveedor de widget:

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

@Waza_be tiene razón, ya que mirar la lista "AppWidgetIDs" para saber el número de widgets activos (los 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 obtener 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 widget anula AppWidgetProvider, ¡no entrará en el método onupdate () si no tiene widgets activos en la pantalla de inicio!

Consulte el código OnReceive () de Android AppWidgetProvider que verifica ya 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);
            }
        }
    }

(...)
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top