首先下载依赖

导包

import 'package:im_flutter_sdk/im_flutter_sdk.dart';

登录
import 'package:flutter/material.dart';
import 'package:test1/Do/UserDao.dart'; // Make sure this path is correct
import 'package:test1/page/logined.dart';
import 'register.dart'; // Import your RegisterPage class
import 'package:im_flutter_sdk/im_flutter_sdk.dart';

class LoginPage extends StatefulWidget {
LoginPage({required Key key}) : super(key: key);

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

class _LoginPage extends State<LoginPage> {

ScrollController scrollController = ScrollController();
String _username = "";
String _password = "";
String _messageContent = "";
String _chatId = "";
final List<String> _logText = [];

@override
void initState() {
super.initState();
_initSDK();
_addChatListener();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('登录'),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
decoration: const InputDecoration(hintText: "输入用户名"),
onChanged: (username) => _username = username,
),
const SizedBox(height: 20.0),
TextField(
decoration: const InputDecoration(hintText: "输入密码"),
onChanged: (password) => _password = password,
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
// Remove extra condition check
if (_username.isNotEmpty && _password.isNotEmpty) {
// 调用后端登录函数
login(context, _username, _password);

// Navigate to MyApp2 with username parameter
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyApp2(username: _username),
),
);
} else {
// 提示用户输入完整的信息
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('请输入完整的信息'),
),
);
}
_signIn();
},
child: const Text('登录'),
),
const SizedBox(height: 10.0),
TextButton(
onPressed: () {
// Navigate to the RegisterPage
Navigator.push(
context,
MaterialPageRoute(builder: (context) => RegisterPage(key: UniqueKey())),
);
},
child: const Text('注册'),
),
],
),
),
);
}

void _initSDK() async {
EMOptions options = EMOptions(
appKey: "1169240414209351#youxiandechulun",
autoLogin: false,
);
await EMClient.getInstance.init(options);
// 通知sdk ui已经准备好,执行后才会收到`EMChatRoomEventHandler`, `EMContactEventHandler`, `EMGroupEventHandler` 回调。
await EMClient.getInstance.startCallback();
}

void _addChatListener() {

// 添加消息状态变更监听
EMClient.getInstance.chatManager.addMessageEvent(
// ChatMessageEvent 对应的 key。
"UNIQUE_HANDLER_ID",
ChatMessageEvent(
onSuccess: (msgId, msg) {
_addLogToConsole("发送消息成功");
},
onProgress: (msgId, progress) {
_addLogToConsole("发送消息成功");
},
onError: (msgId, msg, error) {
_addLogToConsole(
"发送消息失败,代码: ${error.code}, 描述: ${error.description}",
);
},
));

// 添加收消息监听
EMClient.getInstance.chatManager.addEventHandler(
// EMChatEventHandle 对应的 key。
"UNIQUE_HANDLER_ID",
EMChatEventHandler(
onMessagesReceived: (messages) {
for (var msg in messages) {
switch (msg.body.type) {
case MessageType.TXT:
{
EMTextMessageBody body = msg.body as EMTextMessageBody;
_addLogToConsole(
"接收到文本消息: ${body.content}, 来自: ${msg.from}",
);
}
break;
case MessageType.IMAGE:
{
_addLogToConsole(
"接收到图片消息, 来自: ${msg.from}",
);
}
break;
case MessageType.VIDEO:
{
_addLogToConsole(
"接收到视频消息, 来自: ${msg.from}",
);
}
break;
case MessageType.LOCATION:
{
_addLogToConsole(
"接收到位置消息, 来自: ${msg.from}",
);
}
break;
case MessageType.VOICE:
{
_addLogToConsole(
"接收到语音消息, 来自: ${msg.from}",
);
}
break;
case MessageType.FILE:
{
_addLogToConsole(
"接收到文件消息, 来自: ${msg.from}",
);
}
break;
case MessageType.CUSTOM:
{
_addLogToConsole(
"接收到自定义消息, 来自: ${msg.from}",
);
}
break;
case MessageType.CMD:
{
// 当前回调中不会有 CMD 类型消息,CMD 类型消息通过 [EMChatEventHandler.onCmdMessagesReceived] 回调接收
}
break;
case MessageType.COMBINE:
// TODO: Handle this case.
}
}
},
),
);
}

void _signIn() async {
if (_username.isEmpty || _password.isEmpty) {
_addLogToConsole("用户名或密码为空");
return;
}

try {
await EMClient.getInstance.login(_username, _password);
_addLogToConsole("登录成功, 用户名: $_username");
} on EMError catch (e) {
_addLogToConsole("登录失败, 错误代码: ${e.code} , ${e.description}");
}
}
void _signOut() async {
try {
await EMClient.getInstance.logout(true);
_addLogToConsole("退出成功");
} on EMError catch (e) {
_addLogToConsole(
"退出失败, 代码: ${e.code}, 描述: ${e.description}");
}
}

