Check if a widget is exists on homescreen using appWidgetId

血红的双手。 提交于 2019-11-29 14:35:22

问题


I am using AlarmManager to update my widgets. And I want to stop it if there is no widget on homescreen. But I am facing a problem with detecting if there is no widget on home screen.

As whenever I try to get the AppWidgetIds using this way:

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

int[] appWidgetIDs = appWidgetManager
    .getAppWidgetIds(new ComponentName(context, Widget.class));

I get the a length of appWidgetIDs while actually there is no widget on homescreen. Why?

Therefore, I would like to know if there is a way to detect that a widget id is exists on homescreen.

Thank you upfront.


回答1:


Congratulations, you've encountered phantom appwidgets. It appears to be documented on the Android issue tracker. They usually occur when the configuration activity for an appwidget is canceled, though it seems to be through improper implementation of the configuration activity; developers neglect to include the appwidget ID as an extra when setting the activity result to RESULT_CANCELED. (even Google's ApiDemos sample application neglects to do this!)

The proper implementation is like this:

public class AppWidgetConfigActivity extends Activity {

    private int appWidgetId;
    private Intent resultValue;

    protected void onCreate(bundle saved) {
        super.onCreate(saved);

        // get the appwidget id from the intent
        Intent intent = getIntent();
        appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);

        // make the result intent and set the result to canceled
        resultValue = new Intent();
        resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        setResult(RESULT_CANCELED, resultValue);

        // if we weren't started properly, finish here
        if (appwidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
            finish();
        }

        /* ... */
    }

    /* ... */

    private void finishConfigure() {
        /* finish configuring appwidget ... */
        setResult(RESULT_OK, resultValue);
    }
}

Thus far I know of no way to detect the presence of a phantom appwidget without doing your own bookkeeping. I suggest storing a SharedPreferences value indicating that the configuration activity was not canceled and then querying this value in your other code. You can also use this information to "delete" a phantom widget if you come across one. In your appwidget configuration activity:

private void finishConfigure() {
    /* finish configuring appwidget ... */
    setResult(RESULT_OK, resultValue);

    String key = String.format("appwidget%d_configured", appwidgetId);
    SharedPreferences prefs = getSharedPreferences("widget_prefs", 0);
    prefs.edit().putBoolean(key, true).commit;
}

Then you can check that you have at least one non-phantom appwidget like so:

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
AppWidgetHost appWidgetHost = new AppWidgetHost(context, 1); // for removing phantoms
SharedPreferences prefs = getSharedPreferences("widget_prefs", 0);
boolean hasWidget = false;

int[] appWidgetIDs = appWidgetManager.getAppWidgetIds(new ComponentName(context, Widget.class));
for (int i = 0; i < appWidgetIDs.length; i++) {
    int id = appWidgetIDs[i];
    String key = String.format("appwidget%d_configured", id);
    if (prefs.getBoolean(key, false)) {
        hasWidget = true;
    } else {
        // delete the phantom appwidget
        appWidgetHost.deleteAppWidgetId(id);
    }
}

if (hasWidget) {
    // proceed
} else {
    // turn off alarms
}


来源:https://stackoverflow.com/questions/17387191/check-if-a-widget-is-exists-on-homescreen-using-appwidgetid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!