Flutter应用集成原生Google Calendar组件需求咨询
直接在Flutter中集成原生Google Calendar实现日程展示与管理
要直接对接原生Google Calendar并实现日/周/月视图展示、日程增删,核心是通过Google Calendar API结合Flutter的授权工具完成,以下是具体实现步骤:
1. 配置Google Cloud项目与API
- 登录Google Cloud Console,创建新项目并启用Google Calendar API
- 创建OAuth 2.0客户端ID:分别配置Android(包名、SHA-1签名哈希)和iOS(Bundle ID)平台信息
- 下载配置文件:Android的
google-services.json放到android/app/目录,iOS的GoogleService-Info.plist放到ios/Runner/目录
2. 实现用户OAuth授权
使用google_sign_in插件完成授权,获取访问令牌用于后续API请求:
import 'package:google_sign_in/google_sign_in.dart'; final GoogleSignIn _googleSignIn = GoogleSignIn( scopes: [ 'https://www.googleapis.com/auth/calendar', // 读写日历权限 ], ); Future<void> signInToGoogleCalendar() async { try { await _googleSignIn.signIn(); // 授权成功后可获取令牌用于API请求 } catch (err) { print('授权失败: $err'); } }
3. 调用Google Calendar API实现核心功能
获取指定时段的日程
根据日/周/月的时间范围,调用events.list接口拉取事件:
import 'package:http/http.dart' as http; import 'dart:convert'; Future<List<dynamic>> fetchCalendarEvents(DateTime timeMin, DateTime timeMax) async { final currentUser = _googleSignIn.currentUser; if (currentUser == null) return []; final authHeaders = await currentUser.authHeaders; final accessToken = authHeaders['Authorization']?.split(' ')[1]; final response = await http.get( Uri.parse( 'https://www.googleapis.com/calendar/v3/calendars/primary/events' '?timeMin=${timeMin.toIso8601String()}' '&timeMax=${timeMax.toIso8601String()}' '&singleEvents=true' '&orderBy=startTime', ), headers: {'Authorization': 'Bearer $accessToken'}, ); if (response.statusCode == 200) { return json.decode(response.body)['items']; } else { throw Exception('拉取日程失败: ${response.statusCode}'); } }
新增日程
调用events.insert接口创建新事件:
Future<void> addNewCalendarEvent(String title, DateTime start, DateTime end) async { final currentUser = _googleSignIn.currentUser; if (currentUser == null) return; final accessToken = (await currentUser.authHeaders)['Authorization']?.split(' ')[1]; final eventData = { 'summary': title, 'start': {'dateTime': start.toIso8601String(), 'timeZone': 'Asia/Shanghai'}, 'end': {'dateTime': end.toIso8601String(), 'timeZone': 'Asia/Shanghai'}, }; await http.post( Uri.parse('https://www.googleapis.com/calendar/v3/calendars/primary/events'), headers: { 'Authorization': 'Bearer $accessToken', 'Content-Type': 'application/json', }, body: json.encode(eventData), ); }
删除日程
调用events.delete接口删除指定事件:
Future<void> deleteCalendarEvent(String eventId) async { final currentUser = _googleSignIn.currentUser; if (currentUser == null) return; final accessToken = (await currentUser.authHeaders)['Authorization']?.split(' ')[1]; await http.delete( Uri.parse('https://www.googleapis.com/calendar/v3/calendars/primary/events/$eventId'), headers: {'Authorization': 'Bearer $accessToken'}, ); }
4. 自定义日/周/月视图UI
由于现有插件不符合需求,需自行封装UI组件:
- 日视图:用
ListView按小时划分时间段,每个时间段填充对应事件卡片,可通过DateTime判断事件是否落在当前小时区间 - 周视图:横向排列7个日期列,每列内部按小时展示事件,可使用
Row包裹7个Column实现 - 月视图:用
GridView.builder生成日期格子,每个格子显示日期数字,若当天有事件则添加标记(比如小红点),点击格子可跳转至日视图查看详情 - 可借助
intl包处理日期格式化,简化时间范围计算
关键注意事项
- 时区处理:API请求中必须指定正确的时区(如
Asia/Shanghai),避免时间显示偏差 - 令牌刷新:
google_sign_in会自动处理令牌过期刷新,无需手动操作 - 错误捕获:API请求需处理网络异常、权限不足、令牌失效等情况,给用户友好提示
- 平台配置:Android需在
AndroidManifest.xml添加<uses-permission android:name="android.permission.INTERNET"/>;iOS需在Info.plist配置Google授权相关的URL Scheme
内容的提问来源于stack exchange,提问作者Shiwang
相关产品推荐
相关产品推荐

