From 9d1ee4f9094d006ed6a9bc72f7bdfc5ec6557bee Mon Sep 17 00:00:00 2001 From: xuqm Date: Tue, 6 Jun 2023 18:47:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E6=81=AF=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetDropDown.xml | 17 +++ .../lib/im/common/json/GsonImplHelp.java | 6 + .../android/lib/im/common/json/Json.java | 2 + .../im/common/json/reflect/TypeBuilder.java | 111 ++++++++++++++++ .../lib/im/common/json/reflect/TypeToken.java | 40 ++++++ .../json/reflect/exception/TypeException.java | 38 ++++++ .../typeimpl/ParameterizedTypeImpl.java | 124 ++++++++++++++++++ .../reflect/typeimpl/WildcardTypeImpl.java | 106 +++++++++++++++ .../android/lib/im/im/manager/ImManager.java | 2 +- .../android/lib/im/kit/IMMsgCallback.java | 10 ++ .../android/lib/im/kit/SdkMsgInterface.java | 26 +++- .../lib/im/manager/SZYXGroupManager.java | 2 +- .../lib/im/manager/SZYXMessageManager.java | 108 ++++++++++++++- .../android/lib/im/repository/Service.java | 6 + .../msg/MsgHistoryForCountData.java | 37 ++++++ .../lib/im/request/RequestConstant.java | 6 + .../lib/im/request/RequestInterface.java | 5 +- .../lib/im/request/RequestManager.java | 61 ++++++++- .../trust/android/imdemo/ui/ChatActivity.java | 60 +++++---- .../imdemo/ui/adapter/ChatAdapter.java | 39 ++++++ .../bjca/trust/android/imdemo/vm/ChatVM.java | 57 ++++++++ app/src/main/res/layout/activity_chat.xml | 1 + app/src/main/res/layout/chat_view_text.xml | 23 ++++ 23 files changed, 850 insertions(+), 37 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeBuilder.java create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeToken.java create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/exception/TypeException.java create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/ParameterizedTypeImpl.java create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/WildcardTypeImpl.java create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/IMMsgCallback.java create mode 100644 SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/msg/MsgHistoryForCountData.java create mode 100644 app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/adapter/ChatAdapter.java create mode 100644 app/src/main/java/cn/org/bjca/trust/android/imdemo/vm/ChatVM.java create mode 100644 app/src/main/res/layout/chat_view_text.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..14bf141 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/GsonImplHelp.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/GsonImplHelp.java index d190134..a403265 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/GsonImplHelp.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/GsonImplHelp.java @@ -5,6 +5,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -25,6 +26,11 @@ public class GsonImplHelp extends Json { public T toObject(String json, Class claxx) { return gson.fromJson(json, claxx); + } + @Override + public T toObject(String json, Type typeOfT) { + return gson.fromJson(json, typeOfT); + } @Override diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/Json.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/Json.java index ab85be1..6fc889a 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/Json.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/Json.java @@ -1,5 +1,6 @@ package cn.org.bjca.trust.android.lib.im.common.json; +import java.lang.reflect.Type; import java.util.List; /** @@ -21,6 +22,7 @@ public abstract class Json { public abstract String toJson(Object src); public abstract T toObject(String json, Class claxx); + public abstract T toObject(String json, Type typeOfT); public abstract T toObject(byte[] bytes, Class claxx); diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeBuilder.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeBuilder.java new file mode 100644 index 0000000..807badc --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeBuilder.java @@ -0,0 +1,111 @@ +/* + * Copyright 2016 ikidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.org.bjca.trust.android.lib.im.common.json.reflect; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +import cn.org.bjca.trust.android.lib.im.common.json.reflect.exception.TypeException; +import cn.org.bjca.trust.android.lib.im.common.json.reflect.typeimpl.ParameterizedTypeImpl; +import cn.org.bjca.trust.android.lib.im.common.json.reflect.typeimpl.WildcardTypeImpl; + + +public class TypeBuilder { + private final TypeBuilder parent; + private final Class raw; + private final List args = new ArrayList<>(); + + + private TypeBuilder(Class raw, TypeBuilder parent) { + assert raw != null; + this.raw = raw; + this.parent = parent; + } + + public static TypeBuilder newInstance(Class raw) { + return new TypeBuilder(raw, null); + } + + private static TypeBuilder newInstance(Class raw, TypeBuilder parent) { + return new TypeBuilder(raw, parent); + } + + + public TypeBuilder beginSubType(Class raw) { + return newInstance(raw, this); + } + + public TypeBuilder endSubType() { + if (parent == null) { + throw new TypeException("expect beginSubType() before endSubType()"); + } + + parent.addTypeParam(getType()); + + return parent; + } + + public TypeBuilder addTypeParam(Class clazz) { + return addTypeParam((Type) clazz); + } + + public TypeBuilder addTypeParamExtends(Class... classes) { + if (classes == null) { + throw new NullPointerException("addTypeParamExtends() expect not null Class"); + } + + WildcardTypeImpl wildcardType = new WildcardTypeImpl(null, classes); + + return addTypeParam(wildcardType); + } + + public TypeBuilder addTypeParamSuper(Class... classes) { + if (classes == null) { + throw new NullPointerException("addTypeParamSuper() expect not null Class"); + } + + WildcardTypeImpl wildcardType = new WildcardTypeImpl(classes, null); + + return addTypeParam(wildcardType); + } + + public TypeBuilder addTypeParam(Type type) { + if (type == null) { + throw new NullPointerException("addTypeParam expect not null Type"); + } + + args.add(type); + + return this; + } + + public Type build() { + if (parent != null) { + throw new TypeException("expect endSubType() before build()"); + } + + return getType(); + } + + private Type getType() { + if (args.isEmpty()) { + return raw; + } + return new ParameterizedTypeImpl(raw, args.toArray(new Type[args.size()]), null); + } +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeToken.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeToken.java new file mode 100644 index 0000000..e69c8c4 --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeToken.java @@ -0,0 +1,40 @@ +/* + * Copyright 2016 ikidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.org.bjca.trust.android.lib.im.common.json.reflect; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import cn.org.bjca.trust.android.lib.im.common.json.reflect.exception.TypeException; + + +public abstract class TypeToken { + private final Type type; + + public TypeToken() { + Type superclass = getClass().getGenericSuperclass(); + if (superclass instanceof Class) { + throw new TypeException("No generics found!"); + } + ParameterizedType type = (ParameterizedType) superclass; + this.type = type.getActualTypeArguments()[0]; + } + + public Type getType() { + return type; + } +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/exception/TypeException.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/exception/TypeException.java new file mode 100644 index 0000000..1a29155 --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/exception/TypeException.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 ikidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.org.bjca.trust.android.lib.im.common.json.reflect.exception; + +public class TypeException extends RuntimeException { + public TypeException() { + } + + public TypeException(String message) { + super(message); + } + + public TypeException(String message, Throwable cause) { + super(message, cause); + } + + public TypeException(Throwable cause) { + super(cause); + } + + public TypeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/ParameterizedTypeImpl.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/ParameterizedTypeImpl.java new file mode 100644 index 0000000..87cf5f1 --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/ParameterizedTypeImpl.java @@ -0,0 +1,124 @@ +/* + * Copyright 2016 ikidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.org.bjca.trust.android.lib.im.common.json.reflect.typeimpl; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.Arrays; + +import cn.org.bjca.trust.android.lib.im.common.json.reflect.exception.TypeException; + + +@SuppressWarnings("SpellCheckingInspection") +public class ParameterizedTypeImpl implements ParameterizedType { + private final Class raw; + private final Type[] args; + private final Type owner; + + public ParameterizedTypeImpl(Class raw, Type[] args, Type owner) { + this.raw = raw; + this.args = args != null ? args : new Type[0]; + this.owner = owner; + checkArgs(); + } + + private void checkArgs() { + if (raw == null) { + throw new TypeException("raw class can't be null"); + } + TypeVariable[] typeParameters = raw.getTypeParameters(); + if (args.length != 0 && typeParameters.length != args.length) { + throw new TypeException(raw.getName() + " expect " + typeParameters.length + " arg(s), got " + args.length); + } + } + + @Override + public Type[] getActualTypeArguments() { + return args; + } + + @Override + public Type getRawType() { + return raw; + } + + @Override + public Type getOwnerType() { + return owner; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(raw.getName()); + if (args.length != 0) { + sb.append('<'); + for (int i = 0; i < args.length; i++) { + if (i != 0) { + sb.append(", "); + } + Type type = args[i]; + if (type instanceof Class) { + Class clazz = (Class) type; + + if (clazz.isArray()) { + int count = 0; + do { + count++; + clazz = clazz.getComponentType(); + } while (clazz.isArray()); + + sb.append(clazz.getName()); + + for (int j = count; j > 0; j--) { + sb.append("[]"); + } + } else { + sb.append(clazz.getName()); + } + } else { + sb.append(args[i].toString()); + } + } + sb.append('>'); + } + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ParameterizedTypeImpl that = (ParameterizedTypeImpl) o; + + if (!raw.equals(that.raw)) return false; + // Probably incorrect - comparing Object[] arrays with Arrays.equals + if (!Arrays.equals(args, that.args)) return false; + return owner != null ? owner.equals(that.owner) : that.owner == null; + + } + + @Override + public int hashCode() { + int result = raw.hashCode(); + result = 31 * result + Arrays.hashCode(args); + result = 31 * result + (owner != null ? owner.hashCode() : 0); + return result; + } +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/WildcardTypeImpl.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/WildcardTypeImpl.java new file mode 100644 index 0000000..9aa5fe1 --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/WildcardTypeImpl.java @@ -0,0 +1,106 @@ +/* + * Copyright 2016 ikidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.org.bjca.trust.android.lib.im.common.json.reflect.typeimpl; + +import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; +import java.util.Arrays; + +public class WildcardTypeImpl implements WildcardType { + private final Class[] upper; + private final Class[] lower; + + public WildcardTypeImpl(Class[] lower, Class[] upper) { + this.lower = lower != null ? lower : new Class[0]; + this.upper = upper != null ? upper : new Class[0]; + + checkArgs(); + } + + private void checkArgs() { + if (lower.length == 0 && upper.length == 0) { + throw new IllegalArgumentException("lower or upper can't be null"); + } + + checkArgs(lower); + checkArgs(upper); + } + + private void checkArgs(Class[] args) { + for (int i = 1; i < args.length; i++) { + Class clazz = args[i]; + if (!clazz.isInterface()) { + throw new IllegalArgumentException(clazz.getName() + " not a interface!"); + } + } + } + + @Override + public Type[] getUpperBounds() { + return upper; + } + + @Override + public Type[] getLowerBounds() { + return lower; + } + + @Override + public String toString() { + if (upper.length > 0) { + if (upper[0] == Object.class) { + return "?"; + } + return getTypeString("? extends ", upper); + } else { + return getTypeString("? super ", lower); + } + } + + private String getTypeString(String suffix, Class[] type) { + StringBuilder sb = new StringBuilder(); + sb.append(suffix); + + for (int i = 0; i < type.length; i++) { + if (i != 0) { + sb.append(" & "); + } + sb.append(type[i].getName()); + } + + return sb.toString(); + + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + WildcardTypeImpl that = (WildcardTypeImpl) o; + + return Arrays.equals(upper, that.upper) && Arrays.equals(lower, that.lower); + + } + + @Override + public int hashCode() { + int result = Arrays.hashCode(upper); + result = 31 * result + Arrays.hashCode(lower); + return result; + } +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/im/manager/ImManager.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/im/manager/ImManager.java index 18a6910..d742fad 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/im/manager/ImManager.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/im/manager/ImManager.java @@ -338,7 +338,7 @@ public class ImManager implements IMInterface { } String msg = GsonImplHelp.get().toJson(message); try { - mqttClient.publish("server" + packetType, msg.getBytes(Charsets.UTF_8), 2, false); + mqttClient.publish("server1" + packetType, msg.getBytes(Charsets.UTF_8), 2, false); // 如果是发送的消息,需要应答 if (PacketType.SEND == packetType) { if (null != callback) diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/IMMsgCallback.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/IMMsgCallback.java new file mode 100644 index 0000000..be5f071 --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/IMMsgCallback.java @@ -0,0 +1,10 @@ +package cn.org.bjca.trust.android.lib.im.kit; + +import java.util.List; + +import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXMessage; + +public interface IMMsgCallback { + void success(List messages); + void failed (int code, String error); +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/SdkMsgInterface.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/SdkMsgInterface.java index 78f9982..b4f66a4 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/SdkMsgInterface.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/SdkMsgInterface.java @@ -1,5 +1,7 @@ package cn.org.bjca.trust.android.lib.im.kit; +import androidx.annotation.NonNull; + import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXMessage; public interface SdkMsgInterface { @@ -8,8 +10,28 @@ public interface SdkMsgInterface { void removeMsgListener(MsgListener listener); - SZYXMessage sendMsgForTextToC(String toUserId, String text, IMSDKCallback callback); + SZYXMessage sendMsgForText(@NonNull String toClientId, String text); - SZYXMessage sendMsgForTextToG(String toGroupId, String text, IMSDKCallback callback); + SZYXMessage sendMsgForText(String toClientId, String text, String describe); + + SZYXMessage sendMsgForText(String toClientId, String text, String describe, IMSDKCallback callback); + + SZYXMessage sendMsgForText(String toClientId, String text, IMSDKCallback callback); + + SZYXMessage sendMsgForText(String toClientId, boolean isGroup, String text); + + SZYXMessage sendMsgForText(String toClientId, boolean isGroup, String text, IMSDKCallback callback); + + SZYXMessage sendMsgForText(String toClientId, boolean isGroup, String text, String describe); + + SZYXMessage sendMsgForText(@NonNull String toClientId, boolean isGroup, @NonNull String text, String describe, IMSDKCallback callback); + + void getHistory(String userId, IMMsgCallback callback); + + void getHistory(String userId, long timestamp, IMMsgCallback callback); + + void getHistory(String userId, long timestamp, int size, IMMsgCallback callback); + + void getHistory(String userId, long timestampStart, long timestampEnd, IMMsgCallback callback); } diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXGroupManager.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXGroupManager.java index 667d717..cdfda56 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXGroupManager.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXGroupManager.java @@ -45,7 +45,7 @@ public class SZYXGroupManager implements SdkGroupInterface { return; } GroupCreateData data = new GroupCreateData(groupName, faceUrl, userList); - RequestHelper.getInstance().request(Group_create_v1, data, new RequestCallback() { + RequestHelper.getInstance().request(Group_create_v1, data,String.class, new RequestCallback() { @Override public void success(HttpResult result) { diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXMessageManager.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXMessageManager.java index 31b2f36..dffb1ae 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXMessageManager.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXMessageManager.java @@ -1,12 +1,28 @@ package cn.org.bjca.trust.android.lib.im.manager; +import static cn.org.bjca.trust.android.lib.im.request.RequestConstant.MsgHistoryForCount; + +import androidx.annotation.NonNull; + +import java.util.List; + import cn.org.bjca.trust.android.lib.im.enums.MsgType; +import cn.org.bjca.trust.android.lib.im.http.HttpManage; +import cn.org.bjca.trust.android.lib.im.http.HttpResult; import cn.org.bjca.trust.android.lib.im.im.IMHelper; import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXMessage; import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXTextMessage; +import cn.org.bjca.trust.android.lib.im.kit.IMMsgCallback; import cn.org.bjca.trust.android.lib.im.kit.IMSDKCallback; import cn.org.bjca.trust.android.lib.im.kit.MsgListener; import cn.org.bjca.trust.android.lib.im.kit.SdkMsgInterface; +import cn.org.bjca.trust.android.lib.im.repository.Service; +import cn.org.bjca.trust.android.lib.im.repository.msg.MsgHistoryForCountData; +import cn.org.bjca.trust.android.lib.im.request.RequestCallback; +import cn.org.bjca.trust.android.lib.im.request.RequestHelper; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; public class SZYXMessageManager implements SdkMsgInterface { @@ -22,22 +38,100 @@ public class SZYXMessageManager implements SdkMsgInterface { } @Override - public SZYXMessage sendMsgForTextToC(String toUserId, String text, IMSDKCallback callback) { + public SZYXMessage sendMsgForText(@NonNull String toClientId, String text) { + return this.sendMsgForText(toClientId, false, text, null, null); + } + + @Override + public SZYXMessage sendMsgForText(String toClientId, String text, String describe) { + return this.sendMsgForText(toClientId, false, text, describe, null); + } + + @Override + public SZYXMessage sendMsgForText(String toClientId, String text, String describe, IMSDKCallback callback) { + return this.sendMsgForText(toClientId, false, text, describe, callback); + } + + @Override + public SZYXMessage sendMsgForText(String toClientId, String text, IMSDKCallback callback) { + return this.sendMsgForText(toClientId, false, text, null, callback); + } + + @Override + public SZYXMessage sendMsgForText(String toClientId, boolean isGroup, String text) { + return this.sendMsgForText(toClientId, isGroup, text, null, null); + } + + @Override + public SZYXMessage sendMsgForText(String toClientId, boolean isGroup, String text, IMSDKCallback callback) { + return this.sendMsgForText(toClientId, isGroup, text, null, callback); + } + + @Override + public SZYXMessage sendMsgForText(String toClientId, boolean isGroup, String text, String describe) { + return this.sendMsgForText(toClientId, isGroup, text, describe, null); + } + + @Override + public SZYXMessage sendMsgForText(@NonNull String toClientId, boolean isGroup, @NonNull String text, String describe, IMSDKCallback callback) { SZYXTextMessage textMessage = new SZYXTextMessage(text); - SZYXMessage szyxMessage = IMHelper.getInstance().createMsg(MsgType.Text, toUserId, false, textMessage, null); + SZYXMessage szyxMessage = IMHelper.getInstance().createMsg(MsgType.Text, toClientId, isGroup, textMessage, describe); IMHelper.getInstance().sendSZYXMessage(szyxMessage, callback); return szyxMessage; } @Override - public SZYXMessage sendMsgForTextToG(String toGroupId, String text, IMSDKCallback callback) { - SZYXTextMessage textMessage = new SZYXTextMessage(text); + public void getHistory(String userId, IMMsgCallback callback) { + this.getHistory(userId, System.currentTimeMillis(), 10, callback); + } - SZYXMessage szyxMessage = IMHelper.getInstance().createMsg(MsgType.Text, toGroupId, true, textMessage, null); + @Override + public void getHistory(String userId, long timestamp, IMMsgCallback callback) { + this.getHistory(userId, timestamp, 10, callback); + } + + @Override + public void getHistory(@NonNull String userId, long timestamp, int size, @NonNull IMMsgCallback callback) { + MsgHistoryForCountData data = new MsgHistoryForCountData(userId, timestamp, size); + RequestHelper.getInstance().requestList(MsgHistoryForCount, data, SZYXMessage.class, new RequestCallback>() { + + @Override + public void success(HttpResult> result) { + if (result.getCode() == 200) { + callback.success(result.getData()); + } else + callback.failed(result.getCode(), result.getMsg()); + } + + @Override + public void failed(int code, String error) { + callback.failed(code, error); + } + + @Override + public void standby(RequestCallback> imCallback) { + + Disposable d = HttpManage.getApi(Service.class) + .getHistoryForCount(data) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(httpResult -> { + if (httpResult.getCode() == 200) { + imCallback.success(httpResult); + } else + imCallback.failed(httpResult.getCode(), httpResult.getMsg()); + }, throwable -> { + imCallback.failed(4002, throwable.getMessage()); + }); + } + + }); + } + + @Override + public void getHistory(String userId, long timestampStart, long timestampEnd, IMMsgCallback callback) { - IMHelper.getInstance().sendSZYXMessage(szyxMessage, callback); - return szyxMessage; } } diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/Service.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/Service.java index f8a8af9..04f89d5 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/Service.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/Service.java @@ -1,10 +1,14 @@ package cn.org.bjca.trust.android.lib.im.repository; +import java.util.List; + import cn.org.bjca.trust.android.lib.im.bean.UserInfo; import cn.org.bjca.trust.android.lib.im.http.HttpResult; +import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXMessage; import cn.org.bjca.trust.android.lib.im.repository.bean.LoginBean; import cn.org.bjca.trust.android.lib.im.repository.data.LoginData; import cn.org.bjca.trust.android.lib.im.repository.group.GroupCreateData; +import cn.org.bjca.trust.android.lib.im.repository.msg.MsgHistoryForCountData; import io.reactivex.Observable; import retrofit2.http.Body; import retrofit2.http.GET; @@ -20,4 +24,6 @@ public interface Service { Observable> register(@Body LoginData loginData); @POST("group/v1/create") Observable> groupCreate(@Body GroupCreateData data); + @POST("message/v1/getHistoryForCount") + Observable>> getHistoryForCount(@Body MsgHistoryForCountData data); } diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/msg/MsgHistoryForCountData.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/msg/MsgHistoryForCountData.java new file mode 100644 index 0000000..b4c249b --- /dev/null +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/msg/MsgHistoryForCountData.java @@ -0,0 +1,37 @@ +package cn.org.bjca.trust.android.lib.im.repository.msg; + +public class MsgHistoryForCountData { + private String userId; + private long timestamp; + private int size; + + public MsgHistoryForCountData(String userId, long timestamp, int size) { + this.userId = userId; + this.timestamp = timestamp; + this.size = size; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } +} diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestConstant.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestConstant.java index a358031..c9c2dbd 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestConstant.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestConstant.java @@ -2,4 +2,10 @@ package cn.org.bjca.trust.android.lib.im.request; public class RequestConstant { public static final String Group_create_v1 = "/group/v1/create"; + + + public static final String MsgHistoryForTime = "/msg/v1/getHistoryForTime"; + public static final String MsgHistoryForCount = "/message/v1/getHistoryForCount"; + public static final String MsgListForTime = "/message/v1/getListForTime"; + public static final String MsgListForCount = "/message/v1/getListForCount"; } diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestInterface.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestInterface.java index 12bc372..8337ea7 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestInterface.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestInterface.java @@ -1,5 +1,8 @@ package cn.org.bjca.trust.android.lib.im.request; +import java.util.List; + public interface RequestInterface { - void request(String path, Object data, RequestCallback callback); + void request(String path, Object data, Class clazz, RequestCallback callback); + void requestList(String path, Object data, Class clazz, RequestCallback> callback); } diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestManager.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestManager.java index 250b5d4..4cda130 100644 --- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestManager.java +++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestManager.java @@ -1,6 +1,10 @@ package cn.org.bjca.trust.android.lib.im.request; +import java.lang.reflect.Type; +import java.util.List; + import cn.org.bjca.trust.android.lib.im.common.json.GsonImplHelp; +import cn.org.bjca.trust.android.lib.im.common.json.reflect.TypeBuilder; import cn.org.bjca.trust.android.lib.im.http.HttpResult; import cn.org.bjca.trust.android.lib.im.im.IMHelper; import cn.org.bjca.trust.android.lib.im.im.kit.RequestImCallback; @@ -10,7 +14,8 @@ import cn.org.bjca.trust.android.lib.im.im.msg.ResultMessage; public class RequestManager implements RequestInterface { - public void request(String path, Object data, RequestCallback callback) { + @Override + public void request(String path, Object data, Class clazz, RequestCallback callback) { RequestMessage rm = new RequestMessage(path, GsonImplHelp.get().toJson(data)); @@ -18,7 +23,11 @@ public class RequestManager implements RequestInterface { @Override public void success(ResultMessage message) { - HttpResult h = GsonImplHelp.get().toObject(message.getBody(), HttpResult.class); + Type type = TypeBuilder + .newInstance(HttpResult.class) + .addTypeParam(clazz) + .build(); + HttpResult h = GsonImplHelp.get().toObject(message.getBody(), type); if (h.getCode() == 200) { callback.success(h); } else { @@ -52,4 +61,52 @@ public class RequestManager implements RequestInterface { }); } + @Override + public void requestList(String path, Object data, Class clazz, RequestCallback> callback) { + + RequestMessage rm = new RequestMessage(path, GsonImplHelp.get().toJson(data)); + + IMHelper.getInstance().request(rm, new RequestImCallback() { + + @Override + public void success(ResultMessage message) { + Type type = TypeBuilder + .newInstance(HttpResult.class) + .beginSubType(List.class) + .addTypeParam(clazz) + .endSubType() + .build(); + HttpResult> h = GsonImplHelp.get().toObject(message.getBody(), type); + if (h.getCode() == 200) { + callback.success(h); + } else { + callback.failed(h.getCode(), h.getMsg()); + } + } + + @Override + public void failed(int code, String error) { + if (null != callback) { + callback.standby(new RequestCallback>() { + @Override + public void success(HttpResult> result) { + callback.success(result); + } + + @Override + public void failed(int code, String error) { + callback.failed(code, error); + } + + @Override + public void standby(RequestCallback> imCallback) { + + } + }); + + } + } + + }); + } } diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/ChatActivity.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/ChatActivity.java index 21b7127..6674b6d 100644 --- a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/ChatActivity.java +++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/ChatActivity.java @@ -3,16 +3,25 @@ package cn.org.bjca.trust.android.imdemo.ui; import android.os.Bundle; import android.view.View; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; + import com.xuqm.base.common.ToolsHelper; import com.xuqm.base.ui.BaseActivity; +import com.xuqm.base.view.enu.Status; import cn.org.bjca.trust.android.imdemo.R; import cn.org.bjca.trust.android.imdemo.databinding.ActivityChatBinding; +import cn.org.bjca.trust.android.imdemo.ui.adapter.ChatAdapter; +import cn.org.bjca.trust.android.imdemo.vm.ChatVM; import cn.org.bjca.trust.android.lib.im.SZYXImSdk; import cn.org.bjca.trust.android.lib.im.kit.IMSDKCallback; public class ChatActivity extends BaseActivity { + private ChatVM vm; + private final ChatAdapter adapter = new ChatAdapter(); + @Override public int getLayoutId() { return R.layout.activity_chat; @@ -21,40 +30,45 @@ public class ChatActivity extends BaseActivity { @Override public void initView(Bundle savedInstanceState) { super.initView(savedInstanceState); + vm = new ViewModelProvider(this).get(ChatVM.class); String userId = getIntent().getStringExtra("userId"); String userName = getIntent().getStringExtra("userName"); boolean isGroup = getIntent().getBooleanExtra("isGroup", false); setTitleText(userName + "(" + (isGroup ? "群组" : userId) + ")"); getBaseBinding().baseToolbar.getToolbarMenu().setVisibility(View.VISIBLE); + + getBinding().baseRecyclerView.setAdapter(adapter); + getBinding().baseRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + + getBinding().refreshLayout.setOnRefreshListener(() -> vm.onRefresh()); + getBinding().btnSend.setOnClickListener(v -> { String msg = getBinding().et.getText().toString(); if (!ToolsHelper.isNull(msg)) { - if (isGroup) { - SZYXImSdk.getMessageManager().sendMsgForTextToG(userId, msg, new IMSDKCallback() { - @Override - public void success() { - ToolsHelper.showMessage("发送消息成功"); - } + vm.add(SZYXImSdk.getMessageManager().sendMsgForText(userId, isGroup, msg, new IMSDKCallback() { + @Override + public void success() { + ToolsHelper.showMessage("发送消息成功"); + } - @Override - public void failed(int code, String error) { - ToolsHelper.showMessage("发送消息失败" + error); - } - }); - } else { - SZYXImSdk.getMessageManager().sendMsgForTextToC(userId, msg, new IMSDKCallback() { - @Override - public void success() { - ToolsHelper.showMessage("发送消息成功"); - } + @Override + public void failed(int code, String error) { + ToolsHelper.showMessage("发送消息失败" + error); + } + })); + } else ToolsHelper.showMessage("请输入内容后再发送"); + }); - @Override - public void failed(int code, String error) { - ToolsHelper.showMessage("发送消息失败" + error); - } - }); - } + getBinding().baseEmptyView.setStatus(Status.NO_DATA); + + vm.getMessage().observe(this, messages -> { + getBinding().refreshLayout.setRefreshing(false); + if (null == messages || messages.size() == 0) { + } else { + getBinding().baseEmptyView.setStatus(Status.DISMISS); + adapter.setmDatas(messages); } }); + vm.getMessageList(userId); } } \ No newline at end of file diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/adapter/ChatAdapter.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/adapter/ChatAdapter.java new file mode 100644 index 0000000..3dbe9fc --- /dev/null +++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/adapter/ChatAdapter.java @@ -0,0 +1,39 @@ +package cn.org.bjca.trust.android.imdemo.ui.adapter; + +import com.xuqm.base.adapter.BaseNormalAdapter; +import com.xuqm.base.adapter.ItemViewDelegate; +import com.xuqm.base.adapter.ViewHolder; +import com.xuqm.base.common.LogHelper; + +import cn.org.bjca.trust.android.imdemo.R; +import cn.org.bjca.trust.android.lib.im.enums.MsgType; +import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXMessage; + +public class ChatAdapter extends BaseNormalAdapter { + public ChatAdapter() { + addItemViewDelegate(new ItemViewDelegate() { + @Override + public int getItemViewLayoutId() { + return R.layout.chat_view_text; + } + + @Override + public boolean isForViewType(SZYXMessage item, int position) { + return item.getMsgType().equals(MsgType.Text); + } + + @Override + public void convert(ViewHolder holder, SZYXMessage item, int position) { + if (item.isArrive()) { + holder.setText(R.id.left, item.getTextMessage().getText()); + holder.setVisibility(R.id.left, true); + holder.setVisibility(R.id.right, false); + } else { + holder.setText(R.id.right, item.getTextMessage().getText()); + holder.setVisibility(R.id.left, false); + holder.setVisibility(R.id.right, true); + } + } + }); + } +} diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/vm/ChatVM.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/vm/ChatVM.java new file mode 100644 index 0000000..c287b13 --- /dev/null +++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/vm/ChatVM.java @@ -0,0 +1,57 @@ +package cn.org.bjca.trust.android.imdemo.vm; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import com.xuqm.base.common.LogHelper; +import com.xuqm.base.common.TimeHelper; +import com.xuqm.base.viewmodel.BaseViewModel; + +import java.util.ArrayList; +import java.util.List; + +import cn.org.bjca.trust.android.lib.im.SZYXImSdk; +import cn.org.bjca.trust.android.lib.im.im.msg.message.SZYXMessage; +import cn.org.bjca.trust.android.lib.im.kit.IMMsgCallback; + +public class ChatVM extends BaseViewModel { + private final MutableLiveData> _message = new MutableLiveData<>(); + private final LiveData> message = _message; + + public LiveData> getMessage() { + return message; + } + + private final List list = new ArrayList<>(); + private String userId; + private long timestamp = TimeHelper.getTimeMillis(); + + public void getMessageList(String userId) { + this.userId = userId; + + SZYXImSdk.getMessageManager().getHistory(userId,timestamp, new IMMsgCallback() { + @Override + public void success(List messages) { + if (messages.size()>0){ + list.addAll(0,messages); + timestamp = messages.get(0).getTimestamp(); + } + _message.postValue(list); + } + + @Override + public void failed(int code, String error) { + LogHelper.e("=====>", code + error); + _message.postValue(null); + } + }); + } + + public void onRefresh() { + this.getMessageList(this.userId); + } + public void add(SZYXMessage msg) { + this.list.add(msg); + _message.postValue(list); + } +} diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index 0228cae..034d542 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -25,6 +25,7 @@ diff --git a/app/src/main/res/layout/chat_view_text.xml b/app/src/main/res/layout/chat_view_text.xml new file mode 100644 index 0000000..c9fd943 --- /dev/null +++ b/app/src/main/res/layout/chat_view_text.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file