Browse Source

消息记录

xuqm 1 year ago
parent
commit
9d1ee4f909
23 changed files with 852 additions and 39 deletions
  1. 17 0
      .idea/deploymentTargetDropDown.xml
  2. 6 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/GsonImplHelp.java
  3. 2 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/Json.java
  4. 111 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeBuilder.java
  5. 40 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/TypeToken.java
  6. 38 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/exception/TypeException.java
  7. 124 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/ParameterizedTypeImpl.java
  8. 106 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/json/reflect/typeimpl/WildcardTypeImpl.java
  9. 1 1
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/im/manager/ImManager.java
  10. 10 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/IMMsgCallback.java
  11. 24 2
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/kit/SdkMsgInterface.java
  12. 1 1
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXGroupManager.java
  13. 101 7
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXMessageManager.java
  14. 6 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/Service.java
  15. 37 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/msg/MsgHistoryForCountData.java
  16. 6 0
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestConstant.java
  17. 4 1
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestInterface.java
  18. 59 2
      SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/request/RequestManager.java
  19. 39 25
      app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/ChatActivity.java
  20. 39 0
      app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/adapter/ChatAdapter.java
  21. 57 0
      app/src/main/java/cn/org/bjca/trust/android/imdemo/vm/ChatVM.java
  22. 1 0
      app/src/main/res/layout/activity_chat.xml
  23. 23 0
      app/src/main/res/layout/chat_view_text.xml

+ 17 - 0
.idea/deploymentTargetDropDown.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="deploymentTargetDropDown">
+    <runningDeviceTargetSelectedWithDropDown>
+      <Target>
+        <type value="RUNNING_DEVICE_TARGET" />
+        <deviceKey>
+          <Key>
+            <type value="SERIAL_NUMBER" />
+            <value value="192.168.115.170:43303" />
+          </Key>
+        </deviceKey>
+      </Target>
+    </runningDeviceTargetSelectedWithDropDown>
+    <timeTargetWasSelectedWithDropDown value="2023-06-06T09:25:14.359761300Z" />
+  </component>
+</project>

+ 6 - 0
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> T toObject(String json, Class<T> claxx) {
         return gson.fromJson(json, claxx);
 
+    }
+    @Override
+    public <T> T toObject(String json, Type typeOfT) {
+        return gson.fromJson(json, typeOfT);
+
     }
 
     @Override

+ 2 - 0
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> T toObject(String json, Class<T> claxx);
+    public abstract <T> T toObject(String json, Type typeOfT);
 
     public abstract <T> T toObject(byte[] bytes, Class<T> claxx);
 

+ 111 - 0
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<Type> 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);
+    }
+}

+ 40 - 0
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<T> {
+    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;
+    }
+}

+ 38 - 0
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);
+    }
+}

+ 124 - 0
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;
+    }
+}

+ 106 - 0
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;
+    }
+}

+ 1 - 1
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)

+ 10 - 0
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<SZYXMessage> messages);
+    void failed (int code, String error);
+}

+ 24 - 2
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 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);
 
-    SZYXMessage sendMsgForTextToG(String toGroupId, String text, IMSDKCallback callback);
+    void getHistory(String userId, long timestampStart, long timestampEnd, IMMsgCallback callback);
 
 }

