data = new ArrayList<>(conversationList.size());
for (V2TIMConversation v2TIMConversation : conversationList) {
data.add(new CustomConversationEntity(v2TIMConversation));
}
TencentImPlugin.invokeListener(ListenerTypeEnum.ConversationChanged, data);
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/listener/CustomFriendshipListener.java
================================================
package top.huic.tencent_im_plugin.listener;
import com.tencent.imsdk.v2.V2TIMFriendApplication;
import com.tencent.imsdk.v2.V2TIMFriendInfo;
import com.tencent.imsdk.v2.V2TIMFriendshipListener;
import java.util.List;
import top.huic.tencent_im_plugin.TencentImPlugin;
import top.huic.tencent_im_plugin.enums.ListenerTypeEnum;
/**
* 自定义关系链监听器
*/
public class CustomFriendshipListener extends V2TIMFriendshipListener {
/**
* 好友申请新增通知,两种情况会收到这个回调:
*
* 自己申请加别人好友
* 别人申请加自己好友
*/
@Override
public void onFriendApplicationListAdded(List applicationList) {
super.onFriendApplicationListAdded(applicationList);
TencentImPlugin.invokeListener(ListenerTypeEnum.FriendApplicationListAdded, applicationList);
}
/**
* 好友申请删除通知,四种情况会收到这个回调
*
* 调用 deleteFriendApplication 主动删除好友申请
* 调用 refuseFriendApplication 拒绝好友申请
* 调用 acceptFriendApplication 同意好友申请且同意类型为 V2TIM_FRIEND_ACCEPT_AGREE 时
* 申请加别人好友被拒绝
*/
@Override
public void onFriendApplicationListDeleted(List userIDList) {
super.onFriendApplicationListDeleted(userIDList);
TencentImPlugin.invokeListener(ListenerTypeEnum.FriendApplicationListDeleted, userIDList);
}
/**
* 好友申请已读通知,如果调用 setFriendApplicationRead 设置好友申请列表已读,会收到这个回调(主要用于多端同步)
*/
@Override
public void onFriendApplicationListRead() {
super.onFriendApplicationListRead();
TencentImPlugin.invokeListener(ListenerTypeEnum.FriendApplicationListRead, null);
}
/**
* 好友新增通知
*/
@Override
public void onFriendListAdded(List users) {
super.onFriendListAdded(users);
TencentImPlugin.invokeListener(ListenerTypeEnum.FriendListAdded, users);
}
/**
* 好友删除通知,,两种情况会收到这个回调:
*
* 自己删除好友(单向和双向删除都会收到回调)
* 好友把自己删除(双向删除会收到)
*/
@Override
public void onFriendListDeleted(List userList) {
super.onFriendListDeleted(userList);
TencentImPlugin.invokeListener(ListenerTypeEnum.FriendListDeleted, userList);
}
/**
* 黑名单新增通知
*/
@Override
public void onBlackListAdd(List infoList) {
super.onBlackListAdd(infoList);
TencentImPlugin.invokeListener(ListenerTypeEnum.BlackListAdd, infoList);
}
/**
* 黑名单删除通知
*/
@Override
public void onBlackListDeleted(List userList) {
super.onBlackListDeleted(userList);
TencentImPlugin.invokeListener(ListenerTypeEnum.BlackListDeleted, userList);
}
/**
* 好友资料更新通知
*/
@Override
public void onFriendInfoChanged(List infoList) {
super.onFriendInfoChanged(infoList);
TencentImPlugin.invokeListener(ListenerTypeEnum.FriendInfoChanged, infoList);
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/listener/CustomGroupListener.java
================================================
package top.huic.tencent_im_plugin.listener;
import com.tencent.imsdk.v2.V2TIMGroupChangeInfo;
import com.tencent.imsdk.v2.V2TIMGroupListener;
import com.tencent.imsdk.v2.V2TIMGroupMemberChangeInfo;
import com.tencent.imsdk.v2.V2TIMGroupMemberInfo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import top.huic.tencent_im_plugin.TencentImPlugin;
import top.huic.tencent_im_plugin.enums.ListenerTypeEnum;
/**
* 自定义群监听
*/
public class CustomGroupListener extends V2TIMGroupListener {
/**
* 有用户加入群(全员能够收到)
*/
@Override
public void onMemberEnter(final String groupID, final List memberList) {
super.onMemberEnter(groupID, memberList);
TencentImPlugin.invokeListener(ListenerTypeEnum.MemberEnter, new HashMap() {
{
put("groupID", groupID);
put("memberList", memberList);
}
});
}
/**
* 有用户离开群(全员能够收到)
*/
@Override
public void onMemberLeave(final String groupID, final V2TIMGroupMemberInfo member) {
super.onMemberLeave(groupID, member);
TencentImPlugin.invokeListener(ListenerTypeEnum.MemberLeave, new HashMap() {
{
put("groupID", groupID);
put("member", member);
}
});
}
/**
* 某些人被拉入某群(全员能够收到)
*/
@Override
public void onMemberInvited(final String groupID, final V2TIMGroupMemberInfo opUser, final List memberList) {
super.onMemberInvited(groupID, opUser, memberList);
TencentImPlugin.invokeListener(ListenerTypeEnum.MemberInvited, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
put("memberList", memberList);
}
});
}
/**
* 某些人被踢出某群(全员能够收到)
*/
@Override
public void onMemberKicked(final String groupID, final V2TIMGroupMemberInfo opUser, final List memberList) {
super.onMemberKicked(groupID, opUser, memberList);
TencentImPlugin.invokeListener(ListenerTypeEnum.MemberKicked, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
put("memberList", memberList);
}
});
}
/**
* 群成员信息被修改(全员能收到)
*/
@Override
public void onMemberInfoChanged(final String groupID, final List v2TIMGroupMemberChangeInfoList) {
super.onMemberInfoChanged(groupID, v2TIMGroupMemberChangeInfoList);
TencentImPlugin.invokeListener(ListenerTypeEnum.MemberInfoChanged, new HashMap() {
{
put("groupID", groupID);
put("changInfo", v2TIMGroupMemberChangeInfoList);
}
});
}
/**
* 创建群(主要用于多端同步)
*/
@Override
public void onGroupCreated(String groupID) {
super.onGroupCreated(groupID);
TencentImPlugin.invokeListener(ListenerTypeEnum.GroupCreated, groupID);
}
/**
* 群被解散了(全员能收到)
*/
@Override
public void onGroupDismissed(final String groupID, final V2TIMGroupMemberInfo opUser) {
super.onGroupDismissed(groupID, opUser);
TencentImPlugin.invokeListener(ListenerTypeEnum.GroupDismissed, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
}
});
}
/**
* 群被回收(全员能收到)
*/
@Override
public void onGroupRecycled(final String groupID, final V2TIMGroupMemberInfo opUser) {
super.onGroupRecycled(groupID, opUser);
TencentImPlugin.invokeListener(ListenerTypeEnum.GroupRecycled, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
}
});
}
/**
* 群信息被修改(全员能收到)
*/
@Override
public void onGroupInfoChanged(final String groupID, final List changeInfos) {
super.onGroupInfoChanged(groupID, changeInfos);
TencentImPlugin.invokeListener(ListenerTypeEnum.GroupInfoChanged, new HashMap() {
{
put("groupID", groupID);
put("changInfo", changeInfos);
}
});
}
/**
* 有新的加群请求(只有群主或管理员会收到)
*/
@Override
public void onReceiveJoinApplication(final String groupID, final V2TIMGroupMemberInfo member, final String opReason) {
super.onReceiveJoinApplication(groupID, member, opReason);
TencentImPlugin.invokeListener(ListenerTypeEnum.ReceiveJoinApplication, new HashMap() {
{
put("groupID", groupID);
put("member", member);
put("opReason", opReason);
}
});
}
/**
* 加群请求已经被群主或管理员处理了(只有申请人能够收到)
*/
@Override
public void onApplicationProcessed(final String groupID, final V2TIMGroupMemberInfo opUser, final boolean isAgreeJoin, final String opReason) {
super.onApplicationProcessed(groupID, opUser, isAgreeJoin, opReason);
TencentImPlugin.invokeListener(ListenerTypeEnum.ApplicationProcessed, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
put("isAgreeJoin", isAgreeJoin);
put("opReason", opReason);
}
});
}
/**
* 指定管理员身份
*/
@Override
public void onGrantAdministrator(final String groupID, final V2TIMGroupMemberInfo opUser, final List memberList) {
super.onGrantAdministrator(groupID, opUser, memberList);
TencentImPlugin.invokeListener(ListenerTypeEnum.GrantAdministrator, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
put("memberList", memberList);
}
});
}
/**
* 取消管理员身份
*/
@Override
public void onRevokeAdministrator(final String groupID, final V2TIMGroupMemberInfo opUser, final List memberList) {
super.onRevokeAdministrator(groupID, opUser, memberList);
TencentImPlugin.invokeListener(ListenerTypeEnum.RevokeAdministrator, new HashMap() {
{
put("groupID", groupID);
put("opUser", opUser);
put("memberList", memberList);
}
});
}
/**
* 主动退出群组(主要用于多端同步,直播群(AVChatRoom)不支持)
*/
@Override
public void onQuitFromGroup(String groupID) {
super.onQuitFromGroup(groupID);
TencentImPlugin.invokeListener(ListenerTypeEnum.QuitFromGroup, groupID);
}
/**
* 收到 RESTAPI 下发的自定义系统消息
*/
@Override
public void onReceiveRESTCustomData(final String groupID, final byte[] customData) {
super.onReceiveRESTCustomData(groupID, customData);
TencentImPlugin.invokeListener(ListenerTypeEnum.ReceiveRESTCustomData, new HashMap() {
{
put("groupID", groupID);
put("customData", new String(customData));
}
});
}
/**
* 收到群属性更新的回调
*/
@Override
public void onGroupAttributeChanged(final String groupID, final Map groupAttributeMap) {
super.onGroupAttributeChanged(groupID, groupAttributeMap);
TencentImPlugin.invokeListener(ListenerTypeEnum.GroupAttributeChanged, new HashMap() {
{
put("groupID", groupID);
put("attributes", groupAttributeMap);
}
});
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/listener/CustomSDKListener.java
================================================
package top.huic.tencent_im_plugin.listener;
import com.tencent.imsdk.v2.V2TIMSDKListener;
import com.tencent.imsdk.v2.V2TIMUserFullInfo;
import java.util.HashMap;
import top.huic.tencent_im_plugin.TencentImPlugin;
import top.huic.tencent_im_plugin.enums.ListenerTypeEnum;
/**
* SDK基本监听器
*/
public class CustomSDKListener extends V2TIMSDKListener {
/**
* 正在连接到腾讯云服务器
*/
@Override
public void onConnecting() {
super.onConnecting();
TencentImPlugin.invokeListener(ListenerTypeEnum.Connecting, null);
}
/**
* 网络连接成功
*/
@Override
public void onConnectSuccess() {
super.onConnectSuccess();
TencentImPlugin.invokeListener(ListenerTypeEnum.ConnectSuccess, null);
}
/**
* 网络连接失败
*/
@Override
public void onConnectFailed(final int code, final String error) {
super.onConnectFailed(code, error);
TencentImPlugin.invokeListener(ListenerTypeEnum.ConnectFailed, new HashMap() {
{
put("code", code);
put("error", error);
}
});
}
/**
* 踢下线通知
*/
@Override
public void onKickedOffline() {
super.onKickedOffline();
TencentImPlugin.invokeListener(ListenerTypeEnum.KickedOffline, null);
}
/**
* 当前用户的资料发生了更新
*/
@Override
public void onSelfInfoUpdated(V2TIMUserFullInfo info) {
super.onSelfInfoUpdated(info);
TencentImPlugin.invokeListener(ListenerTypeEnum.SelfInfoUpdated, info);
}
/**
* 用户登录的 userSig 过期(用户需要重新获取 userSig 后登录)
*/
@Override
public void onUserSigExpired() {
super.onUserSigExpired();
TencentImPlugin.invokeListener(ListenerTypeEnum.UserSigExpired, null);
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/listener/CustomSignalingListener.java
================================================
package top.huic.tencent_im_plugin.listener;
import com.tencent.imsdk.v2.V2TIMSignalingListener;
import java.util.HashMap;
import java.util.List;
import top.huic.tencent_im_plugin.TencentImPlugin;
import top.huic.tencent_im_plugin.enums.ListenerTypeEnum;
/**
* 自定义信令监听器
*/
public class CustomSignalingListener extends V2TIMSignalingListener {
/**
* 收到新邀请时
*/
@Override
public void onReceiveNewInvitation(final String inviteID, final String inviter, final String groupID, final List inviteeList, final String data) {
super.onReceiveNewInvitation(inviteID, inviter, groupID, inviteeList, data);
TencentImPlugin.invokeListener(ListenerTypeEnum.ReceiveNewInvitation, new HashMap() {
{
put("inviteID", inviteID);
put("inviter", inviter);
put("groupID", groupID);
put("inviteeList", inviteeList);
put("data", data);
}
});
}
/**
* 被邀请者接受邀请
*/
@Override
public void onInviteeAccepted(final String inviteID, final String invitee, final String data) {
super.onInviteeAccepted(inviteID, invitee, data);
TencentImPlugin.invokeListener(ListenerTypeEnum.InviteeAccepted, new HashMap() {
{
put("inviteID", inviteID);
put("invitee", invitee);
put("data", data);
}
});
}
/**
* 被邀请者拒绝邀请
*/
@Override
public void onInviteeRejected(final String inviteID, final String invitee, final String data) {
super.onInviteeRejected(inviteID, invitee, data);
TencentImPlugin.invokeListener(ListenerTypeEnum.InviteeRejected, new HashMap() {
{
put("inviteID", inviteID);
put("invitee", invitee);
put("data", data);
}
});
}
/**
* 邀请被取消
*/
@Override
public void onInvitationCancelled(final String inviteID, final String inviter, final String data) {
super.onInvitationCancelled(inviteID, inviter, data);
TencentImPlugin.invokeListener(ListenerTypeEnum.InvitationCancelled, new HashMap() {
{
put("inviteID", inviteID);
put("inviter", inviter);
put("data", data);
}
});
}
/**
* 邀请超时
*/
@Override
public void onInvitationTimeout(final String inviteID, final List inviteeList) {
super.onInvitationTimeout(inviteID, inviteeList);
TencentImPlugin.invokeListener(ListenerTypeEnum.InvitationTimeout, new HashMap() {
{
put("inviteID", inviteID);
put("inviteeList", inviteeList);
}
});
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/AbstractMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMMessage;
import top.huic.tencent_im_plugin.message.entity.AbstractMessageEntity;
/**
* 消息节点接口
*
* @param 节点类型,对应腾讯云 TIMElem
*/
public abstract class AbstractMessageNode {
/**
* 获得发送的消息体
*
* @param entity 消息实体
* @return 结果
*/
public V2TIMMessage getV2TIMMessage(E entity) {
throw new RuntimeException("This node does not support sending");
}
/**
* 根据消息节点获得描述
*
* @param elem 节点
*/
public abstract String getNote(N elem);
/**
* 将节点解析为实体对象
*
* @param elem 节点
* @return 实体对象
*/
public abstract E analysis(N elem);
/**
* 获得实体类型
*
* @return 类型
*/
public abstract Class getEntityClass();
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/CustomMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMCustomElem;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import top.huic.tencent_im_plugin.message.entity.CustomMessageEntity;
/**
* 自定义消息节点
*/
public class CustomMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(CustomMessageEntity entity) {
return V2TIMManager.getMessageManager().createCustomMessage(entity.getData().getBytes(), entity.getDesc(), entity.getExt() == null ? null : entity.getExt().getBytes());
}
@Override
public String getNote(V2TIMCustomElem elem) {
return "[其它消息]";
}
@Override
public CustomMessageEntity analysis(V2TIMCustomElem elem) {
return new CustomMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return CustomMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/FaceMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMFaceElem;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import top.huic.tencent_im_plugin.message.entity.FaceMessageEntity;
/**
* 表情消息节点
*/
public class FaceMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(FaceMessageEntity entity) {
return V2TIMManager.getMessageManager().createFaceMessage(entity.getIndex(), entity.getData().getBytes());
}
@Override
public String getNote(V2TIMFaceElem elem) {
return "[表情]";
}
@Override
public FaceMessageEntity analysis(V2TIMFaceElem elem) {
return new FaceMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return FaceMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/FileMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMFileElem;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import top.huic.tencent_im_plugin.message.entity.FileMessageEntity;
/**
* 文件消息节点
*/
public class FileMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(FileMessageEntity entity) {
return V2TIMManager.getMessageManager().createFileMessage(entity.getFilePath(), entity.getFileName());
}
@Override
public String getNote(V2TIMFileElem elem) {
return "[文件]";
}
@Override
public FileMessageEntity analysis(V2TIMFileElem elem) {
return new FileMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return FileMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/GroupTipsMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMGroupTipsElem;
import top.huic.tencent_im_plugin.message.entity.GroupTipsMessageEntity;
/**
* 群提示消息节点
*/
public class GroupTipsMessageNode extends AbstractMessageNode {
@Override
public String getNote(V2TIMGroupTipsElem elem) {
return "[群提示]";
}
@Override
public GroupTipsMessageEntity analysis(V2TIMGroupTipsElem elem) {
return new GroupTipsMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return GroupTipsMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/ImageMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMImageElem;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import top.huic.tencent_im_plugin.message.entity.ImageMessageEntity;
/**
* 图片消息节点
*/
public class ImageMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(ImageMessageEntity entity) {
return V2TIMManager.getMessageManager().createImageMessage(entity.getPath());
}
@Override
public String getNote(V2TIMImageElem elem) {
return "[图片]";
}
@Override
public ImageMessageEntity analysis(V2TIMImageElem elem) {
ImageMessageEntity entity = new ImageMessageEntity();
entity.setPath(elem.getPath());
entity.setImageData(elem.getImageList());
return entity;
}
@Override
public Class getEntityClass() {
return ImageMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/LocationMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMLocationElem;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import top.huic.tencent_im_plugin.message.entity.LocationMessageEntity;
/**
* 位置消息节点
*/
public class LocationMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(LocationMessageEntity entity) {
return V2TIMManager.getMessageManager().createLocationMessage(entity.getDesc(), entity.getLongitude(), entity.getLatitude());
}
@Override
public String getNote(V2TIMLocationElem elem) {
return "[位置消息]";
}
@Override
public LocationMessageEntity analysis(V2TIMLocationElem elem) {
return new LocationMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return LocationMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/SoundMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMSoundElem;
import top.huic.tencent_im_plugin.message.entity.SoundMessageEntity;
/**
* 语音消息节点
*/
public class SoundMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(SoundMessageEntity entity) {
return V2TIMManager.getMessageManager().createSoundMessage(entity.getPath(), entity.getDuration());
}
@Override
public String getNote(V2TIMSoundElem elem) {
return "[语音]";
}
@Override
public SoundMessageEntity analysis(V2TIMSoundElem elem) {
return new SoundMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return SoundMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/TextMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMGroupAtInfo;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMTextElem;
import java.util.ArrayList;
import java.util.List;
import top.huic.tencent_im_plugin.message.entity.TextMessageEntity;
/**
* 文本消息节点
*/
public class TextMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(TextMessageEntity entity) {
// 有@用户或者@所有人则进入分支
if ((entity.getAtUserList() != null && entity.getAtUserList().size() >= 1) || (entity.getAtAll() != null && entity.getAtAll())) {
List atList = new ArrayList<>();
// @所有人
if (entity.getAtAll() != null && entity.getAtAll()) {
atList.add(V2TIMGroupAtInfo.AT_ALL_TAG);
}
// @目标用户
if (entity.getAtUserList() != null) {
atList.addAll(entity.getAtUserList());
}
return V2TIMManager.getMessageManager().createTextAtMessage(entity.getContent(), atList);
}
return V2TIMManager.getMessageManager().createTextMessage(entity.getContent());
}
@Override
public String getNote(V2TIMTextElem elem) {
return elem.getText();
}
@Override
public TextMessageEntity analysis(V2TIMTextElem elem) {
return new TextMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return TextMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/VideoMessageNode.java
================================================
package top.huic.tencent_im_plugin.message;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMVideoElem;
import top.huic.tencent_im_plugin.message.entity.VideoMessageEntity;
/**
* 视频消息节点
*/
public class VideoMessageNode extends AbstractMessageNode {
@Override
public V2TIMMessage getV2TIMMessage(VideoMessageEntity entity) {
String suffix = null;
if (entity.getVideoPath().contains(".")) {
String[] ss = entity.getVideoPath().split("\\.");
suffix = ss[ss.length - 1];
}
return V2TIMManager.getMessageManager().createVideoMessage(entity.getVideoPath(), suffix, entity.getDuration(), entity.getSnapshotPath());
}
@Override
public String getNote(V2TIMVideoElem elem) {
return "[视频]";
}
@Override
public VideoMessageEntity analysis(V2TIMVideoElem elem) {
return new VideoMessageEntity(elem);
}
@Override
public Class getEntityClass() {
return VideoMessageEntity.class;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/AbstractMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import java.io.Serializable;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 消息实体
*
* @author 蒋具宏
*/
public class AbstractMessageEntity implements Serializable {
private MessageNodeType nodeType;
public AbstractMessageEntity(MessageNodeType nodeType) {
this.nodeType = nodeType;
}
public MessageNodeType getNodeType() {
return nodeType;
}
public void setNodeType(MessageNodeType nodeType) {
this.nodeType = nodeType;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/CustomMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMCustomElem;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 自定义消息实体
*
* @author 蒋具宏
*/
public class CustomMessageEntity extends AbstractMessageEntity {
/**
* 自定义内容
*/
private String data;
/**
* 描述
*/
private String desc;
/**
* 扩展内容
*/
private String ext;
public CustomMessageEntity() {
super(MessageNodeType.Custom);
}
public CustomMessageEntity(V2TIMCustomElem elem) {
super(MessageNodeType.Custom);
if (elem.getData() == null || elem.getData().length == 0) {
this.data = null;
} else {
this.data = new String(elem.getData());
}
this.desc = elem.getDescription();
if (elem.getExtension() != null && elem.getExtension().length != 0) {
this.ext = new String(elem.getExtension());
}
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getExt() {
return ext;
}
public void setExt(String ext) {
this.ext = ext;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/FaceMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMFaceElem;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 表情消息实体
*/
public class FaceMessageEntity extends AbstractMessageEntity {
/**
* 索引
*/
private int index;
/**
* 数据
*/
private String data;
public FaceMessageEntity() {
super(MessageNodeType.Face);
}
public FaceMessageEntity(V2TIMFaceElem elem) {
super(MessageNodeType.Face);
this.setIndex(elem.getIndex());
this.setData(elem.getData() == null ? null : new String(elem.getData()));
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/FileMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMFileElem;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 文件消息实体
*/
public class FileMessageEntity extends AbstractMessageEntity {
/**
* 文件路径
*/
private String filePath;
/**
* 文件名
*/
private String fileName;
/**
* 文件UUID
*/
private String uuid;
/**
* 文件大小
*/
private int size;
public FileMessageEntity() {
super(MessageNodeType.File);
}
public FileMessageEntity(V2TIMFileElem elem) {
super(MessageNodeType.File);
this.setFileName(elem.getFileName());
this.setFilePath(elem.getPath());
this.setSize(elem.getFileSize());
this.setUuid(elem.getUUID());
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/GroupTipsMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMGroupChangeInfo;
import com.tencent.imsdk.v2.V2TIMGroupMemberChangeInfo;
import com.tencent.imsdk.v2.V2TIMGroupMemberInfo;
import com.tencent.imsdk.v2.V2TIMGroupTipsElem;
import java.util.List;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 群提示消息实体
*
* @author 蒋具宏
*/
public class GroupTipsMessageEntity extends AbstractMessageEntity {
/**
* 群ID
*/
private String groupID;
/**
* 群事件通知类型
*/
private int type;
/**
* 操作用户
*/
private V2TIMGroupMemberInfo opMember;
/**
* 被操作人列表
*/
private List memberList;
/**
* 群资料变更信息列表,仅当tipsType值为V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE时有效
*/
private List groupChangeInfoList ;
/**
* 获取群成员变更信息列表,仅当tipsType值为V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE时有效
*/
private List memberChangeInfoList;
/**
* 当前群成员数,仅当tipsType值为V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_JOIN, V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_QUIT, V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_KICKED的时候有效
*/
private int memberCount;
public GroupTipsMessageEntity() {
super(MessageNodeType.GroupTips);
}
public GroupTipsMessageEntity(V2TIMGroupTipsElem elem){
super(MessageNodeType.GroupTips);
this.groupID = elem.getGroupID();
this.type = elem.getType();
this.opMember = elem.getOpMember();
this.memberList = elem.getMemberList();
this.groupChangeInfoList = elem.getGroupChangeInfoList();
this.memberChangeInfoList = elem.getMemberChangeInfoList();
this.memberCount = elem.getMemberCount();
}
public String getGroupID() {
return groupID;
}
public void setGroupID(String groupID) {
this.groupID = groupID;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public V2TIMGroupMemberInfo getOpMember() {
return opMember;
}
public void setOpMember(V2TIMGroupMemberInfo opMember) {
this.opMember = opMember;
}
public List getMemberList() {
return memberList;
}
public void setMemberList(List memberList) {
this.memberList = memberList;
}
public List getGroupChangeInfoList() {
return groupChangeInfoList;
}
public void setGroupChangeInfoList(List groupChangeInfoList) {
this.groupChangeInfoList = groupChangeInfoList;
}
public List getMemberChangeInfoList() {
return memberChangeInfoList;
}
public void setMemberChangeInfoList(List memberChangeInfoList) {
this.memberChangeInfoList = memberChangeInfoList;
}
public int getMemberCount() {
return memberCount;
}
public void setMemberCount(int memberCount) {
this.memberCount = memberCount;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/ImageMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMImageElem;
import java.util.List;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 图片消息实体
*
* @author 蒋具宏
*/
public class ImageMessageEntity extends AbstractMessageEntity {
/**
* 原图本地文件路径,发送方有效
*/
private String path;
/**
* 图片列表,根据类型分开
*/
private List imageData;
public ImageMessageEntity() {
super(MessageNodeType.Image);
}
public ImageMessageEntity(V2TIMImageElem elem) {
super(MessageNodeType.Image);
this.setPath(elem.getPath());
this.setImageData(elem.getImageList());
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public List getImageData() {
return imageData;
}
public void setImageData(List imageData) {
this.imageData = imageData;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/LocationMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMLocationElem;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 位置消息实体
*
* @author 蒋具宏
*/
public class LocationMessageEntity extends AbstractMessageEntity {
/**
* 描述
*/
private String desc;
/**
* 经度
*/
private double latitude;
/**
* 纬度
*/
private double longitude;
public LocationMessageEntity() {
super(MessageNodeType.Location);
}
public LocationMessageEntity(V2TIMLocationElem elem) {
super(MessageNodeType.Location);
this.setDesc(elem.getDesc());
this.setLongitude(elem.getLongitude());
this.setLatitude(elem.getLatitude());
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/SoundMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMSoundElem;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 语音消息实体
*
* @author 蒋具宏
*/
public class SoundMessageEntity extends AbstractMessageEntity {
/**
* 语音ID
*/
private String uuid;
/**
* 路径
*/
private String path;
/**
* 时长
*/
private Integer duration;
/**
* 数据大小
*/
private Integer dataSize;
public SoundMessageEntity() {
super(MessageNodeType.Sound);
}
public SoundMessageEntity(V2TIMSoundElem elem) {
super(MessageNodeType.Sound);
this.setPath(elem.getPath());
this.setDuration(elem.getDuration());
this.setDataSize(elem.getDataSize());
this.setUuid(elem.getUUID());
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Integer getDuration() {
return duration;
}
public void setDuration(Integer duration) {
this.duration = duration;
}
public Integer getDataSize() {
return dataSize;
}
public void setDataSize(Integer dataSize) {
this.dataSize = dataSize;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/TextMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMTextElem;
import java.util.List;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 文本消息实体
*
* @author 蒋具宏
*/
public class TextMessageEntity extends AbstractMessageEntity {
/**
* 消息内容
*/
private String content;
/**
* \@的用户列表
*/
private List atUserList;
/**
* 是否@所有人
*/
private Boolean atAll;
public TextMessageEntity() {
super(MessageNodeType.Text);
}
public TextMessageEntity(V2TIMTextElem elem) {
super(MessageNodeType.Text);
this.content = elem.getText();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List getAtUserList() {
return atUserList;
}
public void setAtUserList(List atUserList) {
this.atUserList = atUserList;
}
public Boolean getAtAll() {
return atAll;
}
public void setAtAll(Boolean atAll) {
this.atAll = atAll;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/message/entity/VideoMessageEntity.java
================================================
package top.huic.tencent_im_plugin.message.entity;
import com.tencent.imsdk.v2.V2TIMVideoElem;
import java.io.Serializable;
import top.huic.tencent_im_plugin.enums.MessageNodeType;
/**
* 视频消息实体
*
* @author 蒋具宏
*/
public class VideoMessageEntity extends AbstractMessageEntity implements Serializable {
/**
* 视频路径
*/
private String videoPath;
/**
* 视频UUID
*/
private String videoUuid;
/**
* 视频大小
*/
private int videoSize;
/**
* 时长
*/
private int duration;
/**
* 缩略图路径
*/
private String snapshotPath;
/**
* 缩略图UUID
*/
private String snapshotUuid;
/**
* 缩略图大小
*/
private int snapshotSize;
/**
* 缩略图宽度
*/
private int snapshotWidth;
/**
* 缩略图高度
*/
private int snapshotHeight;
public VideoMessageEntity() {
super(MessageNodeType.Video);
}
public VideoMessageEntity(V2TIMVideoElem elem) {
super(MessageNodeType.Video);
this.setVideoUuid(elem.getVideoUUID());
this.setVideoPath(elem.getVideoPath());
this.setVideoSize(elem.getVideoSize());
this.setDuration(elem.getDuration());
this.setSnapshotUuid(elem.getSnapshotUUID());
this.setSnapshotWidth(elem.getSnapshotWidth());
this.setSnapshotHeight(elem.getSnapshotHeight());
this.setSnapshotPath(elem.getSnapshotPath());
this.setSnapshotSize(elem.getSnapshotSize());
}
public String getVideoPath() {
return videoPath;
}
public void setVideoPath(String videoPath) {
this.videoPath = videoPath;
}
public String getVideoUuid() {
return videoUuid;
}
public void setVideoUuid(String videoUuid) {
this.videoUuid = videoUuid;
}
public int getVideoSize() {
return videoSize;
}
public void setVideoSize(int videoSize) {
this.videoSize = videoSize;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getSnapshotPath() {
return snapshotPath;
}
public void setSnapshotPath(String snapshotPath) {
this.snapshotPath = snapshotPath;
}
public String getSnapshotUuid() {
return snapshotUuid;
}
public void setSnapshotUuid(String snapshotUuid) {
this.snapshotUuid = snapshotUuid;
}
public int getSnapshotSize() {
return snapshotSize;
}
public void setSnapshotSize(int snapshotSize) {
this.snapshotSize = snapshotSize;
}
public int getSnapshotWidth() {
return snapshotWidth;
}
public void setSnapshotWidth(int snapshotWidth) {
this.snapshotWidth = snapshotWidth;
}
public int getSnapshotHeight() {
return snapshotHeight;
}
public void setSnapshotHeight(int snapshotHeight) {
this.snapshotHeight = snapshotHeight;
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/util/BeanUtils.java
================================================
package top.huic.tencent_im_plugin.util;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* Bean工具类
*/
public class BeanUtils {
/**
* 复制属性
*
* @param source 源对象
* @param target 目标对象
* @param ignoreProperties 忽略的参数列表
*/
public static void copyProperties(Object source, Object target, String... ignoreProperties) {
Class> sourceClass = source.getClass();
Class> targetClass = target.getClass();
// 填充目标方法列表
Map targetMethodMap = new HashMap<>();
for (Method method : targetClass.getDeclaredMethods()) {
targetMethodMap.put(method.getName(), method);
}
try {
for (Method method : sourceClass.getDeclaredMethods()) {
String name = method.getName();
// 验证是否是属性方法(get / is)
if (method.getReturnType() != Void.class || method.getParameterTypes().length >= 1 || !(name.startsWith("get") || name.startsWith("is"))) {
// 获得方法后缀名(不包含 get is 前缀的内容)
String methodSuffixName = name.replaceFirst(name.startsWith("get") ? "get" : "is", "");
if (methodSuffixName.length() == 0) {
continue;
}
// 获得真实属性名
String fieldName = methodSuffixName.substring(0, 1).toLowerCase() + methodSuffixName.substring(1);
// 如果是忽略的属性
if (ignoreProperties != null && Arrays.asList(ignoreProperties).contains(fieldName)) {
continue;
}
// 如果不存在设置方法
String setMethodName = "set" + methodSuffixName;
if (!targetMethodMap.containsKey(setMethodName)) {
continue;
}
// 方法校验(非普通set参数(1个参数)) 或 不是公开方法,则不进行赋值确认
Method targetMethod = targetMethodMap.get(setMethodName);
if (targetMethod.getParameterTypes().length != 1 || targetMethod.getModifiers() != Modifier.PUBLIC) {
continue;
}
// 获得值,如果为null则忽略
Object resultValue = method.invoke(source);
if (resultValue == null) {
continue;
}
// 赋值
targetMethod.invoke(target, resultValue);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/util/CommonUtil.java
================================================
package top.huic.tencent_im_plugin.util;
import android.os.Handler;
import android.os.Looper;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
/**
* 工具类
*/
public class CommonUtil {
/**
* 主线程处理器
*/
private final static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
/**
* 通用方法,获得参数值,如未找到参数,则直接中断
*
* @param methodCall 方法调用对象
* @param result 返回对象
* @param param 参数名
*/
public static T getParam(MethodCall methodCall, MethodChannel.Result result, String param) {
T par = methodCall.argument(param);
if (par == null) {
result.error("Missing parameter", "Cannot find parameter `" + param + "` or `" + param + "` is null!", 5);
throw new RuntimeException("Cannot find parameter `" + param + "` or `" + param + "` is null!");
}
return par;
}
/**
* 运行主线程返回结果执行
*
* @param result 返回结果对象
* @param param 返回参数
*/
public static void runMainThreadReturn(final MethodChannel.Result result, final Object param) {
MAIN_HANDLER.post(new Runnable() {
@Override
public void run() {
result.success(param);
}
});
}
/**
* 运行主线程返回错误结果执行
*
* @param result 返回结果对象
* @param errorCode 错误码
* @param errorMessage 错误信息
* @param errorDetails 错误内容
*/
public static void runMainThreadReturnError(final MethodChannel.Result result, final String errorCode, final String errorMessage, final Object errorDetails) {
MAIN_HANDLER.post(new Runnable() {
@Override
public void run() {
result.error(errorCode, errorMessage, errorDetails);
}
});
}
/**
* 运行主线程方法
*/
public static void runMainThreadMethod(Runnable runnable){
MAIN_HANDLER.post(runnable);
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/util/JsonUtil.java
================================================
package top.huic.tencent_im_plugin.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.ValueFilter;
/**
* JSON工具类
*
* @author 蒋具宏
*/
public class JsonUtil {
/**
* 自定义数据过滤器
*/
private static final ValueFilter filter = new ValueFilter() {
@Override
public Object process(Object object, String name, Object value) {
if (value instanceof byte[]) {
return new String((byte[]) value);
}
return value;
}
};
/**
* 将对象序列化为JSON
*
* @param data 对象
* @return 解析结果
*/
public static String toJSONString(Object data) {
if (data instanceof String) return data.toString();
return JSON.toJSONString(data, filter);
}
}
================================================
FILE: android/src/main/java/top/huic/tencent_im_plugin/util/TencentImUtils.java
================================================
package top.huic.tencent_im_plugin.util;
import com.alibaba.fastjson.JSON;
import com.tencent.imsdk.v2.V2TIMFriendApplication;
import com.tencent.imsdk.v2.V2TIMFriendApplicationResult;
import com.tencent.imsdk.v2.V2TIMGroupApplication;
import com.tencent.imsdk.v2.V2TIMGroupApplicationResult;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMValueCallback;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import top.huic.tencent_im_plugin.ValueCallBack;
import top.huic.tencent_im_plugin.entity.FindFriendApplicationEntity;
import top.huic.tencent_im_plugin.entity.FindGroupApplicationEntity;
import top.huic.tencent_im_plugin.entity.FindMessageEntity;
/**
* 腾讯云IM工具类
*/
public class TencentImUtils {
/**
* 获得好友申请对象
*
* @param json json 字符串
* @param call 回调对象
*/
public static void getFriendApplicationByFindGroupApplicationEntity(String json, ValueCallBack call) {
getFriendApplicationByFindGroupApplicationEntity(JSON.parseObject(json, FindFriendApplicationEntity.class), call);
}
/**
* 获得好友申请对象
*
* @param data 实体对象
* @param call 回调对象
*/
public static void getFriendApplicationByFindGroupApplicationEntity(final FindFriendApplicationEntity data, final ValueCallBack call) {
V2TIMManager.getFriendshipManager().getFriendApplicationList(new V2TIMValueCallback() {
@Override
public void onError(int i, String s) {
call.onError(i, s);
}
@Override
public void onSuccess(V2TIMFriendApplicationResult v2TIMFriendApplicationResult) {
if (v2TIMFriendApplicationResult.getFriendApplicationList() != null) {
for (V2TIMFriendApplication item : v2TIMFriendApplicationResult.getFriendApplicationList()) {
if (item.getUserID().equals(data.getUserID()) && item.getType() == data.getType()) {
call.onSuccess(item);
return;
}
}
}
call.onSuccess(null);
}
});
}
/**
* 获得群申请对象
*
* @param json json 字符串
* @param call 回调对象
*/
public static void getGroupApplicationByFindGroupApplicationEntity(String json, ValueCallBack call) {
getGroupApplicationByFindGroupApplicationEntity(JSON.parseObject(json, FindGroupApplicationEntity.class), call);
}
/**
* 获得群申请对象
*
* @param data 实体对象
* @param call 回调对象
*/
public static void getGroupApplicationByFindGroupApplicationEntity(final FindGroupApplicationEntity data, final ValueCallBack call) {
V2TIMManager.getGroupManager().getGroupApplicationList(new V2TIMValueCallback() {
@Override
public void onError(int i, String s) {
call.onError(i, s);
}
@Override
public void onSuccess(V2TIMGroupApplicationResult v2TIMGroupApplicationResult) {
if (v2TIMGroupApplicationResult.getGroupApplicationList() != null) {
for (V2TIMGroupApplication item : v2TIMGroupApplicationResult.getGroupApplicationList()) {
if (item.getGroupID().equals(data.getGroupID()) && item.getFromUser().equals(data.getFromUser())) {
call.onSuccess(item);
return;
}
}
}
call.onSuccess(null);
}
});
}
/**
* 获得消息对象
*
* @param json json字符串
* @param call 回调对象
*/
public static void getMessageByFindMessageEntity(String json, ValueCallBack call) {
getMessageByFindMessageEntity(JSON.parseObject(json, FindMessageEntity.class), call);
}
/**
* 获得消息对象
*
* @param data 查找消息对象实体
* @param call 回调对象
*/
public static void getMessageByFindMessageEntity(final FindMessageEntity data, final ValueCallBack call) {
getMessageByFindMessageEntity(Collections.singletonList(data), new ValueCallBack>(null) {
@Override
public void onSuccess(List v2TIMMessages) {
if (v2TIMMessages == null || v2TIMMessages.size() == 0) {
call.onError(-1, "未找到消息对象!消息ID不存在");
return;
}
call.onSuccess(v2TIMMessages.get(0));
}
@Override
public void onError(int code, String desc) {
call.onError(code, desc);
}
});
}
/**
* 获得消息对象
*
* @param data 查找消息对象实体
* @param call 回调对象
*/
public static void getMessageByFindMessageEntity(List data, final ValueCallBack> call) {
List ids = new ArrayList<>();
for (FindMessageEntity datum : data) {
ids.add(datum.getMsgId());
}
V2TIMManager.getMessageManager().findMessages(ids, new V2TIMValueCallback>() {
@Override
public void onError(int i, String s) {
call.onError(i, s);
}
@Override
public void onSuccess(List v2TIMMessages) {
call.onSuccess(v2TIMMessages);
}
});
}
}
================================================
FILE: example/.gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
================================================
FILE: example/.metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: d345a3b303ce041846ff895eb49a104bef133c4b
channel: master
project_type: app
================================================
FILE: example/README.md
================================================
# tencent_im_plugin_example
Demonstrates how to use the tencent_im_plugin plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
================================================
FILE: example/android/.gitignore
================================================
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
================================================
FILE: example/android/app/agconnect-services.json
================================================
{
"agcgw":{
"backurl":"connect-drcn.dbankcloud.cn",
"url":"connect-drcn.hispace.hicloud.com"
},
"client":{
"cp_id":"890086000102176873",
"product_id":"736430079244549109",
"client_id":"400572237515588608",
"client_secret":"76A8613ED5A461B6AA74396CAF70DBB0B23690F8B4136A0A66AA202FFEEA890D",
"app_id":"102514829",
"package_name":"top.huic.tencent_im_plugin_example",
"api_key":"CgB6e3x9I8KuPeIag8AT0fhvvrEf57HaQCYqoB91348bgNFNEim2y+8s3/ervtmQDygm6EKiBqCBRdNurhYotfYi"
},
"service":{
"analytics":{
"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"cloudstorage":{
"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn"
},
"ml":{
"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"
}
},
"region":"CN",
"configuration_version":"1.0"
}
================================================
FILE: example/android/app/build.gradle
================================================
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
//def keystorePropertiesFile = rootProject.file("key.properties")
//def keystoreProperties = new Properties()
//keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
compileSdkVersion 28
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "top.huic.tencent_im_plugin_example"
minSdkVersion 17
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
// 证书参数
signingConfigs {
config {
storeFile file('key.jks')
storePassword '123456'
keyAlias 'key'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
debug {
signingConfig signingConfigs.config
}
release {
signingConfig signingConfigs.config
// // 开启混淆
// minifyEnabled true
// useProguard true
}
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
// 减小应用程序大小的配置
aaptOptions {
ignoreAssetsPattern "!x86:!*ffprobe"
}
}
flutter {
source '../..'
}
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
apply plugin: 'com.huawei.agconnect'
================================================
FILE: example/android/app/src/debug/AndroidManifest.xml
================================================
================================================
FILE: example/android/app/src/main/AndroidManifest.xml
================================================
================================================
FILE: example/android/app/src/main/java/top/huic/tencent_im_plugin_example/MainActivity.java
================================================
package top.huic.tencent_im_plugin_example;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Bundle;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
/**
* Flutter 通知器
*/
public static MethodChannel channel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
channel = new MethodChannel(this.getFlutterEngine().getDartExecutor(), "tencent_im_plugin_example");
}
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
================================================
FILE: example/android/app/src/main/res/drawable/launch_background.xml
================================================
================================================
FILE: example/android/app/src/main/res/values/styles.xml
================================================
================================================
FILE: example/android/app/src/profile/AndroidManifest.xml
================================================
================================================
FILE: example/android/build.gradle
================================================
buildscript {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: example/android/gradle/wrapper/gradle-wrapper.properties
================================================
#Fri Feb 28 14:11:06 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
================================================
FILE: example/android/gradle.properties
================================================
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
================================================
FILE: example/android/settings.gradle
================================================
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
================================================
FILE: example/ios/.gitignore
================================================
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
================================================
FILE: example/ios/Flutter/AppFrameworkInfo.plist
================================================
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
App
CFBundleIdentifier
io.flutter.flutter.app
CFBundleInfoDictionaryVersion
6.0
CFBundleName
App
CFBundlePackageType
FMWK
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1.0
MinimumOSVersion
9.0
================================================
FILE: example/ios/Flutter/Debug.xcconfig
================================================
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
================================================
FILE: example/ios/Flutter/Release.xcconfig
================================================
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
================================================
FILE: example/ios/Podfile
================================================
# Uncomment this line to define a global platform for your project
platform :ios, '8.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
def install_plugin_pods(application_path = nil, relative_symlink_dir, platform)
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
raise 'Could not find application path' unless application_path
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
symlink_dir = File.expand_path(relative_symlink_dir, application_path)
system('rm', '-rf', symlink_dir) # Avoid the complication of dependencies like FileUtils.
symlink_plugins_dir = File.expand_path('plugins', symlink_dir)
system('mkdir', '-p', symlink_plugins_dir)
plugins_file = File.join(application_path, '..', '.flutter-plugins-dependencies')
plugin_pods = flutter_parse_plugins_file(plugins_file, platform)
plugin_pods.each do |plugin_hash|
plugin_name = plugin_hash['name']
plugin_path = plugin_hash['path']
if (plugin_name && plugin_path)
specPath = "#{plugin_path}/#{platform}/#{plugin_name}.podspec"
pod plugin_name, :path => specPath
end
end
end
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_ios_engine_pod(File.dirname(File.realpath(__FILE__)))
install_plugin_pods(File.dirname(File.realpath(__FILE__)), '.symlinks', 'ios')
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
================================================
FILE: example/ios/Runner/AppDelegate.swift
================================================
import UIKit
import Flutter
@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)
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
================================================
FILE: example/ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
================================================
FILE: example/ios/Runner/Base.lproj/Main.storyboard
================================================
================================================
FILE: example/ios/Runner/Info.plist
================================================
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
tencent_im_plugin_example
CFBundlePackageType
APPL
CFBundleShortVersionString
$(FLUTTER_BUILD_NAME)
CFBundleSignature
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
LSRequiresIPhoneOS
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSCameraUsageDescription
App需要您的同意,才能访问相册
NSLocationWhenInUseUsageDescription
是否允许需要访问位置?
NSMicrophoneUsageDescription
App需要您的同意,才能访问麦克风
NSPhotoLibraryUsageDescription
是否允许访问图片库?
NSPhotoLibraryAddUsageDescription
是否允许保存图片?
Privacy - Calendars Usage Description
是否允许访问日历?
Privacy - Location Always Usage Description
是否允许始终访问位置?
Privacy - Location When In Use Usage Description
是否允许使用期间访问位置?
UIBackgroundModes
audio
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UIViewControllerBasedStatusBarAppearance
================================================
FILE: example/ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"
================================================
FILE: example/ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
F421BC9C2F4D92DF91A983A8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5951A49241F164BFC879FD8A /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
453EE5ABF54A138152CF911D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
4B436B647E9F79944B465D68 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
5951A49241F164BFC879FD8A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
E27FEED2BBEF82CCFCE08B08 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F421BC9C2F4D92DF91A983A8 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
38FEDA953939FFB3CD8B4370 /* Pods */ = {
isa = PBXGroup;
children = (
453EE5ABF54A138152CF911D /* Pods-Runner.debug.xcconfig */,
E27FEED2BBEF82CCFCE08B08 /* Pods-Runner.release.xcconfig */,
4B436B647E9F79944B465D68 /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
38FEDA953939FFB3CD8B4370 /* Pods */,
A3BD4893CCA84354F64352B2 /* Frameworks */,
);
sourceTree = "";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "";
};
A3BD4893CCA84354F64352B2 /* Frameworks */ = {
isa = PBXGroup;
children = (
5951A49241F164BFC879FD8A /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
F39B2611AF028A7ADB261525 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
5F1A0E9208832B656E3DB0F2 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = ZVZ337XL75;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
5F1A0E9208832B656E3DB0F2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/HandyJSON/HandyJSON.framework",
"${PODS_ROOT}/TXIMSDK_Plus_iOS_Bitcode/ImSDK_Plus.framework",
"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
"${BUILT_PRODUCTS_DIR}/fluttertoast/fluttertoast.framework",
"${BUILT_PRODUCTS_DIR}/image_picker/image_picker.framework",
"${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework",
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
"${BUILT_PRODUCTS_DIR}/tencent_im_plugin/tencent_im_plugin.framework",
"${BUILT_PRODUCTS_DIR}/video_player/video_player.framework",
"${BUILT_PRODUCTS_DIR}/video_thumbnail/video_thumbnail.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HandyJSON.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ImSDK_Plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fluttertoast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tencent_im_plugin.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_thumbnail.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
F39B2611AF028A7ADB261525 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = YYHJZM64K7;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = top.huic.tencentImPluginExample;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = ZVZ337XL75;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = top.huic.tencentImPluginExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = YYHJZM64K7;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = top.huic.tencentImPluginExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
================================================
FILE: example/ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: example/lib/main.dart
================================================
import 'package:flutter/material.dart';
import 'package:tencent_im_plugin_example/page/chat.dart';
import 'package:tencent_im_plugin_example/page/home.dart';
import 'package:tencent_im_plugin_example/page/interfaces_test.dart';
import 'package:tencent_im_plugin_example/page/login.dart';
import 'package:tencent_im_plugin_example/page/main/main.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
routes: {
"/": (context) => HomePage(),
"/interfaces_test": (context) => InterfacesTest(),
"/login": (context) => Login(),
"/main": (context) => Main(),
"/chat": (context) => Chat(),
},
);
}
}
================================================
FILE: example/lib/page/chat.dart
================================================
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tencent_im_plugin/entity/conversation_entity.dart';
import 'package:tencent_im_plugin/entity/message_entity.dart';
import 'package:tencent_im_plugin/entity/user_entity.dart';
import 'package:tencent_im_plugin/entity/find_message_entity.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin/enums/tencent_im_listener_type_enum.dart';
import 'package:tencent_im_plugin/message_node/text_message_node.dart';
import 'package:tencent_im_plugin/message_node/custom_message_node.dart';
import 'package:tencent_im_plugin/message_node/image_message_node.dart';
import 'package:tencent_im_plugin/message_node/video_message_node.dart';
import 'package:tencent_im_plugin/message_node/sound_message_node.dart';
import 'package:tencent_im_plugin/message_node/message_node.dart';
import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart';
import 'package:tencent_im_plugin/enums/image_type_enum.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import 'package:tencent_im_plugin/enums/message_status_enum.dart';
/// 聊天页面
class Chat extends StatefulWidget {
@override
_ChatState createState() => _ChatState();
}
class _ChatState extends State {
/// 文本组件控制器
TextEditingController _textEditingController = TextEditingController();
/// 会话实体
ConversationEntity _conversation;
/// 消息列表
List _messages = [];
/// 用户信息
UserEntity _selfUser;
/// 临时目录
String _tempPath;
@override
void initState() {
super.initState();
TencentImPlugin.addListener(_imListener);
_loadTempPath();
SchedulerBinding.instance.addPostFrameCallback((_) {
_conversation = ModalRoute.of(context).settings.arguments;
this.setState(() {});
_loadUserInfo();
_onLoadMessages();
_textEditingController.text = _conversation.draftText;
});
}
@override
void dispose() {
super.dispose();
TencentImPlugin.removeListener(_imListener);
String text = _textEditingController.text.trim();
TencentImPlugin.setConversationDraft(
conversationID: _conversation.conversationID,
draftText: text.trim() != '' ? text : null);
}
/// IM监听器
_imListener(type, params) {
if (type == TencentImListenerTypeEnum.NewMessage) {
this.setState(() {
this._messages.insert(0, params);
});
}
if (type == TencentImListenerTypeEnum.MessageSendProgress) {
print("===================");
print("消息发送进度更新:${params.msgId}");
print("===================");
}
if (type == TencentImListenerTypeEnum.MessageSendSucc) {
print("===================");
print("消息发送成功");
print("===================");
}
if (type == TencentImListenerTypeEnum.MessageSendFail) {
print("===================");
print("消息发送失败");
print("===================");
}
}
/// 加载连目录
_loadTempPath() async {
_tempPath = (await getTemporaryDirectory()).path;
this.setState(() {});
}
/// 加载当前登录用户信息
_loadUserInfo() async {
this._selfUser = (await TencentImPlugin.getUsersInfo(
userIDList: [await TencentImPlugin.getLoginUser()]))[0];
this.setState(() {});
}
/// 加载消息
_onLoadMessages() async {
if (_conversation == null) {
return;
}
List messages = await (_conversation.groupID != null
? TencentImPlugin.getGroupHistoryMessageList(
groupID: _conversation.groupID, count: 100)
: TencentImPlugin.getC2CHistoryMessageList(
userID: _conversation.userID, count: 100));
this.setState(() {
this._messages = messages;
});
// 下载语音、视频缩略图
for (var item in messages) {
if (item.elemType == MessageElemTypeEnum.Video) {
File file = new File(
_tempPath + "/" + (item.node as VideoMessageNode).snapshotUuid);
if (!file.existsSync()) {
TencentImPlugin.downloadVideoThumbnail(
message: FindMessageEntity(msgId: item.msgID),
path: file.path)
.then((value) {
this.setState(() {});
});
}
}
if (item.elemType == MessageElemTypeEnum.Sound) {
File file =
new File(_tempPath + "/" + (item.node as SoundMessageNode).uuid);
if (!file.existsSync()) {
TencentImPlugin.downloadSound(
message: FindMessageEntity(msgId: item.msgID),
path: file.path)
.then((value) {
this.setState(() {});
});
}
}
}
this.setState(() {});
}
/// 发送按钮点击事件
_onSend() async {
String text = _textEditingController.text;
if (text.trim() == '') {
return;
}
this._sendMessage(TextMessageNode(content: text, atUserList: []));
_textEditingController.text = "";
}
/// 图片选择按钮
_onImageSelect() async {
int value = await showCupertinoModalPopup(
builder: (BuildContext context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
child: Text("图片"),
onPressed: () => Navigator.pop(this.context, 0),
),
CupertinoActionSheetAction(
child: Text("视频"),
onPressed: () => Navigator.pop(this.context, 1),
),
],
cancelButton: CupertinoActionSheetAction(
child: Text("取消"),
onPressed: () => Navigator.pop(this.context),
), // 取消按钮
),
context: context,
);
if (value == null) {
return;
}
// 图片
if (value == 0) {
final pickedFile =
await ImagePicker().getImage(source: ImageSource.gallery);
if (pickedFile == null) return;
this._sendMessage(ImageMessageNode(path: pickedFile.path));
}
// 视频
if (value == 1) {
final pickedFile =
await ImagePicker().getVideo(source: ImageSource.gallery);
if (pickedFile == null) return;
// 获得视频缩略图
String thumb = await VideoThumbnail.thumbnailFile(
video: pickedFile.path,
thumbnailPath: _tempPath,
imageFormat: ImageFormat.JPEG,
quality: 25,
);
// 获得控制器并获得视频时长
VideoPlayerController playerController =
VideoPlayerController.file(File(pickedFile.path));
await playerController.initialize();
int duration = playerController.value.duration.inSeconds;
this._sendMessage(VideoMessageNode(
duration: duration, snapshotPath: thumb, videoPath: pickedFile.path));
}
}
/// 根据消息获得组件
_getMessageComponent(MessageEntity message) {
// 文本消息
if (message.elemType == MessageElemTypeEnum.Text) {
return Text((message.node as TextMessageNode).content);
}
// 图片消息
if (message.elemType == MessageElemTypeEnum.Image) {
ImageMessageNode node = message.node;
if ((node.path == null || node.path == '') && node.imageData != null) {
return Container(
constraints: BoxConstraints(
maxHeight: 100,
maxWidth: 100,
),
child: Image.network(node.imageData[ImageTypeEnum.Thumb]?.url),
);
}
return Container(
constraints: BoxConstraints(
maxHeight: 100,
maxWidth: 100,
),
child: Image.file(File(node.path)),
);
}
// 视频消息
if (message.elemType == MessageElemTypeEnum.Video) {
VideoMessageNode node = message.node;
String path = node.snapshotPath == null || node.snapshotPath == ''
? (_tempPath + "/" + node.snapshotUuid)
: node.snapshotPath;
return Container(
constraints: BoxConstraints(
maxHeight: 100,
maxWidth: 100,
),
child: Image.file(File(path)),
);
}
if (message.elemType == MessageElemTypeEnum.Custom) {
CustomMessageNode node = message.node;
return Text("[自定义消息]data:${node.data},desc:${node.desc},ext:${node.ext}");
}
return Text("暂不支持的数据格式");
}
/// 发送消息
_sendMessage(MessageNode node) async {
String msgId = await TencentImPlugin.sendMessage(
node: node,
receiver: _conversation.userID,
groupID: _conversation.groupID,
);
this._messages.insert(
0,
MessageEntity(
msgID: msgId,
node: node,
faceUrl: _selfUser.faceUrl,
elemType: node.nodeType,
status: MessageStatusEnum.Sending,
),
);
this.setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(_conversation?.showName ?? "加载中..."),
centerTitle: true,
actions: [
_conversation == null
? null
: IconButton(
icon: Icon(_conversation.groupID != null
? Icons.supervisor_account
: Icons.settings),
onPressed: () => {},
),
Container(width: 8),
]..removeWhere((element) => element == null),
),
body: Column(
children: [
Expanded(
child: Column(
children: [
Flexible(
child: ListView(
reverse: true,
shrinkWrap: true,
children: _messages
.map(
(item) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Row(
mainAxisAlignment: item.self
? MainAxisAlignment.end
: MainAxisAlignment.start,
children: [
Offstage(
child: Row(
children: [
CircleAvatar(
backgroundImage:
item.faceUrl == null ||
item.faceUrl == ''
? null
: NetworkImage(item.faceUrl),
),
Container(width: 10),
],
),
offstage: item.self,
),
_getMessageComponent(item),
Offstage(
child: Row(
children: [
Container(width: 10),
CircleAvatar(
backgroundImage:
item.faceUrl == null ||
item.faceUrl == ''
? null
: NetworkImage(item.faceUrl),
),
],
),
offstage: !item.self,
),
],
),
),
),
)
.toList(),
),
),
],
),
),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: _onImageSelect,
child: Icon(
Icons.image_outlined,
size: 30,
),
),
Container(width: 8),
// GestureDetector(
// onTap: () {},
// child: Icon(
// Icons.mic,
// size: 30,
// ),
// ),
// Container(width: 8),
Expanded(
child: Container(
constraints: BoxConstraints(
maxHeight: 40,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)),
color: Color(0xFFEEEEEE),
),
child: TextField(
controller: _textEditingController,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15,
top: -8,
bottom: 0,
right: 15,
),
),
),
),
),
Container(width: 8),
OutlinedButton(onPressed: _onSend, child: Text("发送"))
],
),
),
),
],
),
);
}
}
================================================
FILE: example/lib/page/home.dart
================================================
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State {
@override
void initState() {
super.initState();
TencentImPlugin.initSDK(appid: '1400294314');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("页面导航")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: () => Navigator.pushNamed(context, "/interfaces_test"),
child: Text("接口测试"),
),
OutlinedButton(
onPressed: () => Navigator.pushNamed(context, "/login"),
child: Text("进入Demo"),
),
],
),
),
);
}
}
================================================
FILE: example/lib/page/interfaces_test.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin/utils/enum_util.dart';
import 'package:tencent_im_plugin/entity/group_info_entity.dart';
import 'package:tencent_im_plugin/entity/signaling_info_entity.dart';
import 'package:tencent_im_plugin/entity/user_entity.dart';
import 'package:tencent_im_plugin/entity/group_member_entity.dart';
import 'package:tencent_im_plugin/entity/friend_info_entity.dart';
import 'package:tencent_im_plugin/entity/friend_add_application_entity.dart';
import 'package:tencent_im_plugin/message_node/text_message_node.dart';
import 'package:tencent_im_plugin/enums/signaling_action_type_enum.dart';
import 'package:tencent_im_plugin/enums/receive_message_opt_enum.dart';
import 'package:tencent_im_plugin/enums/group_member_role_enum.dart';
import 'package:tencent_im_plugin/enums/friend_type_enum.dart';
import 'package:logger/logger.dart';
typedef TestCallback = Future Function();
/// 接口测试页面
class InterfacesTest extends StatefulWidget {
@override
_InterfacesTestState createState() => _InterfacesTestState();
}
class _InterfacesTestState extends State {
/// 日志输出
static Logger _logger = Logger();
/// 群ID
static String _groupId = "@TGS#2HAKW7YGC";
/// 直播群ID
static String _avGroupId = "@TGS#aRXCQ7YGG";
/// 好友ID
static String _friendId = "test";
/// 接口列表
Map _interfaces = {
"getLoginStatus": () => TencentImPlugin.getLoginStatus(),
"getLoginUser": () => TencentImPlugin.getLoginUser(),
"invite": () => TencentImPlugin.invite(data: "邀请你进行视频通话1", invitee: _friendId),
"inviteInGroup": () => TencentImPlugin.inviteInGroup(data: "邀请你进行视频通话2", groupID: _groupId, inviteeList: [_friendId]),
"cancel": () async => TencentImPlugin.cancel(inviteID: await TencentImPlugin.invite(data: "邀请你进行视频通话3", invitee: _friendId), data: "123"),
"accept": () async => TencentImPlugin.accept(inviteID: await TencentImPlugin.invite(data: "邀请你进行视频通话4", invitee: _friendId), data: "123"),
"reject": () async => TencentImPlugin.reject(inviteID: await TencentImPlugin.invite(data: "邀请你进行视频通话5", invitee: _friendId), data: "123"),
// "getSignalingInfo": () async => TencentImPlugin.getSignalingInfo(inviteID: await TencentImPlugin.invite(data: "邀请你进行视频通话", invitee: _friendId), data: "123"),
"addInvitedSignaling": () async => TencentImPlugin.addInvitedSignaling(
info: SignalingInfoEntity(
inviter: _friendId,
data: "test",
actionType: SignalingActionTypeEnum.Invite,
inviteeList: ["dev"],
),
),
"sendMessage": () async => TencentImPlugin.sendMessage(receiver: _friendId, node: TextMessageNode(content: "1433223")),
// "revokeMessage": () async => TencentImPlugin.revokeMessage(receiver: "dev", node: TextMessageNode(content: "1433223")),
"getC2CHistoryMessageList": () async => TencentImPlugin.getC2CHistoryMessageList(userID: _friendId, count: 100),
"getGroupHistoryMessageList": () async => TencentImPlugin.getGroupHistoryMessageList(groupID: _groupId, count: 100),
"markC2CMessageAsRead": () async => TencentImPlugin.markC2CMessageAsRead(userID: _friendId),
"markGroupMessageAsRead": () async => TencentImPlugin.markGroupMessageAsRead(groupID: _groupId),
// "deleteMessageFromLocalStorage": () async => TencentImPlugin.deleteMessageFromLocalStorage(groupID: _groupId),
// "deleteMessages": () async => TencentImPlugin.deleteMessages(groupID: _groupId),
"insertGroupMessageToLocalStorage": () async => TencentImPlugin.insertGroupMessageToLocalStorage(
node: TextMessageNode(content: "1433223"),
groupID: _groupId,
sender: _friendId,
),
// "createGroup": () async => TencentImPlugin.createGroup(
// info: GroupInfoEntity(
// groupType: GroupTypeEnum.Public,
// groupName: "测试群聊",
// notification: "这是群公告",
// introduction: "这是群简介",
// ),
// ),
// "joinGroup": () async => TencentImPlugin.joinGroup(message: "申请入群", groupID: _groupId),
// "quitGroup": () async => TencentImPlugin.quitGroup(groupID: _groupId),
// "dismissGroup": () async => TencentImPlugin.dismissGroup(groupID: _groupId),
"getJoinedGroupList": () async => TencentImPlugin.getJoinedGroupList(),
"getGroupsInfo": () async => TencentImPlugin.getGroupsInfo(groupIDList: [_groupId]),
"setGroupInfo": () async => TencentImPlugin.setGroupInfo(
info: GroupInfoEntity(
groupID: _groupId,
groupName: "${DateTime.now()}",
),
),
"searchGroups": () async => TencentImPlugin.searchGroups(
keywordList: ["1", "2"],
isSearchGroupID: true,
isSearchGroupName: true,
),
"searchGroupMembers": () async => TencentImPlugin.searchGroupMembers(
keywordList: ["1", "2"],
groupIDList: [_groupId],
isSearchMemberNameCard: true,
isSearchMemberUserID: true,
isSearchMemberRemark: true,
isSearchMemberNickName: true,
),
"setGroupReceiveMessageOpt": () async => TencentImPlugin.setGroupReceiveMessageOpt(
groupID: _groupId,
opt: ReceiveMessageOptEnum.ReceiveAndNotify,
),
"setC2CReceiveMessageOpt": () async => TencentImPlugin.setC2CReceiveMessageOpt(
ids: [_friendId],
opt: ReceiveMessageOptEnum.ReceiveAndNotify,
),
"getC2CReceiveMessageOpt": () async => await TencentImPlugin.getC2CReceiveMessageOpt(ids: [_friendId]),
"initGroupAttributes": () async => TencentImPlugin.initGroupAttributes(
groupID: _avGroupId,
attributes: {
"a": "1",
"b": "2",
},
),
"setGroupAttributes": () async => TencentImPlugin.setGroupAttributes(
groupID: _avGroupId,
attributes: {
"c": "3",
"d": "4",
},
),
"deleteGroupAttributes": () async => TencentImPlugin.deleteGroupAttributes(groupID: _avGroupId, keys: ["b"]),
"getGroupAttributes": () async => TencentImPlugin.getGroupAttributes(groupID: _avGroupId),
"getGroupMemberList": () async => TencentImPlugin.getGroupMemberList(groupID: _groupId),
"getGroupMembersInfo": () async => TencentImPlugin.getGroupMembersInfo(groupID: _groupId, memberList: [_friendId]),
"setGroupMemberInfo": () async => TencentImPlugin.setGroupMemberInfo(
groupID: _groupId,
info: GroupMemberEntity(
userID: _friendId,
nameCard: "测试群名片",
),
),
"muteGroupMember": () async => TencentImPlugin.muteGroupMember(
groupID: _groupId,
seconds: 60,
userID: _friendId,
),
// "inviteUserToGroup": () async => TencentImPlugin.inviteUserToGroup(
// groupID: _groupId,
// userList: [_friendId],
// ),
// "kickGroupMember": () async => TencentImPlugin.kickGroupMember(
// groupID: _groupId,
// memberList: [_friendId],
// ),
"setGroupMemberRole": () async => TencentImPlugin.setGroupMemberRole(
groupID: _groupId,
userID: _friendId,
role: GroupMemberRoleEnum.Admin,
),
// "transferGroupOwner": () async => TencentImPlugin.transferGroupOwner(
// groupID: _groupId,
// userID: _friendId,
// ),
// "getGroupApplicationList": () async => TencentImPlugin.getGroupApplicationList(),
// "acceptGroupApplication": () async => TencentImPlugin.acceptGroupApplication(),
// "refuseGroupApplication": () async => TencentImPlugin.refuseGroupApplication(),
"setGroupApplicationRead": () async => TencentImPlugin.setGroupApplicationRead(),
"getConversationList": () async => TencentImPlugin.getConversationList(),
"getConversation": () async => TencentImPlugin.getConversation(conversationID: (await TencentImPlugin.getConversationList()).conversationList[0].conversationID),
"deleteConversation": () async => TencentImPlugin.deleteConversation(conversationID: (await TencentImPlugin.getConversationList()).conversationList[0].conversationID),
"setConversationDraft": () async => TencentImPlugin.setConversationDraft(
conversationID: (await TencentImPlugin.getConversationList()).conversationList[0].conversationID,
draftText: "测试会话草稿",
),
"getUsersInfo": () async => TencentImPlugin.getUsersInfo(userIDList: [_friendId]),
"setSelfInfo": () async => TencentImPlugin.setSelfInfo(info: UserEntity(nickName: "${DateTime.now()}")),
"addToBlackList": () async => TencentImPlugin.addToBlackList(userIDList: [_friendId]),
"getBlackList": () async => TencentImPlugin.getBlackList(),
"deleteFromBlackList": () async => TencentImPlugin.deleteFromBlackList(userIDList: [_friendId]),
"setOfflinePushConfig": () async => TencentImPlugin.setOfflinePushConfig(bussid: 10301, token: "请输入您的Token"),
"setUnreadBadge": () async => TencentImPlugin.setUnreadBadge(number: 10),
"getFriendList": () async => TencentImPlugin.getFriendList(),
"getFriendsInfo": () async => TencentImPlugin.getFriendsInfo(userIDList: [_friendId]),
"setFriendInfo": () async => TencentImPlugin.setFriendInfo(
info: FriendInfoEntity(
userID: _friendId,
friendRemark: "这是测试备注",
),
),
"addFriend": () async => TencentImPlugin.addFriend(
info: FriendAddApplicationEntity(
userID: _friendId,
friendRemark: "这是测试备注",
addWording: "申请加为好友",
addSource: "手动查找",
addType: FriendTypeEnum.Both,
),
),
"deleteFromFriendList": () async => TencentImPlugin.deleteFromFriendList(deleteType: FriendTypeEnum.Both, userIDList: [_friendId]),
"checkFriend": () async => TencentImPlugin.checkFriend(userID: _friendId, checkType: FriendTypeEnum.Both),
"getFriendApplicationList": () async => TencentImPlugin.getFriendApplicationList(),
// "acceptFriendApplication": () async => TencentImPlugin.acceptFriendApplication(),
// "refuseFriendApplication": () async => TencentImPlugin.refuseFriendApplication(),
// "deleteFriendApplication": () async => TencentImPlugin.deleteFriendApplication(),
"setFriendApplicationRead": () async => TencentImPlugin.setFriendApplicationRead(),
"createFriendGroup": () async => TencentImPlugin.createFriendGroup(userIDList: [_friendId], groupName: "测试分组"),
"getFriendGroups": () async => TencentImPlugin.getFriendGroups(groupNameList: ["测试分组"]),
"renameFriendGroup": () async => TencentImPlugin.renameFriendGroup(oldName: "测试分组", newName: "test"),
"addFriendsToFriendGroup": () async => TencentImPlugin.addFriendsToFriendGroup(groupName: "test", userIDList: [_friendId]),
"deleteFriendsFromFriendGroup": () async => TencentImPlugin.deleteFriendsFromFriendGroup(groupName: "test", userIDList: [_friendId]),
"deleteFriendGroup": () async => TencentImPlugin.deleteFriendGroup(groupNameList: ["test"]),
};
/// 当前正在测试的Key
String _currentTestKey;
/// 已测试数量
int _finishTestCount = 0;
/// 未通过接口列表
List _failInterfaces = [];
/// 是否开始测试
bool _start = false;
/// 测试结果描述
List _result = [];
/// 回调描述
List _callResult = [];
@override
void initState() {
super.initState();
TencentImPlugin.addListener(_listener);
TencentImPlugin.login(
userID: "dev",
userSig: "eJwtzEELgjAYxvHvsnPIu7U5EzoEQRDWITWqW7KVr8MaS8Yi*u6Zenx*D-w-pMjyyGtHUsIiILNho9KPDm84sNJ*4pcyV2tRkZRyALbgc8rHRweLTvcuhGAAMGqH7d9iEAKSWMipgve*ulZS1vKoT83uXO6rkAWzaoqtgVAdNpecu9Y-38aXtE6W5PsDr9ExPw__",
);
}
@override
void dispose() {
super.dispose();
TencentImPlugin.removeListener(_listener);
TencentImPlugin.logout();
}
/// 监听器对象
_listener(type, params) {
_callResult.add("${_getDateTime()}-[${EnumUtil.getEnumName(type)}]:$params");
if (this.mounted) {
this.setState(() {});
}
}
/// 获得时间字符串
_getDateTime() {
DateTime dateTime = DateTime.now();
return "${dateTime.hour <= 9 ? "0${dateTime.hour}" : dateTime.hour}:${dateTime.minute <= 9 ? "0${dateTime.minute}" : dateTime.minute}:${dateTime.second <= 9 ? "0${dateTime.second}" : dateTime.second}";
}
/// 开始测试
startTest() async {
this.setState(() => _start = true);
for (var key in _interfaces.keys) {
this.setState(() => _currentTestKey = key);
try {
var resultData = await _interfaces[key]();
_result.add("${_getDateTime()}-[$key]:测试通过;结果:$resultData");
} catch (err) {
_failInterfaces.add("$key : $err");
_result.add("${_getDateTime()}-[$key]:$err");
_logger.e(err, "[测试结果出错] $key");
}
this.setState(() => _finishTestCount += 1);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("接口测试列表")),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
RichText(
text: TextSpan(
text: "接口数量:${_interfaces.length}",
style: TextStyle(color: Colors.black),
children: [
TextSpan(text: ",已通过:"),
TextSpan(text: "${_finishTestCount - _failInterfaces.length}", style: TextStyle(color: Colors.green)),
TextSpan(text: ",未通过:"),
TextSpan(text: "${_failInterfaces.length}", style: TextStyle(color: Colors.red)),
],
),
),
_start
? Text((_finishTestCount == _interfaces.length) ? "测试完成" : "正在测试:$_currentTestKey")
: OutlinedButton(
onPressed: startTest,
child: Text("开始测试"),
),
Divider(),
Text("日志信息"),
Expanded(
child: ListView(
children: _result
.map(
(e) => RichText(
text: TextSpan(
text: e,
style: TextStyle(color: e.contains("测试通过") ? Colors.green : Colors.red),
),
),
)
.toList(),
)),
Divider(),
Text("回调信息"),
Expanded(
child: ListView(
children: _callResult
.map(
(e) => Text(e),
)
.toList(),
)),
],
),
),
);
}
}
================================================
FILE: example/lib/page/login.dart
================================================
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin_example/utils/GenerateTestUserSig.dart';
/// 登录页面
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State {
TextEditingController _controller = TextEditingController();
/// 用户名
String _userName = "dev";
@override
void initState() {
super.initState();
_controller.text = _userName;
}
/// 登录按钮点击事件
_onLogin() async {
String sign = GenerateTestUserSig(
sdkappid: 1400294314,
key: "706da51f9280812611bcc80b5182b1c5554db8d053bc00b8a37ae8cba887f6a7",
).genSig(identifier: _userName, expire: 1 * 60 * 1000);
await TencentImPlugin.login(
userID: _userName,
userSig: sign,
);
Navigator.pushNamedAndRemoveUntil(
context, "/main", (Route route) => false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("登录页面"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(hintText: "请输入用户名"),
textAlign: TextAlign.center,
onChanged: (value) => this.setState(() => _userName = value),
controller: _controller,
),
Container(height: 20),
OutlinedButton(
onPressed: _userName.trim() == '' ? null : _onLogin,
child: Text("立即登录"),
),
],
),
),
),
);
}
}
================================================
FILE: example/lib/page/main/components/conversation.dart
================================================
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:tencent_im_plugin/entity/conversation_result_entity.dart';
import 'package:tencent_im_plugin/entity/conversation_entity.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin/enums/tencent_im_listener_type_enum.dart';
/// 会话页面
class Conversation extends StatefulWidget {
@override
_ConversationState createState() => _ConversationState();
}
class _ConversationState extends State {
/// 刷新指示器Key
GlobalKey _refreshIndicatorKey = GlobalKey();
/// 会话结果对象
ConversationResultEntity _data;
@override
void initState() {
super.initState();
TencentImPlugin.addListener(_imListener);
SchedulerBinding.instance.addPostFrameCallback((_) {
_refreshIndicatorKey.currentState.show();
});
}
@override
void dispose() {
super.dispose();
TencentImPlugin.removeListener(_imListener);
}
/// IM监听器
_imListener(type, params) {
if (type == TencentImListenerTypeEnum.ConversationChanged) {
_onRefresh();
}
}
/// 刷新事件
Future _onRefresh() {
return TencentImPlugin.getConversationList().then((value) {
this.setState(() => _data = value);
});
}
/// 会话点击事件
_onConversationClick(ConversationEntity data) {
Navigator.pushNamed(context, "/chat", arguments: data);
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _onRefresh,
child: ListView(
children: ListTile.divideTiles(
context: context,
tiles: _data?.conversationList == null
? []
: _data.conversationList
.map(
(item) => ListTile(
onTap: () => _onConversationClick(item),
leading: CircleAvatar(
backgroundImage:
item.faceUrl == null || item.faceUrl == ''
? null
: NetworkImage(item.faceUrl)),
title: RichText(
text: TextSpan(
children: [
TextSpan(
text:
"[${item.groupID == null ? "私聊" : "群聊"}] ",
style: TextStyle(color: Colors.grey)),
TextSpan(text: item.showName),
],
style: TextStyle(color: Colors.black),
),
),
subtitle: RichText(
text: TextSpan(
children: [
TextSpan(
text: item.draftText == null ? "" : "[草稿]",
style: TextStyle(color: Colors.red)),
TextSpan(
text: item.draftText ??
item.lastMessage?.note ??
"",
),
],
style: TextStyle(color: Colors.black),
),
),
),
)
.toList(),
).toList(),
),
);
}
}
================================================
FILE: example/lib/page/main/components/friend.dart
================================================
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin/entity/friend_info_entity.dart';
import 'package:tencent_im_plugin/enums/tencent_im_listener_type_enum.dart';
import 'package:tencent_im_plugin/enums/friend_application_agree_type_enum.dart';
import 'package:tencent_im_plugin/entity/friend_application_result_entity.dart';
import 'package:tencent_im_plugin/entity/find_friend_application_entity.dart';
/// 好友页面
class Friend extends StatefulWidget {
@override
_FriendState createState() => _FriendState();
}
class _FriendState extends State {
/// 刷新指示器Key
GlobalKey _refreshIndicatorKey = GlobalKey();
/// 数据结果对象
List _data = [];
@override
void initState() {
super.initState();
TencentImPlugin.addListener(_imListener);
SchedulerBinding.instance.addPostFrameCallback((_) {
_refreshIndicatorKey.currentState.show();
});
}
@override
void dispose() {
super.dispose();
TencentImPlugin.removeListener(_imListener);
}
/// IM监听器
_imListener(type, params) {
if (type == TencentImListenerTypeEnum.FriendListAdded) {
this.setState(() {});
}
}
/// 刷新事件
Future _onRefresh() {
return TencentImPlugin.getFriendList().then((value) => this.setState(() => _data = value));
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _onRefresh,
child: Column(
children: [
Center(child: Padding(padding: const EdgeInsets.all(20.0), child: Text("好友申请列表"))),
SingleChildScrollView(
child: FutureBuilder(
future: TencentImPlugin.getFriendApplicationList(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) return Center(child: Padding(padding: const EdgeInsets.all(20.0), child: Text("正在拉取好友申请列表")));
if (snapshot.data.friendApplicationList.length == 0) return Center(child: Padding(padding: const EdgeInsets.all(20.0), child: Text("暂无待处理好友申请")));
return Column(
children: ListTile.divideTiles(
context: context,
tiles: snapshot.data.friendApplicationList
.map(
(item) => ListTile(
title: Row(
children: [
Expanded(
child: RichText(
text: TextSpan(
children: [
TextSpan(text: item.nickname == null || item.nickname == '' ? item.userID : item.nickname),
],
style: TextStyle(color: Colors.black),
),
),
),
Row(
children: [
RaisedButton(
onPressed: () async {
Future result = TencentImPlugin.acceptFriendApplication(application: FindFriendApplicationEntity.fromFriendApplicationEntity(item), responseType: FriendApplicationAgreeTypeEnum.AgreeAndAdd);
await result.then((value) => Fluttertoast.showToast(msg: "处理成功!")).catchError((e) => Fluttertoast.showToast(msg: "处理失败!"));
if (this.mounted) this.setState(() {});
},
child: Text("同意"),
),
RaisedButton(
onPressed: () async {
Future result = TencentImPlugin.refuseFriendApplication(application: FindFriendApplicationEntity.fromFriendApplicationEntity(item));
await result.then((value) => Fluttertoast.showToast(msg: "处理成功!")).catchError((e) => Fluttertoast.showToast(msg: "处理失败!"));
if (this.mounted) this.setState(() {});
},
child: Text("拒绝"),
),
],
),
],
),
),
)
.toList(),
).toList(),
);
},
),
),
Center(child: Padding(padding: const EdgeInsets.all(20.0), child: Text("好友列表"))),
Expanded(
child: ListView(
children: ListTile.divideTiles(
context: context,
tiles: _data
.map(
(item) => ListTile(
leading: CircleAvatar(backgroundImage: item.userProfile?.faceUrl == null || item.userProfile.faceUrl == '' ? null : NetworkImage(item.userProfile.faceUrl)),
title: RichText(
text: TextSpan(
children: [
TextSpan(text: item.userProfile.nickName == null || item.userProfile.nickName == '' ? item.userID : item.userProfile.nickName),
],
style: TextStyle(color: Colors.black),
),
),
),
)
.toList(),
).toList(),
),
),
],
),
);
}
}
================================================
FILE: example/lib/page/main/components/group.dart
================================================
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin/entity/group_info_entity.dart';
/// 群组列表
class Group extends StatefulWidget {
@override
_GroupState createState() => _GroupState();
}
class _GroupState extends State {
/// 刷新指示器Key
GlobalKey _refreshIndicatorKey = GlobalKey();
/// 数据结果对象
List _data = [];
@override
void initState() {
super.initState();
TencentImPlugin.addListener(_imListener);
SchedulerBinding.instance.addPostFrameCallback((_) {
_refreshIndicatorKey.currentState.show();
});
}
@override
void dispose() {
super.dispose();
TencentImPlugin.removeListener(_imListener);
}
/// IM监听器
_imListener(type, params) {}
/// 刷新事件
Future