void _signUp() async {
if (_username.isEmpty || _password.isEmpty) {
_addLogToConsole("用户名或密码为空");
return;
}

try {
_addLogToConsole("开始创建账号...");
await EMClient.getInstance.createAccount(_username, _password);
_addLogToConsole("创建账号成功, 用户名: $_username");
} on EMError catch (e) {
_addLogToConsole(
"创建账号失败, 代码: ${e.code}, 描述: ${e.description}");
}
}

void _sendMessage() async {
if (_chatId.isEmpty || _messageContent.isEmpty) {
_addLogToConsole("聊天ID或消息内容为空");
return;
}

var msg = EMMessage.createTxtSendMessage(
targetId: _chatId,
content: _messageContent,
);

EMClient.getInstance.chatManager.sendMessage(msg);
}

void _addLogToConsole(String log) {
_logText.add(_timeString + ": " + log);
setState(() {
scrollController.jumpTo(scrollController.position.maxScrollExtent);
});
}

String get _timeString {
return DateTime.now().toString().split(".").first;
}

}

注册
import 'package:flutter/material.dart';
import 'package:im_flutter_sdk/im_flutter_sdk.dart';
import '../Do/UserDao.dart';

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

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

class _RegisterPageState extends State<RegisterPage> {
TextEditingController _usernameController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
TextEditingController _usernameController2 = TextEditingController();
TextEditingController _phoneNumberController = TextEditingController();
TextEditingController _emailController = TextEditingController();

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

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('注册')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
controller: _usernameController,
decoration: const InputDecoration(labelText: '账号'),
),
TextFormField(
controller: _passwordController,
decoration: const InputDecoration(labelText: '密码'),
obscureText: true,
),
TextFormField(
controller: _usernameController2,
decoration: const InputDecoration(labelText: '用户名'),
obscureText: true,
),
TextFormField(
controller: _phoneNumberController,
decoration: const InputDecoration(labelText: '手机号'),
keyboardType: TextInputType.phone,
),
TextFormField(
controller: _emailController,
decoration: const InputDecoration(labelText: '邮箱'),
keyboardType: TextInputType.emailAddress,
),
SizedBox(height: 16),
ElevatedButton(
onPressed:(){

String username = _usernameController.text.trim();
String password = _passwordController.text.trim();
String username2 = _usernameController2.text.trim();
String phoneNumber = _phoneNumberController.text.trim();
String email = _emailController.text.trim();

// 做简单的输入验证,你也可以根据需要增加更多的验证逻辑
if (username.isNotEmpty &&
password.isNotEmpty &&
username2.isNotEmpty &&
phoneNumber.isNotEmpty &&
email.isNotEmpty) {
// 调用后端注册函数
register(context, username, password, username2, phoneNumber, email);
} else {
// 提示用户输入完整的信息
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('请输入完整的信息'),
),
);
}
_signUp();
},
child: const Text('注册'),
),
],
),
),
);
}

void _initSDK() async {
EMOptions options = EMOptions(
appKey: "1169240414209351#youxiandechulun",
autoLogin: false,
);
await EMClient.getInstance.init(options);
await EMClient.getInstance.startCallback();
}

Future<void> _signUp() async {
final username = _usernameController.text.trim();
final password = _passwordController.text.trim();

try {
await EMClient.getInstance.createAccount(username, password);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('注册成功')),
);
// 注册成功后可以做一些清理或导航操作
} on EMError catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('注册失败, 代码: ${e.code}, 描述: ${e.description}')),
);
}
}
}

