tencent_im_plugin

pub package

腾讯云IM插件

Getting Started

集成腾讯云IM SDK,同时支持 Android 和 IOS
🎉🎉🎉🎉🎉离线推送部分接口已实现,关注:setOfflinePushSettingssetOfflinePushToken🎉🎉🎉🎉🎉
注意:当前为测试版本,如果您要集成到正式项目,请保持关注新版本。稳定版本将大于等于 v1.0.0
注意:由于腾讯云IM升级了新版本,但是本插件基于上一个版本,所以浏览开发文档时请通过以下地址:Android IOS ,在完成基本工作后,插件将进行相应更新

功能清单

x初始化
x登录相关
x消息收发
x未读计数
x群组相关
x用户资料与关系链
-离线推送

近期计划(已完成内容将会被移除)

升级IM SDK版本
验证 群提示消息修改时 不能获取到具体类型的问题
- 腾讯云离线推送
TIMProfileSystemElem
TIMGroupSystemElem

下版本计划(0.3.0)

  1. 将不同类别的方法封装到不同实体

集成

Flutter

tencent_im_plugin: ^[最新版本号]

Android 端集成

无需额外配置,已内部打入混淆配置

IOS

无需额外配置

使用

Demo截图:

功能清单

消息发送节点

节点进度说明
TextMessageNode文本消息
ImageMessageNode图片消息
SoundMessageNode语音消息
VideoMessageNode视频消息
CustomMessageNode自定义消息
LocationMessageNode位置消息

消息接收节点

节点进度说明
TIMCustomElem已完成
TIMFaceElem-暂不考虑
TIMFileElem-暂不考虑,建议使用 TIMCustomElem 代替
TIMGroupSystemElem-计划内
TIMGroupTipsElem已完成
TIMImageElem已完成
TIMLocationElem已完成
TIMProfileSystemElem-计划内容
TIMSNSSystemElem已完成
TIMSoundElem已完成
TIMTextElem已完成
TIMVideoElem已完成
OtherMessageNode已完成,仅Android(IOS能够解析,但是内容体没有数据)

接口(右滑查看详细参数)

