{"id":13687017,"url":"https://github.com/rongcloud/rongcloud-im-flutter-sdk","last_synced_at":"2025-05-01T12:32:27.314Z","repository":{"id":36772552,"uuid":"191494323","full_name":"rongcloud/rongcloud-im-flutter-sdk","owner":"rongcloud","description":"IM Flutter SDK of RongCloud","archived":true,"fork":false,"pushed_at":"2022-07-22T10:02:34.000Z","size":106252,"stargazers_count":199,"open_issues_count":6,"forks_count":56,"subscribers_count":41,"default_branch":"master","last_synced_at":"2024-08-03T15:06:11.720Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rongcloud.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-12T03:56:40.000Z","updated_at":"2024-07-11T09:51:40.000Z","dependencies_parsed_at":"2022-07-15T20:17:23.367Z","dependency_job_id":null,"html_url":"https://github.com/rongcloud/rongcloud-im-flutter-sdk","commit_stats":null,"previous_names":[],"tags_count":95,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rongcloud%2Frongcloud-im-flutter-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rongcloud%2Frongcloud-im-flutter-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rongcloud%2Frongcloud-im-flutter-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rongcloud%2Frongcloud-im-flutter-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rongcloud","download_url":"https://codeload.github.com/rongcloud/rongcloud-im-flutter-sdk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224257393,"owners_count":17281698,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T15:00:46.553Z","updated_at":"2024-11-12T10:30:36.790Z","avatar_url":"https://github.com/rongcloud.png","language":"Dart","funding_links":[],"categories":["Dart"],"sub_categories":[],"readme":"# 融云即时通讯 Flutter 插件\n\n本存储库为融云即时通讯的 [Flutter](https://flutter.dev/) 插件。插件基于融云 iOS/Android 平台的 IMLib SDK。\n\n## 更新提示\n\n- 从 2.0.0 开始废弃核心类 RongcloudImPlugin，新的核心类名为 `RongIMClient`。\n\n- 从 1.1.0 开始为方便排查 Android 问题将即时通讯 Flutter SDK Android 的包名改为 `io.rong.flutter.imlib`。\n\n完整发版历史，请移步 [CHANGELOG.md](CHANGELOG.md)。\n\n## 获取 App Key\n\n应用需要有 App Key 才能换取客户端连接融云服务器的身份凭证。通过开发者后台[获取 App Key](https://developer.rongcloud.cn/app/appkey/)。\n\n\u003c!-- 通过管理后台的 \"IM 服务\"—\u003e\"API 调用\"-\u003e\"用户服务\"-\u003e\"获取 Token\"，通过用户 id 获取 IMToken --\u003e\n\n## 导入 SDK\n\n1. 在项目的 `pubspec.yaml` 中，添加融云即时通讯 Flutter 插件为依赖项：\n\n    ```dart\n    dependencies:\n      flutter:\n        sdk: flutter\n    \n    rongcloud_im_plugin: ^5.1.8+7\n    ```\n\n2. 在项目路径下，下载插件：\n\n    ```\n    flutter packages get\n    ```\n\n## 初始化 SDK\n\n使用从开发者后台获取的 App Key 初始化 SDK。\n\n```dart\nRongIMClient.init(RongAppKey);\n```\n\n## 连接 IM\n\n连接融云服务器。\n\n```dart\nRongIMClient.connect(RongIMToken, (int code, String userId) {\n  print('connect result ' + code.toString());\n  EventBus.instance.commit(EventKeys.UpdateNotificationQuietStatus, {});\nif (code == 31004 || code == 12) {\n  Navigator.of(context).pushAndRemoveUntil(new MaterialPageRoute(builder: (context) =\u003e new LoginPage()), (route) =\u003e route == null);\n} else if (code == 0) {\n  print(\"connect userId\" + userId);\n  // 连接成功后打开数据库\n  // _initUserInfoCache();\n}\n```\n\n## API 调用\n\n### 断开 IM 连接\n\n```dart\n//needPush 断开连接之后是否需要远程推送\nRongIMClient.disconnect(bool needPush)\n```\n\n### 发送消息\n\n发送文本消息\n\n  ```dart\n  onSendMessage() async{\n        TextMessage txtMessage = new TextMessage();\n        txtMessage.content = \"这条消息来自 Flutter\";\n        Message msg = await RongIMClient.sendMessage(RCConversationType.Private, privateUserId, txtMessage);\n        print(\"send message start senderUserId = \"+msg.senderUserId);\n    }\n  ```\n\n发送图片消息\n\n```dart\nonSendImageMessage() async {\n    ImageMessage imgMessage = new ImageMessage();\n    imgMessage.localPath = \"image/local/path.jpg\";\n    Message msg = await RongIMClient.sendMessage(RCConversationType.Private, privateUserId, imgMessage);\n    print(\"send image message start senderUserId = \"+msg.senderUserId);\n  }\n```\n\n发送 Gif 消息\n\n```dart\nonSendGifMessage() async {\n    GIFMessage gifMessage = GifMessage.obtain(\"gif/local/path.jpg\");\n    Message msg = await RongIMClient.sendMessage(RCConversationType.Private, privateUserId, gifMessage);\n    print(\"send gif message start senderUserId = \"+msg.senderUserId);\n  }\n```\n\n\n发送文件消息\n\n```dart\nonSendFileMessage() async {\n    // localPath 为文件本地路径,注意 Android 必须以 file:// 开头\n    FileMessage fileMessage = FileMessage.obtain(localPaht);\n    // 文件后缀如 \"png\" \"txt\"\n    fileMessage.mType = \"XXX\";\n    Message msg = await RongIMClient.sendMessage(\n              conversationType, targetId, fileMessage);\n  }\n```\n\n发送结果回调\n\n```dart\n//消息发送结果回调\n    RongIMClient.onMessageSend = (int messageId,int status,int code) {\n      print(\"send message messsageId:\"+messageId.toString()+\" status:\"+status.toString()+\" code:\"+code.toString());\n    };\n```\n\n媒体消息媒体文件上传进度\n\n```dart\n//媒体消息（图片/语音消息）上传媒体进度的回调\n    RongIMClient.onUploadMediaProgress = (int messageId,int progress) {\n      print(\"upload media messsageId:\"+messageId.toString()+\" progress:\"+progress.toString());\n    };\n```\n\n### 接收消息\n\n\u003e **注意**：以下两个接收消息的回调只能实现一个，否则会重复收到消息。\n\n如果离线消息量不大，可以使用下面这个回调。\n\n```dart\n//消息接收回调\n    RongIMClient.onMessageReceived = (Message msg,int left) {\n      print(\"receive message messsageId:\"+msg.messageId.toString()+\" left:\"+left.toString());\n    };\n```\n\n离线消息量巨大时，建议使用以下回调分批拉取离线消息。建议在 left == 0 且 hasPackage == false 时刷新会话列表。\n\n```dart\n//消息接收回调\n    RongIMClient.onMessageReceivedWrapper = (Message msg, int left, bool hasPackage, bool offline) {\n      print(\"receive message messsageId:\"+msg.messageId.toString()+\" left:\"+left.toString());\n    };\n```\n\n### 历史消息\n\n获取本地历史消息\n    \n```dart\nonGetHistoryMessages() async {\n    List msgs = await RongIMClient.getHistoryMessage(RCConversationType.Private, privateUserId, 0, 10);\n    print(\"get history message\");\n    for(Message m in msgs) {\n      print(\"sentTime = \"+m.sentTime.toString());\n    }\n  }\n```\n\n获取远端历史消息\n\n```dart\nRongIMClient.getRemoteHistoryMessages(1, \"1001\", 0, 20,(List\u003cMessage\u003e msgList,int code) {\n      if(code == 0) {\n        for(Message msg in msgList) {\n          print(\"getRemoteHistoryMessages  success \"+ msg.messageId.toString());\n        }\n      }else {\n        print(\"getRemoteHistoryMessages error \"+code.toString());\n      }\n    });\n```\n\n插入发出的消息\n\n```dart\nRongIMClient.insertOutgoingMessage(RCConversationType.Private, \"1001\", 10, msgT, 0, (msg,code){\n      print(\"insertOutgoingMessage \" + msg.content.encode() + \" code \" + code.toString());\n\n    });\n```\n\n插入收到的消息\n\n```dart\nRongIMClient.insertIncomingMessage(RCConversationType.Private, \"1002\", \"1002\", 1, msgT , 0, (msg,code){\n      print(\"insertIncomingMessage \" + msg.content.encode() + \" code \" + code.toString());\n    });\n```\n\n删除特定会话消息\n\n```dart\nRongIMClient.deleteMessages(RCConversationType.Private, \"2002\", (int code) {\n\n});\n```\n\n批量删除消息\n\n```dart\nList\u003cint\u003e mids =  [];\nmids.add(1);\nRongIMClient.deleteMessageByIds(mids, (int code) {\n\n});\n```\n\n### 未读数\n\n获取特定会话的未读数\n\n```dart\nRongIMClient.getUnreadCount(RCConversationType.Private, \"targetId\", (int count,int code) {\n      if( 0 == code) {\n        print(\"未读数为\"+count.toString());\n      }\n    });\n```\n\n获取特定会话类型的未读数\n\n```dart\nRongIMClient.getUnreadCountConversationTypeList([RCConversationType.Private,RCConversationType.Group], true, (int count, int code) {\n      if( 0 == code) {\n        print(\"未读数为\"+count.toString());\n      }\n    });\n```\n\n获取所有未读数\n\n```dart\nRongIMClient.getTotalUnreadCount((int count, int code) {\n      if( 0 == code) {\n        print(\"未读数为\"+count.toString());\n      }\n    });\n```\n\n### 会话列表\n\n获取会话列表\n\n```dart\nonGetConversationList() async {\n    List conversationList = await RongIMClient.getConversationList([RCConversationType.Private,RCConversationType.Group,RCConversationType.System]);\n\n    for(Conversation con in cons) {\n      print(\"conversation latestMessageId \" + con.latestMessageId.toString());\n    }\n  }\n```\n\n删除指定会话\n\n```dart\nRongIMClient.removeConversation(RCConversationType.Private, \"1001\", (success) {\n      if(success) {\n        print(\"删除会话成功\");\n      }\n    });\n```\n\n### 黑名单\n\n把用户加入黑名单\n\n```dart\nRongIMClient.addToBlackList(blackUserId, (int code) {\n      print(\"_addBlackList:\" + blackUserId + \" code:\" + code.toString());\n    });\n```\n\n把用户移出黑名单\n\n```dart\nRongIMClient.removeFromBlackList(blackUserId, (int code) {\n      print(\"_removeBalckList:\" + blackUserId + \" code:\" + code.toString());\n    });\n```\n\n查询特定用户的黑名单状态\n\n```dart\nRongIMClient.getBlackListStatus(blackUserId,\n        (int blackStatus, int code) {\n      if (0 == code) {\n        if (RCBlackListStatus.In == blackStatus) {\n          print(\"用户:\" + blackUserId + \" 在黑名单中\");\n        } else {\n          print(\"用户:\" + blackUserId + \" 不在黑名单中\");\n        }\n      } else {\n        print(\"用户:\" + blackUserId + \" 黑名单状态查询失败\" + code.toString());\n      }\n    });\n```\n\n查询已经设置的黑名单列表\n\n```dart\nRongIMClient.getBlackList((List/*\u003cString\u003e*/ userIdList, int code) {\n      print(\"_getBlackList:\" + userIdList.toString() + \" code:\" + code.toString());\n      userIdList.forEach((userId) {\n        print(\"userId:\"+userId);\n      });\n    });\n```\n\n### 聊天室\n\n加入聊天室\n\n```dart\nonJoinChatRoom() {\n    RongIMClient.joinChatRoom(\"testchatroomId\", 10);\n  }\n```\n\n加入聊天室回调\n\n```dart\n//加入聊天室结果回调\n    RongIMClient.onJoinChatRoom = (String targetId,int status) {\n      print(\"join chatroom:\"+targetId+\" status:\"+status.toString());\n    };\n```\n\n退出聊天室\n\n```dart\nonQuitChatRoom() {\n    RongIMClient.quitChatRoom(\"testchatroomId\");\n  }\n```\n\n退出聊天室回调\n\n```dart\n//退出聊天室结果回调\n    RongIMClient.onQuitChatRoom = (String targetId,int status) {\n      print(\"quit chatroom:\"+targetId+\" status:\"+status.toString());\n    };\n```\n\n获取聊天室信息\n\n```dart\nonGetChatRoomInfo() async {\n    ChatRoomInfo chatRoomInfo = await RongIMClient.getChatRoomInfo(\"testchatroomId\", 10, RCChatRoomMemberOrder.Desc);\n    print(\"onGetChatRoomInfo targetId =\"+chatRoomInfo.targetId);\n  }\n```\n\n### Native 向 Flutter 传递数据\n\niOS 端传递数据:\n\n```objective-c\n[[RCIMFlutterWrapper sharedWrapper] sendDataToFlutter:@{@\"key\":@\"ios\"}];\n\n```\n\nAndroid 端传递数据:\n\n```java\nMap map = new HashMap();\nmap.put(\"key\",\"android\");\nRCIMFlutterWrapper.getInstance().sendDataToFlutter(map);\n```\n\nFlutter 端接收数据:\n\n```dart\nRongIMClient.onDataReceived = (Map map) {\n  print(\"object onDataReceived \" + map.toString());\n};\n```\n\n### 单聊已读回执\n\n发送已读回执:\n\n```dart\nRongIMClient.sendReadReceiptMessage(conversationType, targetId, timestamp, (int code){\n  if (code == 0) {\n    print('sendReadReceiptMessageSuccess');\n  } else {\n    print('sendReadReceiptMessageFailed:code = + $code');\n  }\n});\n```\n\n接收已读回执:\n\n```\nRongIMClient.onReceiveReadReceipt = (Map map) {\n  print(\"object onReceiveReadReceipt \" + map.toString());\n};\n```\n\n### 群组已读回执\n\n[如何实现群组已读回执](https://doc.rongcloud.cn/im/Flutter/5.X/noui/message/receiptGroup)\n\n\n### 消息撤回\n\n撤回消息调用如下接口会返回 `RecallNotificationMessage` 类型的消息体，需要把原有消息的内容替换，刷新 UI 显示为此类型消息的展示。\n\n```dart\nvoid _recallMessage(Message message) async {\n    RecallNotificationMessage recallNotifiMessage =\n        await RongIMClient.recallMessage(message, \"\");\n    if (recallNotifiMessage != null) {\n      message.content = recallNotifiMessage;\n      _insertOrReplaceMessage(message);\n    } else {\n      showShortToast(\"撤回失败\");\n    }\n  }\n```\n\n### 聊天室属性自定义\n\n详细参见[聊天室存储相关接口](https://doc.rongcloud.cn/im/Flutter/5.X/noui/chatroom/chatroomKV)\n\n\n### 消息搜索\n\n首先搜索关键词相关的会话信息。\n\n```dart\nstatic void searchConversations(\n      String keyword,\n      List conversationTypes,\n      List objectNames,\n      Function(int code, List searchConversationResult) finished)\n```\n\n接着，根据搜索会话返回的信息，针对某个会话搜索相应会话的消息。\n\n```dart\nstatic void searchMessages(\n      int conversationType,\n      String targetId,\n      String keyword,\n      int count,\n      int beginTime,\n      Function(List/*\u003cMessage\u003e*/ msgList, int code) finished) \n```\n\n### 全局消息提醒\n\n全局屏蔽某个时间段的消息提醒\n\n```dart\nvoid _setNotificationQuietHours() {\n    RongIMClient.setNotificationQuietHours(\"09:00:00\", 600,\n        (int code) {\n      String toast = \"设置全局屏蔽某个时间段的消息提醒:\\n\" +\n          (code == 0 ? \"设置成功\" : \"设置失败, code:\" + code.toString());\n      print(toast);\n    });\n  }\n```\n\n查询已设置的全局时间段消息提醒屏蔽\n\n```dart\n  void _getNotificationQuietHours() {\n    RongIMClient.getNotificationQuietHours(\n        (int code, String startTime, int spansMin) {\n      String toast = \"查询已设置的全局时间段消息提醒屏蔽\\n: startTime:\" +\n          startTime +\n          \" spansMin:\" +\n          spansMin.toString() +\n          (code == 0 ? \"\" : \"\\n设置失败, code:\" + code.toString());\n      print(toast);\n    });\n  }\n```\n\n删除已设置的全局时间段消息提醒屏蔽\n\n```dart\n  void _removeNotificationQuietHours() {\n    RongIMClient.removeNotificationQuietHours((int code) {\n      String toast = \"删除已设置的全局时间段消息提醒屏蔽:\\n\" +\n          (code == 0 ? \"删除成功\" : \"删除失败, code:\" + code.toString());\n      print(toast);\n    });\n  }\n```\n\n### 获取会话中@提醒自己的消息\n\n```dart\ngetUnreadMentionedMessages(int conversationType, String targetId) {\n  Future\u003cList\u003e messages = RongIMClient.getUnreadMentionedMessages(conversationType, targetId);\n  print(\"get unread mentioned messages = \" + messages.toString());\n}\n```\n\n### 发送群定向消息\n\n1. 此方法用于在群组中发送消息给其中的部分用户，其它用户不会收到这条消息。\n2. 此方法目前仅支持群组。\n3. 群定向消息不存储到云端，通过“单群聊消息云存储”服务无法获取到定向消息。\n\n```dart\nonSendDirectionalMessage() async {\n    TextMessage txtMessage = new TextMessage();\n    txtMessage.content = \"这条消息来自 Flutter 的群定向消息\";\n    Message message = await RongIMClient.sendDirectionalMessage(\n        RCConversationType.Group, targetId, ['UserId1', 'UserId2'], txtMessage);\n    print(\"send directional message start senderUserId = \" + msg.senderUserId);\n  }\n```\n\n### 设置断线重连时是否踢出当前正在重连的设备\n\n设置 enable 为 YES 时，SDK 重连的时候发现此时已有别的设备连接成功，不再强行踢出已有设备，而是踢出重连设备。\n\n```dart\nRongIMClient.setReconnectKickEnable(true);\n```\n\n### 获取当前 SDK 的连接状态\n\n```dart\nvoid getConnectionStatus() async {\n  int status = await RongIMClient.getConnectionStatus();\n  print('getConnectionStatus: $status');\n}\n```\n\n### 取消下载中的媒体文件\n\n```dart\nRongIMClient.cancelDownloadMediaMessage(100);\n```\n\n### 从服务器端获取聊天室的历史消息\n\n```dart\nvoid _getChatRoomHistoryMessage() {\n  RongIMClient.getRemoteChatroomHistoryMessages(\n      targetId, 0, 20, RCTimestampOrder.RC_Timestamp_Desc,\n      (List/*\u003cMessage\u003e*/ msgList, int syncTime, int code) {\n    DialogUtil.showAlertDiaLog(\n        context,\n        \"获取聊天室历史消息：code：\" +\n            CodeUtil.codeString(code) +\n            \"，msgListCount：${msgList.length} 条消息\\n\" +\n            \"，msgList：$msgList\" +\n            \"，syncTime：$syncTime\");\n  });\n}\n```\n\n### 通过 messageUId 获取消息实体\n\nmessageUID: 发送 message 成功后，服务器会给每个 message 分配一个唯一 messageUId。\n\n```dart\nMessage msg = await RongIMClient.getMessageByUId(message.messageUId);\n```\n\n### 删除指定的一条或者一组消息\n\n该操作会同时删除本地和远端消息 (会话类型不支持聊天室)。\n\n```dart\nRongIMClient.deleteRemoteMessages(conversationType, targetId, messageList, (code){\n    print(\"result: $code\");\n    });\n```\n\n### 清空指定会话的聊天记录\n\n该操作要求指定会话的类型和 targetId。\n\n```dart\nRongIMClient.clearMessages(con.conversationType, con.targetId, (code) {\n    print(\"result:$code\");\n    });\n```\n\n### 设置本地消息的附加信息（message.extra）\n\n```dart\nRongIMClient.setMessageExtra(int messageId, value, (code) {\n    print(\"result:$code\");\n    });\n```\n\n### 设置接收到的消息状态\n\n根据 messageId 设置接收到的消息状态。用于 UI 标记消息为已读、已下载等状态。\n\n```dart\nRongIMClient.setMessageReceivedStatus(message.messageId, 1, (code) async{\n    print(\"setMessageReceivedStatus result:$code\");\n    });\n```\n\n### 设置消息的发送状态\n\n根据 messageId 设置消息的发送状态。用于 UI 标记消息为正在发送、对方已接收等状态。\n\n```dart\nRongIMClient.setMessageSentStatus(message.messageId, 1, (code) async{\n    print(\"setMessageReceivedStatus result:$code\");\n    });\n```\n\n### 清空会话类型列表中的所有会话及会话信息\n\n```dart\nRongIMClient.clearConversations(conversations, (code) async{\n    print(\"clearConversations result:$code\");\n    });\n```\n\n### 获取本地时间与服务器时间的差值\n\n消息发送成功后，SDK 会与服务器同步时间，消息所在数据库中存储的时间就是服务器时间。\n\n```dart\nint deltaTime = await RongIMClient.getDeltaTime()\n```\n\n### 设置当前用户离线消息补偿时间\n\n```dart\nRongIMClient.setOfflineMessageDuration(3, (code, result){\n    print(\"setOfflineMessageDuration code:$code result:$result\");\n    });\n```\n\n### 获取当前用户离线消息的存储时间\n\n离线消息的存储时间取值范围为 int 值 1~7 天。\n\n```dart\nint duration = await RongIMClient.getOfflineMessageDuration();\n```\n\n## 文档\n\n- GitHub：[融云即时通讯 Flutter 参考文档](https://doc.rongcloud.cn/im/Flutter/5.X/noui/quick_integration)\n\n- 官网：[融云 iOS 文档集成](https://doc.rongcloud.cn/im/IOS/5.X/noui/quick_integration)\n\n- 官网：[融云 Android 文档集成](https://doc.rongcloud.cn/im/Android/5.X/noui/quick_integration)\n\n- 官网：[设置 Android 端推送](https://doc.rongcloud.cn/im/Android/5.X/noui/push/summary)\n\n\n## 支持\n\n\n源码地址 [Github](https://github.com/rongcloud/rongcloud-im-flutter-sdk)。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frongcloud%2Frongcloud-im-flutter-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frongcloud%2Frongcloud-im-flutter-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frongcloud%2Frongcloud-im-flutter-sdk/lists"}