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

如何开发联动Google Sheets的Flutter监控应用,实现无需重启的实时更新?

实现Flutter与Google Sheets的自动更新方案

一、核心逻辑:无需重启的关键

要实现不重启应用就能更新UI,核心是在应用运行时主动/定时获取最新数据,并通过Flutter状态管理刷新界面。由于Google Sheets没有原生实时推送API,常用两种可行方案:

  • 定时轮询:周期性调用Sheets API拉取最新数据
  • 主动触发:通过Google Apps Script设置触发器,单元格更新时通知Flutter应用(适合低延迟场景)

二、基础准备:配置Google Sheets访问权限

  1. 在Google Cloud Console创建项目,启用Google Sheets API,生成服务账号密钥(JSON格式)
  2. 给Flutter项目添加依赖:
    dependencies:
      flutter:
        sdk: flutter
      gsheets: ^0.4.0 # 简化Sheets操作的封装库
      http: ^1.1.0
    
  3. 将目标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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 08:54:25