flutter 调用环信sdk 实现即时通讯的更多相关文章

  1. android-使用环信SDK开发即时通信功能及源代码下载

    近期项目中集成即时聊天功能.挑来拣去,终于选择环信SDK来进行开发,选择环信的主要原因是接口方便.简洁.说明文档清楚易懂.文档有android.ios.和后台server端.还是非常全的. 环信官网: ...

  2. 基于环信SDK的IM即时通讯填坑之路(vue)

    公司最近使用第三方环信SDK的进行通信聊天,基本已完成.记录下填坑之路 1.可以通过以下方式引用 WebSDK 1.安装 npm install easemob-websdk --save 2. 先 ...

  3. 环信SDK集成

    利用环信SDK可以实现即时通讯,但在集成的过程中碰到了不少的坑. 注意 选择项目路径,这里以最新版环信demo为例 注意:环信的ChatDemoUI这个demo里边因为研发的同事为了照顾老版本的And ...

  4. 李洪强iOS开发之-环信02.2_环信官网下载环信 SDK

    李洪强iOS开发之-环信02.2_环信官网下载环信 SDK 移动客服即时通讯云 iOS SDK 当前版本:V3.1.4 2016-07-08 [ 版本历史 ] | 开发指南 | 知识库 | Demo源 ...

  5. 集成IOS 环信SDK

    集成IOS SDK 在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念. 下载SDK 通过Cocoapods下载地址 不包含实时语音版本SDK(EaseMobC ...

  6. 李洪强iOS开发本人集成环信的经验总结_01环信SDK的导入

    李洪强iOS开发本人集成环信的经验总结_01环信SDK的导入 01 - 直接在项目中导入SDK和一些静态库 这个时候,没有错误的编译没有错误的话,就说明SDK已经配置成功 还有一种方法是用cocoap ...

  7. 李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档

    李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档 SDK 2.x 至 3.0 升级指南 环信 SDK 3.0 升级文档 3.0 中的核心类为 EMClient 类,通过 EMCl ...

  8. 环信SDK 头像、昵称、表情自定义和群聊设置的实现 一(附源码)

    前言: 环信的SDK在公司的项目中有用到,现在用到的是群聊的部分,这里我们分析总结一下自己对环信给的DEMO大概的拆解一下,说说我们怎么样充分的利用这个demo来写我们所需要的业务.这个也由于篇幅的原 ...

  9. 环信SDK与Apple Watch的结合(2)

    这一篇主要是介绍怎么拖apple watch上的相关页面,附源码EMWatchOCDemo. 需要在工程中的“EMWatchOCDemo WatchKit App”中进行操作,该文件夹的结构如图 Wa ...

  10. 环信SDK与Apple Watch的结合(1)

    该系列是记录在apple watch上开发IM,用到了最近挺流行的环信IM SDK. 一.先来一段网上随处可查到的信息: 1.两种分辨率 1.65寸 312*390 1.5寸 272*340 2.开发 ...

随机推荐

  1. Python:Lambda

    Lambda >>> (lambda: 3)() # Using a lambda expression as an operator in a call exp. 经过查阅资料,理 ...

  2. jumpserver-v3搭建配置与使用

    一.jumpserver简介 官网:https://www.jumpserver.org/ 文档:https://docs.jumpserver.org/zh/v3/ 单机部署:https://doc ...

  3. 零侵入!试试这款Api接口文档生成器!

    大家好,我是 Java陈序员. 作为一名合格的程序员,不仅代码要写好,而且文档要写好. 虽然目前有成熟的框架可以快速生成接口文档,如大名鼎鼎的 Swagger.但是 Swagger 需要编写大量的注解 ...

  4. 简说Python之列表,元祖,字典

    目录 Python列表 创建列表 添加元素 查询元素 列表分片 分片简写 修改元素 一些其他添加列表元素的方法 extend() insert() 删除元素 remove()删除 del 通过索引删除 ...

  5. [4]自定义Lua解析器管理器-------演化脚本V0.7

    [4]自定义Lua解析器管理器-------演化脚本V0.7 使用自定义委托来调用lua脚本中的多返回值函数和长参数类型的函数. 先看代码,依旧是上篇文章中所贴的脚本.新增调用两个函数testFunc ...

  6. mac更新nodejs

    查看本机node.js版本: node -v 清除node.js的cache:sudo npm cache clean -f 安装 n 工具:sudo npm install -g n 安装最新版本的 ...

  7. Java面试题:让依赖注入变得简单,面对@Autowired和@Resource,该如何选择?

    @Autowired和@Resource都是Java Spring框架中的注解,用于实现依赖注入(DI)和控制反转(IoC).它们的区别主要在以下三个方面: 源头不同  @Autowired是Spri ...

  8. Avalonia中的线性渐变画刷LinearGradientBrush

    在WPF中使用Shape实现复杂线条动画后,尝试在Avalonia中也实现同样效果.尽管官方提供了从WPF到Avalonia的快速入门文档,但由于第一次使用Avalonia,体验过程中并不是很顺利,主 ...

  9. C#老码农的职业生涯

    开头白 大家好,我是tibos,19年10月1号由深圳回武汉的码农,目前入职武汉福禄网络,最近刷到的年终总结也比较多,赶在这最后一天,我也来凑个热闹 心路历程 -> 菜鸟入江湖 13年开启码农的 ...

  10. lodash已死?radash库方法介绍及源码解析 —— 对象方法篇

    写在前面 主页有更多其他篇章的方法,欢迎访问查看. 本篇我们介绍radash中对象相关方法的使用和源码解析. assign:递归合并两个对象 使用说明 功能说明:类似于 JavaScript 的 Ob ...