Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 271
Jeff Avatar asked Jan 12 '12 14:01

Jeff


3 Answers

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();
like image 113
Waza_Be Avatar answered Nov 14 '22 04:11

Waza_Be


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:

@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 code, you would check to see if the widget is active by:

public boolean isWidgetActive(Context context){
    Context appContext = context.getApplicationContext();
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    return prefs.getBoolean(Constants.WIDGET_ACTIVE, false);
}
like image 10
larsona1 Avatar answered Nov 14 '22 03:11

larsona1


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.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 this:

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;
}
like image 7
Amir Uval Avatar answered Nov 14 '22 04:11

Amir Uval