【问题标题】:Programmatically update widget from activity/service/receiver以编程方式从活动/服务/接收器更新小部件
【发布时间】:2011-03-28 04:12:15
【问题描述】:

我知道这是可能的,但我想不出一种方法来从主要活动中触发我的小部件更新。我不能广播一些一般意图吗?

【问题讨论】:

    标签: android android-activity android-widget


    【解决方案1】:

    如果你正在使用AppWidgetProvider,你可以这样更新它:

    Intent intent = new Intent(this, MyAppWidgetProvider.class);
    intent.setAction(AppWidgetManager.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 = AppWidgetManager.getInstance(getApplication())
        .getAppWidgetI‌​ds(new ComponentName(getApplication(), MyAppWidgetProvider.class));
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
    sendBroadcast(intent);
    

    【讨论】:

    • 你在哪里设置widgetId
    • @KrisB 从下面的答案中获取数组: int ids[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), WidgetProvider.class)) ;
    • 可以使用常量,无需硬编码:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    • 不要跟随@gelupa 评论使用R.xml.mywidget 作为widgetID!这是完全错误的,只花了我 4 小时的调试时间!!!使用 MobileMon 解决方案获取正确的 widgetID
    • 对于 ids:` int widgetIDs[] = AppWidgetManager.getInstance(activity).getAppWidgetIds(new ComponentName(activity, widget.class));`
    【解决方案2】:

    这有助于我搜索如何从服务/或操作更新小部件(但可能从每个上下文中都可以):

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

    【讨论】:

    • 我知道我迟到了 6 个月。但我同意安德鲁的观点。我在这个线程中尝试了原始方法。还有一些关于如何抓取 ID 的事情导致它开始失败。这种方法(直接手动更新字段)效果更好。至少对我而言。
    • 很棒的东西。不知道你是怎么结束的,但对于我的 Widget 的所有实例都可以正常工作。 :)
    • 这对我也有用。我认为我们需要进行广播和 onReceive,但我的要求完全符合此
    【解决方案3】:

    所以要从一个活动中更新一个小部件,你可以这样做:

    Intent intent = new Intent(this, DppWidget.class);
    intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
    int ids[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), DppWidget.class));
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
    sendBroadcast(intent);
    

    为我工作:)

    【讨论】:

    • 它调用 onRecieve 覆盖方法。但我想如何调用 onUpdate 方法。
    【解决方案4】:

    试试这个:

    int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), MyWidget.class));
            MyWidget myWidget = new MyWidget();
            myWidget.onUpdate(this, AppWidgetManager.getInstance(this),ids);
    

    【讨论】:

    • 令人惊讶的是,只有这个小答案解决了它。我仍然不知道实例化 Widget 类并直接调用 onUpdate 方法的含义,但是,它终于可以工作了 :)
    • 谢谢。我现在正在对其进行测试,并将发布反馈。测试并确认工作。我想知道,如果有不同类型的小部件,它的工作方式是否相同? (顺便说一下工作+1)
    • 我总是得到 ids 0
    • 这不适用于 Android Oreo 任何解决方法修复?
    【解决方案5】:

    如果您使用的小部件使用 ListView、GridView 或 StackView 等集合来更新小部件的项目,请执行以下操作:

    Context context = getApplicationContext();
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName thisWidget = new ComponentName(context, StackWidgetProvider.class);
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
    appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.stack_view);
    

    使用 notifyAppWidgetViewDataChanged() 方法,您可以强制小部件项实时获取任何新数据。

    【讨论】:

      【解决方案6】:
      int widgetIDs[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), WidgetProvider.class));
      
      for (int id : widgetIDs)
          AppWidgetManager.getInstance(getApplication()).notifyAppWidgetViewDataChanged(id, R.id.widget_view);
      }
      

      【讨论】:

      • 需要 min-api 级别:11。
      • 太棒了。您甚至不必循环,notifyAppWidgetViewDataChanged() 的版本需要一个数组。
      【解决方案7】:

      Phaethon 在 Kotlin 中被接受的解决方案:

      val intent = Intent(this, MyAppWidgetProvider::class.java)
      intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
      val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(ComponentName(getApplicationContext(),MyAppWidgetProvider::class.java!!))
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
      sendBroadcast(intent)
      

      其中 MyAppWidgetProvider 是从 AppWidgetProvider 派生的:

      MyAppWidgetProvider : AppWidgetProvider() {
      

      【讨论】:

        【解决方案8】:

        如果您尝试以编程方式更新您无法显式访问 YourWidgetProvider.class 的小部件,例如从另一个模块或库中,您可以捕获 YourWidgetProvider.class.getName() 输出的内容并创建一个常量:

        val WIDGET_CLASS_NAME = "com.example.yourapplication.YourWidgetProvider"
        

        然后您就可以隐式使用它了:

        val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
        val widgetManager = AppWidgetManager.getInstance(context)
        val ids = widgetManager.getAppWidgetIds(ComponentName(context, WIDGET_CLASS_NAME))
        AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(ids, android.R.id.list)
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
        context.sendBroadcast(intent)
        

        【讨论】:

          【解决方案9】:

          作为参考,我不得不在片段中这样做:

          Application app = getActivity().getApplication();
          Intent intent = new Intent(context, RQWidget.class);
          intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
          
          int[] ids = AppWidgetManager.getInstance(app).getAppWidgetIds(new ComponentName(app, RQWidget.class));
          intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
          context.sendBroadcast(intent);
          

          【讨论】:

            【解决方案10】:

            我的待办事项列表中的示例:

            Intent intent = new Intent(this, TodosAppWidget.class);
            intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), TodosAppWidget.class));
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
            sendBroadcast(intent);
            
            sendBrodcast(Intent(this, TodosAppWidget::class.java).apply {
              action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
              val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(ComponentName(application, TodosAppWidget::class.java))
              putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
            })
            

            【讨论】:

              猜你喜欢
              • 2012-09-27
              • 1970-01-01
              • 2017-01-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-04-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多