Flutter Kakao Login插件的集成与使用

Flutter Kakao Login插件的集成与使用

要求

Android

Android SDK를 사용하기 위한 최소 요구사양은 다음과 같습니다:

  • API 21: Android 5.0(Lollipop) 이상

iOS

iOS SDK를 사용하기 위한 최소 요구사양은 아래와 같습니다:

  • iOS 11.0 이상
  • iOS Deployment Target 11.0 이상

Getting Started

此项目是一个用于Flutter的插件包起点, 这是一个专门包含Android和/或iOS平台特定实现代码的插件包。 有关如何开始使用Flutter的教程、示例、移动开发指南以及完整的API参考,请访问 Flutter官方文档

该插件项目是在未指定--platforms标志的情况下生成的,目前不支持任何平台。要添加平台,请在相同目录下运行以下命令:

flutter create -t plugin --platforms <platforms> .

您还可以在 pubspec.yaml 中找到如何添加平台的详细说明,地址为 Flutter官方文档


集成与使用示例

以下是使用 kakao_login 插件进行集成和使用的完整示例代码:

示例代码

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:kakao_login/kakao_login.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  static final KakaoLogin kakaoSignIn = KakaoLogin.instance;

  String _loginMessage = '当前未登录 :(';
  String _accessToken = '';
  String _refreshToken = '';
  String _accountInfo = '';
  bool _isLogined = false;

  List<Map<String, String>> _litems = [
    {"key": "login", "title": "登录", "subtitle": ""},
    {"key": "logout", "title": "登出", "subtitle": ""},
    {"key": "unlink", "title": "解绑", "subtitle": ""},
    {"key": "account", "title": "获取账户信息", "subtitle": ""},
    {"key": "accessToken", "title": "获取访问令牌", "subtitle": ""},
    {"key": "refreshToken", "title": "获取刷新令牌", "subtitle": ""}
  ];

  [@override](/user/override)
  void initState() {
    super.initState();
    load();
  }

  load() async {
    // 初始化插件,设置您的应用密钥
    await kakaoSignIn.init("04dabb63618fa8e2018e4a0f622336b3");
    print('初始化完成');
    // 对于Android,打印签名哈希值
    final String? hashKey = await (kakaoSignIn.hashKey);
    print("签名哈希值: $hashKey");
  }

  Future<void> _login() async {
    try {
      final login = await kakaoSignIn.logIn();
      final result = await kakaoSignIn.currentUser;
      result.when(
        () {},
        success: (value) {},
        fail: (error) {
          _updateLoginMessage("${error.cause} ${error.message}");
        },
      );
      if (result.isValue) {
        _processLoginResult("loggedIn");
      } else {
        // 登录失败处理
      }
    } catch (e) {
      _updateLoginMessage("${e}");
    }
  }

  Future<void> _logOut() async {
    final result = await kakaoSignIn.logOut();
    result.when(
      () {},
      success: (value) {
        _processLoginResult("loggedOut");
        _processAccountResult(null);
      },
      fail: (e) {
        _updateLoginMessage("${e.cause} ${e.message}");
      },
    );
  }

  Future<void> _unlink() async {
    final result = await kakaoSignIn.unlink();
    _processLoginResult("unlinked");
  }

  Future<void> _getAccountInfo() async {
    final result = await kakaoSignIn.currentUser;
    result.when(
      () {},
      success: (value) => _processAccountResult(value),
      fail: (e) => _updateLoginMessage("${e.cause} ${e.message}"),
    );
  }

  Future<void> _getAccessToken() async {
    final OAuthToken? token = await kakaoSignIn.currentToken;
    final accessToken = token?.accessToken;
    if (accessToken != null) {
      _updateAccessToken('访问令牌\n' +
          accessToken +
          '\n过期时间: ${token!.accessTokenExpiresAt}');
    } else {
      _updateAccessToken('');
    }
  }

  Future<void> _getRefreshToken() async {
    final OAuthToken? token = await kakaoSignIn.currentToken;
    final refreshToken = token?.refreshToken;
    if (refreshToken != null) {
      _updateRefreshToken(
          '刷新令牌\n$refreshToken\n过期时间: ${token!.refreshTokenExpiresAt}');
    } else {
      _updateRefreshToken('');
    }
  }

  void _updateLoginMessage(String message) {
    setState(() {
      _loginMessage = message;
    });
  }

  void _updateStateLogin(bool logined) {
    setState(() {
      _isLogined = logined;
    });
    if (!logined) {
      _updateAccessToken('');
      _updateRefreshToken('');
      _updateAccountMessage('');
    }
  }

  void _updateAccessToken(String accessToken) {
    setState(() {
      _accessToken = accessToken;
    });
  }

  void _updateRefreshToken(String refreshToken) {
    setState(() {
      _refreshToken = refreshToken;
    });
  }

  void _updateAccountMessage(String message) {
    setState(() {
      _accountInfo = message;
    });
  }

  void _processLoginResult(String status) {
    switch (status) {
      case "loggedIn":
        _updateLoginMessage('已登录');
        _updateStateLogin(true);
        break;
      case "loggedOut":
        _updateLoginMessage('已登出');
        _updateStateLogin(false);
        break;
      case "unlinked":
        _updateLoginMessage('已解绑');
        _updateStateLogin(false);
        break;
    }
  }

  void _processAccountResult(User? user) {
    if (user?.kakaoAccount == null) {
      _updateAccountMessage('');
    } else {
      final account = user!.kakaoAccount;
      final userID = (user.id == null) ? '无' : user.id;
      final userEmail = (account!.email == null) ? '无' : account.email;
      final userPhoneNumber =
          (account.phoneNumber == null) ? '无' : account.phoneNumber;
      final userNickname = (account.profile!.nickname == null)
          ? '无'
          : account.profile!.nickname;
      final userGender = (account.gender == null) ? '无' : account.gender;
      final userAgeRange =
          (account.ageRange == null) ? '无' : account.ageRange;
      final userBirthyear =
          (account.birthyear == null) ? '无' : account.birthyear;
      final userBirthday =
          (account.birthday == null) ? '无' : account.birthday;
      final userProfileImagePath = (account.profile!.profileImageUrl == null)
          ? '无'
          : account.profile!.profileImageUrl.toString();
      final userThumbnailImagePath =
          (account.profile!.thumbnailImageUrl == null)
              ? '无'
              : account.profile!.thumbnailImageUrl.toString();

      _updateAccountMessage('- 用户ID: ${userID}\n'
          '- 邮箱: ${userEmail}\n'
          '- 手机号: ${userPhoneNumber}\n'
          '- 昵称: ${userNickname}\n'
          '- 性别: ${userGender}\n'
          '- 年龄范围: ${userAgeRange}\n'
          '- 出生年份: ${userBirthyear}\n'
          '- 生日: ${userBirthday}\n'
          '- 头像路径: ${userProfileImagePath}\n'
          '- 缩略图路径: ${userThumbnailImagePath}');
    }
  }

  void _showAlert(BuildContext context, String value) {
    if (value.isEmpty) return;

    showDialog(
      context: context,
      builder: (BuildContext context) {
        return new AlertDialog(
          content: new Text(value, style: new TextStyle(fontWeight: FontWeight.bold)),
          actions: <Widget>[
            new FlatButton(
              child: new Text('确定'),
              onPressed: () {
                Navigator.of(context).pop(true);
              },
            )
          ],
        );
      },
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Kakao Login插件应用'),
        ),
        body: new SafeArea(
          child: new ListView.builder(
            itemCount: _litems.length + 1,
            itemBuilder: (BuildContext context, int index) {
              if (index == 0) {
                return KakaoInfo(
                  loginMessage: _loginMessage,
                  accessToken: _accessToken,
                  refreshToken: _refreshToken,
                  accountInfo: _accountInfo,
                );
              }
              final actionIndex = index - 1;
              return ListTile(
                title: new Text(_litems[actionIndex]['title']!),
                subtitle: new Text(_litems[actionIndex]['subtitle']!),
                onTap: () {
                  final key = _litems[actionIndex]['key'];
                  switch (key) {
                    case "login":
                      if (!_isLogined) {
                        _login();
                      }
                      break;
                    case "logout":
                      if (_isLogined) {
                        _logOut();
                      }
                      break;
                    case "unlink":
                      if (_isLogined) {
                        _unlink();
                      }
                      break;
                    case "account":
                      if (!_isLogined) {
                        _showAlert(context, '需要先登录。');
                      } else {
                        _getAccountInfo();
                      }
                      break;
                    case "accessToken":
                      if (!_isLogined) {
                        _showAlert(context, '需要先登录。');
                      } else {
                        _getAccessToken();
                      }
                      break;
                    case "refreshToken":
                      if (!_isLogined) {
                        _showAlert(context, '需要先登录。');
                      } else {
                        _getRefreshToken();
                      }
                      break;
                  }
                },
              );
            },
          ),
        ),
      ),
    );
  }
}

