admin管理员组文章数量:1583363
Google登录及获取Calendar信息
firebase方案(实际是一个三方登录集成,由于是google的所以使用Google账户登录以后可以使用google api)
firebase官网
使用firebase Auth集成并登录
firebase创建项目后会在google cloud中创建并关联项目,登录成功后接着就可以按照下述方法使用google api获取相应信息。
flutter中用到的插件:
firebase_auth
firebase_core
参考firebase flutter网站
在google开发者平台构建项目(单独集成)
进入Google Cloud登录并注册,之后按照提示构建项目。
进入Apis&Services->Credentials下点击CREATE CREDENTIALS
创建OAuth 2.0 Client IDs。(ios和android需分别创建)。
创建过程中根据提示android需要配置sha-1签名证书,ios需要配置url scheme。
android需要配置签名:
Android 怎么创建签名文件和解析签名文件
将生成好的签名文件放到工程app文件夹下,与app的build.gradle平行,之后再app的build.gradle中做如下配置:
...
android{
...
buildTypes {
release {
signingConfig signingConfigs.debug
}
debug {
signingConfig signingConfigs.debug
}
}
signingConfigs {
debug {
storeFile file("nearhubone.keystore")//签名文件名
storePassword "123456"//密码
keyAlias "nearhubone"//别名
keyPassword "123456"//密码
}
release {
storeFile file("nearhubone.keystore")
storePassword "123456"
keyAlias "nearhubone"
keyPassword "123456"
}
}
...
}
申请需要使用的api
点击Google Cloud-APIs&Services下的Enabled APIs&services,enable需要使用的api,如Google Calendar API。需要创建api key的则创建api key(非所有api都需要创建api key)。
集成到对于项目
Flutter中集成
需要使用的插件有:
google_sign_in//用于登录
extension_google_sign_in_as_googleapis_auth//配合拓展google_sign_in用于提供api初始化需要的Client
googleapis//提供丰富的google api
Flutter使用 Google API
Flutter使用 Google API 英文
流程如下:
使用google_sign_in插件实现登录
- serverClientId参数填写OAuth 2.0 Client IDs里相对应的ClientId。
- 注意初始化配置中的scopes,这个scopes用于用户授权范围,只有填入的scopes才会显示在用户授权页上并得到授权,否则api将会调用失败。这个scopes的字段在api文档里可得。如CalendarList get这个api在其文档里的Authorization就可看到scope列表。
登录的示例代码如下:
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';//登录所需插件
import 'package:http/http.dart' as http;
import 'dart:convert' show json;
//配置google登录
GoogleSignIn _googleSignIn = GoogleSignIn(
// Optional clientId
serverClientId: '781114075503-2qscj6a0ahsqedt6cellol0ur7qij645.apps.googleusercontent',
//授权范围(用户授权页会提示用户授权)
scopes: <String>[
'email',
'https://www.googleapis/auth/contacts.readonly',
'https://www.googleapis/auth/calendar',//获取日历信息授权
],
);
class SignInDemo extends StatefulWidget {
const SignInDemo({Key? key}) : super(key: key);
@override
State createState() => SignInDemoState();
}
class SignInDemoState extends State<SignInDemo> {
GoogleSignInAccount? _currentUser;
String _contactText = '';
@override
void initState() {
super.initState();
//注册登录回调
_googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
setState(() {
_currentUser = account;
});
if (_currentUser != null) {
_handleGetContact(_currentUser!);
}
});
_googleSignIn.signInSilently();
}
//【非登录必须流程】登录后获取用户个人信息用于显示
Future<void> _handleGetContact(GoogleSignInAccount user) async {
setState(() {
_contactText = 'Loading contact info...';
});
//通过http请求获取用户个人信息
final http.Response response = await http.get(
Uri.parse('https://people.googleapis/v1/people/me/connections'
'?requestMask.includeField=person.names'),
headers: await user.authHeaders,//请求头置入登录成功信息
);
if (response.statusCode != 200) {
setState(() {
_contactText = 'People API gave a ${response.statusCode} '
'response. Check logs for details.';
});
print('People API ${response.statusCode} response: ${response.body}');
return;
}
//解析用户信息
final Map<String, dynamic> data =
json.decode(response.body) as Map<String, dynamic>;
final String? namedContact = _pickFirstNamedContact(data);
setState(() {
if (namedContact != null) {
_contactText = 'I see you know $namedContact!';
} else {
_contactText = 'No contacts to display.';
}
});
}
String? _pickFirstNamedContact(Map<String, dynamic> data) {
final List<dynamic>? connections = data['connections'] as List<dynamic>?;
final Map<String, dynamic>? contact = connections?.firstWhere(
(dynamic contact) => contact['names'] != null,
orElse: () => null,
) as Map<String, dynamic>?;
if (contact != null) {
final Map<String, dynamic>? name = contact['names'].firstWhere(
(dynamic name) => name['displayName'] != null,
orElse: () => null,
) as Map<String, dynamic>?;
if (name != null) {
return name['displayName'] as String?;
}
}
return null;
}
//登录
Future<void> _handleSignIn() async {
try {
await _googleSignIn.signIn();
} catch (error) {
print(error);
}
}
//登出
Future<void> _handleSignOut() => _googleSignIn.disconnect();
//界面展示
Widget _buildBody() {
final GoogleSignInAccount? user = _currentUser;
if (user != null) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
ListTile(
leading: GoogleUserCircleAvatar(
identity: user,
),
title: Text(user.displayName ?? ''),
subtitle: Text(user.email),
),
const Text('Signed in successfully.'),
Text(_contactText),
ElevatedButton(
onPressed: _handleSignOut,
child: const Text('SIGN OUT'),
),
ElevatedButton(
child: const Text('REFRESH'),
onPressed: () => _handleGetContact(user),
),
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Text('You are not currently signed in.'),
ElevatedButton(
onPressed: _handleSignIn,
child: const Text('SIGN IN'),
),
],
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Google Sign In'),
),
body: ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: _buildBody(),
));
}
}
参考:
官方示例
获取日历信息
获取日历信息可使用两种方式:
- 一种方式直接使用http请求,无需其他插件,只需在请求头中添加登录信息
api查看官方文档
import 'package:google_sign_in/google_sign_in.dart';
...
class SignInDemo extends State<SignInDemo> {
...
GoogleSignInAccount? _currentUser;
@override
void initState() {
super.initState();
//注册登录回调
_googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
setState(() {
_currentUser = account;
});
...
});
}
...
onGetCalendarClick(){
handleGetCalendar(_currentUser);
}
...
//获取谷歌日历列表信息(http方式)
handleGetCalendar(GoogleSignInAccount user) async {
final http.Response response = await http.get(
Uri.parse('https://www.googleapis/calendar/v3/calendars/primary/events'),//api查看官方文档
headers: await user.authHeaders,//在请求头中添加登录信息
);
if (response.statusCode != 200) {
print('Calendar API ${response.statusCode} response: ${response.body}');
} else {
final Map<String, dynamic> data =
json.decode(response.body) as Map<String, dynamic>;
debugPrint(data.toString());
}
}
}
- 【推荐】另一种方式使用
googleapis
插件配合google登录拓展插件extension_google_sign_in_as_googleapis_auth
使用
由于googleapis初始化对应api时需要提供client,extension_google_sign_in_as_googleapis_auth
插件可以配合google_sign_in
提供client。
代码如下:
import 'package:google_sign_in/google_sign_in.dart';
import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart';
import 'package:googleapis/calendar/v3.dart';
//获取谷歌日历列表信息(sdk方式)
getCalendarEvent() async {
var httpClient = (await _googleSignIn.authenticatedClient())!;
var calendar = CalendarApi(httpClient);
var calEvents = calendar.events.list("primary");
calEvents.then((events) => {
events.items?.forEach((event) => print("EVENT ${event.summary}"))
});
}
参考:
如何在flutter中使用google日历api获取一个月内的所有活动 (仅参考使用googleapis-CalendarApi部分)
获取身份验证后的 HTTP 客户端
完整代码参考:
google_sign_in_get_calendar_demo.dart
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart';
import 'package:googleapis/calendar/v3.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' show json;
//配置google登录
GoogleSignIn _googleSignIn = GoogleSignIn(
// Optional clientId
serverClientId: '781114075503-2qscj6a0ahsqedt6cellol0ur7qij645.apps.googleusercontent',
//授权范围(用户授权页会提示用户授权)
scopes: <String>[
'email',
'https://www.googleapis/auth/contacts.readonly',
'https://www.googleapis/auth/calendar',
],
);
class SignInDemo extends StatefulWidget {
const SignInDemo({Key? key}) : super(key: key);
@override
State createState() => SignInDemoState();
}
class SignInDemoState extends State<SignInDemo> {
GoogleSignInAccount? _currentUser;
String _contactText = '';
@override
void initState() {
super.initState();
//注册登录回调
_googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
setState(() {
_currentUser = account;
});
if (_currentUser != null) {
_handleGetContact(_currentUser!);
}
});
_googleSignIn.signInSilently();
}
//【非登录必须流程】登录后获取用户个人信息用于显示
Future<void> _handleGetContact(GoogleSignInAccount user) async {
setState(() {
_contactText = 'Loading contact info...';
});
//通过http请求获取用户个人信息
final http.Response response = await http.get(
Uri.parse('https://people.googleapis/v1/people/me/connections'
'?requestMask.includeField=person.names'),
headers: await user.authHeaders,//请求头置入登录成功信息
);
if (response.statusCode != 200) {
setState(() {
_contactText = 'People API gave a ${response.statusCode} '
'response. Check logs for details.';
});
print('People API ${response.statusCode} response: ${response.body}');
return;
}
//解析用户信息
final Map<String, dynamic> data =
json.decode(response.body) as Map<String, dynamic>;
final String? namedContact = _pickFirstNamedContact(data);
setState(() {
if (namedContact != null) {
_contactText = 'I see you know $namedContact!';
} else {
_contactText = 'No contacts to display.';
}
});
}
String? _pickFirstNamedContact(Map<String, dynamic> data) {
final List<dynamic>? connections = data['connections'] as List<dynamic>?;
final Map<String, dynamic>? contact = connections?.firstWhere(
(dynamic contact) => contact['names'] != null,
orElse: () => null,
) as Map<String, dynamic>?;
if (contact != null) {
final Map<String, dynamic>? name = contact['names'].firstWhere(
(dynamic name) => name['displayName'] != null,
orElse: () => null,
) as Map<String, dynamic>?;
if (name != null) {
return name['displayName'] as String?;
}
}
return null;
}
//登录
Future<void> _handleSignIn() async {
try {
await _googleSignIn.signIn();
} catch (error) {
print(error);
}
}
//登出
Future<void> _handleSignOut() => _googleSignIn.disconnect();
//获取谷歌日历列表信息(sdk方式)
getCalendarEvent() async {
var httpClient = (await _googleSignIn.authenticatedClient())!;
var calendar = CalendarApi(httpClient);
var calEvents = calendar.events.list("primary");
calEvents.then((events) => {
events.items?.forEach((event) => print("EVENT ${event.summary}"))
});
}
//获取谷歌日历列表信息(http方式)
handleGetCalendar(GoogleSignInAccount user) async {
final http.Response response = await http.get(
Uri.parse('https://www.googleapis/calendar/v3/users/me/calendarList/primary'),//api查看官方文档
headers: await user.authHeaders,//在请求头中添加登录信息
);
if (response.statusCode != 200) {
print('Calendar API ${response.statusCode} response: ${response.body}');
} else {
}
}
//界面展示
Widget _buildBody() {
final GoogleSignInAccount? user = _currentUser;
if (user != null) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
ListTile(
leading: GoogleUserCircleAvatar(
identity: user,
),
title: Text(user.displayName ?? ''),
subtitle: Text(user.email),
),
const Text('Signed in successfully.'),
Text(_contactText),
ElevatedButton(
onPressed: ()=>handleGetCalendar(user),
child: const Text('getCalendarEvent http'),
),
ElevatedButton(
onPressed: getCalendarEvent,
child: const Text('getCalendarEvent'),
),
ElevatedButton(
onPressed: _handleSignOut,
child: const Text('SIGN OUT'),
),
ElevatedButton(
child: const Text('REFRESH'),
onPressed: () => _handleGetContact(user),
),
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Text('You are not currently signed in.'),
ElevatedButton(
onPressed: _handleSignIn,
child: const Text('SIGN IN'),
),
],
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Google Sign In'),
),
body: ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: _buildBody(),
));
}
}
pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_signin_button: ^2.0.0
google_sign_in: ^5.1.0
extension_google_sign_in_as_googleapis_auth: ^2.0.7
googleapis: ^9.2.0
googleapis_auth: ^1.3.1
url_launcher: ^6.1.5
dev_dependencies:
flutter_test:
sdk: flutter
drive: 1.0.0-1.0.nullsafety.1
flutter_driver:
sdk: flutter
http: ^0.13.3
flutter_lints: ^2.0.0
其他参考
Flutter: Use Google Calendar API — Adding the events to Calendar
将dart和flutter与Google Calendar API结合使用以获取用户日历上的事件列表
版权声明:本文标题:Google登录及获取Calendar信息 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1725993558a1051773.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论