Flutter即时通讯插件jmessage_flutter的使用
Flutter即时通讯插件jmessage_flutter的使用
安装
在工程 pubspec.yaml
文件中加入依赖项:
// GitHub集成
dependencies:
jmessage_flutter:
git:
url: git://github.com/jpush/jmessage-flutter-plugin.git
ref: master
// pub.dev集成
dependencies:
jmessage_flutter: 2.2.0
配置
在 android/app/build.gradle
文件中添加以下配置:
android {
......
defaultConfig {
applicationId "com.xxx.xxx" // JPush上注册的包名.
......
ndk {
// 选择要添加的对应CPU类型的.so库。
abiFilters 'armeabi', 'armeabi-v7a', 'armeabi-v8a'
// 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
}
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_APPKEY : "你的appkey", // JPush上注册的包名对应的appkey.
JPUSH_CHANNEL : "developer-default", // 暂时填写默认值即可.
]
......
}
......
}
使用
首先,在项目中导入插件:
import 'package:jmessage_flutter/jmessage_flutter.dart';
初始化插件
在应用程序启动时,调用 JmessageFlutter().init
方法来初始化插件。
void initState() {
super.initState();
print("demo main init state");
jmessage.setDebugMode(enable: true);
jmessage.init(isOpenMessageRoaming: true, appkey: kMockAppkey);
jmessage.applyPushAuthority(
JMNotificationSettingsIOS(sound: true, alert: true, badge: true));
addListener();
}
注册用户
void demoRegisterAction() async {
print("registerAction : " + usernameTextEC1.text);
setState(() => _loading = true);
if (usernameTextEC1.text.isEmpty) {
setState(() {
_loading = false;
_result = "【注册】username 不能为空";
});
return;
}
String name = usernameTextEC1.text;
await jmessage.userRegister(
username: name, password: kCommonPassword, nickname: name);
setState(() {
_loading = false;
});
}
登录用户
void demoLoginUserAction() async {
print("loginUserAction : " + usernameTextEC1.text);
setState(() {
_loading = true;
});
if (usernameTextEC1.text.isEmpty) {
setState(() {
_loading = false;
_result = "【登录】username 不能为空";
});
return;
}
String name = usernameTextEC1.text;
await jmessage.login(username: name, password: kCommonPassword).then(
(onValue) {
setState(() {
_loading = false;
if (onValue is JMUserInfo) {
JMUserInfo u = onValue;
_result = "【登录后】${u.toJson()}";
} else {
_result = "【登录后】null}";
}
});
}, onError: (error) {
setState(() {
_loading = false;
if (error is PlatformException) {
PlatformException ex = error;
_result = "【登录后】code = ${ex.code},message = ${ex.message}";
} else {
_result = "【登录后】code = ${error.toString()}";
}
});
});
}
获取当前用户信息
void demoGetCurrentUserInfo() async {
print("demoGetCurrentUserInfo : ");
setState(() {
_loading = true;
});
JMUserInfo? u = await jmessage.getMyInfo();
setState(() {
_loading = false;
if (u == null) {
_result = " ===== 您还未登录账号 ===== \n【获取登录用户信息】null";
} else {
_result = " ===== 您已经登录 ===== \n【获取登录用户信息】${u.toJson()}";
}
});
}
发送文本消息
void demoSendTextMessage() async {
print("demoSendTextMessage " + usernameTextEC2.text);
setState(() {
_loading = true;
});
if (usernameTextEC2.text.isEmpty) {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String name = usernameTextEC2.text;
int textIndex = DateTime.now().millisecondsSinceEpoch;
JMSingle type = JMSingle.fromJson({"username": name});
JMMessageSendOptions option =
JMMessageSendOptions.fromJson({"needReadReceipt": true});
JMTextMessage msg = await jmessage.sendTextMessage(
type: type,
text: "send msg current time: $textIndex",
sendOption: option);
setState(() {
_loading = false;
String messageString = "【文本消息】${msg.toJson()}";
_result = messageString;
print("【文本消息】${msg.toJson()}");
});
}
发送图片消息
void demoSendImageMessage() async {
print("demoSendImageMessage " + usernameTextEC2.text);
setState(() => _loading = true);
if (usernameTextEC2.text.isEmpty) {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String username = usernameTextEC2.text;
PickedFile? selectImageFile =
await ImagePicker().getImage(source: ImageSource.gallery);
JMSingle type = JMSingle.fromJson({"username": username});
JMImageMessage msg = await jmessage.sendImageMessage(
type: type, path: selectImageFile?.path);
setState(() {
_loading = false;
_result = "【图片消息】${msg.toJson()}";
});
}
发送地理位置消息
void demoSendLocationMessage() async {
print("demoSendLocationMessage " + usernameTextEC2.text);
setState(() => _loading = true);
if (usernameTextEC2.text.isEmpty) {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String username = usernameTextEC2.text;
JMSingle type = JMSingle.fromJson({"username": username});
JMLocationMessage msg = await jmessage.sendLocationMessage(
type: type,
latitude: 100.0,
longitude: 200.0,
scale: 1,
address: "详细地址");
setState(() {
_loading = false;
_result = "【地理位置消息】${msg.toJson()}";
});
}
发送视频消息
void demoSendVideoMessage() async {
print("demoSendVideoMessage " + usernameTextEC2.text);
setState(() {
_loading = true;
});
if (usernameTextEC2.text == "") {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String username = usernameTextEC2.text;
PickedFile? selectVideoPath = await ImagePicker().getVideo(
source: ImageSource.gallery, maxDuration: const Duration(seconds: 10));
String? thumbnailPath = await VideoThumbnail.thumbnailFile(
video: selectVideoPath!.path,
imageFormat: ImageFormat.PNG,
maxWidth: 128,
// 指定宽度,高度自动缩放以保持源宽高比
quality: 25,
);
JMSingle type = JMSingle.fromJson({"username": username});
JMVideoMessage msg = await jmessage.sendVideoMessage(
type: type,
duration: null,
thumbFormat: "",
videoFileName: "",
thumbImagePath: thumbnailPath,
videoPath: selectVideoPath.path);
setState(() {
_loading = false;
_result = "【视频消息】${msg.toJson()}";
});
}
监听消息事件
void addListener() async {
print('add listener receive ReceiveMessage');
jmessage.addReceiveMessageListener((msg) {
//+
print('listener receive event - message : ${msg.toJson()}');
setState(() {
_result = "【收到消息】${msg.toJson()}";
});
});
jmessage.addClickMessageNotificationListener((msg) {
//+
print(
'listener receive event - click message notification : ${msg.toJson()}');
});
jmessage.addSyncOfflineMessageListener((conversation, msgs) {
print('listener receive event - sync office message ');
List<Map> list = [];
for (JMNormalMessage msg in msgs) {
print('offline msg: ${msg.toJson()}');
list.add(msg.toJson());
}
setState(() {
_result = "【离线消息】${list.toString()}";
});
});
// 其他监听器的设置...
}
示例代码
以下是完整的示例代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:image_picker/image_picker.dart';
import 'package:jmessage_flutter/jmessage_flutter.dart';
import 'package:jmessage_flutter_example/conversation_manage_view.dart';
import 'package:jmessage_flutter_example/group_manage_view.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:platform/platform.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
const String kMockAppkey = "e58a32cb3e4469ebf31867e5"; //'你自己应用的 AppKey';
const String kMockUserName = '0001';
const String kMockPassword = '1111';
const String kCommonPassword = '123456a';
const String kMockGroupName = 'TESTGroupName';
const String kMockGroupDesc = 'TESTGroupDecs';
const String kMockTargetUserName = '0002';
// Target test data
final JMSingle kMockUser =
JMSingle.fromJson({'username': kMockTargetUserName, 'appKey': kMockAppkey});
const String kMockGroupId = '29033635';
final JMGroup kMockGroup =
JMGroup.fromJson({'type': JMGroupType.private, 'groupId': kMockGroupId});
const String kMockChatRoomid = '10003152';
final JMChatRoom kMockChatRoom =
JMChatRoom.fromJson({'roomId': kMockChatRoomid});
MethodChannel channel = MethodChannel('jmessage_flutter');
JmessageFlutter jmessage =
JmessageFlutter.private(channel, const LocalPlatform());
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final String flutterLog = "| Example | Flutter | ";
bool _loading = false;
String _result = "展示信息栏";
var usernameTextEC1 = TextEditingController();
var usernameTextEC2 = TextEditingController();
[@override](/user/override)
void initState() {
super.initState();
print(flutterLog + "demo main init state");
// initPlatformState();
jmessage.setDebugMode(enable: true);
jmessage.init(isOpenMessageRoaming: true, appkey: kMockAppkey);
jmessage.applyPushAuthority(
JMNotificationSettingsIOS(sound: true, alert: true, badge: true));
addListener();
}
void demoRegisterAction() async {
print(flutterLog + "registerAction : " + usernameTextEC1.text);
setState(() => _loading = true);
if (usernameTextEC1.text.isEmpty) {
setState(() {
_loading = false;
_result = "【注册】username 不能为空";
});
return;
}
String name = usernameTextEC1.text;
await jmessage.userRegister(
username: name, password: kCommonPassword, nickname: name);
setState(() {
_loading = false;
});
}
void demoLoginUserAction() async {
print(flutterLog + "loginUserAction : " + usernameTextEC1.text);
setState(() {
_loading = true;
});
if (usernameTextEC1.text.isEmpty) {
setState(() {
_loading = false;
_result = "【登录】username 不能为空";
});
return;
}
String name = usernameTextEC1.text;
await jmessage.login(username: name, password: kCommonPassword).then(
(onValue) {
setState(() {
_loading = false;
if (onValue is JMUserInfo) {
JMUserInfo u = onValue;
_result = "【登录后】${u.toJson()}";
} else {
_result = "【登录后】null}";
}
});
}, onError: (error) {
setState(() {
_loading = false;
if (error is PlatformException) {
PlatformException ex = error;
_result = "【登录后】code = ${ex.code},message = ${ex.message}";
} else {
_result = "【登录后】code = ${error.toString()}";
}
});
});
}
void demoLogoutAction() async {
print(flutterLog + "demoLogoutAction : ");
setState(() {
_loading = true;
});
await jmessage.logout().then((onValue) {
print(flutterLog + "demoLogoutAction : then");
demoShowMessage(false, "【已退出】");
}, onError: (onError) {
print(flutterLog + "demoLogoutAction : onError $onError");
demoShowMessage(false, onError.toString());
});
}
void demoGetCurrentUserInfo() async {
print(flutterLog + "demoGetCurrentUserInfo : ");
setState(() {
_loading = true;
});
JMUserInfo? u = await jmessage.getMyInfo();
setState(() {
_loading = false;
if (u == null) {
_result = " ===== 您还未登录账号 ===== \n【获取登录用户信息】null";
} else {
_result = " ===== 您已经登录 ===== \n【获取登录用户信息】${u.toJson()}";
}
});
}
void demoSendTextMessage() async {
print(flutterLog + "demoSendTextMessage " + usernameTextEC2.text);
setState(() {
_loading = true;
});
if (usernameTextEC2.text.isEmpty) {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String name = usernameTextEC2.text;
int textIndex = DateTime.now().millisecondsSinceEpoch;
JMSingle type = JMSingle.fromJson({"username": name});
JMMessageSendOptions option =
JMMessageSendOptions.fromJson({"needReadReceipt": true});
JMTextMessage msg = await jmessage.sendTextMessage(
type: type,
text: "send msg current time: $textIndex",
sendOption: option);
setState(() {
_loading = false;
String messageString = "【文本消息】${msg.toJson()}";
_result = messageString;
print(flutterLog + messageString);
});
}
void demoSendImageMessage() async {
print(flutterLog + "demoSendImageMessage " + usernameTextEC2.text);
setState(() => _loading = true);
if (usernameTextEC2.text.isEmpty) {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String username = usernameTextEC2.text;
PickedFile? selectImageFile =
await ImagePicker().getImage(source: ImageSource.gallery);
JMSingle type = JMSingle.fromJson({"username": username});
JMImageMessage msg = await jmessage.sendImageMessage(
type: type, path: selectImageFile?.path);
setState(() {
_loading = false;
_result = "【图片消息】${msg.toJson()}";
});
}
void demoSendLocationMessage() async {
print(flutterLog + "demoSendLocationMessage " + usernameTextEC2.text);
setState(() => _loading = true);
if (usernameTextEC2.text.isEmpty) {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String username = usernameTextEC2.text;
JMSingle type = JMSingle.fromJson({"username": username});
JMLocationMessage msg = await jmessage.sendLocationMessage(
type: type,
latitude: 100.0,
longitude: 200.0,
scale: 1,
address: "详细地址");
setState(() {
_loading = false;
_result = "【地理位置消息】${msg.toJson()}";
});
}
void demoSendVideoMessage() async {
print(flutterLog + "demoSendVideoMessage " + usernameTextEC2.text);
setState(() {
_loading = true;
});
if (usernameTextEC2.text == "") {
setState(() {
_loading = false;
_result = "【发消息】对方 username 不能为空";
});
return;
}
String username = usernameTextEC2.text;
PickedFile? selectVideoPath = await ImagePicker().getVideo(
source: ImageSource.gallery, maxDuration: const Duration(seconds: 10));
String? thumbnailPath = await VideoThumbnail.thumbnailFile(
video: selectVideoPath!.path,
imageFormat: ImageFormat.PNG,
maxWidth: 128,
// 指定宽度,高度自动缩放以保持源宽高比
quality: 25,
);
JMSingle type = JMSingle.fromJson({"username": username});
JMVideoMessage msg = await jmessage.sendVideoMessage(
type: type,
duration: null,
thumbFormat: "",
videoFileName: "",
thumbImagePath: thumbnailPath,
videoPath: selectVideoPath.path);
setState(() {
_loading = false;
_result = "【视频消息】${msg.toJson()}";
});
}
void demoShowMessage(bool isShow, String msg) {
setState(() {
_loading = isShow;
_result = msg;
});
}
void addListener() async {
print('add listener receive ReceiveMessage');
jmessage.addReceiveMessageListener((msg) {
//+
print('listener receive event - message : ${msg.toJson()}');
setState(() {
_result = "【收到消息】${msg.toJson()}";
});
});
// 其他监听器的设置...
}
Widget _buildContext() {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
color: Colors.grey,
height: double.infinity,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(5, 10, 5, 0),
height: 35,
color: Colors.brown,
child: CustomTextField(
hintText: "请输入登录的 username", controller: usernameTextEC1),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(" "),
CustomButton(title: "注册", onPressed: demoRegisterAction),
Text(" "),
CustomButton(title: "登录", onPressed: demoLoginUserAction),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(" "),
CustomButton(title: "用户信息", onPressed: demoGetCurrentUserInfo),
Text(" "),
CustomButton(title: "退出", onPressed: demoLogoutAction),
],
),
Container(
margin: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 35,
color: Colors.brown,
child: CustomTextField(
hintText: "请输入username", controller: usernameTextEC2),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(" "),
CustomButton(title: "发送文本消息", onPressed: demoSendTextMessage),
Text(" "),
CustomButton(title: "发送图片消息", onPressed: demoSendImageMessage),
Text(" "),
CustomButton(
title: "发送位置消息", onPressed: demoSendLocationMessage),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(" "),
CustomButton(title: "发送视频消息", onPressed: demoSendVideoMessage),
Text(" "),
CustomButton(
title: "会话管理界面",
onPressed: () {
jmessage.getMyInfo().then((JMUserInfo? userInfo) {
if (userInfo != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ConversationManageView()));
} else {
setState(() {
_result = " 请先登录 ";
});
}
});
}),
Text(" "),
CustomButton(
title: "群组管理界面",
onPressed: () {
jmessage.getMyInfo().then((JMUserInfo? userInfo) {
if (userInfo != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GroupManageView()));
} else {
setState(() {
_result = " 请先登录 ";
});
}
});
},
),
],
),
Container(
margin: EdgeInsets.fromLTRB(5, 5, 5, 20),
color: Colors.brown,
child: Text(_result),
width: double.infinity,
constraints: BoxConstraints(minHeight: 200),
),
],
),
),
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('JMessage Plugin App'),
),
body: ModalProgressHUD(child: _buildContext(), inAsyncCall: _loading),
);
}
}
class CustomButton extends StatelessWidget {
final VoidCallback? onPressed;
final String? title;
const CustomButton({[@required](/user/required) this.onPressed, [@required](/user/required) this.title});
[@override](/user/override)
Widget build(BuildContext context) {
return TextButton(
onPressed: onPressed,
child: Text("$title"),
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(Colors.white),
overlayColor: MaterialStateProperty.all(Color(0xff888888)),
backgroundColor: MaterialStateProperty.all(Color(0xff585858)),
),
);
}
}
class CustomTextField extends StatelessWidget {
final String? hintText;
final TextEditingController? controller;
const CustomTextField({[@required](/user/required) this.hintText, [@required](/user/required) this.controller});
[@override](/user/override)
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.fromLTRB(5, 10, 5, 0),
height: 35,
color: Colors.brown,
child: TextField(
autofocus: false,
style: TextStyle(color: Colors.black),
decoration: InputDecoration(
hintText: hintText, hintStyle: TextStyle(color: Colors.black)),
controller: controller,
),
);
}
}
更多关于Flutter即时通讯插件jmessage_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter即时通讯插件jmessage_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用jmessage_flutter
插件进行即时通讯的示例代码。这个示例将展示如何初始化JMessage,登录用户,以及发送和接收消息的基本流程。
首先,确保你已经在pubspec.yaml
文件中添加了jmessage_flutter
依赖:
dependencies:
flutter:
sdk: flutter
jmessage_flutter: ^最新版本号 # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
初始化与登录
在你的Flutter应用的入口文件(通常是main.dart
)中,进行JMessage的初始化和登录。
import 'package:flutter/material.dart';
import 'package:jmessage_flutter/jmessage_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
initJMessage();
}
void initJMessage() async {
// 初始化JMessage
await JMessage.init({
"appKey": "你的AppKey", // 替换为你的JMessage AppKey
"channelName": "defaultChannel", // 替换为你的渠道名称
"isProduction": false, // 是否是生产环境
});
// 登录用户
await JMessage.login({
"username": "testUser", // 替换为你的用户名
"password": "testPassword" // 替换为你的密码
}).then((result) {
print("登录结果: $result");
// 登录成功后的处理
}).catchError((error) {
print("登录错误: $error");
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('JMessage Flutter Demo'),
),
body: Center(
child: Text('正在初始化JMessage...'),
),
),
);
}
}
发送消息
你可以创建一个按钮来发送消息。以下是一个简单的示例,展示如何发送文本消息给某个用户。
// 在你的_MyAppState类中添加以下函数和按钮
void sendMessage() async {
// 获取当前登录的用户
JUser user = await JMessage.getMyInfo();
// 构造接收者
JConversation conversation = await JMessage.createSingleConversation(user.username);
// 发送文本消息
await conversation.sendMessage({
"type": "text",
"content": "Hello, this is a test message!",
}).then((message) {
print("消息发送成功: $message");
}).catchError((error) {
print("消息发送失败: $error");
});
}
// 在Scaffold的body中添加一个按钮来触发发送消息
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('正在初始化JMessage...'),
SizedBox(height: 20),
ElevatedButton(
onPressed: sendMessage,
child: Text('发送消息'),
),
],
),
接收消息
为了接收消息,你需要监听JMessage的事件。你可以使用JMessage.addMessageListener
来监听消息事件。
// 在initJMessage函数中添加消息监听器
void initJMessage() async {
// 初始化JMessage
await JMessage.init({
"appKey": "你的AppKey",
"channelName": "defaultChannel",
"isProduction": false,
});
// 登录用户
await JMessage.login({
"username": "testUser",
"password": "testPassword"
}).then((result) {
print("登录结果: $result");
// 添加消息监听器
JMessage.addMessageListener((message) {
print("收到消息: $message");
// 处理收到的消息
});
}).catchError((error) {
print("登录错误: $error");
});
}
这个示例展示了如何在Flutter应用中使用jmessage_flutter
插件进行基本的即时通讯功能,包括初始化、登录、发送和接收消息。根据你的需求,你可以进一步扩展这些功能,比如处理不同类型的消息(图片、语音、视频等),管理会话,处理用户状态等。