从活动中更新Android小部件

14

我有一个widget,它的设置是这样的:当我点击它时,会在活动中打开一些设置。

views.setOnClickPendingIntent(R.id.btnActivate, pendingIntent);

这个配置了一些应用程序的设置。我想要实现的是,当我启动的Activity关闭时,小部件更新其视图以反映更改的设置。使用更新间隔或任何其他类型的轮询不适用于此。

我在这里和Android文档中看到过几个地方使用了这段代码:

appWidgetManager.updateAppWidget(mAppWidgetId, views);

但我不知道如何获取mAppWidgetId值。 我尝试按照这里的小部件配置活动示例http://developer.android.com/guide/topics/appwidgets/index.html,但在以下代码中,

    Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
    mAppWidgetId = extras.getInt(
            AppWidgetManager.EXTRA_APPWIDGET_ID, 
            AppWidgetManager.INVALID_APPWIDGET_ID);
}

extras参数始终为空,因此我无法获取AppWidgetID。

好的,现在我只是胡言乱语。你认为我该怎么办?

5个回答

18

我终于找到了我一直在寻找的答案,它在updateAppWidget函数的一个重载中。

   appWidgetManager.updateAppWidget(new ComponentName(this.getPackageName(), Widget.class.getName()), views);
这让我能够访问小部件而不必知道appWidgetID。 我的活动中最终的代码如下:
        // Create an Intent to launch ExampleActivity
    Intent intent = new Intent(this, Settings.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

    views.setOnClickPendingIntent(R.id.btnActivate, pendingIntent);

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
    appWidgetManager.updateAppWidget(new ComponentName(this.getPackageName(), Widget.class.getName()), views);
    finish();

现在我不仅需要在小部件的onUpdate方法中进行所有相同的设置,而且每次退出我的活动时小部件都显示正确状态。


谢谢分享答案!!!我们应该把这段代码放在小部件设置活动中还是小部件类中? - BamsBamx
没关系,我把它放在updateWidget方法里了,将一些“this”改成了“context”,并删除了“AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this)”现在它可以工作了...谢谢! - BamsBamx
1
如果您有多个小部件的配置,您可能想尝试使用appWidgetManager.getAppWidgetIds(component)并对它们进行迭代。 - Reese
@Kratz 我也遇到了同样的问题,但是不知道在我的代码中应该在哪里写这个。http://stackoverflow.com/questions/15523736/app-widget-issue-while-showing-list-of-images?noredirect=1#comment22016477_15523736 - AndroidDev
这真是令人沮丧,它不遵循DRY原则,一定有办法。 - DoruChidean

14

还有另一种方法可以实现 - 在启动活动的待定意图中传递小部件id:

Intent clickIntent=new Intent(context, MyConfigActivity.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
// you have the widgetId here, since it's your onUpdate
PendingIntent pendingIntent=PendingIntent
        .getActivity(context, 0,
                clickIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.btnActivate, pendingIntent);

此外,为了避免从 onUpdate() 中重复编写代码,您可以向 AppWidgetProvider 广播一个意图:

Intent intent = new Intent(this,MyAppWidgetProvider.class);
intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");

// Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
int[] ids = {widgetId};
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
sendBroadcast(intent);

感谢分享代码。现在我可以从活动中更新小部件。 - Amit Thaper

11

我知道这个问题早已有人回答并被接受。然而,在我搜索同样的事情时,我发现了一个非常简单的更新小部件的方法。

对于未来的读者:

最好的部分是,这适用于小部件的所有实例,无论在任何上下文中(Activity、Service 等等)。

以下是代码:

Context context = this;
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_2x1);
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
remoteViews.setTextViewText(R.id.my_text_view, "myText" + System.currentTimeMillis());
appWidgetManager.updateAppWidget(thisWidget, remoteViews);

感谢 - Stuck :)


1
这个!!我已经苦战许久,试图更新一个小部件上的TextView,而这解决了它。谢谢! :) - wislon
非常欢迎。我的荣幸。愉快的编码。 :) - Atul O Holic

1

与其在活动中进行调用,我更喜欢向小部件发送广播请求以进行更新。 onUpdate 方法将被触发并传递所有小部件布局。

以下是我的代码:

1- 从活动发送广播:

Intent intent = new Intent(ctxt, MyAppWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

int[] ids = {R.layout.appwidget};
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
ctxt.sendBroadcast(intent);

现在,2- 实现 onUpdate 方法:
Intent i = new Intent(ctxt, Settings.class);
PendingIntent pi = PendingIntent.getActivity(ctxt, 0, i, 0);

for (int widgetId : allWidgetIds) {
    RemoteViews remoteViews = new RemoteViews(ctxt.getPackageName(), widgetId);
    remoteViews.setTextViewText(R.id.statusMsg, msg);
    remoteViews.setOnClickPendingIntent(R.id.rootView, pi);
    AppWidgetManager mngr = AppWidgetManager.getInstance(ctxt);
    ComponentName wdgt = new ComponentName(ctxt, MyAppWidgetProvider.class);
    mngr.updateAppWidget(wdgt, remoteViews);
}

就是这样!希望能对您有所帮助 :)


0
RemoteViews view = new RemoteViews("pakagename", R.layout.widget_layout_name);
view.setTextViewText(R.id.textView_id, String.valueOf(hr + ":" + mi)); // for setting a textview
view.setCharSequence(R.id.PunchIn, "setText", "Punch In"); //for setting a button name
view.setInt(R.id.PunchIn, "setBackgroundResource", R.color.black); //for setting button color
ComponentName theWidget = new ComponentName(getActivity(), AppWidget_name.class);
AppWidgetManager manager = AppWidgetManager.getInstance(getActivity());
manager.updateAppWidget(theWidget, view);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接