You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Flutter代码向Android原生代码发送数据更新Android Widget

实现Flutter向Android Widget定时传数据并更新的方案

1. 搭建Flutter与Android的通信通道

在Flutter侧通过MethodChannel建立和原生的通信,用于主动发送数据:

import 'package:flutter/services.dart';

final MethodChannel _widgetUpdateChannel = MethodChannel('com.yourpackage/widget_updater');

// 封装发送数据到原生的方法
Future<void> sendWidgetData(Map<String, dynamic> data) async {
  try {
    await _widgetUpdateChannel.invokeMethod('update_widget', data);
  } on PlatformException catch (e) {
    print('数据发送失败: ${e.message}');
  }
}

在Android的MainActivity中注册该通道,接收Flutter传来的数据并触发Widget更新:

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.yourpackage/widget_updater"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "update_widget") {
                // 解析Flutter传来的数据
                val widgetData = call.arguments as HashMap<String, Any>
                // 执行Widget更新逻辑
                updateAppWidget(widgetData)
                result.success(null)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun updateAppWidget(data: HashMap<String, Any>) {
        val appWidgetManager = AppWidgetManager.getInstance(this)
        val componentName = ComponentName(this, YourWidgetProvider::class.java)
        val widgetIds = appWidgetManager.getAppWidgetIds(componentName)

        // 将数据存入SharedPreferences,供Widget Provider读取
        val prefs = getSharedPreferences("WidgetDataStore", Context.MODE_PRIVATE)
        with(prefs.edit()) {
            data.forEach { (key, value) ->
                when (value) {
                    is String -> putString(key, value)
                    is Int -> putInt(key, value)
                    is Float -> putFloat(key, value)
                    // 根据业务需求扩展数据类型
                }
            }
            apply()
        }

        // 触发Widget刷新
        YourWidgetProvider.refreshWidgets(this, appWidgetManager, widgetIds)
    }
}

2. 实现Android AppWidgetProvider

创建Widget Provider类,负责读取存储的数据并更新Widget UI:

class YourWidgetProvider : AppWidgetProvider() {
    companion object {
        fun refreshWidgets(context: Context, manager: AppWidgetManager, widgetIds: IntArray) {
            widgetIds.forEach { id ->
                val views = RemoteViews(context.packageName, R.layout.your_widget_layout)
                
                // 从SharedPreferences读取数据
                val prefs = context.getSharedPreferences("WidgetDataStore", Context.MODE_PRIVATE)
                val displayContent = prefs.getString("content", "默认内容")
                views.setTextViewText(R.id.widget_content_tv, displayContent)
                
                // 执行更新
                manager.updateAppWidget(id, views)
            }
        }
    }

    override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
        refreshWidgets(context, appWidgetManager, appWidgetIds)
    }
}

同时在AndroidManifest.xml中注册Widget:

<receiver android:name=".YourWidgetProvider">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/widget_info" />
</receiver>

3. Flutter侧定时触发数据发送

使用dart:async的Timer.periodic实现每30分钟主动发送数据:

import 'dart:async';

Timer? _widgetUpdateTimer;

void startWidgetUpdateTask() {
    // 立即发送一次初始数据
    sendWidgetData({"content": "更新时间: ${DateTime.now().toLocal()}"});
    // 每30分钟触发一次
    _widgetUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) {
        sendWidgetData({"content": "更新时间: ${DateTime.now().toLocal()}"});
    });
}

// 在页面销毁时取消定时器
@override
void dispose() {
    _widgetUpdateTimer?.cancel();
    super.dispose();
}

关键注意事项

  • 若Flutter应用处于后台,系统可能暂停定时器,此时可结合Android的WorkManager实现更可靠的定时逻辑,让原生主动请求Flutter数据。
  • 数据传递时需严格匹配类型,避免序列化异常。
  • 确保Widget布局文件your_widget_layout.xml中存在对应ID的控件(如示例中的R.id.widget_content_tv)。

内容的提问来源于stack exchange,提问作者thinkcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:54:25