class KakaoInfo extends StatelessWidget {
  final String loginMessage;
  final String accessToken;
  final String refreshToken;
  final String accountInfo;

  KakaoInfo({
    this.loginMessage = "",
    this.accessToken = "",
    this.refreshToken = "",
    this.accountInfo = "",
  });

  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.fromLTRB(18, 25, 18, 25),
      color: Colors.grey[300],
      child: Column(
        children: [
          Text(loginMessage),
          accountInfo != "" ? SizedBox(height: 25) : Container(),
          accountInfo != "" ? Text(accountInfo) : Container(),
          accessToken != "" ? SizedBox(height: 10) : Container(),
          accessToken != "" ? Text(accessToken) : Container(),
          refreshToken != "" ? SizedBox(height: 10) : Container(),
          refreshToken != "" ? Text(refreshToken) : Container(),
        ],
      ),
    );
  }
}

更多关于Flutter Kakao Login插件的集成与使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Kakao Login插件的集成与使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在 Flutter 应用中集成 Kakao Login 插件可以通过 kakao_flutter_sdk 插件来实现。以下是详细的集成与使用步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 kakao_flutter_sdk 依赖:

dependencies:
  flutter:
    sdk: flutter
  kakao_flutter_sdk: ^latest_version

然后运行 flutter pub get 来安装依赖。

