Flutter集成Zalo功能插件zalo_flutter的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter集成Zalo功能插件zalo_flutter的使用

简介

zalo_flutter 是一个用于访问 Zalo APIs 的Flutter插件。请注意,此插件仍在开发中,某些API可能尚未可用。欢迎提交反馈Pull Requests

1. 设置

1.1 创建Zalo应用程序

要访问Zalo API,请确保创建您的应用程序

1.2 获取ZaloAppID

然后,您可以进入仪表板(https://developers.zalo.me/app/[ZaloAppID]/settings)。记住您的ZaloAppID

1.3 导入包

按照插件安装说明来使用这个插件。

1.4 Android集成

步骤1: 修改android/app/build.gradle

minSdkVersion 21 // 或更大
compileSdkVersion 34 // 或更大
targetSdkVersion 34 // 或更大

步骤2: 修改/android/app/src/main/AndroidManifest.xml

<application
    ...
    android:name=".MyApplication">
    <activity
        ...
        android:name=".MainActivity">
        ...
    </activity>

    <!-- ZaloFlutter start -->
    <meta-data
        android:name="com.zing.zalo.zalosdk.appID"
        android:value="@string/zalo_flutter_app_id" />
    <activity
        android:name="com.zing.zalo.zalosdk.oauth.BrowserLoginActivity"
        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:scheme="@string/zalo_flutter_app_id_protocol"/>
        </intent-filter>
    </activity>
    <!-- ZaloFlutter end -->
</application>
...
<!-- ZaloFlutter start -->
<queries>
    <package android:name="com.zing.zalo" />
</queries>
<!-- ZaloFlutter end -->

步骤3: 创建或编辑strings.xml

/android/app/src/main/res/values/strings.xml文件夹中创建或编辑strings.xml文件。替换为您的ZaloAppID。

<resources>
    <string name="zalo_flutter_app_id">[ZaloAppID]</string>
    <string name="zalo_flutter_app_id_protocol">zalo-[ZaloAppID]</string>
</resources>

步骤4: 添加获取HashKey的小部件

main.dart文件中添加以下小部件以获取HashKey。

const ZaloHashKeyAndroid(),

构建应用后复制HashKey

步骤5: 在Zalo仪表板上配置HashKey

打开Zalo仪表板=>登录=>Android(https://developers.zalo.me/app/[ZaloAppID]/login) 粘贴HashKeyYourPackageName并点击保存。

注意:如果您上传.aab文件到Google Store,它将生成另一个HashKey,请将其复制到仪表板。

步骤6: 添加proguard规则

-keep class com.zing.zalo.**{ *; }
-keep enum com.zing.zalo.**{ *; }
-keep interface com.zing.zalo.**{ *; }

继续使用Kotlin

编辑MainActivity.kt文件如下。记得替换YourPackageName

package [YourPackageName]

import io.flutter.embedding.android.FlutterActivity
import android.content.Intent
import com.zing.zalo.zalosdk.oauth.ZaloSDK

class MainActivity: FlutterActivity() {
    override fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)
        ZaloSDK.Instance.onActivityResult(this, requestCode, resultCode, data)
    }
}

创建MyApplication.kt文件在同一文件夹中。替换为您的YourPackageName

package [YourPackageName]

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import com.zing.zalo.zalosdk.oauth.ZaloSDKApplication

class MyApplication : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
    override fun onCreate() {
        super.onCreate()
        ZaloSDKApplication.wrap(this)
    }
    override fun registerWith(registry: PluginRegistry) {}
}

继续使用Java

编辑MainActivity.java文件如下。记得替换YourPackageName

package [YourPackageName];

import io.flutter.embedding.android.FlutterActivity;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;

import android.content.Intent;
import com.zing.zalo.zalosdk.oauth.ZaloSDK;

public class MainActivity extends FlutterActivity {
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ZaloSDK.Instance.onActivityResult(this, requestCode, resultCode, data);
    }
}

创建MyApplication.java文件在同一文件夹中。替换为您的YourPackageName

package [YourPackageName]

import android.app.Application;
import com.zing.zalo.zalosdk.oauth.ZaloSDKApplication;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ZaloSDKApplication.wrap(this);
    }
}

iOS集成

