Skip to content Skip to sidebar Skip to footer

Check Widget Is Placed On Android Screen

Can someone tell me how to check that my widget have been placed on the homescreen? I have some code in my app that should run only if the widget is placed on the homescreen.

Solution 1:

Just saying, but...

    int ids[] = AppWidgetManager.getInstance(this).getAppWidgetIds(new ComponentName(this,MyAppWidgetProvider.class));

    Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();

Solution 2:

You need to store that information yourself. I usually use the application preferences, but you could use anything. Generally widgets use services to communicate, so your code that does stuff is likely in a service, but using the preference allows any portion of your app to access this.

In your widget class that extends AppWidgetProvider the onEnabled is called when the widget is put on a homescreen and the onDeleted is (usually) called when it's removed. onDisabled is called when all copies are removed.

So in the code of your widget provider:

@OverridepublicvoidonEnabled(Context context) {
    super.onEnabled(context);
    setWidgetActive(true);
    context.startService(newIntent(appContext, WidgetUpdateService.class));
}

@OverridepublicvoidonDisabled(Context context) {
    ContextappContext= context.getApplicationContext();
    setWidgetActive(false);
    context.stopService(newIntent(appContext, WidgetUpdateService.class));
    super.onDisabled(context);
}

privatevoidsetWidgetActive(boolean active){
    ContextappContext= context.getApplicationContext();
    SharedPreferencesprefs= PreferenceManager.getDefaultSharedPreferences(appContext);
    SharedPreferences.Editoredit= prefs.edit();
    edit.putBoolean(Constants.WIDGET_ACTIVE, active);
    edit.commit();
}

Elsewhere in code, you would check to see if the widget is active by:

publicbooleanisWidgetActive(Context context){
    ContextappContext= context.getApplicationContext();
    SharedPreferencesprefs= PreferenceManager.getDefaultSharedPreferences(context);
    return prefs.getBoolean(Constants.WIDGET_ACTIVE, false);
}

Solution 3:

I know it's an old question, but looking at this today I saw that there are a couple of problems with the accepted answer from @larsona1:

  1. if the user cleared the shared preferences - there's still widget, but the app won't know about it.
  2. if the user regret between "add widget" and before pressing "ok" - onEnabled will be called anyway, and a widget will be registered in the home screen even though there is no widget, and no way to remove it later. (it may be a bug in ADT home launcher).

I found a solution to the first problem. No shared preferences are needed at all, since it's unreliable anyway. It has to be checked in runtime.

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

In your widget provider:

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

@OverridepublicvoidonDisabled(Context context) {
    super.onDisabled(context);
    S.sWidgetMayExist = true;
}

And, in your service code add this:

AppWidgetManagermanager=null;
RemoteViewsviews=null;
ComponentNamewidgetComponent=null;

    // ..and in your update threadif (!S.sWidgetMayExist) { return; }

if (manager == null || widgetComponent == null) {
    widgetComponent = newComponentName(c,
            MyAppWidgetProvider.class);
    manager = AppWidgetManager.getInstance(c);
}

if (manager.getAppWidgetIds(widgetComponent) == null) {
    S.sWidgetMayExist = false;
}

Solution 4:

@Waza_Be is right as looking at the "AppWidgetIds" list to know the number of active widgets (those installed on your homescreen) is the correct way to know this information.

However, keep in mind that you SHOULD don't have to look at this by yourself.

Check the official Android documentation for best practice about widgets : https://developer.android.com/guide/topics/appwidgets/index.html#AppWidgetProvider

The right approach is to override only the onUpdate() method and iterate through the list of "active" widgets :

publicclassExampleAppWidgetProviderextendsAppWidgetProvider {

    publicvoidonUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        finalintN= appWidgetIds.length;

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

            // Create an Intent to launch ExampleActivityIntentintent=newIntent(context, ExampleActivity.class);
            PendingIntentpendingIntent= PendingIntent.getActivity(context, 0, intent, 0);

            // Get the layout for the App Widget and attach an on-click listener// to the buttonRemoteViewsviews=newRemoteViews(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);
        }
    }
}

And as your own widget provider overrides AppWidgetProvider, you will NOT go into the onUpdate() method if you have no widgets active on the home screen!

See the onReceive() code of Android AppWidgetProvider that checks already for you that "appWidgetIds.length > 0":

publicvoidonReceive(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).Stringaction= intent.getAction();
    if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
        Bundleextras= 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);
            }
        }
    }

(...)
}

Solution 5:

What about the following:

booleanwidgetExists(Context context, int appWidgetId) {
    AppWidgetManagerappWidgetManager= AppWidgetManager.getInstance(context);
    AppWidgetProviderInfoinfo= appWidgetManager.getAppWidgetInfo(appWidgetId);
    return (info != null);
}

From the docs for appWidgetManager.getAppWidgetInfo():

If the appWidgetId has not been bound to a provider yet, or you don't have access to that appWidgetId, null is returned.

Post a Comment for "Check Widget Is Placed On Android Screen"