diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 26d3352..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index 56efcef..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-ImAndroid
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 288b36b..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,7 +1,6 @@
-
-
+
\ No newline at end of file
diff --git a/SzyxBaseSdk/build.gradle b/SzyxBaseSdk/build.gradle
index 94f35cb..15df89e 100644
--- a/SzyxBaseSdk/build.gradle
+++ b/SzyxBaseSdk/build.gradle
@@ -7,7 +7,7 @@ android {
compileSdk 33
defaultConfig {
- minSdk 24
+ minSdk 26
targetSdk 33
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/SzyxImSdk/build.gradle b/SzyxImSdk/build.gradle
index f2b2905..f944707 100644
--- a/SzyxImSdk/build.gradle
+++ b/SzyxImSdk/build.gradle
@@ -1,19 +1,22 @@
plugins {
id 'com.android.library'
+ id "io.sentry.android.gradle" version "3.4.2"
}
+def versionCode = 1
+def versionName = "0.0.1.011"
android {
namespace 'cn.org.bjca.trust.android.lib.im'
compileSdk 33
defaultConfig {
- minSdk 24
+ minSdk 26
targetSdk 33
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
- versionCode 1
- versionName '1.0.0'
+
+ buildConfigField("String", "versionName", "\"${versionName}\"")
}
buildTypes {
@@ -31,9 +34,25 @@ android {
dependencies {
api project(path: ':SzyxBaseSdk')
+
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+ //数据库相关
+ implementation("androidx.room:room-runtime:2.5.0")
+ annotationProcessor ("androidx.room:room-compiler:2.5.0")
+
+ // 网络相关
+ //Rxjava
+ implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
+ //Retrofit
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
+ implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
+ implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
+
+
}
\ No newline at end of file
diff --git a/SzyxImSdk/src/main/AndroidManifest.xml b/SzyxImSdk/src/main/AndroidManifest.xml
index a5918e6..7834f97 100644
--- a/SzyxImSdk/src/main/AndroidManifest.xml
+++ b/SzyxImSdk/src/main/AndroidManifest.xml
@@ -1,4 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SZYXDbHelper.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SZYXDbHelper.java
new file mode 100644
index 0000000..814791a
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SZYXDbHelper.java
@@ -0,0 +1,25 @@
+package cn.org.bjca.trust.android.lib.im;
+
+import android.content.Context;
+
+import androidx.room.Room;
+
+import cn.org.bjca.trust.android.lib.im.db.ImDatabase;
+
+public class SZYXDbHelper {
+
+ private static ImDatabase dataBase;
+
+ public static ImDatabase get() {
+ return dataBase;
+ }
+
+ public static void get(Context context) {
+ if (null == dataBase) {
+ dataBase = Room.databaseBuilder(context, ImDatabase.class, "szyx-im-db")
+// .addMigrations(MIGRATION_1_2)
+ .allowMainThreadQueries() //允许在主线程 操作db
+ .build();
+ }
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SzyxPush.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SzyxPush.java
index 079bb5e..781667d 100644
--- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SzyxPush.java
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/SzyxPush.java
@@ -1,12 +1,12 @@
package cn.org.bjca.trust.android.lib.im;
import cn.org.bjca.trust.android.lib.im.kit.SdkInterface;
-import cn.org.bjca.trust.android.lib.im.manager.PushSdkManager;
+import cn.org.bjca.trust.android.lib.im.manager.SZYXImManager;
public class SzyxPush {
private static final class SdkInterfaceHolder {
- static final SdkInterface instance = new PushSdkManager();
+ static final SdkInterface instance = new SZYXImManager();
}
public static SdkInterface getInstance() {
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/cfg/Constant.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/cfg/Constant.java
new file mode 100644
index 0000000..5e7fb73
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/cfg/Constant.java
@@ -0,0 +1,15 @@
+package cn.org.bjca.trust.android.lib.im.cfg;
+
+public class Constant {
+ public static final String BaseUrl = "https://221n3i2201.goho.co";
+
+ private static String sdkAppID;
+
+ public static void setSdkAppID(String sdkAppID) {
+ Constant.sdkAppID = sdkAppID;
+ }
+
+ public static String getSdkAppID() {
+ return sdkAppID;
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/CommonHelper.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/CommonHelper.java
new file mode 100644
index 0000000..27310f0
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/CommonHelper.java
@@ -0,0 +1,14 @@
+package cn.org.bjca.trust.android.lib.im.common;
+
+import android.util.Log;
+
+import java.util.Arrays;
+
+public class CommonHelper {
+ public static String anyToString(Object obj) {
+ if (null == obj) return "";
+ else if (obj.getClass().getTypeName().equals("java.lang.String[]")) {
+ return Arrays.toString((String[]) obj);
+ } else return obj.toString();
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/DeviceHelper.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/DeviceHelper.java
new file mode 100644
index 0000000..b2c722c
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/common/DeviceHelper.java
@@ -0,0 +1,56 @@
+package cn.org.bjca.trust.android.lib.im.common;
+
+import android.os.Build;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import cn.org.bjca.trust.android.lib.im.SZYXDbHelper;
+import cn.org.bjca.trust.android.lib.im.db.device.DeviceEntity;
+
+public class DeviceHelper {
+ public static DeviceEntity getDevice() {
+ List entityList = SZYXDbHelper.get().deviceDao().getAll();
+ if (entityList.size() == 0) {
+ DeviceEntity device = new DeviceEntity();
+
+ Field[] fields = Build.class.getDeclaredFields();
+ for (Field field : fields) {
+ try {
+ switch (field.getName()) {
+ case "MANUFACTURER":
+ device.setManufacturer(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "BRAND":
+ device.setBrand(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "MODEL":
+ device.setModel(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "CPU_ABI":
+ device.setCpuAbi(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "FINGERPRINT":
+ device.setFingerprint(CommonHelper.anyToString(field.get(null)));
+ device.setDeviceId(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "SUPPORTED_32_BIT_ABIS":
+ device.setSupported32BitAbis(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "SUPPORTED_64_BIT_ABIS":
+ device.setSupported64BitAbis(CommonHelper.anyToString(field.get(null)));
+ break;
+ case "SUPPORTED_ABIS":
+ device.setSupportedAbis(CommonHelper.anyToString(field.get(null)));
+ break;
+ }
+ } catch (Exception e) {
+
+ }
+ }
+ SZYXDbHelper.get().deviceDao().insertAll(device);
+ return device;
+ } else return entityList.get(0);
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/BaseEntity.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/BaseEntity.java
new file mode 100644
index 0000000..44bd291
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/BaseEntity.java
@@ -0,0 +1,16 @@
+package cn.org.bjca.trust.android.lib.im.db;
+
+import androidx.room.PrimaryKey;
+
+public class BaseEntity {
+ @PrimaryKey(autoGenerate = true)
+ private int _uid;
+
+ public int get_uid() {
+ return _uid;
+ }
+
+ public void set_uid(int _uid) {
+ this._uid = _uid;
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/ImDatabase.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/ImDatabase.java
new file mode 100644
index 0000000..a3e0315
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/ImDatabase.java
@@ -0,0 +1,14 @@
+package cn.org.bjca.trust.android.lib.im.db;
+
+import androidx.room.Database;
+import androidx.room.RoomDatabase;
+
+import cn.org.bjca.trust.android.lib.im.db.device.DeviceDao;
+import cn.org.bjca.trust.android.lib.im.db.device.DeviceEntity;
+
+@Database(entities = {DeviceEntity.class}, version = 1, exportSchema = false)
+public abstract class ImDatabase extends RoomDatabase {
+
+ public abstract DeviceDao deviceDao();
+
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/device/DeviceDao.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/device/DeviceDao.java
new file mode 100644
index 0000000..773e971
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/device/DeviceDao.java
@@ -0,0 +1,25 @@
+package cn.org.bjca.trust.android.lib.im.db.device;
+
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.Query;
+import androidx.room.Update;
+
+import java.util.List;
+
+@Dao
+public interface DeviceDao {
+
+ @Query("SELECT * FROM device")
+ List getAll();
+
+ @Insert
+ void insertAll(DeviceEntity... devices);
+
+ @Update
+ void update(DeviceEntity device);
+
+ @Delete
+ void delete(DeviceEntity device);
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/device/DeviceEntity.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/device/DeviceEntity.java
new file mode 100644
index 0000000..f746077
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/db/device/DeviceEntity.java
@@ -0,0 +1,125 @@
+package cn.org.bjca.trust.android.lib.im.db.device;
+
+import androidx.annotation.NonNull;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+
+import cn.org.bjca.trust.android.lib.im.db.BaseEntity;
+
+@Entity(tableName = "device")
+public class DeviceEntity extends BaseEntity {
+ @ColumnInfo(name = "device_id")
+ private String deviceId;
+ // 厂商 MANUFACTURER
+ @ColumnInfo(name = "manufacturer")
+ private String manufacturer;
+ // 品牌 BRAND
+ @ColumnInfo(name = "brand")
+ private String brand;
+ // 型号 MODEL
+ @ColumnInfo(name = "model")
+ private String model;
+ // cpu CPU_ABI
+ @ColumnInfo(name = "cpu_abi")
+ private String cpuAbi;
+ // 指纹 FINGERPRINT
+ @ColumnInfo(name = "fingerprint")
+ private String fingerprint;
+ // SUPPORTED_32_BIT_ABIS
+ @ColumnInfo(name = "supported_32_bit_abis")
+ private String supported32BitAbis;
+ // SUPPORTED_64_BIT_ABIS
+ @ColumnInfo(name = "supported_64_bit_abis")
+ private String supported64BitAbis;
+ // SUPPORTED_ABIS
+ @ColumnInfo(name = "supported_abis")
+ private String supportedAbis;
+
+ public String getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ public String getManufacturer() {
+ return manufacturer;
+ }
+
+ public void setManufacturer(String manufacturer) {
+ this.manufacturer = manufacturer;
+ }
+
+ public String getBrand() {
+ return brand;
+ }
+
+ public void setBrand(String brand) {
+ this.brand = brand;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public String getCpuAbi() {
+ return cpuAbi;
+ }
+
+ public void setCpuAbi(String cpuAbi) {
+ this.cpuAbi = cpuAbi;
+ }
+
+ public String getFingerprint() {
+ return fingerprint;
+ }
+
+ public void setFingerprint(String fingerprint) {
+ this.fingerprint = fingerprint;
+ }
+
+ public String getSupported32BitAbis() {
+ return supported32BitAbis;
+ }
+
+ public void setSupported32BitAbis(String supported32BitAbis) {
+ this.supported32BitAbis = supported32BitAbis;
+ }
+
+ public String getSupported64BitAbis() {
+ return supported64BitAbis;
+ }
+
+ public void setSupported64BitAbis(String supported64BitAbis) {
+ this.supported64BitAbis = supported64BitAbis;
+ }
+
+ public String getSupportedAbis() {
+ return supportedAbis;
+ }
+
+ public void setSupportedAbis(String supportedAbis) {
+ this.supportedAbis = supportedAbis;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "DeviceEntity{" +
+ "deviceId='" + deviceId + '\'' +
+ ", manufacturer='" + manufacturer + '\'' +
+ ", brand='" + brand + '\'' +
+ ", model='" + model + '\'' +
+ ", cpuAbi='" + cpuAbi + '\'' +
+ ", fingerprint='" + fingerprint + '\'' +
+ ", supported32BitAbis='" + supported32BitAbis + '\'' +
+ ", supported64BitAbis='" + supported64BitAbis + '\'' +
+ ", supportedAbis='" + supportedAbis + '\'' +
+ '}';
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HeaderInterceptor.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HeaderInterceptor.java
new file mode 100644
index 0000000..ffb8105
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HeaderInterceptor.java
@@ -0,0 +1,23 @@
+package cn.org.bjca.trust.android.lib.im.http;
+
+import androidx.annotation.NonNull;
+
+import java.io.IOException;
+
+import cn.org.bjca.trust.android.lib.im.BuildConfig;
+import cn.org.bjca.trust.android.lib.im.cfg.Constant;
+import okhttp3.Interceptor;
+import okhttp3.Response;
+
+public class HeaderInterceptor implements Interceptor {
+ @NonNull
+ @Override
+ public Response intercept(@NonNull Chain chain) throws IOException {
+
+ return chain.proceed(chain.request().newBuilder()
+ .header("AppID", Constant.getSdkAppID())
+ .addHeader("Version", BuildConfig.versionName)
+ .addHeader("OsType", "1")
+ .build());
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HttpManage.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HttpManage.java
new file mode 100644
index 0000000..eac9f91
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HttpManage.java
@@ -0,0 +1,47 @@
+package cn.org.bjca.trust.android.lib.im.http;
+
+
+import java.util.concurrent.TimeUnit;
+
+import cn.org.bjca.trust.android.lib.im.cfg.Constant;
+import okhttp3.OkHttpClient;
+import okhttp3.logging.HttpLoggingInterceptor;
+import retrofit2.Retrofit;
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class HttpManage {
+
+ private static Retrofit retrofit;
+ private static OkHttpClient okHttpClient;
+
+
+ public static T getApi(final Class service) {
+
+ if (null == okHttpClient) {
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.hostnameVerifier((s, sslSession) -> true);
+ HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
+ loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
+
+ okHttpClient = builder
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .addInterceptor(loggingInterceptor)
+ .addInterceptor(new HeaderInterceptor())
+ .build();
+ }
+
+
+ if (null == retrofit) {
+ retrofit = new Retrofit.Builder()
+ .baseUrl(Constant.BaseUrl)
+ .client(okHttpClient)
+ .addConverterFactory(GsonConverterFactory.create())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .build();
+ }
+
+
+ return retrofit.create(service);
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HttpResult.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HttpResult.java
new file mode 100644
index 0000000..3ed9558
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/http/HttpResult.java
@@ -0,0 +1,37 @@
+package cn.org.bjca.trust.android.lib.im.http;
+
+public class HttpResult {
+ /**
+ * "code": 200
+ * "message": "success"
+ * data :
+ */
+
+ private int code;
+ private String msg;
+ private T data;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/PushSdkManager.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/PushSdkManager.java
deleted file mode 100644
index 6452f36..0000000
--- a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/PushSdkManager.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package cn.org.bjca.trust.android.lib.im.manager;
-
-import android.content.Context;
-
-import cn.org.bjca.trust.android.lib.im.kit.IMSDKCallback;
-import cn.org.bjca.trust.android.lib.im.kit.IMSDKListener;
-import cn.org.bjca.trust.android.lib.im.kit.MsgListener;
-import cn.org.bjca.trust.android.lib.im.kit.SdkInterface;
-
-public class PushSdkManager implements SdkInterface {
- @Override
- public void addIMSDKListener(IMSDKListener listener) {
-
- }
-
- @Override
- public void removeIMSDKListener(IMSDKListener listener) {
-
- }
-
- @Override
- public void init(Context context, String sdkAppID, IMSDKCallback callback) {
-
- }
-
- @Override
- public void login(String userID, String userSig, IMSDKCallback callback) {
-
- }
-
- @Override
- public void logout(IMSDKCallback callback) {
-
- }
-
- @Override
- public void addMsgListener(MsgListener listener) {
-
- }
-
- @Override
- public void removeMsgListener(MsgListener listener) {
-
- }
-
- @Override
- public void sendMsgForTextToC(String toUserId, String text, IMSDKCallback callback) {
-
- }
-
- @Override
- public void sendMsgForTextToG(String toGroupId, String text, IMSDKCallback callback) {
-
- }
-
- @Override
- public String getVersion() {
- return null;
- }
-}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXImManager.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXImManager.java
new file mode 100644
index 0000000..107b771
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/manager/SZYXImManager.java
@@ -0,0 +1,88 @@
+package cn.org.bjca.trust.android.lib.im.manager;
+
+import android.content.Context;
+import android.util.Log;
+
+import cn.org.bjca.trust.android.lib.im.BuildConfig;
+import cn.org.bjca.trust.android.lib.im.SZYXDbHelper;
+import cn.org.bjca.trust.android.lib.im.cfg.Constant;
+import cn.org.bjca.trust.android.lib.im.common.DeviceHelper;
+import cn.org.bjca.trust.android.lib.im.http.HttpManage;
+import cn.org.bjca.trust.android.lib.im.kit.IMSDKCallback;
+import cn.org.bjca.trust.android.lib.im.kit.IMSDKListener;
+import cn.org.bjca.trust.android.lib.im.kit.MsgListener;
+import cn.org.bjca.trust.android.lib.im.kit.SdkInterface;
+import cn.org.bjca.trust.android.lib.im.repository.Service;
+import cn.org.bjca.trust.android.lib.im.repository.data.LoginData;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+
+public class SZYXImManager implements SdkInterface {
+
+ private IMSDKListener imsdkListener;
+
+ @Override
+ public void addIMSDKListener(IMSDKListener listener) {
+ this.imsdkListener = listener;
+ }
+
+ @Override
+ public void removeIMSDKListener(IMSDKListener listener) {
+ this.imsdkListener = null;
+ }
+
+ @Override
+ public void init(Context context, String sdkAppID, IMSDKCallback callback) {
+ Constant.setSdkAppID(sdkAppID);
+ SZYXDbHelper.get(context);
+ DeviceHelper.getDevice();
+ }
+
+ @Override
+ public void login(String userID, String userSig, IMSDKCallback callback) {
+
+ Disposable d = HttpManage.getApi(Service.class)
+ .login(new LoginData(userID, userSig, DeviceHelper.getDevice()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(httpResult -> {
+ if (httpResult.getCode() == 200) {
+ if (null != callback) callback.success();
+ if (null != imsdkListener) imsdkListener.onConnecting();
+ } else if (null != callback) callback.failed(1001, httpResult.getMsg());
+ }, throwable -> {
+ if (null != callback) callback.failed(1001, throwable.getMessage());
+ });
+ }
+
+ @Override
+ public void logout(IMSDKCallback callback) {
+
+ }
+
+ @Override
+ public void addMsgListener(MsgListener listener) {
+
+ }
+
+ @Override
+ public void removeMsgListener(MsgListener listener) {
+
+ }
+
+ @Override
+ public void sendMsgForTextToC(String toUserId, String text, IMSDKCallback callback) {
+
+ }
+
+ @Override
+ public void sendMsgForTextToG(String toGroupId, String text, IMSDKCallback callback) {
+
+ }
+
+ @Override
+ public String getVersion() {
+ return BuildConfig.versionName;
+ }
+}
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
new file mode 100644
index 0000000..b769965
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/Service.java
@@ -0,0 +1,20 @@
+package cn.org.bjca.trust.android.lib.im.repository;
+
+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.repository.bean.LoginBean;
+import cn.org.bjca.trust.android.lib.im.repository.data.LoginData;
+import io.reactivex.Observable;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+
+public interface Service {
+
+ @GET("hello/{id}")
+ Observable> test(@Path("id") String id);
+
+ @POST("user/v1/login")
+ Observable> login(@Body LoginData loginData);
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/bean/LoginBean.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/bean/LoginBean.java
new file mode 100644
index 0000000..3861bd5
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/bean/LoginBean.java
@@ -0,0 +1,8 @@
+package cn.org.bjca.trust.android.lib.im.repository.bean;
+
+public class LoginBean {
+ private String host;
+ private String port;
+ private String clientId;
+ private String sign;
+}
diff --git a/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/data/LoginData.java b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/data/LoginData.java
new file mode 100644
index 0000000..d6e6180
--- /dev/null
+++ b/SzyxImSdk/src/main/java/cn/org/bjca/trust/android/lib/im/repository/data/LoginData.java
@@ -0,0 +1,42 @@
+package cn.org.bjca.trust.android.lib.im.repository.data;
+
+import cn.org.bjca.trust.android.lib.im.db.device.DeviceEntity;
+
+public class LoginData {
+ private String userId;
+ private String userSig;
+ private DeviceEntity device;
+
+ public LoginData() {
+ }
+
+ public LoginData(String userId, String userSig, DeviceEntity device) {
+ this.userId = userId;
+ this.userSig = userSig;
+ this.device = device;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getUserSig() {
+ return userSig;
+ }
+
+ public void setUserSig(String userSig) {
+ this.userSig = userSig;
+ }
+
+ public DeviceEntity getDevice() {
+ return device;
+ }
+
+ public void setDevice(DeviceEntity device) {
+ this.device = device;
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index 857e2f3..25cef0b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "cn.org.bjca.trust.android.imdemo"
- minSdk 24
+ minSdk 26
targetSdk 33
versionCode 1
versionName '1.0.0'
@@ -26,6 +26,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+ buildFeatures {
+ viewBinding true
+ }
}
dependencies {
@@ -34,6 +37,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
+ implementation 'androidx.annotation:annotation:1.3.0'
+ implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5b78bcc..b5ea9ac 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,7 @@
+
+ android:name=".ui.login.LoginActivity"
+ android:exported="true"
+ android:label="@string/title_activity_login">
+
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/LoginDataSource.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/LoginDataSource.java
new file mode 100644
index 0000000..d07b33e
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/LoginDataSource.java
@@ -0,0 +1,29 @@
+package cn.org.bjca.trust.android.imdemo.data;
+
+import cn.org.bjca.trust.android.imdemo.data.model.LoggedInUser;
+
+import java.io.IOException;
+
+/**
+ * Class that handles authentication w/ login credentials and retrieves user information.
+ */
+public class LoginDataSource {
+
+ public Result login(String username, String password) {
+
+ try {
+ // TODO: handle loggedInUser authentication
+ LoggedInUser fakeUser =
+ new LoggedInUser(username,
+ java.util.UUID.randomUUID().toString(),
+ "123456");
+ return new Result.Success<>(fakeUser);
+ } catch (Exception e) {
+ return new Result.Error(new IOException("Error logging in", e));
+ }
+ }
+
+ public void logout() {
+ // TODO: revoke authentication
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/LoginRepository.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/LoginRepository.java
new file mode 100644
index 0000000..ab798a7
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/LoginRepository.java
@@ -0,0 +1,54 @@
+package cn.org.bjca.trust.android.imdemo.data;
+
+import cn.org.bjca.trust.android.imdemo.data.model.LoggedInUser;
+
+/**
+ * Class that requests authentication and user information from the remote data source and
+ * maintains an in-memory cache of login status and user credentials information.
+ */
+public class LoginRepository {
+
+ private static volatile LoginRepository instance;
+
+ private LoginDataSource dataSource;
+
+ // If user credentials will be cached in local storage, it is recommended it be encrypted
+ // @see https://developer.android.com/training/articles/keystore
+ private LoggedInUser user = null;
+
+ // private constructor : singleton access
+ private LoginRepository(LoginDataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ public static LoginRepository getInstance(LoginDataSource dataSource) {
+ if (instance == null) {
+ instance = new LoginRepository(dataSource);
+ }
+ return instance;
+ }
+
+ public boolean isLoggedIn() {
+ return user != null;
+ }
+
+ public void logout() {
+ user = null;
+ dataSource.logout();
+ }
+
+ private void setLoggedInUser(LoggedInUser user) {
+ this.user = user;
+ // If user credentials will be cached in local storage, it is recommended it be encrypted
+ // @see https://developer.android.com/training/articles/keystore
+ }
+
+ public Result login(String username, String password) {
+ // handle login
+ Result result = dataSource.login(username, password);
+ if (result instanceof Result.Success) {
+ setLoggedInUser(((Result.Success) result).getData());
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/Result.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/Result.java
new file mode 100644
index 0000000..0d6a3ed
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/Result.java
@@ -0,0 +1,48 @@
+package cn.org.bjca.trust.android.imdemo.data;
+
+/**
+ * A generic class that holds a result success w/ data or an error exception.
+ */
+public class Result {
+ // hide the private constructor to limit subclass types (Success, Error)
+ private Result() {
+ }
+
+ @Override
+ public String toString() {
+ if (this instanceof Result.Success) {
+ Result.Success success = (Result.Success) this;
+ return "Success[data=" + success.getData().toString() + "]";
+ } else if (this instanceof Result.Error) {
+ Result.Error error = (Result.Error) this;
+ return "Error[exception=" + error.getError().toString() + "]";
+ }
+ return "";
+ }
+
+ // Success sub-class
+ public final static class Success extends Result {
+ private T data;
+
+ public Success(T data) {
+ this.data = data;
+ }
+
+ public T getData() {
+ return this.data;
+ }
+ }
+
+ // Error sub-class
+ public final static class Error extends Result {
+ private Exception error;
+
+ public Error(Exception error) {
+ this.error = error;
+ }
+
+ public Exception getError() {
+ return this.error;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/model/LoggedInUser.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/model/LoggedInUser.java
new file mode 100644
index 0000000..2054d06
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/data/model/LoggedInUser.java
@@ -0,0 +1,29 @@
+package cn.org.bjca.trust.android.imdemo.data.model;
+
+/**
+ * Data class that captures user information for logged in users retrieved from LoginRepository
+ */
+public class LoggedInUser {
+
+ private final String userId;
+ private final String displayName;
+ private final String userSig;
+
+ public LoggedInUser(String userId, String displayName, String userSig) {
+ this.userId = userId;
+ this.displayName = displayName;
+ this.userSig = userSig;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getUserSig() {
+ return userSig;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoggedInUserView.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoggedInUserView.java
new file mode 100644
index 0000000..d17d903
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoggedInUserView.java
@@ -0,0 +1,19 @@
+package cn.org.bjca.trust.android.imdemo.ui.login;
+
+import cn.org.bjca.trust.android.imdemo.data.model.LoggedInUser;
+
+/**
+ * Class exposing authenticated user details to the UI.
+ */
+class LoggedInUserView {
+ private LoggedInUser user;
+ //... other data fields that may be accessible to the UI
+
+ LoggedInUserView(LoggedInUser user) {
+ this.user = user;
+ }
+
+ LoggedInUser getDisplayName() {
+ return user;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginActivity.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginActivity.java
new file mode 100644
index 0000000..680fa4b
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginActivity.java
@@ -0,0 +1,143 @@
+package cn.org.bjca.trust.android.imdemo.ui.login;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import cn.org.bjca.trust.android.imdemo.MainActivity;
+import cn.org.bjca.trust.android.imdemo.databinding.ActivityLoginBinding;
+import cn.org.bjca.trust.android.lib.im.SzyxPush;
+import cn.org.bjca.trust.android.lib.im.kit.IMSDKCallback;
+
+public class LoginActivity extends AppCompatActivity {
+
+ private LoginViewModel loginViewModel;
+ private ActivityLoginBinding binding;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ binding = ActivityLoginBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ loginViewModel = new ViewModelProvider(this, new LoginViewModelFactory())
+ .get(LoginViewModel.class);
+
+ final EditText usernameEditText = binding.username;
+ final EditText passwordEditText = binding.password;
+ final Button loginButton = binding.login;
+ final ProgressBar loadingProgressBar = binding.loading;
+
+ loginViewModel.getLoginFormState().observe(this, new Observer() {
+ @Override
+ public void onChanged(@Nullable LoginFormState loginFormState) {
+ if (loginFormState == null) {
+ return;
+ }
+ loginButton.setEnabled(loginFormState.isDataValid());
+ if (loginFormState.getUsernameError() != null) {
+ usernameEditText.setError(getString(loginFormState.getUsernameError()));
+ }
+ if (loginFormState.getPasswordError() != null) {
+ passwordEditText.setError(getString(loginFormState.getPasswordError()));
+ }
+ }
+ });
+
+ loginViewModel.getLoginResult().observe(this, new Observer() {
+ @Override
+ public void onChanged(@Nullable LoginResult loginResult) {
+ if (loginResult == null) {
+ return;
+ }
+ loadingProgressBar.setVisibility(View.GONE);
+ if (loginResult.getError() != null) {
+ showLoginFailed(loginResult.getError());
+ }
+ if (loginResult.getSuccess() != null) {
+ updateUiWithUser(loginResult.getSuccess());
+ }
+ }
+ });
+
+ TextWatcher afterTextChangedListener = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // ignore
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // ignore
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ loginViewModel.loginDataChanged(usernameEditText.getText().toString(),
+ passwordEditText.getText().toString());
+ }
+ };
+ usernameEditText.addTextChangedListener(afterTextChangedListener);
+ passwordEditText.addTextChangedListener(afterTextChangedListener);
+ passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ loginViewModel.login(usernameEditText.getText().toString(),
+ passwordEditText.getText().toString());
+ }
+ return false;
+ }
+ });
+
+ loginButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ loadingProgressBar.setVisibility(View.VISIBLE);
+ loginViewModel.login(usernameEditText.getText().toString(),
+ passwordEditText.getText().toString());
+ }
+ });
+ }
+
+ private void updateUiWithUser(LoggedInUserView model) {
+ SzyxPush.getInstance().login(model.getDisplayName().getUserId(), model.getDisplayName().getUserSig(), new IMSDKCallback() {
+ @Override
+ public void success() {
+
+ setResult(Activity.RESULT_OK);
+
+ startActivity(new Intent(LoginActivity.this, MainActivity.class));
+ //Complete and destroy login activity once successful
+ finish();
+ }
+
+ @Override
+ public void failed(int code, String error) {
+ Toast.makeText(getApplicationContext(), error, Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ private void showLoginFailed(@StringRes Integer errorString) {
+ Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginFormState.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginFormState.java
new file mode 100644
index 0000000..9659f1d
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginFormState.java
@@ -0,0 +1,40 @@
+package cn.org.bjca.trust.android.imdemo.ui.login;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Data validation state of the login form.
+ */
+class LoginFormState {
+ @Nullable
+ private Integer usernameError;
+ @Nullable
+ private Integer passwordError;
+ private boolean isDataValid;
+
+ LoginFormState(@Nullable Integer usernameError, @Nullable Integer passwordError) {
+ this.usernameError = usernameError;
+ this.passwordError = passwordError;
+ this.isDataValid = false;
+ }
+
+ LoginFormState(boolean isDataValid) {
+ this.usernameError = null;
+ this.passwordError = null;
+ this.isDataValid = isDataValid;
+ }
+
+ @Nullable
+ Integer getUsernameError() {
+ return usernameError;
+ }
+
+ @Nullable
+ Integer getPasswordError() {
+ return passwordError;
+ }
+
+ boolean isDataValid() {
+ return isDataValid;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginResult.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginResult.java
new file mode 100644
index 0000000..1e313f9
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginResult.java
@@ -0,0 +1,31 @@
+package cn.org.bjca.trust.android.imdemo.ui.login;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Authentication result : success (user details) or error message.
+ */
+class LoginResult {
+ @Nullable
+ private LoggedInUserView success;
+ @Nullable
+ private Integer error;
+
+ LoginResult(@Nullable Integer error) {
+ this.error = error;
+ }
+
+ LoginResult(@Nullable LoggedInUserView success) {
+ this.success = success;
+ }
+
+ @Nullable
+ LoggedInUserView getSuccess() {
+ return success;
+ }
+
+ @Nullable
+ Integer getError() {
+ return error;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginViewModel.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginViewModel.java
new file mode 100644
index 0000000..5f6bc76
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginViewModel.java
@@ -0,0 +1,70 @@
+package cn.org.bjca.trust.android.imdemo.ui.login;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+import android.util.Patterns;
+
+import cn.org.bjca.trust.android.imdemo.data.LoginRepository;
+import cn.org.bjca.trust.android.imdemo.data.Result;
+import cn.org.bjca.trust.android.imdemo.data.model.LoggedInUser;
+import cn.org.bjca.trust.android.imdemo.R;
+
+public class LoginViewModel extends ViewModel {
+
+ private MutableLiveData loginFormState = new MutableLiveData<>();
+ private MutableLiveData loginResult = new MutableLiveData<>();
+ private LoginRepository loginRepository;
+
+ LoginViewModel(LoginRepository loginRepository) {
+ this.loginRepository = loginRepository;
+ }
+
+ LiveData getLoginFormState() {
+ return loginFormState;
+ }
+
+ LiveData getLoginResult() {
+ return loginResult;
+ }
+
+ public void login(String username, String password) {
+ // can be launched in a separate asynchronous job
+ Result result = loginRepository.login(username, password);
+
+ if (result instanceof Result.Success) {
+ LoggedInUser data = ((Result.Success) result).getData();
+ loginResult.setValue(new LoginResult(new LoggedInUserView(data)));
+ } else {
+ loginResult.setValue(new LoginResult(R.string.login_failed));
+ }
+ }
+
+ public void loginDataChanged(String username, String password) {
+ if (!isUserNameValid(username)) {
+ loginFormState.setValue(new LoginFormState(R.string.invalid_username, null));
+ } else if (!isPasswordValid(password)) {
+ loginFormState.setValue(new LoginFormState(null, R.string.invalid_password));
+ } else {
+ loginFormState.setValue(new LoginFormState(true));
+ }
+ }
+
+ // A placeholder username validation check
+ private boolean isUserNameValid(String username) {
+ if (username == null) {
+ return false;
+ }
+ if (username.contains("@")) {
+ return Patterns.EMAIL_ADDRESS.matcher(username).matches();
+ } else {
+ return !username.trim().isEmpty();
+ }
+ }
+
+ // A placeholder password validation check
+ private boolean isPasswordValid(String password) {
+ return password != null && password.trim().length() > 5;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginViewModelFactory.java b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginViewModelFactory.java
new file mode 100644
index 0000000..b50b699
--- /dev/null
+++ b/app/src/main/java/cn/org/bjca/trust/android/imdemo/ui/login/LoginViewModelFactory.java
@@ -0,0 +1,26 @@
+package cn.org.bjca.trust.android.imdemo.ui.login;
+
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.annotation.NonNull;
+
+import cn.org.bjca.trust.android.imdemo.data.LoginDataSource;
+import cn.org.bjca.trust.android.imdemo.data.LoginRepository;
+
+/**
+ * ViewModel provider factory to instantiate LoginViewModel.
+ * Required given LoginViewModel has a non-empty constructor
+ */
+public class LoginViewModelFactory implements ViewModelProvider.Factory {
+
+ @NonNull
+ @Override
+ @SuppressWarnings("unchecked")
+ public T create(@NonNull Class modelClass) {
+ if (modelClass.isAssignableFrom(LoginViewModel.class)) {
+ return (T) new LoginViewModel(LoginRepository.getInstance(new LoginDataSource()));
+ } else {
+ throw new IllegalArgumentException("Unknown ViewModel class");
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout-w1240dp/activity_login.xml b/app/src/main/res/layout-w1240dp/activity_login.xml
new file mode 100644
index 0000000..738fb65
--- /dev/null
+++ b/app/src/main/res/layout-w1240dp/activity_login.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout-w936dp/activity_login.xml b/app/src/main/res/layout-w936dp/activity_login.xml
new file mode 100644
index 0000000..8e82562
--- /dev/null
+++ b/app/src/main/res/layout-w936dp/activity_login.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..238e5b0
--- /dev/null
+++ b/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml
new file mode 100644
index 0000000..5f681ae
--- /dev/null
+++ b/app/src/main/res/values-land/dimens.xml
@@ -0,0 +1,3 @@
+
+ 48dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 0000000..7e06511
--- /dev/null
+++ b/app/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,3 @@
+
+ 200dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 0000000..5f681ae
--- /dev/null
+++ b/app/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,3 @@
+
+ 48dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..e00c2dd
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0cde9fc..5993878 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,12 @@
ImAndroid
+ LoginActivity
+ Phone
+ Password
+ Sign in or register
+ Sign in
+ "Welcome !"
+ Not a valid username
+ Password must be >5 characters
+ "Login failed"
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index b944613..0091513 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -5,7 +5,7 @@ pluginManagement {
allowInsecureProtocol true
}
maven {
- url 'http://nexus.51trust.net/repository/maven-public/'
+ url 'http://nexus.51trust.net/repository/gradle-plugin/'
allowInsecureProtocol true
}
}
@@ -18,7 +18,7 @@ dependencyResolutionManagement {
allowInsecureProtocol true
}
maven {
- url 'http://nexus.51trust.net/repository/maven-public/'
+ url 'http://nexus.51trust.net/repository/gradle-plugin/'
allowInsecureProtocol true
}
}