步骤1: 修改ios/Runner/Info.plist文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	...

	<!-- ZaloFlutter start-->
	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>CFBundleURLName</key>
			<string>zalo</string>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>zalo-[ZaloAppID]</string>
			</array>
		</dict>
	</array>
	<key>ZaloAppID</key>
	<string>[ZaloAppID]</string>
	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>zalosdk</string>
		<string>zaloshareext</string>
	</array>
      <!-- ZaloFlutter end-->
</dict>
</plist>

步骤2: 修改ios/Runner/AppDelegate.swift文件

import UIKit
import Flutter
import ZaloSDK

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    // Zalo function go here
    override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        return ZDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
    }
}

步骤3: 获取BundleID

打开ios/Runner.xcodeproj/project.pbxproj,搜索PRODUCT_BUNDLE_IDENTIFIER并复制您的BundleID

步骤4: 在Zalo仪表板上配置BundleID

打开Zalo仪表板=>登录=>iOS(https://developers.zalo.me/app/[ZaloAppID]/login) 粘贴BundleID并点击保存。

使用方法

Dart代码导入

import 'package:zalo_flutter/zalo_flutter.dart';

函数列表

  • 获取HashKey(仅限Android)

    String? data = await ZaloFlutter.getHashKeyAndroid();
    
  • 登录(通过应用或WebView)

    final data = await ZaloFlutter.login(
        refreshToken: refreshToken,
    );
    
  • 登出 - 清除缓存中的OAuth代码

    await ZaloFlutter.logout();
    
  • 验证刷新令牌

    bool data = await ZaloFlutter.validateRefreshToken(
        refreshToken: refreshToken,
    );
    
  • 获取Zalo用户资料

    final data = await ZaloFlutter.getUserProfile(
        accessToken: accessToken,
    );
    

示例Demo

import 'dart:convert';
import 'dart:developer';
import 'dart:io';

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    Key? key,
  }) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _indexReset = -1;
  ValueKey<String> _key = const ValueKey<String>('');

  String zaloId = '2961857761415564889';
  String zaloMessage = 'Hello';
  String zaloLink = 'www.google.com';

  String? _accessToken;
  String? _refreshToken;

  @override
  void initState() {
    super.initState();
    _initZaloFlutter();
  }

  Future<void> _initZaloFlutter() async {
    if (Platform.isAndroid) {
      final String? hashKey = await ZaloFlutter.getHashKeyAndroid();
      log('HashKey: $hashKey');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      body: SafeArea(
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                CommonButton(
                  text: 'clear log',
                  onPressed: () async {
                    _indexReset++;
                    _key = ValueKey<String>(_indexReset.toString());
                    setState(() {});
                    return null;
                  },
                ),
                CommonButton(
                  text: 'login',
                  onPressed: () async {
                    final Map<dynamic, dynamic>? data = await ZaloFlutter.login(
                      refreshToken: _refreshToken,
                    );
                    try {
                      print("login: $data");
                      if (data?['isSuccess'] == true) {
                        _accessToken = data?["data"]["accessToken"] as String?;
                        _refreshToken =
                            data?["data"]["refreshToken"] as String?;
                      }
                    } catch (e) {
                      print("login: $e");
                    }
                    return data;
                  },
                ),
                CommonButton(
                  text: 'logout',
                  onPressed: () async {
                    _accessToken = null;
                    _refreshToken = null;
                    await ZaloFlutter.logout();

                    _indexReset++;
                    _key = ValueKey<String>(_indexReset.toString());
                    setState(() {});
                    return null;
                  },
                ),
                CommonButton(
                  text: 'validateRefreshToken',
                  onPressed: () async {
                    final bool data = await ZaloFlutter.validateRefreshToken(
                      refreshToken: _refreshToken ?? '',
                    );
                    return data.toString();
                  },
                ),
                CommonButton(
                  text: 'getUserProfile',
                  onPressed: () async {
                    final Map<dynamic, dynamic>? data =
                        await ZaloFlutter.getUserProfile(
                      accessToken: _accessToken ?? '',
                    );
                    return data;
                  },
                ),
                CommonButton(
                  text: 'shareMessage',
                  onPressed: () async {
                    // final bool result = await ZaloFlutter.shareMessage(
                    //   link: 'https://huuksocialproduction.page.link/nHKZ',
                    //   message: 'assadda',
                    //   appName: 'Huuk Social',
                    // );
                    // return result;
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class CommonButton extends StatefulWidget {
  const CommonButton({
    Key? key,
    required this.text,
    required this.onPressed,
    this.color = Colors.blue,
  }) : super(key: key);

  final String text;
  final Future<dynamic> Function() onPressed;
  final Color color;

  @override
  _CommonButtonState createState() => _CommonButtonState();
}

class _CommonButtonState extends State<CommonButton> {
  String? result;

  @override
  Widget build(BuildContext context) {
    final Widget childText = Text(
      widget.text,
      style: const TextStyle(
        color: Colors.white,
        fontWeight: FontWeight.bold,
      ),
    );

    final Widget button = MaterialButton(
      minWidth: double.infinity,
      height: 40,
      color: widget.color,
      padding: const EdgeInsets.all(16),
      onPressed: () async {
        _showLoading(context);
        final DateTime time = DateTime.now();
        print('[$time][commonButton] ${widget.text}');
        final dynamic data = await widget.onPressed();
        if (data == null) {
          result = 'null';
        } else if (data is String) {
          result = data;
        } else if (data is Map) {
          result = jsonEncode(data);
        }
        setState(() {});
        Navigator.pop(context);
      },
      shape: const StadiumBorder(),
      child: childText,
    );

    Widget showResult(String? text) {
      if (text == null) {
        return Container();
      }
      String data;
      try {
        final Map<String, dynamic>? object =
            jsonDecode(text) as Map<String, dynamic>?;
        data = const JsonEncoder.withIndent('  ').convert(object);
      } catch (e) {
        data = text;
      }
      return Text(data);
    }

    return Padding(
      padding: const EdgeInsets.all(6.0),
      child: Column(
        children: <Widget>[
          button,
          showResult(result),
        ],
      ),
    );
  }

  Future<void> _showLoading(BuildContext context) async {
    await showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (_) {
        return const Center(
          child: CircularProgressIndicator(),
        );
      },
    );
  }
}

作者

Pham Tien Dung

如果有任何问题,请随时联系我。

Gmail: tiendung01023@gmail.com

Github: https://github.com/tiendung01023


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

1 回复

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


当然,以下是一个关于如何在Flutter项目中集成并使用zalo_flutter插件的示例代码。zalo_flutter插件允许你在Flutter应用中集成Zalo的登录和其他功能。假设你已经创建了一个Flutter项目,以下步骤将指导你如何集成和使用该插件。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加zalo_flutter插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  zalo_flutter: ^最新版本号  # 请替换为实际最新版本号

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

2. 配置Android和iOS

Android

android/app/src/main/AndroidManifest.xml中添加必要的权限和配置,如网络权限等(具体配置请参考zalo_flutter的官方文档)。

iOS

ios/Runner/Info.plist中添加必要的配置,比如LSApplicationQueriesSchemes(具体配置请参考zalo_flutter的官方文档)。

3. 初始化Zalo SDK

在你的Flutter项目的入口文件(通常是main.dart)中,初始化Zalo SDK。

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

void main() {
  runApp(MyApp());
  // 初始化Zalo SDK
  ZaloFlutter.instance.init(
    appId: "你的Zalo App ID", // 替换为你的Zalo App ID
    appSecret: "你的Zalo App Secret", // 替换为你的Zalo App Secret
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Zalo Flutter Integration'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextButton(
              onPressed: () {
                // 调用Zalo登录
                ZaloFlutter.instance.login().then((result) {
                  if (result != null) {
                    // 登录成功后的处理
                    print("Zalo User ID: ${result.userId}");
                    print("Zalo Access Token: ${result.accessToken}");
                  } else {
                    // 登录失败的处理
                    print("Zalo login failed");
                  }
                }).catchError((error) {
                  print("Error during Zalo login: $error");
                });
              },
              child: Text('Login with Zalo'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 处理回调和权限

在实际应用中,你可能需要处理更多的回调和权限请求。请参考zalo_flutter的官方文档来获取更多详细信息和高级用法。

注意事项

  1. 确保你已经在Zalo开发者平台创建了应用并获取了App ID和App Secret
  2. 处理用户隐私和数据安全:确保你遵循Zalo的隐私政策和用户数据保护要求。
  3. 测试:在集成完成后,在多种设备和网络环境下进行测试,以确保功能的稳定性和兼容性。

官方文档

为了获取最新的配置信息和API用法,请参考zalo_flutter官方文档(假设有一个公开的官方文档链接)。

以上代码提供了一个基本的集成示例,你可能需要根据具体需求进行调整和扩展。

回到顶部