如何开发联动Google Sheets的Flutter监控应用,实现无需重启的实时更新?
实现Flutter与Google Sheets的自动更新方案
一、核心逻辑:无需重启的关键
要实现不重启应用就能更新UI,核心是在应用运行时主动/定时获取最新数据,并通过Flutter状态管理刷新界面。由于Google Sheets没有原生实时推送API,常用两种可行方案:
- 定时轮询:周期性调用Sheets API拉取最新数据
- 主动触发:通过Google Apps Script设置触发器,单元格更新时通知Flutter应用(适合低延迟场景)
二、基础准备:配置Google Sheets访问权限
- 在Google Cloud Console创建项目,启用Google Sheets API,生成服务账号密钥(JSON格式)
- 给Flutter项目添加依赖:
dependencies: flutter: sdk: flutter gsheets: ^0.4.0 # 简化Sheets操作的封装库 http: ^1.1.0 - 将目标Google Sheets共享给服务账号邮箱(密钥JSON中的
client_email字段),授予编辑权限
三、方案1:定时轮询实现自动更新(简单易上手)
1. 封装Sheets数据获取方法
创建SheetsService类,负责拉取最新温度数据:
import 'package:gsheets/gsheets.dart'; class SheetsService { static const _credentials = '''你的服务账号JSON内容'''; static const _spreadsheetId = '你的Google Sheets ID'; static const _sheetName = '温度数据页'; static Future<double?> getLatestTemperature() async { final gsheets = GSheets(_credentials); final spreadsheet = await gsheets.spreadsheet(_spreadsheetId); final sheet = spreadsheet.worksheetByTitle(_sheetName); if (sheet == null) return null; // 假设温度存放在最后一行的第2列(根据你的表格结构调整索引) final rows = await sheet.values.allRows(); if (rows.isEmpty) return null; final latestRow = rows.last; return double.tryParse(latestRow[1]); } }
2. 结合定时器与状态管理刷新UI
使用StatefulWidget,通过Timer定时拉取数据并更新状态:
import 'dart:async'; import 'package:flutter/material.dart'; class TemperatureMonitorPage extends StatefulWidget { const TemperatureMonitorPage({super.key}); @override State<TemperatureMonitorPage> createState() => _TemperatureMonitorPageState(); } class _TemperatureMonitorPageState extends State<TemperatureMonitorPage> { double? _currentTemperature; Timer? _pollingTimer; @override void initState() { super.initState(); // 初始化时先拉取一次数据,之后每5秒轮询一次(可根据需求调整间隔) _fetchTemperature(); _pollingTimer = Timer.periodic(const Duration(seconds: 5), (timer) { _fetchTemperature(); }); } Future<void> _fetchTemperature() async { final temp = await SheetsService.getLatestTemperature(); if (mounted) { // 避免页面已销毁时更新状态 setState(() { _currentTemperature = temp; }); } } @override void dispose() { _pollingTimer?.cancel(); // 页面销毁时取消定时器 super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('温度监控')), body: Center( child: _currentTemperature == null ? const CircularProgressIndicator() : Text( '当前温度:${_currentTemperature!.toStringAsFixed(1)}°C', style: const TextStyle(fontSize: 24), ), ), ); } }
该方案会每隔指定时间自动拉取最新数据,UI同步刷新,无需重启应用。
四、方案2:Google Apps Script主动触发(低延迟)
若轮询间隔无法满足实时性需求,可通过Apps Script设置单元格编辑触发器,数据更新时主动通知Flutter应用(需后端中转)。
1. 在Google Sheets中添加触发脚本
打开目标Sheets,点击「扩展程序」→「Apps脚本」,粘贴以下代码:
function onEdit(e) { // 仅监听温度列的编辑(假设温度在B列,可调整列数) if (e.range.getColumn() == 2) { const latestTemp = e.value; // 调用后端API,通知Flutter应用更新 UrlFetchApp.fetch('https://你的后端地址/api/update-temperature', { method: 'post', contentType: 'application/json', payload: JSON.stringify({ temperature: latestTemp }) }); } }
保存并部署脚本,设置onEdit为简单触发器。
2. Flutter端接收实时更新
使用WebSocket连接后端,接收更新通知:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:web_socket_channel/io.dart'; class TemperatureMonitorPage extends StatefulWidget { const TemperatureMonitorPage({super.key}); @override State<TemperatureMonitorPage> createState() => _TemperatureMonitorPageState(); } class _TemperatureMonitorPageState extends State<TemperatureMonitorPage> { double? _currentTemperature; late IOWebSocketChannel _channel; @override void initState() { super.initState(); // 连接后端WebSocket服务 _channel = IOWebSocketChannel.connect('wss://你的后端地址/ws'); // 监听后端推送的更新消息 _channel.stream.listen((message) { final data = jsonDecode(message); setState(() { _currentTemperature = double.tryParse(data['temperature']); }); }); } @override void dispose() { _channel.sink.close(); // 页面销毁时关闭连接 super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('温度监控')), body: Center( child: _currentTemperature == null ? const CircularProgressIndicator() : Text( '当前温度:${_currentTemperature!.toStringAsFixed(1)}°C', style: const TextStyle(fontSize: 24), ), ), ); } }
这种方式能在单元格编辑后几乎实时更新Flutter应用的UI。
五、注意事项
- 服务账号密钥不要硬编码,发布时建议用环境变量或安全存储方案处理
- 轮询间隔不宜过短,避免触发Google API调用限制
- 使用Apps Script时,注意UrlFetchApp的调用配额,确保后端服务稳定
内容的提问来源于stack exchange,提问作者erratical
相关产品推荐
相关产品推荐

