diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..61ab3f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,85 @@
+# Built application files
+*.apk
+*.aar
+*.ap_
+*.aab
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+# Uncomment the following line in case you need and you don't have the release build type files in your app
+# release/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+# Android Studio 3 in .gitignore file.
+.idea/caches
+.idea/modules.xml
+# Comment next line if keeping position of elements in Navigation Editor is relevant for you
+.idea/navEditor.xml
+
+# Keystore files
+# Uncomment the following lines if you do not want to check your keystore files in.
+#*.jks
+#*.keystore
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+.cxx/
+
+# Google Services (e.g. APIs or Firebase)
+# google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
+
+# Version control
+vcs.xml
+
+# lint
+lint/intermediates/
+lint/generated/
+lint/outputs/
+lint/tmp/
+# lint/reports/
+
+/app/key
+output-metadata.json
+# Android Profiling
+*.hprof
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..0e3e997
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,117 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'kotlin-kapt'
+
+
+android {
+ compileSdkVersion versions.compileSdk
+ buildToolsVersion versions.buildTools
+
+ defaultConfig {
+ applicationId apps.applicationId
+ minSdkVersion versions.minSdk
+ targetSdkVersion versions.targetSdk
+ versionCode versions.versionCode
+ versionName versions.versionName
+
+ manifestPlaceholders = [
+ APP_NAME: apps.applicationName,
+ APP_ID : apps.applicationId,
+ ]
+ buildConfigField("String", "APP_Name", "\"" + apps.applicationName + "\"")
+
+ flavorDimensions "versioncode"
+ }
+ buildTypes {
+ debug {
+ minifyEnabled false
+ signingConfig signingConfigs.debug
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ release {
+ minifyEnabled false
+ signingConfig signingConfigs.debug
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ applicationVariants.configureEach { variant ->
+ variant.outputs.configureEach { output ->
+ if ("debug" != variant.buildType.name) {
+ def now = new Date()
+ def path = "../../../../../apks/${variant.buildType.name}/v${defaultConfig.versionName}_" + now.format("yyyy.MM.dd_HH")
+ outputFileName = path + "/${applicationId}.apk"
+ }
+ }
+ }
+ signingConfigs {
+ debug {
+ keyAlias 'livechat'
+ keyPassword '123456'
+ storeFile file('key.jks')
+ storePassword '123456'
+ }
+ releaseConfig {}
+ }
+
+ sourceSets {
+ main {
+ jniLibs.srcDirs = ['libs']
+ }
+ }
+ androidExtensions {
+ experimental = true
+ }
+ namespace 'com.xuqinmin.android.app'
+}
+
+dependencies {
+ implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
+ implementation project(path: ':core')
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.3.0'
+ implementation 'com.google.android.material:material:1.3.0'
+
+ implementation 'tp.xmaihh:serialport:2.1'
+
+ implementation 'com.rabbitmq:amqp-client:5.15.0'
+ implementation 'com.github.weidongjian:androidWheelView:1.0.0'
+
+ // 声网
+ implementation 'io.agora.rtc:full-sdk:4.2.3'
+
+ //毛玻璃
+ implementation 'com.github.centerzx:ShapeBlurView:1.0.5'
+
+// implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
+// implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
+//
+// implementation 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
+// implementation 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
+// implementation 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
+// implementation 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
+//
+// implementation 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
+
+ implementation 'com.github.leifzhang:IjkLib:0.4.3'
+ // json 动画
+ implementation 'com.airbnb.android:lottie:3.4.0'
+ // 视频缓存
+ implementation 'com.danikula:videocache:2.7.1'
+
+ //eventbus
+ implementation 'org.greenrobot:eventbus:3.1.1'
+
+ implementation 'androidx.room:room-runtime:2.2.3'
+// annotationProcessor "androidx.room:room-compiler:2.2.3"
+ kapt "androidx.room:room-compiler:2.2.3"
+
+ implementation("com.android.billingclient:billing:6.2.0")
+// implementation("com.android.billingclient:billing-ktx:6.2.0")
+
+}
diff --git a/app/key.jks b/app/key.jks
new file mode 100644
index 0000000..2685a99
Binary files /dev/null and b/app/key.jks differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..8abd371
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,22 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+# -keep class io.agora.**{*;}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3f555f7
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/answer.json b/app/src/main/assets/answer.json
new file mode 100644
index 0000000..0dfac02
--- /dev/null
+++ b/app/src/main/assets/answer.json
@@ -0,0 +1 @@
+{"v":"5.6.9","fr":20,"ip":0,"op":60,"w":160,"h":160,"nm":"answer","ddd":0,"assets":[{"id":"image_0","w":54,"h":68,"u":"images/","p":"img_0.png","e":0},{"id":"image_1","w":132,"h":132,"u":"images/","p":"img_1.png","e":0}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"路径 4234.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":45,"s":[5]},{"t":50,"s":[0]}],"ix":10},"p":{"a":0,"k":[79.5,81.5,0],"ix":2},"a":{"a":0,"k":[27,34,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"椭圆 795.png","cl":"png","refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[80,80,0],"ix":2},"a":{"a":0,"k":[66,66,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"椭圆 795.png","cl":"png","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[100]},{"t":50,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[80,80,0],"ix":2},"a":{"a":0,"k":[66,66,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":30,"s":[100,100,100]},{"t":50,"s":[120,120,100]}],"ix":6}},"ao":0,"ip":30,"op":50,"st":30,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"椭圆 795.png","cl":"png","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[100]},{"t":35,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[80,80,0],"ix":2},"a":{"a":0,"k":[66,66,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":15,"s":[100,100,100]},{"t":35,"s":[120,120,100]}],"ix":6}},"ao":0,"ip":15,"op":35,"st":15,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"椭圆 795.png","cl":"png","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[80,80,0],"ix":2},"a":{"a":0,"k":[66,66,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"t":20,"s":[120,120,100]}],"ix":6}},"ao":0,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/app/src/main/assets/fonts/Montserrat-Black.ttf b/app/src/main/assets/fonts/Montserrat-Black.ttf
new file mode 100644
index 0000000..93b8bab
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Black.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-BlackItalic.ttf b/app/src/main/assets/fonts/Montserrat-BlackItalic.ttf
new file mode 100644
index 0000000..438630e
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-BlackItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-Bold.ttf b/app/src/main/assets/fonts/Montserrat-Bold.ttf
new file mode 100644
index 0000000..55e0b1a
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Bold.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-BoldItalic.ttf b/app/src/main/assets/fonts/Montserrat-BoldItalic.ttf
new file mode 100644
index 0000000..6b4541d
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-BoldItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-ExtraBold.ttf b/app/src/main/assets/fonts/Montserrat-ExtraBold.ttf
new file mode 100644
index 0000000..7b4f267
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-ExtraBold.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-ExtraBoldItalic.ttf b/app/src/main/assets/fonts/Montserrat-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..66ccd46
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-ExtraBoldItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-ExtraLight.ttf b/app/src/main/assets/fonts/Montserrat-ExtraLight.ttf
new file mode 100644
index 0000000..532cbb5
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-ExtraLight.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-ExtraLightItalic.ttf b/app/src/main/assets/fonts/Montserrat-ExtraLightItalic.ttf
new file mode 100644
index 0000000..150591a
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-ExtraLightItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-Italic.ttf b/app/src/main/assets/fonts/Montserrat-Italic.ttf
new file mode 100644
index 0000000..be99e1c
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Italic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-Light.ttf b/app/src/main/assets/fonts/Montserrat-Light.ttf
new file mode 100644
index 0000000..2c91484
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Light.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-LightItalic.ttf b/app/src/main/assets/fonts/Montserrat-LightItalic.ttf
new file mode 100644
index 0000000..7082e03
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-LightItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-Medium.ttf b/app/src/main/assets/fonts/Montserrat-Medium.ttf
new file mode 100644
index 0000000..0f0fd1d
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Medium.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-MediumItalic.ttf b/app/src/main/assets/fonts/Montserrat-MediumItalic.ttf
new file mode 100644
index 0000000..5bd6dd2
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-MediumItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-Regular.ttf b/app/src/main/assets/fonts/Montserrat-Regular.ttf
new file mode 100644
index 0000000..1cd0259
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Regular.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-SemiBold.ttf b/app/src/main/assets/fonts/Montserrat-SemiBold.ttf
new file mode 100644
index 0000000..ccaba1a
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-SemiBold.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-SemiBoldItalic.ttf b/app/src/main/assets/fonts/Montserrat-SemiBoldItalic.ttf
new file mode 100644
index 0000000..b8278b9
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-SemiBoldItalic.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-Thin.ttf b/app/src/main/assets/fonts/Montserrat-Thin.ttf
new file mode 100644
index 0000000..a6d0321
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-Thin.ttf differ
diff --git a/app/src/main/assets/fonts/Montserrat-ThinItalic.ttf b/app/src/main/assets/fonts/Montserrat-ThinItalic.ttf
new file mode 100644
index 0000000..585c82b
Binary files /dev/null and b/app/src/main/assets/fonts/Montserrat-ThinItalic.ttf differ
diff --git a/app/src/main/assets/images/img_0.png b/app/src/main/assets/images/img_0.png
new file mode 100644
index 0000000..b74d1ed
Binary files /dev/null and b/app/src/main/assets/images/img_0.png differ
diff --git a/app/src/main/assets/images/img_1.png b/app/src/main/assets/images/img_1.png
new file mode 100644
index 0000000..3caf265
Binary files /dev/null and b/app/src/main/assets/images/img_1.png differ
diff --git a/app/src/main/assets/matching.json b/app/src/main/assets/matching.json
new file mode 100644
index 0000000..3a5ee38
--- /dev/null
+++ b/app/src/main/assets/matching.json
@@ -0,0 +1 @@
+{"v":"5.6.9","fr":20,"ip":0,"op":120,"w":700,"h":700,"nm":"matching","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[100]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[350,350,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":60,"s":[10,10,100]},{"t":120,"s":[95,95,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[192.221,0],[0,-192.221],[-192.221,0],[0,192.221]],"o":[[-192.221,0],[0,192.221],[192.221,0],[0,-192.221]],"v":[[0,-348.047],[-348.047,0],[0,348.047],[348.047,0]],"c":true},"ix":2,"x":"var $bm_rt;\n$bm_rt = content('\\u692d\\u5706 1').content('\\u8def\\u5f84 1').path;"},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.007843137255,0.654901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[60]},{"t":120,"s":[12]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.047,0.047],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":120,"st":60,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"形状图层 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[100]},{"t":90,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[350,350,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":30,"s":[10,10,100]},{"t":90,"s":[95,95,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[192.221,0],[0,-192.221],[-192.221,0],[0,192.221]],"o":[[-192.221,0],[0,192.221],[192.221,0],[0,-192.221]],"v":[[0,-348.047],[-348.047,0],[0,348.047],[348.047,0]],"c":true},"ix":2,"x":"var $bm_rt;\n$bm_rt = content('\\u692d\\u5706 1').content('\\u8def\\u5f84 1').path;"},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.007843137255,0.654901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":90,"s":[12]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.047,0.047],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":90,"st":30,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"形状图层 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[350,350,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[10,10,100]},{"t":60,"s":[95,95,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[192.221,0],[0,-192.221],[-192.221,0],[0,192.221]],"o":[[-192.221,0],[0,192.221],[192.221,0],[0,-192.221]],"v":[[0,-348.047],[-348.047,0],[0,348.047],[348.047,0]],"c":true},"ix":2,"x":"var $bm_rt;\n$bm_rt = content('\\u692d\\u5706 1').content('\\u8def\\u5f84 1').path;"},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.007843137255,0.654901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[60]},{"t":60,"s":[12]}],"ix":5},"lc":2,"lj":2,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.047,0.047],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/app/src/main/java/com/xuqinmin/android/app/MyApplication.java b/app/src/main/java/com/xuqinmin/android/app/MyApplication.java
new file mode 100644
index 0000000..b7160bb
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/MyApplication.java
@@ -0,0 +1,273 @@
+package com.xuqinmin.android.app;
+
+import static com.xuqm.base.common.SharedPreferencesConfigsKt.MSG_COUNT;
+import static com.xuqm.base.extensions.CommonExtKt.getIntForPreferences;
+import static com.xuqm.base.extensions.CommonExtKt.putInt;
+
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.annotation.NonNull;
+
+import com.android.billingclient.api.BillingClient;
+import com.android.billingclient.api.BillingClientStateListener;
+import com.android.billingclient.api.BillingFlowParams;
+import com.android.billingclient.api.BillingResult;
+import com.android.billingclient.api.ProductDetailsResponseListener;
+import com.android.billingclient.api.QueryProductDetailsParams;
+import com.danikula.videocache.HttpProxyCacheServer;
+import com.xuqinmin.android.app.common.CrashHandler;
+import com.xuqinmin.android.app.common.LiveHelper;
+import com.xuqinmin.android.app.common.StoreHelper;
+import com.xuqinmin.android.app.db.XuqmDbHelper;
+import com.xuqinmin.android.app.db.msg.MessageEntity;
+import com.xuqinmin.android.app.model.Balance;
+import com.xuqinmin.android.app.model.GiftModel;
+import com.xuqinmin.android.app.model.ModelHideIn;
+import com.xuqinmin.android.app.model.ModelInit;
+import com.xuqinmin.android.app.model.Region;
+import com.xuqinmin.android.app.model.msg.CallModel;
+import com.xuqinmin.android.app.model.msg.ConversationsModel;
+import com.xuqinmin.android.app.model.msg.MessagModel;
+import com.xuqinmin.android.app.model.msg.MsgReceipt;
+import com.xuqinmin.android.app.repository.HeaderInterceptor;
+import com.xuqinmin.android.app.repository.HeaderInterceptorList;
+import com.xuqinmin.android.app.ui.LiveActivity;
+import com.xuqm.base.App;
+import com.xuqm.base.common.AESCBCUtil;
+import com.xuqm.base.common.AppManager;
+import com.xuqm.base.common.GsonImplHelp;
+import com.xuqm.base.common.LogHelper;
+import com.xuqm.base.common.TimeHelper;
+import com.xuqm.base.common.ToolsHelper;
+import com.xuqm.base.di.component.AppComponent;
+import com.xuqm.base.di.manager.HttpManager;
+import com.xuqm.base.webSocket.ConnectStatus;
+import com.xuqm.base.webSocket.WebSocketCallBack;
+import com.xuqm.base.webSocket.WebSocketHandler;
+import com.xuqm.sdhbwfu.core.model.PlayModel;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * @author xuqm
+ */
+public class MyApplication extends App {
+
+ public static String baseUrl = "https://api.heyzvc.com";
+
+ public static ModelInit modelInit;
+ public static ModelHideIn modelHideIn;
+ public static List giftModelList = new ArrayList<>();
+ public static List country = new ArrayList<>();
+// public static List country = GsonImplHelp.get().toObject("{\"Regions\":[{\"code\":\"376\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDE9\",\"iso\":\"AD\",\"name\":\"Andorra\"},{\"code\":\"971\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDEA\",\"iso\":\"AE\",\"name\":\"United Arab Emirates\"},{\"code\":\"93\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDEB\",\"iso\":\"AF\",\"name\":\"Afghanistan\"},{\"code\":\"1268\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDEC\",\"iso\":\"AG\",\"name\":\"Antigua\"},{\"code\":\"1264\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDEE\",\"iso\":\"AI\",\"name\":\"Anguilla\"},{\"code\":\"355\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDF1\",\"iso\":\"AL\",\"name\":\"Albania\"},{\"code\":\"374\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDF2\",\"iso\":\"AM\",\"name\":\"Armenia\"},{\"code\":\"244\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDF4\",\"iso\":\"AO\",\"name\":\"Angola\"},{\"code\":\"54\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDF7\",\"iso\":\"AR\",\"name\":\"Argentina\"},{\"code\":\"247\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDF8\",\"iso\":\"AS\",\"name\":\"American Samoa\"},{\"code\":\"43\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDF9\",\"iso\":\"AT\",\"name\":\"Austria\"},{\"code\":\"61\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDFA\",\"iso\":\"AU\",\"name\":\"Australia\"},{\"code\":\"297\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDFC\",\"iso\":\"AW\",\"name\":\"Aruba\"},{\"code\":\"994\",\"emoji\":\"\uD83C\uDDE6\uD83C\uDDFF\",\"iso\":\"AZ\",\"name\":\"Azerbaijan\"},{\"code\":\"387\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDE6\",\"iso\":\"BA\",\"name\":\"Bosnia and Herzegovina\"},{\"code\":\"1246\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDE7\",\"iso\":\"BB\",\"name\":\"Barbados\"},{\"code\":\"880\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDE9\",\"iso\":\"BD\",\"name\":\"Bangladesh\"},{\"code\":\"32\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDEA\",\"iso\":\"BE\",\"name\":\"Belgium\"},{\"code\":\"226\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDEB\",\"iso\":\"BF\",\"name\":\"Burkina Faso\"},{\"code\":\"359\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDEC\",\"iso\":\"BG\",\"name\":\"Bulgaria\"},{\"code\":\"973\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDED\",\"iso\":\"BH\",\"name\":\"Bahrain\"},{\"code\":\"257\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDEE\",\"iso\":\"BI\",\"name\":\"Burundi\"},{\"code\":\"229\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDEF\",\"iso\":\"BJ\",\"name\":\"Benin\"},{\"code\":\"1441\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF2\",\"iso\":\"BM\",\"name\":\"Bermuda\"},{\"code\":\"673\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF3\",\"iso\":\"BN\",\"name\":\"Brunei\"},{\"code\":\"591\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF4\",\"iso\":\"BO\",\"name\":\"Bolivia\"},{\"code\":\"599\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF6\",\"iso\":\"BQ\",\"name\":\"Bonaire, Sint Eustatius and Saba\"},{\"code\":\"55\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF7\",\"iso\":\"BR\",\"name\":\"Brazil\"},{\"code\":\"1242\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF8\",\"iso\":\"BS\",\"name\":\"The Bahamas\"},{\"code\":\"975\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDF9\",\"iso\":\"BT\",\"name\":\"Bhutan\"},{\"code\":\"267\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDFC\",\"iso\":\"BW\",\"name\":\"Botswana\"},{\"code\":\"375\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDFE\",\"iso\":\"BY\",\"name\":\"Belarus\"},{\"code\":\"501\",\"emoji\":\"\uD83C\uDDE7\uD83C\uDDFF\",\"iso\":\"BZ\",\"name\":\"Belize\"},{\"code\":\"2\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDE6\",\"iso\":\"CA\",\"name\":\"Canada\"},{\"code\":\"243\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDE9\",\"iso\":\"CD\",\"name\":\"Democratic Republic of the Congo\"},{\"code\":\"236\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDEB\",\"iso\":\"CF\",\"name\":\"Central African Republic\"},{\"code\":\"242\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDEC\",\"iso\":\"CG\",\"name\":\"Republic of the Congo\"},{\"code\":\"41\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDED\",\"iso\":\"CH\",\"name\":\"Switzerland\"},{\"code\":\"225\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDEE\",\"iso\":\"CI\",\"name\":\"Côte d\\\\'Ivoire\"},{\"code\":\"682\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDF0\",\"iso\":\"CK\",\"name\":\"Cook Islands\"},{\"code\":\"56\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDF1\",\"iso\":\"CL\",\"name\":\"Chile\"},{\"code\":\"237\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDF2\",\"iso\":\"CM\",\"name\":\"Cameroon\"},{\"code\":\"86\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDF3\",\"iso\":\"CN\",\"name\":\"China\"},{\"code\":\"57\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDF4\",\"iso\":\"CO\",\"name\":\"Colombia\"},{\"code\":\"506\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDF7\",\"iso\":\"CR\",\"name\":\"Costa Rica\"},{\"code\":\"53\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDFA\",\"iso\":\"CU\",\"name\":\"Cuba\"},{\"code\":\"238\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDFB\",\"iso\":\"CV\",\"name\":\"Cape Verde\"},{\"code\":\"600\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDFC\",\"iso\":\"CW\",\"name\":\"Curaçao\"},{\"code\":\"357\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDFE\",\"iso\":\"CY\",\"name\":\"Cyprus\"},{\"code\":\"420\",\"emoji\":\"\uD83C\uDDE8\uD83C\uDDFF\",\"iso\":\"CZ\",\"name\":\"Czech Republic\"},{\"code\":\"49\",\"emoji\":\"\uD83C\uDDE9\uD83C\uDDEA\",\"iso\":\"DE\",\"name\":\"Germany\"},{\"code\":\"253\",\"emoji\":\"\uD83C\uDDE9\uD83C\uDDEF\",\"iso\":\"DJ\",\"name\":\"Djibouti\"},{\"code\":\"45\",\"emoji\":\"\uD83C\uDDE9\uD83C\uDDF0\",\"iso\":\"DK\",\"name\":\"Denmark\"},{\"code\":\"1767\",\"emoji\":\"\uD83C\uDDE9\uD83C\uDDF2\",\"iso\":\"DM\",\"name\":\"Dominica\"},{\"code\":\"1849\",\"emoji\":\"\uD83C\uDDE9\uD83C\uDDF4\",\"iso\":\"DO\",\"name\":\"Dominican Republic\"},{\"code\":\"213\",\"emoji\":\"\uD83C\uDDE9\uD83C\uDDFF\",\"iso\":\"DZ\",\"name\":\"Algeria\"},{\"code\":\"593\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDE8\",\"iso\":\"EC\",\"name\":\"Ecuador\"},{\"code\":\"372\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDEA\",\"iso\":\"EE\",\"name\":\"Estonia\"},{\"code\":\"20\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDEC\",\"iso\":\"EG\",\"name\":\"Egypt\"},{\"code\":\"211\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDED\",\"iso\":\"EH\",\"name\":\"Western Sahara\"},{\"code\":\"291\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDF7\",\"iso\":\"ER\",\"name\":\"Eritrea\"},{\"code\":\"34\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDF8\",\"iso\":\"ES\",\"name\":\"Spain\"},{\"code\":\"251\",\"emoji\":\"\uD83C\uDDEA\uD83C\uDDF9\",\"iso\":\"ET\",\"name\":\"Ethiopia\"},{\"code\":\"358\",\"emoji\":\"\uD83C\uDDEB\uD83C\uDDEE\",\"iso\":\"FI\",\"name\":\"Finland\"},{\"code\":\"679\",\"emoji\":\"\uD83C\uDDEB\uD83C\uDDEF\",\"iso\":\"FJ\",\"name\":\"Fiji\"},{\"code\":\"500\",\"emoji\":\"\uD83C\uDDEB\uD83C\uDDF0\",\"iso\":\"FK\",\"name\":\"Falkland Islands\"},{\"code\":\"691\",\"emoji\":\"\uD83C\uDDEB\uD83C\uDDF2\",\"iso\":\"FM\",\"name\":\"Federated States of Micronesia\"},{\"code\":\"298\",\"emoji\":\"\uD83C\uDDEB\uD83C\uDDF4\",\"iso\":\"FO\",\"name\":\"Faroe Islands\"},{\"code\":\"33\",\"emoji\":\"\uD83C\uDDEB\uD83C\uDDF7\",\"iso\":\"FR\",\"name\":\"France\"},{\"code\":\"241\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDE6\",\"iso\":\"GA\",\"name\":\"Gabon\"},{\"code\":\"44\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDE7\",\"iso\":\"GB\",\"name\":\"United Kingdom\"},{\"code\":\"1473\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDE9\",\"iso\":\"GD\",\"name\":\"Grenada\"},{\"code\":\"995\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDEA\",\"iso\":\"GE\",\"name\":\"Georgia\"},{\"code\":\"594\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDEB\",\"iso\":\"GF\",\"name\":\"French Guiana\"},{\"code\":\"42\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDEC\",\"iso\":\"GG\",\"name\":\"Guernsey\"},{\"code\":\"233\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDED\",\"iso\":\"GH\",\"name\":\"Ghana\"},{\"code\":\"350\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDEE\",\"iso\":\"GI\",\"name\":\"Gibraltar\"},{\"code\":\"299\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF1\",\"iso\":\"GL\",\"name\":\"Greenland\"},{\"code\":\"220\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF2\",\"iso\":\"GM\",\"name\":\"The Gambia\"},{\"code\":\"224\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF3\",\"iso\":\"GN\",\"name\":\"Guinea\"},{\"code\":\"590\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF5\",\"iso\":\"GP\",\"name\":\"Guadeloupe\"},{\"code\":\"240\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF6\",\"iso\":\"GQ\",\"name\":\"Equatorial Guinea\"},{\"code\":\"30\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF7\",\"iso\":\"GR\",\"name\":\"Greece\"},{\"code\":\"502\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDF9\",\"iso\":\"GT\",\"name\":\"Guatemala\"},{\"code\":\"1671\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDFA\",\"iso\":\"GU\",\"name\":\"Guam\"},{\"code\":\"245\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDFC\",\"iso\":\"GW\",\"name\":\"Guinea-Bissau\"},{\"code\":\"592\",\"emoji\":\"\uD83C\uDDEC\uD83C\uDDFE\",\"iso\":\"GY\",\"name\":\"Guyana\"},{\"code\":\"852\",\"emoji\":\"\uD83C\uDDED\uD83C\uDDF0\",\"iso\":\"HK\",\"name\":\"Hong Kong\"},{\"code\":\"504\",\"emoji\":\"\uD83C\uDDED\uD83C\uDDF3\",\"iso\":\"HN\",\"name\":\"Honduras\"},{\"code\":\"385\",\"emoji\":\"\uD83C\uDDED\uD83C\uDDF7\",\"iso\":\"HR\",\"name\":\"Croatia\"},{\"code\":\"509\",\"emoji\":\"\uD83C\uDDED\uD83C\uDDF9\",\"iso\":\"HT\",\"name\":\"Haiti\"},{\"code\":\"36\",\"emoji\":\"\uD83C\uDDED\uD83C\uDDFA\",\"iso\":\"HU\",\"name\":\"Hungary\"},{\"code\":\"62\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDE9\",\"iso\":\"ID\",\"name\":\"Indonesia\"},{\"code\":\"353\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDEA\",\"iso\":\"IE\",\"name\":\"Ireland\"},{\"code\":\"972\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF1\",\"iso\":\"IL\",\"name\":\"Israel\"},{\"code\":\"50\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF2\",\"iso\":\"IM\",\"name\":\"Isle Of Man\"},{\"code\":\"91\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF3\",\"iso\":\"IN\",\"name\":\"India\"},{\"code\":\"246\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF4\",\"iso\":\"IO\",\"name\":\"British Indian Ocean Territory\"},{\"code\":\"964\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF6\",\"iso\":\"IQ\",\"name\":\"Iraq\"},{\"code\":\"98\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF7\",\"iso\":\"IR\",\"name\":\"Iran\"},{\"code\":\"354\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF8\",\"iso\":\"IS\",\"name\":\"Iceland\"},{\"code\":\"39\",\"emoji\":\"\uD83C\uDDEE\uD83C\uDDF9\",\"iso\":\"IT\",\"name\":\"Italy\"},{\"code\":\"59\",\"emoji\":\"\uD83C\uDDEF\uD83C\uDDEA\",\"iso\":\"JE\",\"name\":\"Jersey\"},{\"code\":\"1876\",\"emoji\":\"\uD83C\uDDEF\uD83C\uDDF2\",\"iso\":\"JM\",\"name\":\"Jamaica\"},{\"code\":\"962\",\"emoji\":\"\uD83C\uDDEF\uD83C\uDDF4\",\"iso\":\"JO\",\"name\":\"Jordan\"},{\"code\":\"81\",\"emoji\":\"\uD83C\uDDEF\uD83C\uDDF5\",\"iso\":\"JP\",\"name\":\"Japan\"},{\"code\":\"254\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDEA\",\"iso\":\"KE\",\"name\":\"Kenya\"},{\"code\":\"996\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDEC\",\"iso\":\"KG\",\"name\":\"Kyrgyzstan\"},{\"code\":\"855\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDED\",\"iso\":\"KH\",\"name\":\"Cambodia\"},{\"code\":\"686\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDEE\",\"iso\":\"KI\",\"name\":\"Kiribati\"},{\"code\":\"269\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDF2\",\"iso\":\"KM\",\"name\":\"Comoros\"},{\"code\":\"1869\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDF3\",\"iso\":\"KN\",\"name\":\"Saint Kitts and Nevis\"},{\"code\":\"850\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDF5\",\"iso\":\"KP\",\"name\":\"North Korea\"},{\"code\":\"82\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDF7\",\"iso\":\"KR\",\"name\":\"South Korea\"},{\"code\":\"965\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDFC\",\"iso\":\"KW\",\"name\":\"Kuwait\"},{\"code\":\"345\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDFE\",\"iso\":\"KY\",\"name\":\"Cayman Islands\"},{\"code\":\"6\",\"emoji\":\"\uD83C\uDDF0\uD83C\uDDFF\",\"iso\":\"KZ\",\"name\":\"Kazakhstan\"},{\"code\":\"856\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDE6\",\"iso\":\"LA\",\"name\":\"Laos\"},{\"code\":\"961\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDE7\",\"iso\":\"LB\",\"name\":\"Lebanon\"},{\"code\":\"1758\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDE8\",\"iso\":\"LC\",\"name\":\"St. Lucia\"},{\"code\":\"423\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDEE\",\"iso\":\"LI\",\"name\":\"Liechtenstein\"},{\"code\":\"94\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDF0\",\"iso\":\"LK\",\"name\":\"Sri Lanka\"},{\"code\":\"231\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDF7\",\"iso\":\"LR\",\"name\":\"Liberia\"},{\"code\":\"266\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDF8\",\"iso\":\"LS\",\"name\":\"Lesotho\"},{\"code\":\"370\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDF9\",\"iso\":\"LT\",\"name\":\"Lithuania\"},{\"code\":\"352\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDFA\",\"iso\":\"LU\",\"name\":\"Luxembourg\"},{\"code\":\"371\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDFB\",\"iso\":\"LV\",\"name\":\"Latvia\"},{\"code\":\"218\",\"emoji\":\"\uD83C\uDDF1\uD83C\uDDFE\",\"iso\":\"LY\",\"name\":\"Libya\"},{\"code\":\"212\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDE6\",\"iso\":\"MA\",\"name\":\"Morocco\"},{\"code\":\"377\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDE8\",\"iso\":\"MC\",\"name\":\"Monaco\"},{\"code\":\"373\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDE9\",\"iso\":\"MD\",\"name\":\"Moldova\"},{\"code\":\"382\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDEA\",\"iso\":\"ME\",\"name\":\"Montenegro\"},{\"code\":\"261\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDEC\",\"iso\":\"MG\",\"name\":\"Madagascar\"},{\"code\":\"692\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDED\",\"iso\":\"MH\",\"name\":\"Marshall Islands\"},{\"code\":\"389\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF0\",\"iso\":\"MK\",\"name\":\"Macedonia\"},{\"code\":\"223\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF1\",\"iso\":\"ML\",\"name\":\"Mali\"},{\"code\":\"95\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF2\",\"iso\":\"MM\",\"name\":\"Myanmar\"},{\"code\":\"976\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF3\",\"iso\":\"MN\",\"name\":\"Mongolia\"},{\"code\":\"853\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF4\",\"iso\":\"MO\",\"name\":\"Macau\"},{\"code\":\"1670\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF5\",\"iso\":\"MP\",\"name\":\"Northern Mariana Islands\"},{\"code\":\"596\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF6\",\"iso\":\"MQ\",\"name\":\"Martinique\"},{\"code\":\"222\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF7\",\"iso\":\"MR\",\"name\":\"Mauritania\"},{\"code\":\"1664\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF8\",\"iso\":\"MS\",\"name\":\"Montserrat\"},{\"code\":\"356\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDF9\",\"iso\":\"MT\",\"name\":\"Malta\"},{\"code\":\"230\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDFA\",\"iso\":\"MU\",\"name\":\"Mauritius\"},{\"code\":\"960\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDFB\",\"iso\":\"MV\",\"name\":\"Maldives\"},{\"code\":\"265\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDFC\",\"iso\":\"MW\",\"name\":\"Malawi\"},{\"code\":\"52\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDFD\",\"iso\":\"MX\",\"name\":\"Mexico\"},{\"code\":\"60\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDFE\",\"iso\":\"MY\",\"name\":\"Malaysia\"},{\"code\":\"258\",\"emoji\":\"\uD83C\uDDF2\uD83C\uDDFF\",\"iso\":\"MZ\",\"name\":\"Mozambique\"},{\"code\":\"264\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDE6\",\"iso\":\"NA\",\"name\":\"Namibia\"},{\"code\":\"687\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDE8\",\"iso\":\"NC\",\"name\":\"New Caledonia\"},{\"code\":\"227\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDEA\",\"iso\":\"NE\",\"name\":\"Niger\"},{\"code\":\"672\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDEB\",\"iso\":\"NF\",\"name\":\"Norfolk Island\"},{\"code\":\"234\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDEC\",\"iso\":\"NG\",\"name\":\"Nigeria\"},{\"code\":\"505\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDEE\",\"iso\":\"NI\",\"name\":\"Nicaragua\"},{\"code\":\"31\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDF1\",\"iso\":\"NL\",\"name\":\"Netherlands\"},{\"code\":\"47\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDF4\",\"iso\":\"NO\",\"name\":\"Norway\"},{\"code\":\"977\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDF5\",\"iso\":\"NP\",\"name\":\"Nepal\"},{\"code\":\"674\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDF7\",\"iso\":\"NR\",\"name\":\"Nauru\"},{\"code\":\"683\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDFA\",\"iso\":\"NU\",\"name\":\"Niue\"},{\"code\":\"64\",\"emoji\":\"\uD83C\uDDF3\uD83C\uDDFF\",\"iso\":\"NZ\",\"name\":\"New Zealand\"},{\"code\":\"968\",\"emoji\":\"\uD83C\uDDF4\uD83C\uDDF2\",\"iso\":\"OM\",\"name\":\"Oman\"},{\"code\":\"507\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDE6\",\"iso\":\"PA\",\"name\":\"Panama\"},{\"code\":\"51\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDEA\",\"iso\":\"PE\",\"name\":\"Peru\"},{\"code\":\"689\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDEB\",\"iso\":\"PF\",\"name\":\"French Polynesia\"},{\"code\":\"675\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDEC\",\"iso\":\"PG\",\"name\":\"Papua New Guinea\"},{\"code\":\"63\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDED\",\"iso\":\"PH\",\"name\":\"Philippines\"},{\"code\":\"92\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDF0\",\"iso\":\"PK\",\"name\":\"Pakistan\"},{\"code\":\"48\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDF1\",\"iso\":\"PL\",\"name\":\"Poland\"},{\"code\":\"508\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDF2\",\"iso\":\"PM\",\"name\":\"Saint Pierre and Miquelon\"},{\"code\":\"1939\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDF7\",\"iso\":\"PR\",\"name\":\"Puerto Rico\"},{\"code\":\"970\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDF8\",\"iso\":\"PS\",\"name\":\"Palestine\"},{\"code\":\"351\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDF9\",\"iso\":\"PT\",\"name\":\"Portugal\"},{\"code\":\"680\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDFC\",\"iso\":\"PW\",\"name\":\"Palau\"},{\"code\":\"595\",\"emoji\":\"\uD83C\uDDF5\uD83C\uDDFE\",\"iso\":\"PY\",\"name\":\"Paraguay\"},{\"code\":\"974\",\"emoji\":\"\uD83C\uDDF6\uD83C\uDDE6\",\"iso\":\"QA\",\"name\":\"Qatar\"},{\"code\":\"270\",\"emoji\":\"\uD83C\uDDF7\uD83C\uDDEA\",\"iso\":\"RE\",\"name\":\"Réunion\"},{\"code\":\"40\",\"emoji\":\"\uD83C\uDDF7\uD83C\uDDF4\",\"iso\":\"RO\",\"name\":\"Romania\"},{\"code\":\"381\",\"emoji\":\"\uD83C\uDDF7\uD83C\uDDF8\",\"iso\":\"RS\",\"name\":\"Serbia\"},{\"code\":\"7\",\"emoji\":\"\uD83C\uDDF7\uD83C\uDDFA\",\"iso\":\"RU\",\"name\":\"Russia\"},{\"code\":\"250\",\"emoji\":\"\uD83C\uDDF7\uD83C\uDDFC\",\"iso\":\"RW\",\"name\":\"Rwanda\"},{\"code\":\"966\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDE6\",\"iso\":\"SA\",\"name\":\"Saudi Arabia\"},{\"code\":\"677\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDE7\",\"iso\":\"SB\",\"name\":\"Solomon Islands\"},{\"code\":\"248\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDE8\",\"iso\":\"SC\",\"name\":\"Seychelles\"},{\"code\":\"249\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDE9\",\"iso\":\"SD\",\"name\":\"Sudan\"},{\"code\":\"46\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDEA\",\"iso\":\"SE\",\"name\":\"Sweden\"},{\"code\":\"65\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDEC\",\"iso\":\"SG\",\"name\":\"Singapore\"},{\"code\":\"290\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDED\",\"iso\":\"SH\",\"name\":\"Saint Helena\"},{\"code\":\"386\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDEE\",\"iso\":\"SI\",\"name\":\"Slovenia\"},{\"code\":\"421\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF0\",\"iso\":\"SK\",\"name\":\"Slovakia\"},{\"code\":\"232\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF1\",\"iso\":\"SL\",\"name\":\"Sierra Leone\"},{\"code\":\"378\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF2\",\"iso\":\"SM\",\"name\":\"San Marino\"},{\"code\":\"221\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF3\",\"iso\":\"SN\",\"name\":\"Senegal\"},{\"code\":\"252\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF4\",\"iso\":\"SO\",\"name\":\"Somalia\"},{\"code\":\"597\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF7\",\"iso\":\"SR\",\"name\":\"Suriname\"},{\"code\":\"210\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF8\",\"iso\":\"SS\",\"name\":\"South Sudan\"},{\"code\":\"239\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDF9\",\"iso\":\"ST\",\"name\":\"Sao Tome and Principe\"},{\"code\":\"503\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDFB\",\"iso\":\"SV\",\"name\":\"El Salvador\"},{\"code\":\"963\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDFE\",\"iso\":\"SY\",\"name\":\"Syria\"},{\"code\":\"268\",\"emoji\":\"\uD83C\uDDF8\uD83C\uDDFF\",\"iso\":\"SZ\",\"name\":\"Swaziland\"},{\"code\":\"1649\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDE8\",\"iso\":\"TC\",\"name\":\"Turks and Caicos Islands\"},{\"code\":\"235\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDE9\",\"iso\":\"TD\",\"name\":\"Chad\"},{\"code\":\"228\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDEC\",\"iso\":\"TG\",\"name\":\"Togo\"},{\"code\":\"66\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDED\",\"iso\":\"TH\",\"name\":\"Thailand\"},{\"code\":\"992\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDEF\",\"iso\":\"TJ\",\"name\":\"Tajikistan\"},{\"code\":\"690\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF0\",\"iso\":\"TK\",\"name\":\"Tokelau\"},{\"code\":\"670\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF1\",\"iso\":\"TL\",\"name\":\"Timor-Leste\"},{\"code\":\"993\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF2\",\"iso\":\"TM\",\"name\":\"Turkmenistan\"},{\"code\":\"216\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF3\",\"iso\":\"TN\",\"name\":\"Tunisia\"},{\"code\":\"676\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF4\",\"iso\":\"TO\",\"name\":\"Tonga\"},{\"code\":\"90\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF7\",\"iso\":\"TR\",\"name\":\"Turkey\"},{\"code\":\"1868\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDF9\",\"iso\":\"TT\",\"name\":\"Trinidad and Tobago\"},{\"code\":\"688\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDFB\",\"iso\":\"TV\",\"name\":\"Tuvalu\"},{\"code\":\"255\",\"emoji\":\"\uD83C\uDDF9\uD83C\uDDFF\",\"iso\":\"TZ\",\"name\":\"Tanzania\"},{\"code\":\"380\",\"emoji\":\"\uD83C\uDDFA\uD83C\uDDE6\",\"iso\":\"UA\",\"name\":\"Ukraine\"},{\"code\":\"256\",\"emoji\":\"\uD83C\uDDFA\uD83C\uDDEC\",\"iso\":\"UG\",\"name\":\"Uganda\"},{\"code\":\"1\",\"emoji\":\"\uD83C\uDDFA\uD83C\uDDF8\",\"iso\":\"US\",\"name\":\"United States\"},{\"code\":\"598\",\"emoji\":\"\uD83C\uDDFA\uD83C\uDDFE\",\"iso\":\"UY\",\"name\":\"Uruguay\"},{\"code\":\"998\",\"emoji\":\"\uD83C\uDDFA\uD83C\uDDFF\",\"iso\":\"UZ\",\"name\":\"Uzbekistan\"},{\"code\":\"1784\",\"emoji\":\"\uD83C\uDDFB\uD83C\uDDE8\",\"iso\":\"VC\",\"name\":\"Saint Vincent and the Grenadines\"},{\"code\":\"58\",\"emoji\":\"\uD83C\uDDFB\uD83C\uDDEA\",\"iso\":\"VE\",\"name\":\"Venezuela\"},{\"code\":\"1284\",\"emoji\":\"\uD83C\uDDFB\uD83C\uDDEC\",\"iso\":\"VG\",\"name\":\"British Virgin Islands\"},{\"code\":\"1340\",\"emoji\":\"\uD83C\uDDFB\uD83C\uDDEE\",\"iso\":\"VI\",\"name\":\"US Virgin Islands\"},{\"code\":\"84\",\"emoji\":\"\uD83C\uDDFB\uD83C\uDDF3\",\"iso\":\"VN\",\"name\":\"Vietnam\"},{\"code\":\"678\",\"emoji\":\"\uD83C\uDDFB\uD83C\uDDFA\",\"iso\":\"VU\",\"name\":\"Vanuatu\"},{\"code\":\"681\",\"emoji\":\"\uD83C\uDDFC\uD83C\uDDEB\",\"iso\":\"WF\",\"name\":\"Wallis and Futuna\"},{\"code\":\"685\",\"emoji\":\"\uD83C\uDDFC\uD83C\uDDF8\",\"iso\":\"WS\",\"name\":\"Samoa\"},{\"code\":\"967\",\"emoji\":\"\uD83C\uDDFE\uD83C\uDDEA\",\"iso\":\"YE\",\"name\":\"Yemen\"},{\"code\":\"262\",\"emoji\":\"\uD83C\uDDFE\uD83C\uDDF9\",\"iso\":\"YT\",\"name\":\"Mayotte\"},{\"code\":\"27\",\"emoji\":\"\uD83C\uDDFF\uD83C\uDDE6\",\"iso\":\"ZA\",\"name\":\"South Africa\"},{\"code\":\"260\",\"emoji\":\"\uD83C\uDDFF\uD83C\uDDF2\",\"iso\":\"ZM\",\"name\":\"Zambia\"},{\"code\":\"263\",\"emoji\":\"\uD83C\uDDFF\uD83C\uDDFC\",\"iso\":\"ZW\",\"name\":\"Zimbabwe\"}]}", CountryModel.class).getRegions();
+
+
+ public static boolean isMatching = false;
+ public static boolean isVideoing = false;
+
+ private HttpProxyCacheServer proxy;
+
+ public static HttpProxyCacheServer getProxy(Context context) {
+ MyApplication app = (MyApplication) context.getApplicationContext();
+ return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
+ }
+
+ private HttpProxyCacheServer newProxy() {
+ return new HttpProxyCacheServer.Builder(this).maxCacheSize(10L * 1024 * 1024 * 1024).fileNameGenerator(new MyFileNameGenerator()).build();
+ }
+
+ public static AppComponent appComponent1;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ appComponent = HttpManager.getAppComponent(baseUrl, new HeaderInterceptor(getApplicationContext()));
+ appComponent1 = HttpManager.getAppComponent("https://xuqinmin.com", new HeaderInterceptorList(getApplicationContext()));
+
+ CrashHandler.getInstance().init(this);
+ XuqmDbHelper.get(this);
+
+ this.billingClient = BillingClient.newBuilder(this).setListener((billingResult, list) -> {
+
+ }).enablePendingPurchases().build();
+
+ new Timer().schedule(new MyTimerTask(), new Date(System.currentTimeMillis() + 1000), 5000);
+ EventBus.getDefault().register(this);
+ }
+
+ @Override
+ public boolean showLog() {
+ return super.showLog();
+ }
+
+ public static WebSocketHandler webSocketHandler;
+
+ public static void connect() {
+ webSocketHandler = WebSocketHandler.getInstance(modelInit.getImserver() + "?imId=" + modelHideIn.getImId() + "&token=" + modelHideIn.getToken());
+ webSocketHandler.setSocketIOCallBack(new WebSocketCallBack() {
+ @Override
+ public void onClose() {
+
+ }
+
+ @Override
+ public void onConnectError(Throwable t) {
+
+ }
+
+ @Override
+ public void onMessage(String message) {
+ String decrypt = AESCBCUtil.decrypt(message, modelInit.getImKey(), modelInit.getImSecret());
+ try {
+ String type = new JSONObject(decrypt).optString("command");
+ if ("MSG".equals(type)) {
+ MessagModel model = GsonImplHelp.get().toObject(decrypt, MessagModel.class);
+ XuqmDbHelper.get().messageDao().insertAll(new MessageEntity("MSG", model.getData().getFromUser().getUserId(), model.getData().getToUser().getUserId(), GsonImplHelp.get().toJson(model)));
+ EventBus.getDefault().post(model);
+
+ if (model.getData().isRead().equals("UNREAD")
+ && model.getData().getDirection().equals("RECEIVE")) {
+ String key = MSG_COUNT + "_" + model.getData().getFromUser().getUserId();
+ int intForPreferences = getIntForPreferences(getInstance().getBaseContext(), key, 0);
+ intForPreferences++;
+ putInt(getInstance().getBaseContext(), key, intForPreferences);
+ }
+ } else if ("RECEIPT".equals(type)) {
+ EventBus.getDefault().post(GsonImplHelp.get().toObject(decrypt, MsgReceipt.class));
+ } else if ("CONVERSATIONS".equals(type)) {
+ EventBus.getDefault().post(GsonImplHelp.get().toObject(decrypt, ConversationsModel.class));
+ } else if ("CALL".equals(type)) {
+ LogHelper.e(decrypt);
+ CallModel callModel = GsonImplHelp.get().toObject(new JSONObject(decrypt).optString("data"), CallModel.class);
+ if ("11006".equals(callModel.getType()) || "11004".equals(callModel.getType()) || "11003".equals(callModel.getType()) || "10002".equals(callModel.getType()) || "10003".equals(callModel.getType()) || "10006".equals(callModel.getType()) || "10007".equals(callModel.getType())) {
+ XuqmDbHelper.get().messageDao().insertAll(new MessageEntity(callModel.getType(), callModel.getUserId(), modelHideIn.getUserId(), GsonImplHelp.get().toJson(callModel)));
+ }
+ if ("11001".equals(callModel.getType()) || "11002".equals(callModel.getType()) || "10002".equals(callModel.getType()) || "10006".equals(callModel.getType())) {
+ EventBus.getDefault().post(GsonImplHelp.get().toObject(new JSONObject(decrypt).optString("data"), CallModel.class));
+ } else if ("10001".equals(callModel.getType())) {
+ if (!isVideoing) {
+ LiveHelper.Companion.start(new JSONObject(decrypt).optString("data"),1);
+// Intent intent = new Intent(AppManager.getInstance().getActivity(), LiveActivity.class);
+// intent.putExtra("model", new JSONObject(decrypt).optString("data"));
+// // 收到邀请
+// intent.putExtra("type", 1);
+// AppManager.getInstance().getActivity().startActivity(intent);
+ }
+ }
+ } else if ("HEART".equals(type)) {
+// EventBus.getDefault().post(GsonImplHelp.get().toObject(decrypt, ConversationsModel.class));
+// LogHelper.e(decrypt);
+ } else if ("BALANCE_CHANGE".equals(type)) {
+ Balance model = GsonImplHelp.get().toObject(new JSONObject(decrypt).optString("data"), Balance.class);
+ LogHelper.e(model.getGoldCoins());
+ LogHelper.e(ToolsHelper.toInt(model.getGoldCoins()));
+ MyApplication.modelHideIn.setCoins(ToolsHelper.toInt(model.getGoldCoins()));
+ LogHelper.e(MyApplication.modelHideIn.getCoins());
+ EventBus.getDefault().post(model);
+ } else {
+ LogHelper.e(decrypt);
+ }
+ } catch (JSONException e) {
+
+ }
+ }
+
+ @Override
+ public void onOpen() {
+// webSocketHandler.send("{\"command\":\"MSG\",\"data\":{\"messageId\":\"dfghjkltgbhn\",\"body\":{\"messageType\":\"TEXT\",\"text\":\"Hello\"},\"times\":" + TimeHelper.getTimeMillis() + ",\"chatType\":\"CHAT\",\"fromUser\":{\"imId\":\"nexts100160813\",\"avatar\":\"https:\\/\\/image.kiteliberatorly.com\\/api\\/pic\\/2024-02-25\\/6de8cee1-4e68-4810-9a82-389b9ff97885.jpg\",\"birth\":\"1992-12-01\",\"userId\":\"100160813\",\"gender\":1},\"toUser\":{\"imId\":\"nexts100160801\",\"nickname\":\"Miami\",\"price\":100,\"avatar\":\"https:\\/\\/image.kiteliberatorly.com\\/api\\/pic\\/2024-01-09\\/5e84e3e4-7f37-4aef-aa24-062444d16f1a.jpg\",\"birth\":\"1992-12-01\",\"userId\":\"100160801\",\"gender\":1}}}");
+
+ }
+ });
+ webSocketHandler.connect();
+
+ }
+
+
+ private Long time = TimeHelper.getTimeMillis();
+
+ class MyTimerTask extends TimerTask {
+
+ @Override
+ public void run() {
+ Long cTime = TimeHelper.getTimeMillis();
+ if (null != webSocketHandler) {
+ if (cTime - time > 3000) {
+ if (webSocketHandler.getStatus() != ConnectStatus.Open) {
+ webSocketHandler.reConnect();
+ }
+ time = cTime;
+ }
+ String text = "{\"command\":\"HEART\",\"data\":\"ping\"}";
+ String encrypt = AESCBCUtil.encrypt(text, modelInit.getImKey(), modelInit.getImSecret());
+ webSocketHandler.send(encrypt);
+ }
+
+ }
+ }
+
+ private static BillingClient billingClient;
+ public static Boolean isInit = false;
+
+ public static void startConnection() {
+
+ billingClient.startConnection(new BillingClientStateListener() {
+ @Override
+ public void onBillingServiceDisconnected() {
+ LogHelper.e("连接失败");
+ }
+
+ @Override
+ public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
+ if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
+ // The BillingClient is ready. You can query purchases here.
+ LogHelper.e("连接成功");
+ isInit = true;
+ }
+ }
+ });
+ }
+
+ public static void startPay(String productId) {
+
+ List l = new ArrayList<>();
+ l.add(QueryProductDetailsParams.Product.newBuilder().setProductId(productId).setProductType(BillingClient.ProductType.INAPP).build());
+
+ QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().setProductList(l).build();
+
+ billingClient.queryProductDetailsAsync(queryProductDetailsParams, (ProductDetailsResponseListener) (billingResult, list) -> {
+ if (list.size() == 0) {
+ MyApplication.getInstance().runOnUiThread(() -> ToolsHelper.showMessage("Error in obtaining order information."));
+ } else {
+ List productDetailsParamsList = new ArrayList<>();
+ productDetailsParamsList.add(BillingFlowParams.ProductDetailsParams.newBuilder()
+ // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
+ .setProductDetails(list.get(0))
+ // For One-time product, "setOfferToken" method shouldn't be called.
+ // For subscriptions, to get an offer token, call ProductDetails.subscriptionOfferDetails()
+ // for a list of offers that are available to the user
+// .setOfferToken(selectedOfferToken)
+ .build());
+ BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder().setProductDetailsParamsList(productDetailsParamsList).build();
+ billingClient.launchBillingFlow(AppManager.getInstance().getActivity(), billingFlowParams);
+ }
+ });
+
+
+ }
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void payM(PlayModel pay){
+ StoreHelper.Companion.showPay();
+ }
+
+}
diff --git a/app/src/main/java/com/xuqinmin/android/app/MyFileNameGenerator.java b/app/src/main/java/com/xuqinmin/android/app/MyFileNameGenerator.java
new file mode 100644
index 0000000..525ec40
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/MyFileNameGenerator.java
@@ -0,0 +1,14 @@
+package com.xuqinmin.android.app;
+
+import android.net.Uri;
+
+import com.danikula.videocache.file.FileNameGenerator;
+
+public class MyFileNameGenerator implements FileNameGenerator {
+
+ public String generate(String url) {
+ Uri uri = Uri.parse(url);
+ String videoId = uri.getQueryParameter("videoId");
+ return videoId + ".mp4";
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/CountryHelper.kt b/app/src/main/java/com/xuqinmin/android/app/common/CountryHelper.kt
new file mode 100644
index 0000000..d715780
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/CountryHelper.kt
@@ -0,0 +1,18 @@
+package com.xuqinmin.android.app.common
+
+import com.xuqinmin.android.app.MyApplication
+
+class CountryHelper {
+ companion object {
+ fun getCountryName(code: String?): String {
+ var name = "United States"
+ if (code == null) return name
+ for (region in MyApplication.country) {
+ if (region.code == code) {
+ name = "${region.emoji} ${region.name}"
+ }
+ }
+ return name
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/CrashHandler.java b/app/src/main/java/com/xuqinmin/android/app/common/CrashHandler.java
new file mode 100644
index 0000000..dcf6f70
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/CrashHandler.java
@@ -0,0 +1,150 @@
+package com.xuqinmin.android.app.common;
+
+import android.content.Context;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class CrashHandler implements Thread.UncaughtExceptionHandler {
+
+
+ private static String TAG = "CrashHandler";
+ // 系统默认的UncaughtException处理类
+ private Thread.UncaughtExceptionHandler mDefaultHandler;
+ // 用于格式化日期,作为日志文件名的一部分
+ private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ private static CrashHandler mCrashHandler;
+ private Context mContext;
+
+
+ private CrashHandler() {
+
+ }
+
+ public static CrashHandler getInstance() {
+ if (mCrashHandler == null) {
+ synchronized (CrashHandler.class) {
+ mCrashHandler = new CrashHandler();
+ }
+ }
+ return mCrashHandler;
+ }
+
+ public void init(Context context) {
+ mContext = context;
+ mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
+ Thread.setDefaultUncaughtExceptionHandler(this);
+ }
+
+ @Override
+ public void uncaughtException(Thread thread, Throwable throwable) {
+ if (!handleException(throwable) && mDefaultHandler != null) {
+ // 如果用户没有处理则让系统默认的异常处理器来处理
+ mDefaultHandler.uncaughtException(thread, throwable);
+ } else {
+ SystemClock.sleep(2000);
+ // 退出程序
+ android.os.Process.killProcess(android.os.Process.myPid());
+ System.exit(1);
+ }
+ }
+
+
+ private boolean handleException(Throwable ex) {
+ if (ex == null) {
+ return false;
+ }
+ try {
+ saveCrashInfoFile(ex);
+ SystemClock.sleep(2000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return true;
+ }
+
+ private String saveCrashInfoFile(Throwable ex) {
+ StringBuffer sb = new StringBuffer();
+
+ if (hasSdcard())
+ try {
+ SimpleDateFormat sDateFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss", Locale.CHINA);
+ String date = sDateFormat.format(new Date());
+ sb.append("\r\n" + date + "\n");
+
+ Writer writer = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(writer);
+ ex.printStackTrace(printWriter);
+ Throwable cause = ex.getCause();
+ while (cause != null) {
+ cause.printStackTrace(printWriter);
+ cause = cause.getCause();
+ }
+ printWriter.flush();
+ printWriter.close();
+ String result = writer.toString();
+ sb.append(result);
+
+ String fileName = writeFile(sb.toString());
+ return fileName;
+ } catch (Exception e) {
+ Log.e(TAG, "an error occured while writing file...", e);
+ sb.append("an error occured while writing file...\r\n");
+ writeFile(sb.toString());
+ }
+ return null;
+ }
+
+ private String writeFile(String text) {
+ Log.e("writeFile", text);
+ String time = formatter.format(new Date());
+ String fileName = "crash-demo-" + time + ".log";
+
+ String path = getGlobalpath();
+
+ File dir = new File(path);
+ if (!dir.exists()) {
+ dir.mkdir();
+ }
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(path + fileName, true);
+ fos.write(text.getBytes());
+ fos.flush();
+ fos.close();
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return fileName;
+ }
+
+
+ public String getGlobalpath() {
+ return Environment.getExternalStorageDirectory().getAbsolutePath()
+ + File.separator + "crash" + File.separator;
+ }
+
+
+ public boolean hasSdcard(){
+ return Environment.getExternalStorageState()
+ .equals(Environment.MEDIA_MOUNTED);
+ }
+}
+
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/GenderHelper.kt b/app/src/main/java/com/xuqinmin/android/app/common/GenderHelper.kt
new file mode 100644
index 0000000..b4f17fd
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/GenderHelper.kt
@@ -0,0 +1,27 @@
+package com.xuqinmin.android.app.common
+
+import com.xuqinmin.android.app.R
+import com.xuqm.base.model.KeyValueData
+
+class GenderHelper {
+ companion object {
+ val list_gender = listOf>(
+ KeyValueData(-1, "Unknown"), KeyValueData(0, "Male"), KeyValueData(1, "Female")
+ )
+
+ fun getString(code: Int): String {
+ for (keyValueData in list_gender) {
+ if (keyValueData.key == code) return keyValueData.value
+ }
+ return "Unknown"
+ }
+
+ fun getImage(code: Int): Int {
+
+ return when (code) {
+ 1 -> R.mipmap.female_selected
+ else -> R.mipmap.male_selected
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/LiveHelper.kt b/app/src/main/java/com/xuqinmin/android/app/common/LiveHelper.kt
new file mode 100644
index 0000000..8009b47
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/LiveHelper.kt
@@ -0,0 +1,42 @@
+package com.xuqinmin.android.app.common
+
+import android.content.Intent
+import com.xuqinmin.android.app.MyApplication
+import com.xuqinmin.android.app.model.msg.CallModel
+import com.xuqinmin.android.app.ui.LiveActivity
+import com.xuqm.base.common.AppManager
+import com.xuqm.base.common.GsonImplHelp
+import com.xuqm.sdhbwfu.core.extensions.loge
+
+class LiveHelper {
+
+ companion object {
+ /**
+ * 1=收到邀请、2=发起邀请、0=直接通话
+ */
+ fun start(model: CallModel, type: Int) {
+
+ model.price.loge()
+ MyApplication.modelHideIn.coins.loge()
+ if (type == 2 && model.price > 0 && MyApplication.modelHideIn.coins < model.price) {
+
+ StoreHelper.showPay()
+
+ return
+ }
+
+ AppManager.getInstance().activity.startActivity(Intent(
+ AppManager.getInstance().activity, LiveActivity::class.java
+ ).apply {
+ putExtra("model", GsonImplHelp.get().toJson(model))
+ putExtra("type", type)
+ })
+ }
+
+ fun start(model: String, type: Int) {
+
+
+ this.start(GsonImplHelp.get().toObject(model, CallModel::class.java), type)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/RabbitMQClient.java b/app/src/main/java/com/xuqinmin/android/app/common/RabbitMQClient.java
new file mode 100644
index 0000000..216ef7e
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/RabbitMQClient.java
@@ -0,0 +1,236 @@
+package com.xuqinmin.android.app.common;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.rabbitmq.client.AMQP;
+import com.rabbitmq.client.AlreadyClosedException;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import com.rabbitmq.client.DefaultConsumer;
+import com.rabbitmq.client.Envelope;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
+
+public class RabbitMQClient {
+ private final String TAG = "RabbitMQ";
+ private final String FLAG_SEND = "send";
+ private final String FLAG_RECEIVE = "receive";
+
+ private final ConnectionFactory factory;
+ private Connection connection;
+ private Map channelMap = new HashMap<>();
+
+ public static final String EXCHANGETYPE_FANOUT = "fanout"; //不用匹配路由,发送给所有绑定转换器的队列
+ public static final String EXCHANGETYPE_DIRECT = "direct"; //匹配路由一致,才发送给绑定转换器队列
+ public static final String EXCHANGETYPE_TOPIC = "topic"; // 通配符* 和 # 匹配路由一致,才发送给绑定转换器队列
+
+
+ public RabbitMQClient(String hostIp, int port, String username, String password) {
+ factory = new ConnectionFactory();
+ factory.setUsername(username);
+ factory.setPassword(password);
+ factory.setHost(hostIp);
+ factory.setPort(port);
+ factory.setVirtualHost("/");//类似数据库的意思
+ factory.setConnectionTimeout(15 * 1000); //连接时间设置为10秒
+ factory.setAutomaticRecoveryEnabled(true); //恢复连接,通道
+ factory.setTopologyRecoveryEnabled(true); //恢复通道中 转换器,队列,绑定关系等
+ factory.setNetworkRecoveryInterval(5 * 1000); //恢复连接间隔,默认5秒
+ }
+
+
+ /**
+ * @param message 需要发送的消息
+ * @param queueName 管道名称
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void sendQueueMessage(String message, String queueName) throws IOException, TimeoutException, AlreadyClosedException {
+ if (connection == null || !connection.isOpen()) {
+ connection = factory.newConnection();
+ }
+ if (!channelMap.containsKey(FLAG_SEND + queueName)) {
+ Channel channel = connection.createChannel();
+ channel.queueDeclare(queueName, false, false, false, null);
+ channelMap.put(FLAG_SEND + queueName, channel);
+ }
+ //空名字的交换机,需要设置routingKey,此时会将routingKey 作为 队列名使用
+ channelMap.get(FLAG_SEND + queueName).basicPublish("", queueName, null, message.getBytes());
+ }
+
+
+ /**
+ * @param exchangeName 交换机名称
+ * @param message 需要发送的消息
+ * @param queueName 队列名称
+ * @param routingKey 路由规则
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion 发送 exchangeType direct 类型的信息
+ **/
+ public void sendDirectTypeMessage(String exchangeName, String message, String queueName, String routingKey) throws IOException, TimeoutException, AlreadyClosedException {
+ if (connection == null || !connection.isOpen()) {
+ connection = factory.newConnection();
+ }
+ if (!channelMap.containsKey(FLAG_SEND + exchangeName + EXCHANGETYPE_DIRECT + queueName)) {
+ Channel channel = connection.createChannel();
+ channel.queueDeclare(queueName, false, false, false, null);
+ channel.exchangeDeclare(exchangeName, EXCHANGETYPE_DIRECT);
+ channelMap.put(FLAG_SEND + exchangeName + EXCHANGETYPE_DIRECT + queueName, channel);
+ }
+ channelMap.get(FLAG_SEND + exchangeName + EXCHANGETYPE_DIRECT + queueName).basicPublish(exchangeName, routingKey, null, message.getBytes());
+ }
+
+ /**
+ * @param exchangeName 交换机名称
+ * @param queueName 队列名称
+ * @param message 发送的消息
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion 发送 exchangeType fanout 类型的信息
+ **/
+ public void sendFanoutTypeMessage(String exchangeName, String queueName, String message) throws IOException, TimeoutException, AlreadyClosedException {
+ if (connection == null || !connection.isOpen()) {
+ connection = factory.newConnection();
+ }
+ if (!channelMap.containsKey(FLAG_SEND + exchangeName + EXCHANGETYPE_FANOUT + queueName)) {
+ Channel channel = connection.createChannel();
+ channel.queueDeclare(queueName, false, false, false, null);
+ channel.exchangeDeclare(exchangeName, EXCHANGETYPE_FANOUT);
+ channelMap.put(FLAG_SEND + exchangeName + EXCHANGETYPE_FANOUT + queueName, channel);
+ }
+ channelMap.get(FLAG_SEND + exchangeName + EXCHANGETYPE_FANOUT + queueName).basicPublish(exchangeName, "", null, message.getBytes());
+ }
+
+ /**
+ * @param exchangeName 交换机名称
+ * @param exchangeType 模式
+ * @param queueName 队列名称
+ * @param message 需要发送的消息
+ * @param routingKey 路由规则
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void sendExchangeNameQueueMessage(String exchangeName, String exchangeType, String message, String queueName, String routingKey) throws IOException, TimeoutException, AlreadyClosedException {
+ if (connection == null || !connection.isOpen()) {
+ connection = factory.newConnection();
+ }
+ if (!channelMap.containsKey(FLAG_SEND + exchangeName + exchangeType + queueName)) {
+ Channel channel = connection.createChannel();
+ channel.queueDeclare(queueName, false, false, false, null);
+ channel.exchangeDeclare(exchangeName, exchangeType);
+ channelMap.put(FLAG_SEND + exchangeName + exchangeType + queueName, channel);
+ }
+ if (exchangeType.equals(EXCHANGETYPE_FANOUT)) {
+ channelMap.get(FLAG_SEND + exchangeName + exchangeType + queueName).basicPublish(exchangeName, "", null, message.getBytes());
+ } else if (exchangeType.equals(EXCHANGETYPE_DIRECT)) {
+ channelMap.get(FLAG_SEND + exchangeName + exchangeType + queueName).basicPublish(exchangeName, routingKey, null, message.getBytes());
+ } else if (exchangeType.equals(EXCHANGETYPE_TOPIC)) {
+ channelMap.get(FLAG_SEND + exchangeName + exchangeType + queueName).basicPublish(exchangeName, routingKey, null, message.getBytes());
+ }
+ }
+
+
+ /**
+ * @param queueName 队列名称
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void receiveQueueMessage(final String queueName, final ResponseListener listener)
+ throws IOException, TimeoutException, AlreadyClosedException {
+ receiveQueueRoutingKeyMessage(queueName, "", "", "", listener);
+ }
+
+
+ /**
+ * @param queueName 队列名称
+ * @param routingKey 路由规则
+ * @param exchangeName 交换机名称
+ * @param exchangeType 交换机类型
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void receiveQueueRoutingKeyMessage(String queueName, final String routingKey, String exchangeName, String exchangeType, final ResponseListener listener)
+ throws IOException, TimeoutException, AlreadyClosedException {
+
+ if (exchangeType.equals(EXCHANGETYPE_DIRECT) || exchangeType.equals(EXCHANGETYPE_TOPIC)) {
+ if (TextUtils.isEmpty(routingKey)) {
+ throw new NullPointerException("路由规则不能为空");
+ }
+ }
+
+ if (!TextUtils.isEmpty(routingKey)) {
+ if (TextUtils.isEmpty(exchangeName)) {
+ throw new NullPointerException("交换机名称不能为空");
+ }
+ }
+
+ if (!channelMap.containsKey(FLAG_RECEIVE + routingKey + queueName)) {
+ if (connection == null || !connection.isOpen()) {
+ connection = factory.newConnection();
+ }
+
+ final Channel channel = connection.createChannel();
+ channel.queueDeclare(queueName, true, false, false, null);
+ //绑定转换器,使用路由筛选消息
+ if (!TextUtils.isEmpty(routingKey)) {
+ channel.exchangeDeclare(exchangeName, exchangeType);
+ channel.queueBind(queueName, exchangeName, routingKey); //设置绑定
+ }
+ //监听队列
+ channel.basicConsume(queueName, false, new DefaultConsumer(channel) {
+ @Override
+ public void handleDelivery(String consumerTag, Envelope envelope,
+ AMQP.BasicProperties properties, byte[] body)
+ throws IOException {
+ String message = new String(body, "UTF-8");
+ if (listener != null) {
+ listener.receive(message);
+ }
+ channel.basicAck(envelope.getDeliveryTag(), false); //消息应答
+ }
+ });
+ channelMap.put(FLAG_RECEIVE + routingKey + queueName, channel);
+ Log.e(TAG,"已经连接上了,队列名称:" + queueName);
+ }
+ }
+
+
+ /**
+ * 关闭所有资源
+ */
+ public void close() {
+ for (Channel next : channelMap.values()) {
+ if (next != null && next.isOpen()) {
+ try {
+ next.close();
+ } catch (IOException | TimeoutException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ channelMap.clear();
+ if (connection != null && connection.isOpen()) {
+ try {
+ connection.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+ public interface ResponseListener {
+ void receive(String message);
+ }
+}
+
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/RabbitMQUtil.java b/app/src/main/java/com/xuqinmin/android/app/common/RabbitMQUtil.java
new file mode 100644
index 0000000..01ad19a
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/RabbitMQUtil.java
@@ -0,0 +1,227 @@
+package com.xuqinmin.android.app.common;
+
+import android.os.SystemClock;
+import android.text.TextUtils;
+
+import com.rabbitmq.client.AlreadyClosedException;
+
+import java.io.IOException;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeoutException;
+
+public class RabbitMQUtil {
+ private boolean isRunning = true;
+ private RabbitMQClient rabbitMQ;
+ private ExecutorService executor;
+
+
+ public RabbitMQUtil(String hostIp, int port, String username, String password) {
+ rabbitMQ = new RabbitMQClient(hostIp, port, username, password);
+ executor = Executors.newSingleThreadExecutor(); //根据项目需要设置常用线程个数
+ }
+
+ /**
+ * @param message 发送的消息
+ * @param queueName 队列名称
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void sendMessage(final String message, final String queueName, final SendMessageListener sendMessageListener,final ErrorMessageListener errorMessageListener) {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ rabbitMQ.sendQueueMessage(message, queueName);
+ if (sendMessageListener != null) sendMessageListener.sendMessage(true);
+ } catch (IOException | TimeoutException | AlreadyClosedException e) {
+ e.printStackTrace();
+ if (errorMessageListener!=null){
+ errorMessageListener.errorMessage(e);
+ }
+ if (sendMessageListener != null) sendMessageListener.sendMessage(false);
+ }
+ }
+ });
+ }
+
+ /**
+ * @param message 发送的消息
+ * @param exchangeName 交换机名称
+ * @param queueName 队列名称
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void sendMessage(final String message, final String exchangeName, final String exchangeType, final String queueName, final String routingKey, final SendMessageListener sendMessageListener,final ErrorMessageListener errorMessageListener) {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ rabbitMQ.sendExchangeNameQueueMessage(exchangeName, exchangeType, message, queueName, routingKey);
+ if (sendMessageListener != null) sendMessageListener.sendMessage(true);
+ } catch (IOException | TimeoutException | AlreadyClosedException e) {
+ e.printStackTrace();
+ if (errorMessageListener!=null){
+ errorMessageListener.errorMessage(e);
+ }
+ if (sendMessageListener != null) sendMessageListener.sendMessage(false);
+ }
+ }
+ });
+ }
+
+ /**
+ * @param exchangeName 交换机名称
+ * @param queueName 队列名称
+ * @param message 需要发送的消息
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void sendFanoutTypeMessage(final String exchangeName, final String message, final String queueName, final SendMessageListener sendMessageListener,final ErrorMessageListener errorMessageListener) {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ rabbitMQ.sendFanoutTypeMessage(exchangeName, queueName, message);
+ if (sendMessageListener != null) sendMessageListener.sendMessage(true);
+ } catch (IOException | TimeoutException | AlreadyClosedException e) {
+ e.printStackTrace();
+ if (errorMessageListener!=null){
+ errorMessageListener.errorMessage(e);
+ }
+ if (sendMessageListener != null) sendMessageListener.sendMessage(false);
+ }
+ }
+ });
+ }
+
+ /**
+ * @param exchangeName 交换机名称
+ * @param message 需要发送的消息
+ * @param queueName 队列名称
+ * @param routingKey 路由规则
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion 发送 exchangeType direct 类型的信息
+ **/
+ public void sendDirectTypeMessage(final String exchangeName, final String queueName, final String message, final String routingKey, final SendMessageListener sendMessageListener,final ErrorMessageListener errorMessageListener) {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ rabbitMQ.sendDirectTypeMessage(exchangeName, queueName, message, routingKey);
+ if (sendMessageListener != null) sendMessageListener.sendMessage(true);
+ } catch (IOException | TimeoutException | AlreadyClosedException e) {
+ e.printStackTrace();
+ if (errorMessageListener!=null){
+ errorMessageListener.errorMessage(e);
+ }
+ if (sendMessageListener != null) sendMessageListener.sendMessage(false);
+ }
+ }
+ });
+ }
+
+ /**
+ * @param queueName 队列名称
+ * @date 创建时间:2020/9/8 0008
+ * @auther gaoxiaoxiong
+ * @Descriptiion
+ **/
+ public void receiveQueueMessage(String queueName, final ReceiveMessageListener listener,final ErrorMessageListener errorMessageListener) {
+ String newQueueName = null;
+ if (TextUtils.isEmpty(queueName)){
+ newQueueName = createDefaultQueueName(queueName);
+ }else {
+ newQueueName = queueName;
+ }
+ final String finalNewQueueName = newQueueName;
+ executor.execute(() -> {
+ while (isRunning) {
+ try {
+ rabbitMQ.receiveQueueMessage(finalNewQueueName, message -> {
+ if (listener != null) listener.receiveMessage(message);
+ });
+ } catch (IOException | TimeoutException | AlreadyClosedException e) {
+ if (errorMessageListener!=null){
+ errorMessageListener.errorMessage(e);
+ }
+ e.printStackTrace();
+ SystemClock.sleep(5000);
+ }
+ }
+ });
+ }
+
+ public void receiveQueueRoutingKeyMessage(String queueName, final String routingKey, final String exchangeName, final String exchangeType, final ReceiveMessageListener listener,final ErrorMessageListener errorMessageListener) {
+ String newQueueName = null;
+ if (TextUtils.isEmpty(queueName)){
+ newQueueName = createDefaultQueueName(queueName);
+ }else {
+ newQueueName = queueName;
+ }
+ final String finalNewQueueName = newQueueName;
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ while (isRunning) {
+ try {
+ rabbitMQ.receiveQueueRoutingKeyMessage(finalNewQueueName, routingKey, exchangeName, exchangeType, new RabbitMQClient.ResponseListener() {
+ @Override
+ public void receive(String message) {
+ if (listener != null) listener.receiveMessage(message);
+ }
+
+ });
+ } catch (IOException | TimeoutException | AlreadyClosedException e) {
+ if (errorMessageListener!=null){
+ errorMessageListener.errorMessage(e);
+ }
+ e.printStackTrace();
+ SystemClock.sleep(5000); //等待五秒
+ }
+ }
+ }
+ });
+ }
+
+ public String createDefaultQueueName(String routingKey) {
+ if (TextUtils.isEmpty(routingKey)){
+ routingKey = "";
+ }
+ return routingKey + "@" + UUID.randomUUID();
+ }
+
+ /**
+ * 建议:
+ * 在application中关闭或者在结束工作时关闭
+ */
+ public void close() {
+ isRunning = false;
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ rabbitMQ.close();
+ executor.shutdownNow();
+ }
+ });
+ }
+
+
+ public interface ReceiveMessageListener {
+ void receiveMessage(String message);
+ }
+
+ public interface SendMessageListener {
+ void sendMessage(boolean isSuccess);
+ }
+
+ public interface ErrorMessageListener{
+ void errorMessage(Exception e);
+ }
+}
+
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/SharedPreferencesConfigs.kt b/app/src/main/java/com/xuqinmin/android/app/common/SharedPreferencesConfigs.kt
new file mode 100644
index 0000000..1e29dbb
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/SharedPreferencesConfigs.kt
@@ -0,0 +1,8 @@
+package com.xuqinmin.android.app.common
+
+const val SHARE_RISK_LOCATION = "share_risk_location"
+const val SHARE_RISK_PURE = "share_risk_pure"
+
+const val MCC = "mcc"
+const val DEVICE_ID = "deviceUuid"
+const val USER_INFO = "user_info"
diff --git a/app/src/main/java/com/xuqinmin/android/app/common/StoreHelper.kt b/app/src/main/java/com/xuqinmin/android/app/common/StoreHelper.kt
new file mode 100644
index 0000000..975ccca
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/common/StoreHelper.kt
@@ -0,0 +1,59 @@
+package com.xuqinmin.android.app.common
+
+import com.xuqinmin.android.app.MyApplication
+import com.xuqinmin.android.app.model.RecommendData
+import com.xuqinmin.android.app.repository.Service
+import com.xuqinmin.android.app.ui.dialog.DialogBalance
+import com.xuqinmin.android.app.ui.dialog.DialogStore
+import com.xuqm.base.di.manager.HttpManager
+import com.xuqm.sdhbwfu.core.extensions.ioMain
+import com.xuqm.sdhbwfu.core.extensions.showMessage
+import com.xuqm.sdhbwfu.core.extensions.subscribeBy
+
+class StoreHelper {
+ companion object {
+ fun showPay() {
+ HttpManager.getApi(Service::class.java)
+ .recommend(RecommendData(1))
+ .ioMain()
+ .subscribeBy(
+ {
+ if (null != it) {
+ DialogBalance.show(it) { ite ->
+ if (!MyApplication.isInit) {
+ "The initialization of the payment component failed. Please try again later.".showMessage()
+ MyApplication.startConnection()
+ } else
+ MyApplication.startPay(ite)
+ }
+ } else {
+ showPayView()
+ }
+ }, {
+ showPayView()
+ }
+ )
+ }
+
+ private fun showPayView() {
+
+ HttpManager.getApi(Service::class.java).orders()
+ .ioMain()
+ .subscribeBy({
+ if (null != it) {
+ DialogStore.show(it) { it2 ->
+ if (!MyApplication.isInit) {
+ "The initialization of the payment component failed. Please try again later.".showMessage()
+ MyApplication.startConnection()
+ } else
+ MyApplication.startPay(it2)
+ }
+ } else {
+ "Insufficient gold coins".showMessage()
+ }
+ }, {
+ it.showMessage()
+ })
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xuqinmin/android/app/db/BaseEntity.java b/app/src/main/java/com/xuqinmin/android/app/db/BaseEntity.java
new file mode 100644
index 0000000..3b2be62
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/db/BaseEntity.java
@@ -0,0 +1,16 @@
+package com.xuqinmin.android.app.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/app/src/main/java/com/xuqinmin/android/app/db/MessageDatabase.java b/app/src/main/java/com/xuqinmin/android/app/db/MessageDatabase.java
new file mode 100644
index 0000000..84c37ae
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/db/MessageDatabase.java
@@ -0,0 +1,14 @@
+package com.xuqinmin.android.app.db;
+
+import androidx.room.Database;
+import androidx.room.RoomDatabase;
+
+import com.xuqinmin.android.app.db.msg.MessageDao;
+import com.xuqinmin.android.app.db.msg.MessageEntity;
+
+@Database(entities = {MessageEntity.class}, version = 2, exportSchema = false)
+public abstract class MessageDatabase extends RoomDatabase {
+
+ public abstract MessageDao messageDao();
+
+}
diff --git a/app/src/main/java/com/xuqinmin/android/app/db/XuqmDbHelper.java b/app/src/main/java/com/xuqinmin/android/app/db/XuqmDbHelper.java
new file mode 100644
index 0000000..c2807ea
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/db/XuqmDbHelper.java
@@ -0,0 +1,23 @@
+package com.xuqinmin.android.app.db;
+
+import android.content.Context;
+
+import androidx.room.Room;
+
+public class XuqmDbHelper {
+
+ private static MessageDatabase dataBase;
+
+ public static MessageDatabase get() {
+ return dataBase;
+ }
+
+ public static void get(Context context) {
+ if (null == dataBase) {
+ dataBase = Room.databaseBuilder(context, MessageDatabase.class, "xuqm-im-db")
+// .addMigrations(MIGRATION_1_2)
+ .allowMainThreadQueries() //允许在主线程 操作db
+ .build();
+ }
+ }
+}
diff --git a/app/src/main/java/com/xuqinmin/android/app/db/msg/MessageDao.java b/app/src/main/java/com/xuqinmin/android/app/db/msg/MessageDao.java
new file mode 100644
index 0000000..f64f23b
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/db/msg/MessageDao.java
@@ -0,0 +1,29 @@
+package com.xuqinmin.android.app.db.msg;
+
+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 MessageDao {
+
+ @Query("SELECT * FROM message WHERE (toUser = :user OR fromUser = :user) AND type = 'MSG' ORDER BY _uid LIMIT :pageSize OFFSET (:currentPage - 1) * :pageSize")
+ List getMessageList(int user, int currentPage, int pageSize);
+
+ @Insert
+ void insertAll(MessageEntity... devices);
+
+ @Update
+ void update(MessageEntity device);
+
+ @Delete
+ void delete(MessageEntity device);
+
+ @Query("DELETE FROM message")
+ void clearTable();
+
+}
diff --git a/app/src/main/java/com/xuqinmin/android/app/db/msg/MessageEntity.java b/app/src/main/java/com/xuqinmin/android/app/db/msg/MessageEntity.java
new file mode 100644
index 0000000..d76f6e7
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/db/msg/MessageEntity.java
@@ -0,0 +1,57 @@
+package com.xuqinmin.android.app.db.msg;
+
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+
+import com.xuqinmin.android.app.db.BaseEntity;
+
+@Entity(tableName = "message")
+public class MessageEntity extends BaseEntity {
+ @ColumnInfo(name = "type")
+ private String type;
+ @ColumnInfo(name = "toUser")
+ private int toUser;
+ @ColumnInfo(name = "fromUser")
+ private int fromUser;
+ @ColumnInfo(name = "msg")
+ private String message;
+
+ public MessageEntity(String type, int fromUser, int toUser, String message) {
+ this.type = type;
+ this.toUser = toUser;
+ this.fromUser = fromUser;
+ this.message = message;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public int getToUser() {
+ return toUser;
+ }
+
+ public void setToUser(int toUser) {
+ this.toUser = toUser;
+ }
+
+ public int getFromUser() {
+ return fromUser;
+ }
+
+ public void setFromUser(int fromUser) {
+ this.fromUser = fromUser;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/app/src/main/java/com/xuqinmin/android/app/model/AnchorInfoModel.kt b/app/src/main/java/com/xuqinmin/android/app/model/AnchorInfoModel.kt
new file mode 100644
index 0000000..491b4ce
--- /dev/null
+++ b/app/src/main/java/com/xuqinmin/android/app/model/AnchorInfoModel.kt
@@ -0,0 +1,28 @@
+package com.xuqinmin.android.app.model
+
+data class AnchorInfoModel(
+ val age: Int,
+ val bodyType: String,
+ val country: Int,
+ val cup: String,
+ val emId: String,
+ val fansNum: Int,
+ val followedNum: Int,
+ // 性别 0-男 1-女 -1 未填写性别
+ val gender: Int,
+ val headImage: String,
+ val height: Int,
+ val imId: String,
+ val isFollow: Int,
+ val language: List,
+ val nickname: String,
+ val online: Int,
+ val pics: List,
+ val price: Float,
+ val signature: String,
+ val sort: Int,
+ val userId: Int,
+ val videos: List