2. 配置 Android

android/app/src/main/AndroidManifest.xml 文件中添加以下配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <application
        android:label="YourApp"
        android:icon="@mipmap/ic_launcher">

        <!-- Kakao Login Configuration -->
        <meta-data
            android:name="com.kakao.sdk.AppKey"
            android:value="YOUR_KAKAO_APP_KEY" />

        <activity
            android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:host="oauth"
                    android:scheme="kakaoYOUR_KAKAO_APP_KEY" />
            </intent-filter>
        </activity>

    </application>
</manifest>

YOUR_KAKAO_APP_KEY 替换为你在 Kakao Developers 平台上注册的应用程序的密钥。

3. 配置 iOS

ios/Runner/Info.plist 文件中添加以下配置:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>kakaoYOUR_KAKAO_APP_KEY</string>
        </array>
    </dict>
</array>

同样,将 YOUR_KAKAO_APP_KEY 替换为你在 Kakao Developers 平台上注册的应用程序的密钥。

4. 初始化 Kakao SDK

在你的 Flutter 应用启动时初始化 Kakao SDK。通常在 main.dart 文件中进行初始化:

import 'package:kakao_flutter_sdk/kakao_flutter_sdk.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  KakaoSdk.init(nativeAppKey: 'YOUR_KAKAO_NATIVE_APP_KEY');
  runApp(MyApp());
}

YOUR_KAKAO_NATIVE_APP_KEY 替换为你在 Kakao Developers 平台上注册的应用程序的密钥。

5. 实现 Kakao 登录

在需要登录的地方,使用以下代码实现 Kakao 登录:

import 'package:kakao_flutter_sdk/kakao_flutter_sdk.dart';

Future<void> loginWithKakao() async {
  try {
    // 카카오톡으로 로그인 시도
    if (await isKakaoTalkInstalled()) {
      await UserApi.instance.loginWithKakaoTalk();
    } else {
      await UserApi.instance.loginWithKakaoAccount();
    }

    // 사용자 정보 가져오기
    User user = await UserApi.instance.me();
    print('User ID: ${user.id}');
    print('User Email: ${user.kakaoAccount?.email}');
    print('User Nickname: ${user.kakaoAccount?.profile?.nickname}');

  } catch (error) {
    print('카카오 로그인 실패: $error');
  }
}

6. 处理登录结果

你可以根据登录结果进行相应的处理,例如跳转到主页或显示错误信息。

7. 登出

如果你需要实现登出功能,可以使用以下代码:

Future<void> logoutFromKakao() async {
  try {
    await UserApi.instance.logout();
    print('로그아웃 성공');
  } catch (error) {
    print('로그아웃 실패: $error');
  }
}
回到顶部