接口说明参数AndroidIOS
init初始化{appid:"xxxxxx",enabledLogPrint:"是否启用日志打印",logPrintLevel:"日志打印级别"}
login登录{identifier:'用户ID',userSig:'用户签名'}
logout登出-
getLoginUser获得当前登录用户ID-
initStorage初始化本地存储(如果这个方法在 login 后进行 await 调用,则会造成卡死){identifier: '用户ID'}
getConversationList获得会话列表(如果是离线状态,则获取出来的会话列表不包含: Group、UserProfile 信息)-
getConversation获得单个会话(如果是离线状态,则获取出来的会话列表不包含: Group、UserProfile 信息){id:'会话ID',sessionType:'会话类型}
getGroupInfo获得群信息(云端){id:'群ID'}
getUserInfo获得用户信息{id:'用户ID',forceUpdate:"是否从云端拉取数据,默认为false"}
setRead设置已读{sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType' }
getMessages获得消息列表(如果是离线状态,则获取出来的消息不包含 UserProfile 信息){sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType',number:"会话数量",lastMessage:'最后一条消息'}
getLocalMessages获得本地消息列表(如果是离线状态,则获取出来的消息不包含 UserProfile 信息){sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType',number:"会话数量",lastMessage:'最后一条消息'}
sendMessage发送消息{sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType',ol:"是否是在线消息(无痕)",node:消息节点对象}
saveMessage向本地消息列表中添加一条消息,但并不将其发送出去。{sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType',node:消息节点对象,sender:"发送人",isReaded:'是否已读'}
getFriendList获得好友列表-
getGroupList获得群组列表-
addFriend添加好友{id:'用户ID',addType:'添加类型',remark:'备注',addWording:'请求说明',addSource:'添加来源',friendGroup:'分组名'}
checkSingleFriends检测单个好友关系{id:'用户ID',type:'检测类型'}
getPendencyList获得未决好友列表(申请中){type:'类型',seq:'未决列表序列号',timestamp:'翻页时间戳',numPerPage:'每页数量'}
pendencyReport未决已读上报{timestamp:"时间戳"}
deletePendency未决删除{id:'用户Id',type:'类型'}
examinePendency未决审核{id:'用户ID',type:'类型',remark:'备注'}
deleteConversation删除会话{sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType',removeCache:'是否删除本地消息缓存'}
deleteLocalMessage删除会话内的本地聊天记录{sessionId:'会话ID',sessionType:'会话类型,枚举值:SessionType'}
createGroup创建群组{groupId:'指定群ID',notification:'群公告',introduction:'描述',faceUrl:'头像',addOption:'入群类型',maxMemberNum:'最大成员数量',members:'成员集合',type:'类型',name:'群名',customInfo:'自定义数据'}
inviteGroupMember邀请加入群组{groupId:'群ID',ids:'群成员ID'}
applyJoinGroup申请加入群组{groupId:'群ID',reason:'申请说明'}
quitGroup退出群组{groupId:'群ID'}
deleteGroupMember删除群组成员{groupId:'群ID',ids:'用户ID集合',reason:"删除说明"}
getGroupMembers获得群成员列表{groupId:'群ID'}
deleteGroup解散群组{groupId:'群ID'}
modifyGroupOwner转让群组{groupId:'群ID',identifier:'新群主ID'}
modifyGroupInfo修改群组资料{groupId:'指定群ID',notification:'群公告',introduction:'描述',faceUrl:'头像',addOption:'入群类型',maxMemberNum:'最大成员数量(IOS不支持)',type:'类型',groupName:'群名',visable:'是否对外可见',silenceAll:'全员禁言',customInfo:'自定义信息'}
modifyMemberInfo修改群成员资料{groupId:'群ID',identifier:'群成员ID',nameCard:'名片',receiveMessageOpt:'接收消息选项,注:IOS不支持',silence:'禁言时间',role:'角色',customInfo:'自定义数据'}
getGroupPendencyList获得未决群列表{timestamp:'翻页时间戳',numPerPage:'每页的数量'}
reportGroupPendency上报群未决已读{timestamp:'已读时间戳'}
groupPendencyAccept群未决审核(同意)会遍历所有未决列表来获得未审核的列表,存在性能隐患{msg:'审核意见',groupId:'群ID',identifier:'申请人ID',addTime:'申请时间'}
groupPendencyRefuse群未决审核(拒绝)会遍历所有未决列表来获得未审核的列表,存在性能隐患{msg:'审核意见',groupId:'群ID',identifier:'申请人ID',addTime:'申请时间'}
getSelfProfile获取登录用户资料{forceUpdate:"是否强制走后台拉取"}
modifySelfProfile修改登录用户资料 字段参考文档{params:'修改参数'}
modifyFriend修改好友资料 字段参考文档{identifier:'好友ID',params:'修改参数'}
deleteFriends删除好友{ids:"用户ID列表",delFriendType:'删除类型'}
addBlackList添加到黑名单{ids:"用户ID列表"}
deleteBlackList从黑名单删除{ids:"用户ID列表"}
getBlackList获得黑名单列表-
createFriendGroup创建好友分组{groupNames:'组名列表',ids:'用户列表'}
deleteFriendGroup删除好友分组{groupNames:'组名列表'}
addFriendsToFriendGroup添加好友到某个分组{groupName:'组名',ids:'ID列表'}
deleteFriendsFromFriendGroup从分组删除好友{groupName:'组名',ids:'ID列表'}
renameFriendGroup重命名分组{oldGroupName:'旧名称',newGroupName:'新名称'}
getFriendGroups获得好友分组{groupNames:'组名'}
revokeMessage撤回一条发送成功的消息{message:'消息对象'}
removeMessage删除一条消息(本地){message:'消息对象'}
setMessageCustomInt设置自定义整数{message:'消息对象',value:'自定义值'}
setMessageCustomStr设置自定义整数{message:'消息对象',value:'自定义值'}
downloadVideoImage获得视频图片(缩略图){message:'消息对象',path:'保存截图的路径'}
downloadVideo获得视频{message:'消息对象',path:'保存视频的路径'}
downloadSound获得语音{message:'消息对象',path:'保存语音的路径'}
findMessage查找一条消息{sessionId:'会话ID',sessionType:'会话类型',rand:'随机码',seq:'消息系列号',timestamp:'消息时间戳',self:'是否是自己发送的消息'}
setOfflinePushSettings设置离线推送相关设置(请保证该方法在登录后调用){enabled:'是否启用',c2cSound:'C2C音频文件',groupSound:'Group音频文件',videoSound:'视频邀请语音'}
setOfflinePushToken设置离线推送相关Token(登录之后调用){token:'各个手机厂商的推送服务对客户端的唯一标识,需要集成各个厂商的推送服务获取',bussid:'推送证书 ID,是在 IM 控制台上生成的'}

消息监听

通过 TencentImPlugin.addListenerTencentImPlugin.removeListener 可进行事件监听

@override
vodi initState(){
  super.initState();
  TencentImPlugin.addListener(_messageListener);
}
@override
void dispose() {
  super.dispose();
  TencentImPlugin.removeListener(_messageListener);
}

 _messageListener(ListenerTypeEnum type, params) {
  // you code
};

注意:addListener 后,请注意在必要时进行 removeListener

离线推送

注意: 本插件仅在腾讯云IM上进行封装,并未集成小米、华为等推送方的SDK,故集成离线推送时根据腾讯云文档进行集成。已封装离线推送配置方法。
如果你要集成

离线推送相关接口

setOfflinePushSettings: 设置离线推送相关设置,包含:是否启用、C2C消息语音、群聊消息语音和视频邀请语音。请保证该方法在登录后调用!
setOfflinePushToken: 设置离线推送相关Token,token 是各个手机厂商的推送服务对客户端的唯一标识,需要集成各个厂商的推送服务获取; bussid 是推送证书 ID,是在 IM 控制台上生成的, 具体步骤请参考 https://cloud.tencent.com/document/product/269/9234

1. 插件集成步骤

小米 xiao_mi_push_plugin pub package
  1. 引入插件
xiao_mi_push_plugin: 1.0.0
  1. 修改 AndroidManifest.xml 文件,增加:
<permission android:name="你的包名.permission.MIPUSH_RECEIVE" android:protectionLevel="signature"/>
<uses-permission android:name="你的包名.permission.MIPUSH_RECEIVE"/>
  1. 初始化以及绑定监听器
void bindXiaoMiPush(){
  XiaoMiPushPlugin.addListener((type,params){
    if(type == XiaoMiPushListenerTypeEnum.ReceiveRegisterResult){
      TencentImPlugin.setOfflinePushToken(token: params.commandArguments[0],bussid: BUSSID)
    }  
  });

  XiaoMiPushPlugin.init(appId: APP_ID, appKey: APP_KEY);
}
  1. 消息接收等使用方法请参考 xiao_mi_push_plugin 插件
华为

暂无符合要求的插件

Google FCM 推送

暂无符合要求的插件

魅族推送

暂无符合要求的插件

OPPO 推送

暂无符合要求的插件

vivo 推送

暂无符合要求的插件

Apple

推荐 flutter-apns(暂未集成测试)

2. 自行集成步骤

Android
IOS
示例: 小米推送

  1. 根据腾讯云文档配置证书(bussid)并下载小米推送SDK

  2. android/app 目录创建 libs 文件夹,并将小米推送SDK拷贝 android/app/libs/MiPush_SDK_Client_3_7_6.jar

  3. 编写 app/build.gradle 文件,引入 libs 的jar包

    dependencies {
        api fileTree(include: ['*.jar'], dir: 'libs')
    }
    
  4. 编写 android/app/src/main/AndroidManifest.xml 文件,添加权限

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.GET_TASKS" />
     <uses-permission android:name="android.permission.VIBRATE" />
    
     <permission
         android:name="top.huic.tencent_im_plugin_example.permission.MIPUSH_RECEIVE"
         android:protectionLevel="signature" />
     <uses-permission android:name="top.huic.tencent_im_plugin_example.permission.MIPUSH_RECEIVE" /> 
    

    注意: 请将 top.huic.tencent_im_plugin_example 替换为你的包名

  5. 编写 android/app/src/main/AndroidManifest.xml,在 application 标签中添加

    <service
        android:name="com.xiaomi.push.service.XMPushService"
        android:enabled="true"
        android:process=":pushservice" />
    <service
        android:name="com.xiaomi.push.service.XMJobService"
        android:enabled="true"
        android:exported="false"
        android:permission="android.permission.BIND_JOB_SERVICE"
        android:process=":pushservice" />
    <service
        android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
        android:enabled="true"
        android:exported="true" />
    <service
        android:name="com.xiaomi.mipush.sdk.MessageHandleService"
        android:enabled="true" />
    <receiver
        android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    <receiver
        android:name="com.xiaomi.push.service.receivers.PingReceiver"
        android:exported="false"
        android:process=":pushservice">
        <intent-filter>
            <action android:name="com.xiaomi.push.PING_TIMER" />
        </intent-filter>
    </receiver>
    
  6. 更改 android/app/src/main/MainActivity.java 文件,加入如下代码

    
    /**
     * Flutter 通知器
     */
     public static MethodChannel channel;
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (shouldInit()) {
            MiPushClient.registerPush(this, APP_ID, APP_KEY);
        }
        channel = new MethodChannel(this.getFlutterEngine().getDartExecutor(), "tencent_im_plugin_example");
    }
    
    /**
     * 通过判断手机里的所有进程是否有这个App的进程
     * 从而判断该App是否有打开
     *
     * @return 是否需要初始化 -true 需要
     */
    private boolean shouldInit() {
        // 通过ActivityManager我们可以获得系统里正在运行的activities
        // 包括进程(Process)等、应用程序/包、服务(Service)、任务(Task)信息。
        ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
        List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
        String mainProcessName = getPackageName();
    
        // 获取本App的唯一标识
        int myPid = android.os.Process.myPid();
        // 利用一个增强for循环取出手机里的所有进程
        for (ActivityManager.RunningAppProcessInfo info : processInfos) {
            // 通过比较进程的唯一标识和包名判断进程里是否存在该App
            if (info.pid == myPid && mainProcessName.equals(info.processName)) {
                return true;
            }
        }
        return false;
    }
    
  7. android/app/src/main/ 中创建包 push(非必须)

  8. android/app/src/main/push 创建类:XiaomiMsgReceiver

    public class XiaomiMsgReceiver extends PushMessageReceiver {
        @Override
        public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
            String command = message.getCommand();
            List<String> arguments = message.getCommandArguments();
            String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);
    
            String token = null;
            if (MiPushClient.COMMAND_REGISTER.equals(command)) {
                if (message.getResultCode() == ErrorCode.SUCCESS) {
                    token = cmdArg1;
                }
            }
    
            // 调用通知监听器传递到Flutter层
            Handler mainHandler = new Handler(Looper.getMainLooper());
            String finalToken = token;
            mainHandler.post(() -> MainActivity.channel.invokeMethod("miPushTokenListener", finalToken));
        }
    }
    
  9. 编写 android/app/src/main/AndroidManifest.xml,在 application 标签中添加

    <receiver
           android:exported="true"
           android:name="top.huic.tencent_im_plugin_example.push.XiaomiMsgReceiver">
           <!--这里com.xiaomi.mipushdemo.DemoMessageRreceiver改成app中定义的完整类名-->
           <intent-filter>
               <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
           </intent-filter>
           <intent-filter>
               <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />
           </intent-filter>
           <intent-filter>
               <action android:name="com.xiaomi.mipush.ERROR" />
           </intent-filter>
       </receiver>
    

    top.huic.tencent_im_plugin_example.push.XiaomiMsgReceiver 修改为 XiaomiMsgReceiver的包路径

  10. 在 lib 目录创建 tencent_im_plugin_example.dart

   class TencentImPluginExample {
     static const MethodChannel _channel = const MethodChannel('tencent_im_plugin_example');
   
     /// 小米推送TOken
     static String miPushToken;
   
     /// 设置监听器
     static setListener(){
       _channel.setMethodCallHandler((call) {
         if (call.method == 'miPushTokenListener') {
           miPushToken = call.arguments as String;
         }
         return null;
       });
     }
   }
  1. 在程序启动后调用
   TencentImPluginExample.setListener();
  1. 最后,在登录之后调用 setOfflinePushToken 即可,可使用 腾讯云离线推送自查工具查看是否注册成功
   if(TencentImPluginExample.miPushToken != null){
     await TencentImPlugin.setOfflinePushToken(token: TencentImPluginExample.miPushToken,bussid: 10301);
   }

缺陷

如果您要集成多个平台,那么需要频繁修改 Android 配置和 Android 代码,这对Flutter新手是极其不友好的,故计划提供分支插件(不确定什么时候):小米(已完成)、华为等推送SDK集成,如果您已经有类似插件,请告诉我,我会使用它并编写接入文档

其它插件

我同时维护的还有如下插件,如果您感兴趣与我一起进行维护,请通过Github联系我,欢迎 issues 和 PR。
平台插件描述版本-
FlutterFlutterTencentImPlugin腾讯云IM插件pub package
FlutterFlutterTencentRtcPlugin腾讯云Rtc插件pub package
FlutterFlutterXiaoMiPushPlugin小米推送SDK插件pub package
FlutterFlutterTextSpanField自定义文本样式输入框pub package
FlutterFlutterQiniucloudLivePluginFlutter 七牛云直播云插件暂未发布,通过 git 集成

Libraries

add_friend_result_entity
add_group_opt_enum
check_friend_result_entity
custom_message_node
entity_factory
enum_util
friend_add_type_enum
friend_check_type_enum
friend_entity
friend_relation_type_enum
friend_status_enum
group_info_entity
group_member_entity
group_pendency_entity
group_pendency_page_entity
group_tips_elem_group_info_entity
group_tips_elem_member_info_entity
group_tips_group_info_type
group_tips_message_node
group_tips_type
image_entity
image_message_node
image_type
list_util
location_message_node
log_print_level
message_entity
message_node
message_node_type
message_status_enum
other_message_node
pendency_entity
pendency_examine_type_enum
pendency_page_entity
pendency_type_enum
receive_message_opt_enum
session_entity
sns_tips_message_node
sns_tips_type
sound_message_node
tencent_im_plugin
text_message_node
user_info_entity
video_info_entity
video_message_node
video_snapshot_info_entity