【问题标题】:How can I update an Android widget from Flutter while android:updatePeriodMillis="0"?如何在 android:updatePeriodMillis="0" 时从 Flutter 更新 Android 小部件?
【发布时间】:2021-04-28 15:09:48
【问题描述】:

我是新来的。我正在慢慢掌握 Flutter,但在 Kotlin/Java 集成方面完全是新手。我正在尝试制作一个 Flutter 应用程序,其中一些数据在 Flutter istelf 内不定期更新,然后显示在主屏幕小部件上。

我不想定期更新 Android 小部件,因为每天可能不会有任何更改,只是偶尔更改。在寻找实际制作小部件的方法时,我发现了这个really helpful answer from bnxm 和一个很好的implementation on Github from timobaehr

以这个为例,如果我想在应用程序中的按钮被按下(或后台服务运行)时更新主屏幕小部件上显示的“结果”,而不是在一组间隔? Timobaehr 在他的演示中使用了默认的 Flutter 计数应用程序,那么我可以如何处理按下按钮时运行的这段代码?

这里是main.dart中的更新函数:

void onWidgetUpdate() {
  WidgetsFlutterBinding.ensureInitialized();

  const MethodChannel channel = MethodChannel('com.example.app/widget');

  channel.setMethodCallHandler(
    (call) async {
      final id = call.arguments;

      print('on Dart ${call.method}!');

      return {
        'id': id,
        // Some data of type int - this is what I want to update
        'value': counter,
      };
    },
  );
}

下面是代码中值被更新的地方,基于默认的 Flutter 启动应用程序。我还把 int counter = 0; 移到了 dart 文件的顶部,这样它就可以在任何地方使用。

void _incrementCounter() {
    setState(() {
      
      counter++;
      
    });

// How can I update the home screen widget from here?
// For example, send the new value of 'counter' to 'value' in the update function
// so that the new value is displayed on the home screen widget

  }

是否像在此处添加内容一样简单,还是需要在其他地方更改 Kotlin 代码?感谢您的帮助。

编辑:我应该说,从增量函数调用 onWidgetUpdate() 根本不会改变小部件,所以我认为肯定有其他事情需要发生,可能在后台 Kotlin 代码或使用 MethodChannels,我不熟悉。

如果你想自己运行它来测试,我从timobaehr's Github project 克隆,只是将“值”更改为来自“计数器”并且是一个 int 而不是 double。

【问题讨论】:

    标签: android flutter kotlin android-widget


    【解决方案1】:

    好吧,我想我明白了。把它贴在这里以防它帮助其他人。

    正如我所怀疑的那样,在 Kotlin 中必须进行更改。所以对我来说有点额外的学习!如果您关注timobaehr's project on Github,您可以尝试进行如下更改:

    我写了一个名为“updateFromFlutter”的新方法并将其添加到 MainActivity.kt:

    when (call.method) {
                "initialize" -> {
                    if (call.arguments == null) return
                    WidgetHelper.setHandle(this, call.arguments as Long)
                }
                "updateFromFlutter" -> {
                    val views = RemoteViews(context.packageName, R.layout.widget_layout).apply {
                        setTextViewText(R.id.text, call.argument("text"))
                    }
    
                    val id: Int = call.argument("id")!!
    
                    val manager = AppWidgetManager.getInstance(this)
                    manager.updateAppWidget(id, views)
                }
            }
    

    记得在 MainActivity.kt 的顶部导入这些:

    import android.widget.RemoteViews
    import com.example.flutter_app_android_widget.R
    import android.appwidget.AppWidgetManager
    

    并在更新计数器值后从 main.dart 调用它:

    const MethodChannel platform = MethodChannel('com.example.flutter_app_android_widget/widget');
    platform.invokeMethod("updateFromFlutter", {
        "text": counter.toString(),
        "id": //get the integer from Shared Preferences - up to you how you do this
              //or feel free to suggest a better way of keeping track of the widget id
      });
    

    然后,您应该能够通过按下 Flutter 应用中的按钮按需更新主屏幕小部件。

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 2022-01-16
      • 2020-04-08
      • 2011-05-03
      • 2018-09-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      • 2018-11-01
      相关资源
      最近更新 更多