Validation widget posted on Android screen

Can someone tell me how to check that my widget is placed on the main screen?

I have code in my application that should only run if the widget is placed on the desktop.

+7
source share
4 answers

You need to save this information yourself. I usually use application settings, but you can use anything. Typically, widgets use services for communication, so your code that does things probably works in the service, but using preferences, allows access to any part of your application.

In your widget class, which extends AppWidgetProvider, onEnabled is called when the widget is placed on the main screen, and the onDeleted call (usually) is called when it is removed. onDisabled is called when all copies are deleted.

So, in the code of the provider of your 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(); } 

Elsewhere in the code, you can check if the widget is active:

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

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(); 
+37
source

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

  • if the user cleared the general settings - there is still a widget, but the application will not know about it.
  • if the user regrets “adding a widget” and before clicking “ok”, onEnabled will be called anyway, and the widget will be registered on the main screen, even if there is no widget, and there is no way to delete it later. (this may be a bug in the ADT home launcher).

I found a solution to the first problem. No general preferences are required at all, as this is unreliable anyway. It must be checked at runtime.

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

In your widget provider:

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

And in your service code add the following:

 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; } 
+5
source

@Waza_Be is right when looking at the AppWidgetIds list to see how many active widgets (installed on your desktop) are the right way to find out this information.

However, keep in mind that you SHOULD NOT look at it yourself.

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

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

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

And since your own widget provider overrides AppWidgetProvider, you will not enter the onUpdate () method unless you have active widgets on the main screen!

See the code onReceive () of the Android AppWidgetProvider, which already checks that "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); } } } (...) } 
+1
source

All Articles