+ 1 - 1
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<String>() {
+        RequestHelper.getInstance().request(Group_create_v1, data,String.class, new RequestCallback<String>() {
 
             @Override
             public void success(HttpResult<String> result) {

+ 101 - 7
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) {
-        SZYXTextMessage textMessage = new SZYXTextMessage(text);
+    public SZYXMessage sendMsgForText(@NonNull String toClientId, String text) {
+        return this.sendMsgForText(toClientId, false, text, null, null);
+    }
 
-        SZYXMessage szyxMessage = IMHelper.getInstance().createMsg(MsgType.Text, toUserId, false, textMessage, null);
+    @Override
+    public SZYXMessage sendMsgForText(String toClientId, String text, String describe) {
+        return this.sendMsgForText(toClientId, false, text, describe, null);
+    }
 
-        IMHelper.getInstance().sendSZYXMessage(szyxMessage, callback);
-        return szyxMessage;
+    @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 sendMsgForTextToG(String toGroupId, String text, IMSDKCallback callback) {
+    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, toGroupId, true, textMessage, null);
+        SZYXMessage szyxMessage = IMHelper.getInstance().createMsg(MsgType.Text, toClientId, isGroup, textMessage, describe);
 
         IMHelper.getInstance().sendSZYXMessage(szyxMessage, callback);
         return szyxMessage;
     }
+
+    @Override
+    public void getHistory(String userId, IMMsgCallback callback) {
+        this.getHistory(userId, System.currentTimeMillis(), 10, callback);
+    }
+
+    @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<List<SZYXMessage>>() {
+
+            @Override
+            public void success(HttpResult<List<SZYXMessage>> 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<List<SZYXMessage>> 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) {
+
+    }
 }

+ 6 - 0
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<HttpResult<LoginBean>> register(@Body LoginData loginData);
     @POST("group/v1/create")
     Observable<HttpResult<String>> groupCreate(@Body GroupCreateData data);
+    @POST("message/v1/getHistoryForCount")
+    Observable<HttpResult<List<SZYXMessage>>> getHistoryForCount(@Body MsgHistoryForCountData data);
 }

+ 37 - 0
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;
+    }
+}

+ 6 - 0
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";
 }

+ 4 - 1
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 {
-    <T> void request(String path, Object data, RequestCallback<T> callback);
+    <T> void request(String path, Object data, Class<T> clazz, RequestCallback<T> callback);
+    <T> void requestList(String path, Object data, Class<T> clazz, RequestCallback<List<T>> callback);
 }

+ 59 - 2
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 <T> void request(String path, Object data, RequestCallback<T> callback) {
+    @Override
+    public <T> void request(String path, Object data, Class<T> clazz, RequestCallback<T> 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<T> h = GsonImplHelp.get().toObject(message.getBody(), HttpResult.class);
+                Type type = TypeBuilder
+                        .newInstance(HttpResult.class)
+                        .addTypeParam(clazz)
+                        .build();
+                HttpResult<T> 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 <T> void requestList(String path, Object data, Class<T> clazz, RequestCallback<List<T>> 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<List<T>> 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<List<T>>() {
+                        @Override
+                        public void success(HttpResult<List<T>> result) {
+                            callback.success(result);
+                        }
+
+                        @Override
+                        public void failed(int code, String error) {
+                            callback.failed(code, error);
+                        }
+
+                        @Override
+                        public void standby(RequestCallback<List<T>> imCallback) {
+
+                        }
+                    });
+
+                }
+            }
+
+        });
+    }
 }

+ 39 - 25
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<ActivityChatBinding> {
 
+    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<ActivityChatBinding> {
     @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("发送消息成功");
-                        }
-
-                        @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);
-                        }
-                    });
-                }
+                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 ToolsHelper.showMessage("请输入内容后再发送");
+        });
+
+        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);
     }
 }

+ 39 - 0
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<SZYXMessage> {
+    public ChatAdapter() {
+        addItemViewDelegate(new ItemViewDelegate<SZYXMessage>() {
+            @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);
+                }
+            }
+        });
+    }
+}

+ 57 - 0
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<List<SZYXMessage>> _message = new MutableLiveData<>();
+    private final LiveData<List<SZYXMessage>> message = _message;
+
+    public LiveData<List<SZYXMessage>> getMessage() {
+        return message;
+    }
+
+    private final List<SZYXMessage> 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<SZYXMessage> 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);
+    }
+}

+ 1 - 0
app/src/main/res/layout/activity_chat.xml

@@ -25,6 +25,7 @@
                 <androidx.recyclerview.widget.RecyclerView
                     android:id="@+id/baseRecyclerView"
                     android:layout_width="match_parent"
+                    android:paddingHorizontal="20dp"
                     android:layout_height="match_parent"
                     android:overScrollMode="never" />
 

+ 23 - 0
app/src/main/res/layout/chat_view_text.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="45dp"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <TextView
+        android:id="@+id/left"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:text="hhdhsao"/>
+    <TextView
+        android:id="@+id/right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:text="sda"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>