xiongzhu пре 7 година
комит
3381f737f8
100 измењених фајлова са 6119 додато и 0 уклоњено
  1. 9 0
      .gitignore
  2. BIN
      .idea/caches/build_file_checksums.ser
  3. 29 0
      .idea/codeStyles/Project.xml
  4. 21 0
      .idea/gradle.xml
  5. 38 0
      .idea/misc.xml
  6. 12 0
      .idea/modules.xml
  7. 12 0
      .idea/runConfigurations.xml
  8. 1 0
      app/.gitignore
  9. 83 0
      app/build.gradle
  10. BIN
      app/libs/AMap2DMap_3.0.0_AMapSearch_3.6.1_AMapLocation_3.2.1_20161228.jar
  11. BIN
      app/libs/HMS_SDK_2.6.1.301.jar
  12. BIN
      app/libs/MiPush_SDK_Client_3_6_2.jar
  13. BIN
      app/libs/alipaySdk.jar
  14. BIN
      app/libs/nim-push-5.4.0.jar
  15. 17 0
      app/proguard-rules.pro
  16. BIN
      app/release.jks
  17. 462 0
      app/src/main/AndroidManifest.xml
  18. BIN
      app/src/main/assets/hmsrootcas.bks
  19. 87 0
      app/src/main/assets/privacy_protocol.html
  20. 108 0
      app/src/main/assets/user_protocol.html
  21. 302 0
      app/src/main/java/com/android/chmo/app/ChmoApplication.java
  22. 58 0
      app/src/main/java/com/android/chmo/app/SpManager.java
  23. 262 0
      app/src/main/java/com/android/chmo/app/VChatManager.java
  24. 136 0
      app/src/main/java/com/android/chmo/base/BaseActivity.java
  25. 36 0
      app/src/main/java/com/android/chmo/base/BaseApplication.java
  26. 152 0
      app/src/main/java/com/android/chmo/base/BaseFragment.java
  27. 9 0
      app/src/main/java/com/android/chmo/constant/Constants.java
  28. 37 0
      app/src/main/java/com/android/chmo/db/CommDbHelper.java
  29. 79 0
      app/src/main/java/com/android/chmo/db/DBHelper.java
  30. 88 0
      app/src/main/java/com/android/chmo/http/HttpApi.java
  31. 11 0
      app/src/main/java/com/android/chmo/http/RequestCallback.java
  32. 13 0
      app/src/main/java/com/android/chmo/http/response/ActivitiesListRes.java
  33. 11 0
      app/src/main/java/com/android/chmo/http/response/AlipayRes.java
  34. 14 0
      app/src/main/java/com/android/chmo/http/response/BannerRes.java
  35. 13 0
      app/src/main/java/com/android/chmo/http/response/BrokerListRes.java
  36. 10 0
      app/src/main/java/com/android/chmo/http/response/CommentListRes.java
  37. 13 0
      app/src/main/java/com/android/chmo/http/response/FindListRes.java
  38. 10 0
      app/src/main/java/com/android/chmo/http/response/LabelListRes.java
  39. 12 0
      app/src/main/java/com/android/chmo/http/response/LoginRes.java
  40. 22 0
      app/src/main/java/com/android/chmo/http/response/ModelDetailRes.java
  41. 11 0
      app/src/main/java/com/android/chmo/http/response/ModelHonorRes.java
  42. 13 0
      app/src/main/java/com/android/chmo/http/response/ModelListRes.java
  43. 13 0
      app/src/main/java/com/android/chmo/http/response/ModelSkillRes.java
  44. 13 0
      app/src/main/java/com/android/chmo/http/response/OrderListRes.java
  45. 13 0
      app/src/main/java/com/android/chmo/http/response/OrderRes.java
  46. 10 0
      app/src/main/java/com/android/chmo/http/response/PayOrderRes.java
  47. 9 0
      app/src/main/java/com/android/chmo/http/response/PayRes.java
  48. 9 0
      app/src/main/java/com/android/chmo/http/response/PhotoRes.java
  49. 9 0
      app/src/main/java/com/android/chmo/http/response/RegisterRes.java
  50. 10 0
      app/src/main/java/com/android/chmo/http/response/Res.java
  51. 13 0
      app/src/main/java/com/android/chmo/http/response/VChatRes.java
  52. 13 0
      app/src/main/java/com/android/chmo/http/response/VideoOrderRes.java
  53. 10 0
      app/src/main/java/com/android/chmo/http/response/VideoPriceRes.java
  54. 16 0
      app/src/main/java/com/android/chmo/http/response/ZoneListRes.java
  55. 74 0
      app/src/main/java/com/android/chmo/http/service/ActivitiesService.java
  56. 64 0
      app/src/main/java/com/android/chmo/http/service/FindService.java
  57. 206 0
      app/src/main/java/com/android/chmo/http/service/ModelService.java
  58. 167 0
      app/src/main/java/com/android/chmo/http/service/OrderService.java
  59. 31 0
      app/src/main/java/com/android/chmo/http/service/PayService.java
  60. 119 0
      app/src/main/java/com/android/chmo/http/service/UserService.java
  61. 10 0
      app/src/main/java/com/android/chmo/http/service/messageService.java
  62. 39 0
      app/src/main/java/com/android/chmo/im/AVChatAction.java
  63. 71 0
      app/src/main/java/com/android/chmo/im/IMManager.java
  64. 208 0
      app/src/main/java/com/android/chmo/im/SessionHelper.java
  65. 87 0
      app/src/main/java/com/android/chmo/im/holder/MsgViewHolderAVChat.java
  66. 103 0
      app/src/main/java/com/android/chmo/im/location/ChmoLocationManager.java
  67. 63 0
      app/src/main/java/com/android/chmo/im/location/ChmoLocationProvider.java
  68. 8 0
      app/src/main/java/com/android/chmo/im/location/LocationInfo.java
  69. 84 0
      app/src/main/java/com/android/chmo/mixpush/ChmoMixPushMessageHandler.java
  70. 44 0
      app/src/main/java/com/android/chmo/mixpush/ChmoPushContentProvider.java
  71. 27 0
      app/src/main/java/com/android/chmo/model/ActivitiesInfo.java
  72. 61 0
      app/src/main/java/com/android/chmo/model/AliPayResult.java
  73. 13 0
      app/src/main/java/com/android/chmo/model/BannerInfo.java
  74. 27 0
      app/src/main/java/com/android/chmo/model/BrokerInfo.java
  75. 14 0
      app/src/main/java/com/android/chmo/model/CommentInfo.java
  76. 25 0
      app/src/main/java/com/android/chmo/model/FindInfo.java
  77. 9 0
      app/src/main/java/com/android/chmo/model/LabelInfo.java
  78. 165 0
      app/src/main/java/com/android/chmo/model/LoginUser.java
  79. 50 0
      app/src/main/java/com/android/chmo/model/ModelInfo.java
  80. 19 0
      app/src/main/java/com/android/chmo/model/ModelLabel.java
  81. 18 0
      app/src/main/java/com/android/chmo/model/ModelOrder.java
  82. 14 0
      app/src/main/java/com/android/chmo/model/ModelPhoto.java
  83. 16 0
      app/src/main/java/com/android/chmo/model/ModelSkill.java
  84. 27 0
      app/src/main/java/com/android/chmo/model/ModelVideo.java
  85. 39 0
      app/src/main/java/com/android/chmo/model/ModelZone.java
  86. 39 0
      app/src/main/java/com/android/chmo/model/OrderInfo.java
  87. 21 0
      app/src/main/java/com/android/chmo/model/UserInfo.java
  88. 89 0
      app/src/main/java/com/android/chmo/receiver/VChatReceiver.java
  89. 130 0
      app/src/main/java/com/android/chmo/ui/activity/GuideActivity.java
  90. 148 0
      app/src/main/java/com/android/chmo/ui/activity/LoginActivity.java
  91. 190 0
      app/src/main/java/com/android/chmo/ui/activity/MainActivity.java
  92. 197 0
      app/src/main/java/com/android/chmo/ui/activity/RegisterActivity.java
  93. 52 0
      app/src/main/java/com/android/chmo/ui/activity/WelcomeActivity.java
  94. 78 0
      app/src/main/java/com/android/chmo/ui/activity/activities/ActivitiesDetailActivity.java
  95. 111 0
      app/src/main/java/com/android/chmo/ui/activity/activities/BannerInfoActivity.java
  96. 123 0
      app/src/main/java/com/android/chmo/ui/activity/activities/SignInActivity.java
  97. 394 0
      app/src/main/java/com/android/chmo/ui/activity/find/FindDetailActivity.java
  98. 62 0
      app/src/main/java/com/android/chmo/ui/activity/me/AboutActivity.java
  99. 177 0
      app/src/main/java/com/android/chmo/ui/activity/me/ForgetPwdActivity.java
  100. 77 0
      app/src/main/java/com/android/chmo/ui/activity/me/ModifyNameActivity.java

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild

BIN
.idea/caches/build_file_checksums.ser


+ 29 - 0
.idea/codeStyles/Project.xml

@@ -0,0 +1,29 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <Objective-C-extensions>
+      <file>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
+      </file>
+      <class>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
+      </class>
+      <extensions>
+        <pair source="cpp" header="h" fileNamingConvention="NONE" />
+        <pair source="c" header="h" fileNamingConvention="NONE" />
+      </extensions>
+    </Objective-C-extensions>
+  </code_scheme>
+</component>

+ 21 - 0
.idea/gradle.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/avchatkit" />
+            <option value="$PROJECT_DIR$/faceunity" />
+            <option value="$PROJECT_DIR$/uikit" />
+          </set>
+        </option>
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 38 - 0
.idea/misc.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="NullableNotNullManager">
+    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
+    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
+    <option name="myNullables">
+      <value>
+        <list size="7">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
+          <item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
+          <item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
+          <item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
+        </list>
+      </value>
+    </option>
+    <option name="myNotNulls">
+      <value>
+        <list size="6">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+          <item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
+        </list>
+      </value>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>

+ 12 - 0
.idea/modules.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/CHMO.iml" filepath="$PROJECT_DIR$/CHMO.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
+      <module fileurl="file://$PROJECT_DIR$/avchatkit/avchatkit.iml" filepath="$PROJECT_DIR$/avchatkit/avchatkit.iml" />
+      <module fileurl="file://$PROJECT_DIR$/faceunity/faceunity.iml" filepath="$PROJECT_DIR$/faceunity/faceunity.iml" />
+      <module fileurl="file://$PROJECT_DIR$/uikit/uikit.iml" filepath="$PROJECT_DIR$/uikit/uikit.iml" />
+    </modules>
+  </component>
+</project>

+ 12 - 0
.idea/runConfigurations.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
+/build

+ 83 - 0
app/build.gradle

@@ -0,0 +1,83 @@
+apply plugin: 'com.android.application'
+apply plugin: 'com.neenbedankt.android-apt'
+
+
+android {
+    compileSdkVersion 26
+    buildToolsVersion "26.0.2"
+    defaultConfig {
+        applicationId "com.android.chmo"
+        minSdkVersion 14
+        targetSdkVersion 26
+        versionCode 1
+        versionName "1.0"
+        ndk {
+            abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
+        }
+        multiDexEnabled = true
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    sourceSets {
+        main {
+            jniLibs.srcDirs = ['libs']
+        }
+    }
+    lintOptions {
+        checkReleaseBuilds false
+        abortOnError false
+    }
+
+    dexOptions {
+        preDexLibraries false
+        jumboMode true
+        javaMaxHeapSize "4g"
+    }
+
+    packagingOptions {
+        exclude 'META-INF/LICENSE.txt'
+        exclude 'META-INF/NOTICE.txt'
+    }
+
+    aaptOptions {
+        cruncherEnabled = false
+        useNewCruncher = false
+    }
+
+
+}
+task copyDownloadableDepsToLibs(type: Copy) {
+    from configurations.compile
+    into 'libs'
+}
+
+dependencies {
+    compile fileTree(include: ['*.jar'], dir: 'libs')
+    compile 'com.android.support:appcompat-v7:26.+'
+    compile 'com.jakewharton:butterknife:8.4.0'
+    apt 'com.jakewharton:butterknife-compiler:8.4.0'
+    compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1'
+    compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.5.1'
+    compile 'com.google.code.gson:gson:2.2.4'
+    compile 'org.xutils:xutils:3.5.0'
+    compile 'com.contrarywind:Android-PickerView:4.1.6'
+    compile 'org.greenrobot:eventbus:3.1.1'
+    compile 'com.android.support:multidex:1.0.1'
+    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
+    compile 'com.lovedise:permissiongen:0.0.6'
+    compile('com.github.chrisbanes:PhotoView:2.1.4') {
+        exclude group: 'com.android.support'
+    }
+    compile files('libs/AMap2DMap_3.0.0_AMapSearch_3.6.1_AMapLocation_3.2.1_20161228.jar')
+    compile project(':uikit')
+    compile files('libs/alipaySdk.jar')
+    compile files('libs/MiPush_SDK_Client_3_6_2.jar')
+    compile files('libs/nim-push-5.4.0.jar')
+    compile files('libs/HMS_SDK_2.6.1.301.jar')
+}

BIN
app/libs/AMap2DMap_3.0.0_AMapSearch_3.6.1_AMapLocation_3.2.1_20161228.jar


BIN
app/libs/HMS_SDK_2.6.1.301.jar


BIN
app/libs/MiPush_SDK_Client_3_6_2.jar


BIN
app/libs/alipaySdk.jar


BIN
app/libs/nim-push-5.4.0.jar


+ 17 - 0
app/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\android\sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# 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 *;
+#}


+ 462 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.android.chmo">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.CALL_PHONE" />
+    <!--用于进行网络定位-->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <!--用于访问GPS定位-->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+
+    <!-- 多媒体相关 -->
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+
+    <!-- 控制呼吸灯,振动器等,用于新消息提醒 -->
+    <uses-permission android:name="android.permission.FLASHLIGHT" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
+    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-feature android:name="android.hardware.camera.autofocus" />
+    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+
+    <!-- 和下面的 uses-permission 一起加入到你的 AndroidManifest 文件中。 -->
+    <permission
+        android:name="com.android.chmo.permission.RECEIVE_MSG"
+        android:protectionLevel="signature"/>
+    <!-- 接收 SDK 消息广播权限, 第三方 APP 接入时,请将 com.netease.nim.demo 替换为自己的包名 -->
+    <uses-permission android:name="com.android.chmo.permission.RECEIVE_MSG"/>
+
+    <!-- 小米推送 -->
+    <permission
+        android:name="com.android.chmo.permission.MIPUSH_RECEIVE"
+        android:protectionLevel="signature" />
+    <uses-permission android:name="com.android.chmo.permission.MIPUSH_RECEIVE" />
+
+    <uses-sdk tools:overrideLibrary="com.huawei.android.hms.base,com.huawei.android.hms.push" />
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
+    <!--魅族推送-->
+
+    <!-- 兼容flyme5.0以下版本,魅族内部集成pushSDK必填,不然无法收到消息-->
+    <uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE" />
+    <permission android:name="com.android.chmo.push.permission.MESSAGE"
+        android:protectionLevel="signature"/>
+    <uses-permission android:name="com.android.chmo.push.permission.MESSAGE" />
+    <!--  兼容flyme3.0配置权限-->
+    <uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" />
+    <permission android:name="com.android.chmo.permission.C2D_MESSAGE"
+        android:protectionLevel="signature" />
+    <uses-permission android:name="com.android.chmo.permission.C2D_MESSAGE"/>
+
+    <application
+        android:name=".app.ChmoApplication"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+
+        <activity
+            android:name=".ui.activity.WelcomeActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeSplash">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name=".ui.activity.GuideActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"></activity>
+
+        <activity
+            android:name=".ui.activity.LoginActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden">
+
+        </activity>
+
+        <activity
+            android:name=".ui.activity.RegisterActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.me.ForgetPwdActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.MainActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.model.ModelDetailActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.model.ModelReserveActivty"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.order.SubmitOrderActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.order.PayOrderActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.order.MyOrderActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.order.OrderDetailActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.order.VideoOrderActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.model.ModelZoneActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.model.ModelZoneDetailActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.model.BrokerModelActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.model.BrokerInfoActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.model.SearchModelActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.model.SearchResultActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.activities.ActivitiesDetailActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.activities.SignInActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.me.RechargeActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.find.FindDetailActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.model.ShowImageActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+        <activity
+            android:name=".ui.activity.me.ModifyNameActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.me.MySignActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.message.LocationMapActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.activities.BannerInfoActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+
+        <activity
+            android:name=".ui.activity.me.ProtocolActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.me.AboutActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <activity
+            android:name=".ui.activity.model.ModelReportActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ThemeScreen"
+            android:windowSoftInputMode="adjustPan|stateHidden"></activity>
+
+        <receiver android:name=".receiver.VChatReceiver">
+            <intent-filter>
+                <action android:name="android.chmo.action.CALL"/>
+                <action android:name="android.chmo.action.INCOMING"/>
+                <action android:name="android.chmo.action.BEGIN_VIDEO"/>
+                <action android:name="android.chmo.action.END_VIDEO"/>
+            </intent-filter>
+        </receiver>
+
+        <!-- 支付宝-->
+        <activity
+            android:name="com.alipay.sdk.app.H5PayActivity"
+            android:configChanges="orientation|keyboardHidden|navigation|screenSize"
+            android:exported="false"
+            android:screenOrientation="behind"
+            android:windowSoftInputMode="adjustResize|stateHidden" >
+        </activity>
+        <activity
+            android:name="com.alipay.sdk.app.H5AuthActivity"
+            android:configChanges="orientation|keyboardHidden|navigation"
+            android:exported="false"
+            android:screenOrientation="behind"
+            android:windowSoftInputMode="adjustResize|stateHidden" >
+        </activity>
+
+        <!-- 微信 -->
+        <activity
+            android:name=".wxapi.WXEntryActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:exported="true"
+            android:screenOrientation="portrait"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
+
+        <activity
+            android:name=".wxapi.WXPayEntryActivity"
+            android:label="@string/app_name"
+            android:exported="true"
+            />
+
+
+        <meta-data
+            android:name="com.amap.api.v2.apikey"
+            android:value="41da1ae28c42ca83d6de30edec201135" />
+
+        <uses-library
+            android:name="com.google.android.maps"
+            android:required="false" />
+
+        <!-- APP key, 可以在这里设置,也可以在 SDKOptions 中提供。
+           如果 SDKOptions 中提供了,取 SDKOptions 中的值。 -->
+        <meta-data
+            android:name="com.netease.nim.appKey"
+            android:value="c545b95fd20d5a20d0d1220dc6831e4d" />
+
+        <!-- 云信后台服务,请使用独立进程。 -->
+        <service
+            android:name="com.netease.nimlib.service.NimService"
+            android:process=":core"/>
+
+        <!-- 云信后台辅助服务 -->
+        <service
+            android:name="com.netease.nimlib.service.NimService$Aux"
+            android:process=":core"/>
+
+        <!-- 云信后台辅助服务 -->
+        <service
+            android:name="com.netease.nimlib.job.NIMJobService"
+            android:exported="true"
+            android:permission="android.permission.BIND_JOB_SERVICE"
+            android:process=":core"/>
+
+        <!-- 云信监视系统启动和网络变化的广播接收器,保持和 NimService 同一进程 -->
+        <receiver android:name="com.netease.nimlib.service.NimReceiver"
+            android:process=":core"
+            android:exported="false">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED"/>
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
+            </intent-filter>
+        </receiver>
+
+        <!-- 云信进程间通信 Receiver -->
+        <receiver android:name="com.netease.nimlib.service.ResponseReceiver"/>
+
+        <!-- 云信进程间通信service -->
+        <service android:name="com.netease.nimlib.service.ResponseService"/>
+
+        <!-- 云信进程间通信provider -->
+        <!-- android:authorities="{包名}.ipc.provider", 请将com.netease.nim.demo替换为自己的包名 -->
+        <provider
+            android:name="com.netease.nimlib.ipc.NIMContentProvider"
+            android:authorities="com.android.chmo.ipc.provider"
+            android:exported="false"
+            android:process=":core" />
+
+
+
+        <!-- 小米推送配置 -->
+        <service
+            android:name="com.xiaomi.push.service.XMJobService"
+            android:enabled="true"
+            android:exported="false"
+            android:permission="android.permission.BIND_JOB_SERVICE"
+            android:process=":mixpush" />
+
+        <service
+            android:name="com.xiaomi.push.service.XMPushService"
+            android:enabled="true"
+            android:process=":mixpush" />
+
+        <receiver
+            android:name="com.xiaomi.push.service.receivers.PingReceiver"
+            android:exported="false"
+            android:process=":mixpush">
+            <intent-filter>
+                <action android:name="com.xiaomi.push.PING_TIMER" />
+            </intent-filter>
+        </receiver>
+
+        <receiver
+            android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </receiver>
+
+        <service
+            android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
+            android:enabled="true"
+            android:exported="true" />
+
+        <service
+            android:name="com.xiaomi.mipush.sdk.MessageHandleService"
+            android:enabled="true" />
+
+        <receiver
+            android:name="com.netease.nimlib.mixpush.mi.MiPushReceiver"
+            android:exported="true">
+            <intent-filter android:priority="0x7fffffff">
+                <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
+                <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />
+                <action android:name="com.xiaomi.mipush.ERROR" />
+            </intent-filter>
+        </receiver>
+
+        <!--华为推送配置-->
+
+        <meta-data
+            android:name="com.huawei.hms.client.appid"
+            android:value="100388425" />
+
+        <provider
+            android:name="com.huawei.hms.update.provider.UpdateProvider"
+            android:authorities="com.android.chmo.hms.update.provider"
+            android:exported="false"
+            android:grantUriPermissions="true" />
+
+        <!-- 第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播 -->
+        <receiver android:name="com.netease.nimlib.mixpush.hw.HWPushReceiver">
+            <intent-filter android:priority="0x7fffffff">
+                <!-- 必须,用于接收token -->
+                <action android:name="com.huawei.android.push.intent.REGISTRATION" />
+                <!-- 必须,用于接收消息 -->
+                <action android:name="com.huawei.android.push.intent.RECEIVE" />
+                <!-- 可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调 -->
+                <action android:name="com.huawei.android.push.intent.CLICK" />
+                <!-- 可选,查看push通道是否连接,不查看则不需要 -->
+                <action android:name="com.huawei.intent.action.PUSH_STATE" />
+            </intent-filter>
+            <meta-data
+                android:name="CS_cloud_ablitity"
+                android:value="successRateAnalytics" />
+        </receiver>
+
+        <receiver android:name="com.huawei.hms.support.api.push.PushEventReceiver">
+            <intent-filter>
+                <!-- 接收通道发来的通知栏消息,兼容老版本Push -->
+                <action android:name="com.huawei.intent.action.PUSH" />
+            </intent-filter>
+        </receiver>
+
+        <!--meizu-->
+        <receiver android:name="com.netease.nimlib.mixpush.mz.MZPushReceiver">
+            <intent-filter android:priority="0x7fffffff">
+                <!-- 接收push消息 -->
+                <action android:name="com.meizu.flyme.push.intent.MESSAGE" />
+                <!-- 接收register消息 -->
+                <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
+                <!-- 接收unregister消息-->
+                <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
+                <!-- 兼容低版本Flyme3推送服务配置 -->
+                <action android:name="com.meizu.c2dm.intent.REGISTRATION" />
+                <action android:name="com.meizu.c2dm.intent.RECEIVE" />
+                <category android:name="com.android.chmo" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+</manifest>

BIN
app/src/main/assets/hmsrootcas.bks


+ 87 - 0
app/src/main/assets/privacy_protocol.html

@@ -0,0 +1,87 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+    <style>
+    </style>
+</head>
+
+<body>
+<div>
+    <h2>用户服务协议</h2>
+
+    <h3>重要提示:</h3>
+    千模APP尊重和保护用户隐私。在您使用千模APP服务时,我们可能会收集和使用您的相关信息。本条款旨在向您说明我们如何收集、使用、存储和分享这些信息,以及我们为保护您的信息安全所采取的相应措施。<br/>
+    请您仔细阅读以下内容,如果您对条款有任何疑虑,请您联系千模APP客服。您使用或继续使用我们的服务,即表示您认可并接受本条款现有内容及其可能随时更新的内容。<br/>
+
+    <h3>1.适用范围</h3>
+    1.1千模APP平台所有的产品和服务均适用本条款。如果某些产品或服务需要适用特定的隐私政策,我们将在提供这些产品或服务前向您说明。<br/>
+    1.2本条款不适用于那些通过我们的产品或服务而接入的、由第三方独立为您提供的产品或服务的情形,例如在我们的产品或服务中链接到的第三方网站。请务必注意,您在使用第三方的产品或服务时,您的信息保护应当适用该第三方的隐私政策。<br/>
+
+    <h3>2.我们可能收集的信息</h3>
+    我们提供服务时,可能会收集、储存和使用下列与您有关的信息。如果您不提供相关信息,可能无法注册成为我们的用户或无法享受我们提供的某些服务,或者无法达到相关服务拟达到的效果。<br/>
+    2.1您提供的信息<br/>
+    2.1.1您在注册账号和使用千模APP服务时向我们提供账号名称、艺名、手机号码或电子邮件等信息及年龄、身高、国籍、三围、风格、艺能或工作意向等个人信息。<br/>
+    2.1.2为了保障您的合法权益与交易安全,在您使用千模APP特定产品或服务时,我们可能会要求您进一步提供真实的身份信息,包括姓名、身份证号码、出生日期等信息,以便进行实名认证。<br/>
+    2.1.3敏感个人信息<br/>
+    特别提示您注意:您的某些个人信息,比如宗教信仰、生物信息、健康和医疗信息等,可能被视为敏感个人信息。您在千模APP平台上传、提供或发布这些信息,将导致他人可以获悉您的敏感个人信息,因此,还请您谨慎处理。<br/>
+
+    2.2在您使用产品或服务过程中收集的信息:<br/>
+    2.2.1您通过我们的服务项其他方提供的共享信息,以及您在使用我们服务时所存储的信息。<br/>
+    2.2.2其他方分享的您的信息。<br/>
+    2.2.3其他方使用我们的服务时提供的您的共享信息。<br/>
+    2.2.4日志信息,即您在使用我们的产品或服务时,系统可能通过cookies、web beacon或其他方式采集的技术信息,包括设备信息(例如您的硬件型号、操作系统版本、设备配置、唯一设备标识符等);地理位置信息;设备连接信息(例如浏览器的类型、电信运营商、使用的语言等);设备状态信息(例如设备传感器数据等信息)。<br/>
+    2.2.5特别提示您注意:<br/>
+    (1)我们有可能会将上述信息相关联,可能会将您的设备信息与您的账户相关联,以便我们能在这些设备上为您提供一致的服务。<br/>
+    (2)您可以通过关闭定位功能、拒绝cookie等方式,终止对您信息的收集,但您可能将无法获得相关服务或者无法达到相关服务拟达到的效果。<br/>
+    2.3来自第三方的信息<br/>
+    在您使用千模APP产品或服务时,我们有可能会按照法律法规的规定或基于您的授权从其他第三方服务商、支付机构等处接收您的个人信息。<br/>
+
+    <h3>3.如何管理您的信息</h3>
+    千模APP按照法律法规的规定和要求尽一切可能保证您可以顺利的访问和管理您千模APP账户内的信息。我们为您提供更新和修改您账户信息的通道。当您需要删除用户信息时,我们有可能会要求您进行身份认证,以保护您的信息安全。<br/>
+
+    <h3>4.关于Cookies等信息收集方式的说明</h3>
+    4.1千模APP可能通过cookies、web beacon等方式收集和使用您的信息,并将该等信息储存为日志信息。您可以选择通过修改浏览器设置的方式拒绝cookie,但您可能无法登录或使用依赖于cookie的千模APP提供的服务或功能。<br/>
+    4.2我们使用自己的cookies、web beacon等方式收集信息的目的是为您提供更为优质的服务,其用途主要在于:识别和记住您的用户身份;保存您向我们提供的用户偏好和其他信息;分析您使用我们服务的情况和您的活动偏好;进行广告优化以便为您投放更具个性化的广告。<br/>
+
+    <h3>5.我们可能使用收集信息的情形</h3>
+    我们收集和使用您的信息的目的旨在:<br/>
+    5.1帮助您完成用户注册,向您提供产品或服务;<br/>
+    5.2改进产品或服务,即对我们运营的产品或提供的服务进行评估、维护和改进;<br/>
+    5.3我们可能会对产品和服务的使用情况进行统计和分析。我们可能会与公众共享这些统计信息以展示我们服务的整体使用趋势,或将该等分析结果提供给我们的广告商、第三方合作伙伴以用于广告服务,无论何种方式,其统计信息都将不会含有您的任何个人身份识别信息。<br/>
+    5.4该等信息可能被用于安全保障用途,例如,我们可能使用您的信息进行身份验证、安全防范、存档和备份等,以便发现、调查和处置危害安全、违法违规的行为,保障用户权益。<br/>
+    5.5我们可能会使用您的信息进行信息推送与通知,包括商业推广和广告类信息推送。如果您不希望接收到这些信息,我们也为您提供取消信息订阅的途径,但是您将无法取消涉及系统服务的、性质上不属于推广广告的消息订阅,例如,千模APP因系统维护而需要暂停某项服务时向您发送的通知。<br/>
+
+    <h3>6.我们可能分享、披露或转让信息的情形</h3>
+    6.1未经您的同意我们不会向任何第三方共享您的信息,以下情形除外:<br/>
+    除以下情形外,未经您同意,我们不会向任何第三方共享您的信息:<br/>
+    6.1.1为实现第5条所列举的目的,我们将以必要性原则为依据与关联公司分享您的信息,以便提升产品和服务质量;<br/>
+    6.1.2向合作合伙或其他受信任的第三方服务机构、第三方供应商、第三方代理商等共享您的信息,以便第三方为您提供服务及改进服务质量;<br/>
+    6.1.3遵循任何适用法律法规的要求、法院裁决或判决、或政府机关的强制性要求;<br/>
+    6.1.4查找、预防或处理欺诈、安全或技术方面的问题;<br/>
+    6.1.5其他依据法律法规、司法机关或政府机关的强制性要求而进行的信息共享、披露。<br/>
+    6.2未经您的同意我们不会向第三方转让数据信息,以下情形除外:<br/>
+    千模APP及关联公司发生合并、分立、清算、资产或业务的收购、出售等交易时,您的个人信息将有可能作为此类交易的一部分而被转移,但我们将尽一切努力确保数据转移时的安全性,您同意对此予以理解和认可。<br/>
+
+    <h3>7.我们如何保留、存储和保护信息</h3>
+    7.1我们收集的您的个人信息将保留在阿里云的服务器上。这些信息和资料可能传送至您所在国家、地区或千模APP收集信息和资料所在地并在该地被访问、存储和展示。<br/>
+    7.2我们高度重视信息安全并按国家法律法规的要求采取技术措施和其他必要措施,确保其收集的个人信息安全。同时,我们也提示您通过如下方式,强化账户及信息的安全保护,即,注意使用较为复杂的密码并定期更换,谨慎披露个人敏感信息,更换设备时注意设备权限的设置。<br/>
+    7.3我们进一步提示您注意已发布的共享信息:<br/>
+    只要您不删除已发布的共享信息,该等信息就会一直留存在公众领域;即使您删除这些共享信息,有关信息仍可能由其他用户或不受我们控制的第三方独立地缓存、复制或储存,或由其他用户或该等第三方在公众领域保存。<br/>
+    因此,还请您在信息发布前,认真考虑您所发布的信息是否包含有敏感隐私信息或您不希望为外界所获知的信息,如果包含,请您务必不要上传、发布、分享。<br/>
+
+    <h3>8.第三方社交媒体或其他服务</h3>
+    8.1本《隐私条款》仅适用于千模APP所收集的信息,并不适用于任何第三方提供的服务或第三方的信息使用规则,我们对任何第三方使用由您提供的信息不承担任何责任。<br/>
+    8.2当您第三方链接接入千模APP或通过平台链接接入第三方的服务或网站并使用相关服务时,您需要接受该第三方的服务条款和隐私政策的约束。<br/>
+
+    <h3>9.未成年人的信息保护</h3>
+    我们非常重视对未成年人信息的保护。若您是18周岁以下的未成年人,建议您请您的监护人仔细阅读本隐私政策,并在征得您的监护人同意的前提下使用我们的产品或服务或向我们提供信息。<br/>
+
+    <h3>10.附则</h3>
+    10.1《隐私条款》长期有效,自您确认接受之时起,或自您以任何方式使用本服务时(以时间在先者为准)生效。<br/>
+    10.2 本条款与《用户协议》构成不可分割的整体,具有同等法律效力。本条款未约定事项以《用户协议》条款之约定为准。<br/>
+
+</div>
+</body>
+</html>

+ 108 - 0
app/src/main/assets/user_protocol.html

@@ -0,0 +1,108 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+    <style>
+    </style>
+</head>
+
+<body>
+<div>
+    <h2>用户服务协议</h2>
+
+    <h3>重要提示:</h3>
+    在您使用千模APP各项服务前,请您务必仔细阅读并充分理解本协议,特别是其中所涉及的免除或限制千模APP责任的条款、排除或限制用户权利的条款、约定司法管辖条款等,这些条款我们通常会以下划线、黑体加粗等方式提示您注意。
+    如果您对协议中的任何条款持有异议,您也可以选择停止使用千模APP服务,因为,一旦使用千模APP服务,您的行为将被视为对本协议全部内容的认可与完全接受。<br/>
+    <b>如果您未满18周岁,请在监护人陪同下阅读本协议、使用千模APP服务。</b><br/><br/>
+
+    <h3>1.服务与协议</h3>
+    1.1千模APP为包括模特/摄影师、经纪人、商业机构等类型在内的用户提供在线模特/摄影师资源信息发布、形象展示、商业合作与推广等服务,其所有权和运作权均归南京千模信息科技有限公司所有。本协议是您与南京千模信息科技有限公司之间关于使用千模APP相关服务所订立的协议,具有合同效力。<br/>
+    1.2在您签署本协议之后,此文本可能因国家政策、产品以及履行本协议的环境发生变化而进行修改,修改后的协议发布在本网站上,若您对修改后的协议有异议的,请立即停止登录、使用千模APP服务,若您登录或继续使用千模APP服务,视为对修改后的协议予以认可。<br/>
+
+    <h3>2.用户注册</h3>
+    2.1您可以通过千模APP用户账号、第三方网站账号(QQ、微信等)登录千模APP平台,也可以选择作为匿名用户仅享受浏览、信息查阅等部分功能及服务。无论何种方式,您均应遵守平台协议及各项业务规则等条款的约定。<br/>
+    2.2为了保护您的合法权益以及交易安全,我们建议您进行注册千模APP用户账户。为保障用户合法权益及交易安全,千模APP可能会就某些功能、服务的开通,要求您进行实名认证并提供更多的身份资料和信息,以便做进一步的身份认证或资格验证。您必须依千模APP要求提示提供真实、最新、有效及完整的资料。如有变动,您应及时修改资料。<br/>
+    2.3在注册用户前,我们提醒您注意,用户使用千模APP服务时须自行准备如下设备和承担如下开支:<br/>
+    (1)上网设备,包括并不限于手机或者其他上网终端;<br/>
+    (2)上网开支,包括并不限于平台接入费、手机流量费等。<br/>
+
+    <h3>3.名称、密码和账户安全管理</h3>
+    3.1用户有权自行创建、修改艺名及个人资料。艺名的命名及使用应遵守相关法律法规并符合社会道德,不能含有任何侮辱、威胁、淫秽、谩骂等侵害他人合法权益的文字。<br/>
+    3.2用户应妥善保管账户信息,包括账号、密码、验证码等信息,因用户原因导致账户泄露而造成的任何法律后果由用户本人负责。<br/>
+    3.3用户账号仅限于注册用户本人使用,禁止转让、交易、赠予、出租、借用。用户一旦登入系统后所发生的所有活动和事件负责,自行承担一切使用该用户名的言语、行为等而直接或者间接导致的法律责任。<br/>
+
+    <h3>4.信息披露与隐私条款</h3>
+    4.1千模APP尊重和保护用户隐私,并为此专门制定《隐私条款》作为本协议的构成部分,与本协议具有同等法律效力。本协议的规定与《隐私条款》存在差异的以及未明确约定的,以《隐私条款》的内容为准。<br/>
+    4.2同时,千模APP特别提示个人用户注意如下事项:<br/>
+    (1)个人信息披露须知:<br/>
+    当您注册的用户类型需要您提供、披露年龄、身高、国籍、三围、风格、艺能或工作意向等信息时,我们提醒您注意,这些内容将作为平台公开查阅内容展示,在您填写该等资料时请务必确认您同意对外展示该等信息,并应确保所填信息的真实性、准确性。<br/>
+    (2)形象展示内容的许可<br/>
+    用户可通过照片、视频、文字介绍内容等展示个人形象。对于该等形象展示内容,您应承诺并保证其著作权、所有权及其他权益,以及该等内容中的造型、肖像等相关权利均归您所有。您同意将您在任何时间段在本站发表的任何形式的形象展示内容授予千模APP在全球范围内免费、不可撤销的、永久的、可再许可或转让的非独家使用权许可,千模APP有权根据该等许可展示、推广及其他不为我国法律所禁止的方式使用上述内容,同时有权在内容上增加相关水印或标记。当然,这并不意味着您放弃对内容的所有权,您只是授予平台和其他用户使用该等内容的权限。<br/>
+
+    <h3>5.用户守法义务与承诺</h3>
+    5.1 您承诺绝不为任何非法目的或以任何非法方式使用千模APP服务,并承诺遵守中国相关法律、法规及一切使用互联网之国际惯例,遵守所有与千模APP服务有关的网络协议、规则和指南。<br/>
+    5.2 您同意并保证在使用本服务时须遵守国家法律法规的规定,不得利用千模APP平台进行下列行为或为其提供便利、帮助,也不得制作、上传、存储、发布或者传播与下列行为有关的内容:<br/>
+    (1)违反宪法所规定的基本原则的行为;<br/>
+    (2)危害国家安全,泄漏国家秘密,颠覆国家政权,破坏国家统一的行为;<br/>
+    (3)损害国家荣誉和利益的行为;<br/>
+    (4)煽动民族仇恨、民族歧视,破坏民族团结的行为;<br/>
+    (5)破坏国家宗教政策,宣扬邪教和封建迷信的行为;<br/>
+    (6)散布谣言,扰乱社会秩序,破坏社会稳定的行为;<br/>
+    (7)散布淫秽、色情、赌博、暴力、凶杀、恐怖信息或者教唆犯罪的行为;<br/>
+    (8)侮辱、滥用英烈形象,否定英烈事迹,美化粉饰侵略战争的行为;<br/>
+    (9)侮辱或者诽谤他人,侵害他人合法权益的行为;<br/>
+    (10)侵害他人知识产权、商业秘密等合法权利的行为;<br/>
+    (11)虚构事实,隐瞒真相以误导、欺骗他人的行为;<br/>
+    (12)发布、传送、传播广告信息、垃圾信息、垃圾邮件的行为;<br/>
+    (13)其他法律法规禁止的行为。<br/>
+    5.3 用户同意并保证在使用本服务时须遵守本协议及相关业务规则与调控,不得利用本服务从事包括但不限于以下行为,也不得为以下行为提供便利等:<br/>
+    (1)未经千模APP的授权或许可,借用平台名义从事商业活动;<br/>
+    (2)涉嫌洗钱、套现或进行传销活动的行为;<br/>
+    (3)其他违法、违规、违反社会主义道德与价值观的行为。<br/>
+    5.4 若千模APP自行发现或根据相关部门的信息、权利人的投诉等,发现您行为存在违反上述违反相关法律法规或本协议约定的,千模APP有权根据自己的独立判断并随时单方采取以下措施中的一种或多种:<br/>
+    (1)要求您立即更换、修改内容;<br/>
+    (2)直接删除、屏蔽相关内容或断开链接等;<br/>
+    (3)限制、中止或终止您使用千模APP服务,终止合作等;<br/>
+    (4)追究您的法律责任。<br/>
+
+    <h3>6.服务暂停与中断</h3>
+    6.1 鉴于网络服务的特殊性,千模APP在有正当理由的情况下可以随时调整或终止部分或全部的服务。但是,千模APP会尽可能事前通知您,以便您做好相关数据的转移备份以及业务调整等,以保护您的合法权益。<br/>
+    6.2您理解并同意,用户服务及/或用户账户的暂停、中断或终止不代表用户责任的终止,用户仍应对使用千模APP服务期间的行为承担可能的违约或损害赔偿责任,同时千模APP仍可保有用户的相关信息。<br/>
+
+    <h3>7.责任免除</h3>
+    7.1在任何情况下,对于用户使用千模APP服务过程中涉及由第三方提供相关服务的责任由该第三方承担,千模APP不承担该等责任。<br/>
+    7.2其他因用户自身的原因导致的任何损失或责任,由用户自行负责,千模APP不承担责任。<br/>
+    7.3千模APP不对任何用户及/或任何交易提供任何担保或条件,无论是明示、默示或法定的。千模APP不能也不试图对用户发布的信息进行控制,对该等信息,千模APP不承担任何形式的证明、鉴定服务。千模APP不能完全保证平台内容的真实性、充分性、可靠性、准确性、完整性和有效性,并且无需承担任何由此引起的法律责任。用户在做出交易决策前,应全面了解相关交易,根据自身的交易目标、风险承受能力和资产状况等谨慎决策,并自行承担全部风险。<br/>
+
+    <h3>8.知识产权</h3>
+    8.1千模APP平台上所有内容,包括但不限于图片、照片、视频、档案、资料、平台架构、界面安排、网页设计,均由千模APP或其他权利人依法拥有其知识产权,包括但不限于商标权、专利权、著作权、商业秘密等。非经千模APP或其他权利人书面同意,任何人不得擅自使用、修改、复制、公开传播、改变、散布、发行或公开发表千模APP平台程序或内容。<br/>
+    8.2未经千模APP明确书面同意,不得以任何商业目的对千模APP网站或其任何部分进行复制、复印、仿造、出售、转售、访问、或以其他方式加以利用。<br/>
+    8.3千模APP为提供网络服务而使用的任何软件(包括但不限于软件中所含的任何图片、照片、视频、音乐、文字和附加程序、材料等)的一切权利均属于该软件的著作权人,未经该软件的著作权人许可,用户不得对该软件进行反向工程、反向编译或反汇编,或以其他方式发现其原始编码,以及实施任何涉嫌侵害著作权的行为。<br/>
+
+    <h3>9.侵权投诉与处理程序</h3>
+    9.1权利通知的发出<br/>
+    如果您认为千模APP用户在平台上所上载、展示的内容侵犯了您的相关权益,请您向千模APP发出权利通知,千模APP将根据相关法律规定采取措施。为了有效处理您的请求,您的“权利通知”应当包含如下内容:<br/>
+    (1)您的姓名、身份证复印件(正反面)或护照复印件(如果您是自然人)、营业执照复印件(如果您是公司)、通信地址、电话号码/手机号码、传真和电子邮件。<br/>
+    (2)请完整、准确地指明涉嫌侵权内容的名称和登载该内容的页面地址。<br/>
+    (3)请提供构成侵权的初步证明材料,包括对涉嫌侵权内容拥有著作权或依法可以行使信息网络传播权的权属证明。<br/>
+    (4)请您在该权利通知落款处亲笔签名(自然人)、加盖公章(公司)。<br/>
+    (5)请您在权利通知签名、盖章上部,手写如下声明:“投诉人对权利通知的真实性负责。若权利通知的内容不真实,投诉人将承担由此造成的全部法律责任。”<br/>
+    9.2反请求通知<br/>
+    千模APP根据前述请求断开连接或删除内容的,内容发布者如果认为不存在侵权情形,可以向千模APP发出反请求通知,千模APP收到该等请求后,会进行核实、处理,确认属实的,可以恢复相关内容。但千模APP不对该恢复行为及恢复后的相关内容承担法律责任。您的反请求通知应当包含如下内容:<br/>
+    (1)您的姓名、身份证复印件(正反面)或护照复印件(如果您是自然人)、营业执照复印件(如果您是公司)、通信地址、电话号码/手机号码、传真和电子邮件。<br/>
+    (2)请完整、准确地指明要求恢复内容的名称和网页的地址。<br/>
+    (3)请提供不构成侵权的初步证明材料(例如,您对被控侵权的作品享有著作权、肖像权、商标权或其他可以依法行使信息网络传播权的权利证明)。<br/>
+    (4)请您在该权利通知落款处亲笔签名(自然人)、加盖公章(公司)。<br/>
+    (5)请您在反请求通知签名、盖章上部,手写如下声明:“反请求人对反请求通知的真实性负责。若该等通知的内容不真实,反请求人将承担由此造成的全部法律责任。”<br/>
+    9.3以上通知请发送至: 1833193888@qq.com   。千模APP有权根据需要,要求您将权利通知、反请求相关文件资料的书面文件邮递至千模APP。<br/>
+    9.4根据《信息网络传播权保护条例》的规定,权利人应当对其权利通知的真实性负责;反请求人应当对其反请求负责。如果您的陈述失实,您将承担对由此造成的全部法律责任(包括但不限于赔偿各种费用及律师费)。<br/>
+
+    <h3>10.法律适用与争议解决</h3>
+    10.1本协议及其修订的有效性、履行与本协议及其修订效力有关的所有事宜,将受中国法律管辖,任何争议仅适用中国法律。<br/>
+    10.2因本协议所引起的用户与千模APP的任何纠纷或争议,首先应友好协商解决,协商不成的,用户在此完全同意将纠纷或争议提交南京千模信息科技有限公司住所地有管辖权的人民法院诉讼解决。<br/>
+
+
+</div>
+</body>
+</html>

+ 302 - 0
app/src/main/java/com/android/chmo/app/ChmoApplication.java

@@ -0,0 +1,302 @@
+package com.android.chmo.app;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Environment;
+import android.text.TextUtils;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseApplication;
+import com.android.chmo.im.SessionHelper;
+import com.android.chmo.im.location.ChmoLocationProvider;
+import com.android.chmo.mixpush.ChmoMixPushMessageHandler;
+import com.android.chmo.model.LoginUser;
+import com.android.chmo.ui.activity.WelcomeActivity;
+import com.android.chmo.utils.LoginUtils;
+import com.android.chmo.utils.NotifyUtils;
+import com.android.chmo.utils.PixelUtils;
+import com.android.chmo.utils.crash.AppCrashHandler;
+import com.netease.nim.avchatkit.AVChatKit;
+import com.netease.nim.avchatkit.config.AVChatOptions;
+import com.netease.nim.avchatkit.model.ITeamDataProvider;
+import com.netease.nim.avchatkit.model.IUserInfoProvider;
+import com.netease.nim.uikit.api.NimUIKit;
+import com.netease.nim.uikit.api.UIKitOptions;
+import com.netease.nim.uikit.business.team.helper.TeamHelper;
+import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
+import com.netease.nimlib.sdk.NIMClient;
+import com.netease.nimlib.sdk.Observer;
+import com.netease.nimlib.sdk.SDKOptions;
+import com.netease.nimlib.sdk.StatusBarNotificationConfig;
+import com.netease.nimlib.sdk.auth.LoginInfo;
+import com.netease.nimlib.sdk.mixpush.MixPushConfig;
+import com.netease.nimlib.sdk.mixpush.NIMPushClient;
+import com.netease.nimlib.sdk.msg.MsgServiceObserve;
+import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
+import com.netease.nimlib.sdk.msg.model.CustomNotification;
+import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
+import com.netease.nimlib.sdk.uinfo.model.UserInfo;
+import com.netease.nimlib.sdk.util.NIMUtil;
+
+import java.io.IOException;
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public class ChmoApplication extends BaseApplication {
+    private static ChmoApplication app;
+    private LoginUser loginUser;
+    private String code; // 验证码
+    public static boolean isInit;
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        app = this;
+
+        SpManager.getInstance().init(getApplicationContext());
+
+        AppCrashHandler.getInstance(this);
+
+        // SDK初始化(启动后台服务,若已经存在用户登录信息, SDK 将完成自动登录)
+        NIMClient.init(this, imLoginInfo(), options());
+
+        if (NIMUtil.isMainProcess(this)) {
+
+            NIMPushClient.registerMixPushMessageHandler(new ChmoMixPushMessageHandler());
+
+            initUIKit();
+            // 初始化消息提醒
+            NIMClient.toggleNotification(true);
+            // 初始化音视频模块
+            initAVChatKit();
+        }
+    }
+
+    public static ChmoApplication getApp() {
+        return app;
+    }
+
+    public void setLoginUser(LoginUser user) {
+        loginUser = user;
+    }
+
+    public LoginUser getLoginUser() {
+        if(null == loginUser) {
+            loginUser = LoginUtils.getLoginUser();
+        }
+        return  loginUser;
+    }
+
+    public void  setCode(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return this.code;
+    }
+
+
+    private SDKOptions options() {
+        SDKOptions options = new SDKOptions();
+
+        // 如果将新消息通知提醒托管给 SDK 完成,需要添加以下配置。否则无需设置。
+        StatusBarNotificationConfig config = new StatusBarNotificationConfig();
+        config.notificationEntrance = WelcomeActivity.class; // 点击通知栏跳转到该Activity
+        config.notificationSmallIconId = R.mipmap.ic_launcher;
+        config.showBadge = true;
+        // 呼吸灯配置
+        config.ledARGB = Color.GREEN;
+        config.ledOnMs = 1000;
+        config.ledOffMs = 1500;
+        // 通知铃声的uri字符串
+        config.notificationSound = "android.resource://com.netease.nim.demo/raw/msg";
+        options.statusBarNotificationConfig = config;
+
+        // 配置保存图片,文件,log 等数据的目录
+        // 如果 options 中没有设置这个值,SDK 会使用采用默认路径作为 SDK 的数据目录。
+        // 该目录目前包含 log, file, image, audio, video, thumb 这6个目录。
+        String sdkPath = getAppCacheDir(getApplicationContext()) + "/nim"; // 可以不设置,那么将采用默认路径
+        // 如果第三方 APP 需要缓存清理功能, 清理这个目录下面个子目录的内容即可。
+        options.sdkStorageRootPath = sdkPath;
+
+        // 配置是否需要预下载附件缩略图,默认为 true
+        options.preloadAttach = true;
+
+        // 配置附件缩略图的尺寸大小。表示向服务器请求缩略图文件的大小
+        // 该值一般应根据屏幕尺寸来确定, 默认值为 Screen.width / 2
+        options.thumbnailSize = PixelUtils.getWindowWidth() / 2;
+
+        // 用户资料提供者, 目前主要用于提供用户资料,用于新消息通知栏中显示消息来源的头像和昵称
+        options.userInfoProvider = new UserInfoProvider() {
+            @Override
+            public UserInfo getUserInfo(String account) {
+                return NimUIKit.getUserInfoProvider().getUserInfo(account);
+            }
+            @Override
+            public String getDisplayNameForMessageNotifier(String account, String sessionId,
+                                                           SessionTypeEnum sessionType) {
+                return UserInfoHelper.getUserDisplayName(account);
+            }
+
+            @Override
+            public Bitmap getAvatarForMessageNotifier(SessionTypeEnum sessionType, String sessionId) {
+                Bitmap bm = null;
+                int defResId = R.drawable.nim_avatar_default;
+                if (SessionTypeEnum.P2P == sessionType) {
+                    UserInfo user = NimUIKit.getUserInfoProvider().getUserInfo(sessionId);
+                    bm = (user != null) ? NimUIKit.getImageLoaderKit().getNotificationBitmapFromCache(user.getAvatar()) : null;
+                }
+                if (bm == null) {
+                    Drawable drawable = getResources().getDrawable(defResId);
+                    if (drawable instanceof BitmapDrawable) {
+                        bm = ((BitmapDrawable) drawable).getBitmap();
+                    }
+                }
+                return bm;
+            }
+        };
+
+        options.mixPushConfig = buildMixPushConfig();
+        return options;
+    }
+
+    // 如果已经存在用户登录信息,返回LoginInfo,否则返回null即可
+    public LoginInfo imLoginInfo() {
+        loginUser = LoginUtils.getLoginUser();
+        if(loginUser == null) {
+            return null;
+        }
+        LoginInfo info = new LoginInfo(loginUser.pk, loginUser.token);
+        return info;
+    }
+
+    /**
+     * 配置 APP 保存图片/语音/文件/log等数据的目录
+     * 这里示例用SD卡的应用扩展存储目录
+     */
+    public static String getAppCacheDir(Context context) {
+        String storageRootPath = null;
+        try {
+            // SD卡应用扩展存储区(APP卸载后,该目录下被清除,用户也可以在设置界面中手动清除),请根据APP对数据缓存的重要性及生命周期来决定是否采用此缓存目录.
+            // 该存储区在API 19以上不需要写权限,即可配置 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
+            if (context.getExternalCacheDir() != null) {
+                storageRootPath = context.getExternalCacheDir().getCanonicalPath();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (TextUtils.isEmpty(storageRootPath)) {
+            // SD卡应用公共存储区(APP卸载后,该目录不会被清除,下载安装APP后,缓存数据依然可以被加载。SDK默认使用此目录),该存储区域需要写权限!
+            storageRootPath = Environment.getExternalStorageDirectory() + "/" + context.getPackageName();
+        }
+
+        return storageRootPath;
+    }
+
+
+    private void initUIKit() {
+        // 初始化
+        NimUIKit.init(this, buildUIKitOptions());
+        LoginInfo info = imLoginInfo();
+        if(null != info) {
+            NimUIKit.setAccount(info.getAccount());
+        }
+
+        // 设置地理位置提供者。如果需要发送地理位置消息,该参数必须提供。如果不需要,可以忽略。
+        NimUIKit.setLocationProvider(new ChmoLocationProvider());
+//        // IM 会话窗口的定制初始化。
+        SessionHelper.init();
+
+        NIMClient.getService(MsgServiceObserve.class).observeCustomNotification(new Observer<CustomNotification>() {
+            @Override
+            public void onEvent(CustomNotification message) {
+                String content = message.getContent();
+                if (content.contains("完成")) {
+                    new NotifyUtils(getApplicationContext()).showOrderNotification("订单已完成","订单已完成",message.getContent(),message.hashCode());
+                }else {
+                    new NotifyUtils(getApplicationContext()).showOrderNotification("模特已接单","模特已接单",message.getContent(),message.hashCode());
+                }
+            }
+        }, true);
+    }
+
+    private UIKitOptions buildUIKitOptions() {
+        UIKitOptions options = new UIKitOptions();
+        // 设置app图片/音频/日志等缓存目录
+        options.appCacheDir = getAppCacheDir(this) + "/app";
+        return options;
+    }
+
+    private void initAVChatKit() {
+        AVChatOptions avChatOptions = new AVChatOptions(){
+            @Override
+            public void logout(Context context) {
+                //被踢出
+            }
+        };
+        avChatOptions.entranceActivity = WelcomeActivity.class;
+        avChatOptions.notificationIconRes = R.mipmap.ic_launcher;
+        AVChatKit.init(avChatOptions);
+        AVChatKit.setContext(getApplicationContext());
+        LoginInfo info = imLoginInfo();
+        if (null != info) {
+            AVChatKit.setAccount(info.getAccount());
+        }
+
+        // 初始化日志系统
+//        LogHelper.init();
+        // 设置用户相关资料提供者
+        AVChatKit.setUserInfoProvider(new IUserInfoProvider() {
+            @Override
+            public UserInfo getUserInfo(String account) {
+                return NimUIKit.getUserInfoProvider().getUserInfo(account);
+            }
+
+            @Override
+            public String getUserDisplayName(String account) {
+                return UserInfoHelper.getUserDisplayName(account);
+            }
+        });
+
+        // 设置群组数据提供者
+        AVChatKit.setTeamDataProvider(new ITeamDataProvider() {
+            @Override
+            public String getDisplayNameWithoutMe(String teamId, String account) {
+                return TeamHelper.getDisplayNameWithoutMe(teamId, account);
+            }
+
+            @Override
+            public String getTeamMemberDisplayName(String teamId, String account) {
+                return TeamHelper.getTeamMemberDisplayName(teamId, account);
+            }
+        });
+
+    }
+
+
+    private static MixPushConfig buildMixPushConfig() {
+
+        // 第三方推送配置
+        MixPushConfig config = new MixPushConfig();
+
+        // 小米推送
+        config.xmAppId = "2882303761517852623";
+        config.xmAppKey = "5401785275623";
+        config.xmCertificateName = "MIPUSH";
+
+        // 华为推送
+        config.hwCertificateName = "HUAWEIPUSH";
+
+        // 魅族推送
+        config.mzAppId = "1001752";
+        config.mzAppKey = "8082e4724ca34784a1f28e04b770661a";
+        config.mzCertificateName = "MEZUPUSH";
+
+
+        return config;
+    }
+}

+ 58 - 0
app/src/main/java/com/android/chmo/app/SpManager.java

@@ -0,0 +1,58 @@
+package com.android.chmo.app;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/**
+ * Created by Administrator on 2018/7/31.
+ */
+
+public class SpManager {
+    private static SpManager spManager;
+    private SharedPreferences mSp;
+
+    private SpManager(){
+    }
+
+    public static SpManager getInstance(){
+        if(spManager == null) {
+            spManager = new SpManager();
+        }
+        return  spManager;
+    }
+    public void init(Context context) {
+        mSp = context.getSharedPreferences("'APP_CONFIG'",Context.MODE_PRIVATE);
+    }
+
+    public void setBoolean(String key, boolean value) {
+        mSp.edit().putBoolean(key, value).commit();
+    }
+
+    public boolean getBoolean(String key) {
+       return mSp.getBoolean(key,false);
+    }
+
+    public void setString(String key, String value) {
+        mSp.edit().putString(key, value).commit();
+    }
+
+    public String getString(String key) {
+        return mSp.getString(key,null);
+    }
+
+    public void setInt(String key, int value) {
+        mSp.edit().putInt(key, value).commit();
+    }
+
+    public int getInt(String key) {
+        return mSp.getInt(key,0);
+    }
+
+    public void setLong(String key, long value) {
+        mSp.edit().putLong(key, value).commit();
+    }
+
+    public long getLong(String key) {
+        return mSp.getLong(key,0);
+    }
+}

+ 262 - 0
app/src/main/java/com/android/chmo/app/VChatManager.java

@@ -0,0 +1,262 @@
+package com.android.chmo.app;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.VChatRes;
+import com.android.chmo.http.response.VideoPriceRes;
+import com.android.chmo.http.service.ModelService;
+import com.android.chmo.http.service.OrderService;
+import com.android.chmo.model.LoginUser;
+import com.android.chmo.ui.activity.me.RechargeActivity;
+import com.android.chmo.ui.dialog.ConfirmDialog;
+import com.android.chmo.utils.LoginUtils;
+import com.google.gson.Gson;
+import com.netease.nim.avchatkit.AVChatKit;
+import com.netease.nim.avchatkit.activity.AVChatActivity;
+import com.netease.nim.avchatkit.common.activity.ActivityManager;
+import com.netease.nimlib.sdk.avchat.constant.AVChatType;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Created by Administrator on 2018/8/9.
+ */
+
+public class VChatManager {
+
+    private static VChatManager vcManager;
+
+    private String videoPk;
+
+    private long beginTime;
+    private long endTime;
+
+    private int duration;
+
+    private Timer timer;
+
+    private float vPrice = 10;
+
+
+    private VChatManager(){
+    }
+
+    public static VChatManager getInstance(){
+        if(vcManager == null) {
+            vcManager = new VChatManager();
+        }
+        return  vcManager;
+    }
+
+
+    public void showPromptDialog(final Context activity,final float vPrice, final VChatCallback callback) {
+        this.vPrice = vPrice;
+
+        if(!checkBalance(vPrice)) {
+            showBalanceOutDialog(activity);
+            return;
+        }
+
+        String timeMsg = "您的余额只够通话"+ getLimitVideoTime(vPrice)+"分钟,请尽快充值吧";
+        new ConfirmDialog(activity)
+                .setOutTouchDismiss(false)
+                .setMsg("视频通话将产生费用\n\n" + timeMsg)
+                .setDialogListener(new ConfirmDialog.DialogListener() {
+                    @Override
+                    public void onOk(Dialog dialog) {
+                        dialog.dismiss();
+                        callback.startVChat();
+                    }
+
+                    @Override
+                    public void onCancel(Dialog dialog) {
+                        dialog.dismiss();
+                        handUpVChat();
+                    }
+                }).show();
+    }
+
+
+
+    public void showBalanceOutDialog(final Context activity) {
+        new ConfirmDialog(activity)
+                .setOutTouchDismiss(false)
+                .setMsg("您的余额不足,请先充值")
+                .setButton("去充值","取消")
+                .setDialogListener(new ConfirmDialog.DialogListener() {
+                    @Override
+                    public void onOk(Dialog dialog) {
+                        handUpVChat();
+                        dialog.dismiss();
+                        Intent intent = new Intent(activity, RechargeActivity.class);
+                        activity.startActivity(intent);
+                    }
+
+                    @Override
+                    public void onCancel(Dialog dialog) {
+                        dialog.dismiss();
+                        handUpVChat();
+                    }
+                }).show();
+    }
+
+
+
+    public static void call(final String account, final String name, final int type) {
+        final Activity activity = ActivityManager.getInstance().currentActivity();
+        ModelService.getModelVideoPrice(account, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                final VideoPriceRes res = new Gson().fromJson(result,VideoPriceRes.class);
+                if(res.msg.equals("success")) {
+                    VChatManager.getInstance().showPromptDialog(activity, res.vprice, new VChatManager.VChatCallback(){
+                        @Override
+                        public void startVChat() {
+                            AVChatActivity.outgoingCall(AVChatKit.getContext(), account, name, type, AVChatActivity.FROM_INTERNAL);
+                        }
+                    });
+                }else {
+                    Toast.makeText(activity, "请求失败,请重试",Toast.LENGTH_SHORT).show();
+                }
+            }
+            @Override
+            public void onFailure(String error) {
+                Toast.makeText(activity, "请求失败,请重试",Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+
+    public void startVChat(final BaseActivity activity, final String account, final String name, float vprice) {
+        showPromptDialog(activity, vprice, new VChatCallback() {
+            @Override
+            public void startVChat() {
+                AVChatKit.outgoingCall(activity, account, name, AVChatType.VIDEO.getValue(), AVChatActivity.FROM_INTERNAL);
+            }
+        });
+    }
+
+    public void requestBegin(String modelPk) {
+        beginTime = System.currentTimeMillis();
+        OrderService.beginVChat(modelPk, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                Log.d("VChat", "requestBegin===================" + result);
+                VChatRes res = new Gson().fromJson(result, VChatRes.class);
+                if(res.msg.equals("success")) {
+                    videoPk = res.videopk;
+                    startTimer();
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+            }
+        });
+    }
+
+    public void requestEnd() {
+        endTimer();
+        endTime = System.currentTimeMillis();
+        double durTime = endTime/1000 - beginTime/1000;
+        if(durTime < 60) {
+            duration = 1;
+        }else {
+            duration =(int) Math.ceil(durTime / 60);
+        }
+
+        check();
+    }
+
+    private void check() {
+        OrderService.checkVChat(videoPk, duration, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                Log.d("VChat", "check ================" + result);
+                final VChatRes res = new Gson().fromJson(result, VChatRes.class);
+                if(res.msg.equals("success")) {
+                    reset();
+                    new Handler().postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            String msg = "视频总花费:" + res.coin + "元 ,当前余额:" +  res.coinfee + "元";
+                            Toast.makeText(ActivityManager.getInstance().currentActivity(), msg, Toast.LENGTH_SHORT).show();
+                            LoginUtils.refreshUser();
+                        }
+                    }, 1000);
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+
+            }
+        });
+    }
+
+
+    public void handUpVChat(){
+        ChmoApplication.getApp().sendBroadcast(new Intent("android.chmo.action.STOP"));
+    }
+
+    public void startTimer() {
+        if(null != timer) {
+            timer.cancel();
+            timer = null;
+        }
+        int times =  getLimitVideoTime(this.vPrice) * 60 * 1000;
+        timer = new Timer();
+        timer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                handUpVChat();
+            }
+        }, times);
+    }
+
+    public void endTimer() {
+        if(null != timer) {
+            timer.cancel();
+            timer = null;
+        }
+    }
+
+    private void reset() {
+        videoPk = null;
+        beginTime = 0;
+        endTime = 0;
+        duration = 0;
+        vPrice = 10;
+    }
+
+
+    private static boolean checkBalance(float vprice) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        float balance = Float.parseFloat(user.coin_a);
+        if(balance < vprice) { // 余额小于 1分钟10块钱
+            return false;
+        }
+        return true;
+    }
+
+    private static int getLimitVideoTime(float vprice) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        float balance = Float.parseFloat(user.coin_a);
+        float  time = balance / vprice;
+        return Math.round(time);
+    }
+
+
+    public interface VChatCallback {
+        void startVChat();
+    }
+}

+ 136 - 0
app/src/main/java/com/android/chmo/base/BaseActivity.java

@@ -0,0 +1,136 @@
+package com.android.chmo.base;
+
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.util.DisplayMetrics;
+import android.widget.Toast;
+
+import com.android.chmo.R;
+import com.android.chmo.ui.dialog.LoadingDialog;
+import com.netease.nim.avchatkit.common.activity.ActivityManager;
+import com.netease.nim.uikit.common.util.StatusBarUtil;
+
+import butterknife.ButterKnife;
+
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public abstract class BaseActivity extends AppCompatActivity {
+    private Toast toast;
+    private LoadingDialog loadingDialog;
+
+
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(getContentResId());
+        ActivityManager.getInstance().pushActivity(this);
+        StatusBarUtil.setStatusBarDrakText(this);
+        ButterKnife.bind(this);
+        initView();
+
+    }
+
+    /**
+     * 布局资源文件
+     */
+    protected abstract int getContentResId();
+
+    /**
+     * 初始化控件
+     */
+    public abstract void initView();
+
+    public Context getContext() {
+        return this;
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        overridePendingTransition(R.anim.push_left_in, R.anim.push_right_out);
+        ActivityManager.getInstance().popActivity(this);
+    }
+
+    public void openPage(Class clazz) {
+        openPage(new Intent(this, clazz));
+    }
+
+    public void openPage(Intent intent) {
+        startActivity(intent);
+        overridePendingTransition(R.anim.push_right_in, R.anim.push_left_out);
+    }
+
+    public void openPageForResult(Intent intent, int requestCode) {
+        startActivityForResult(intent, requestCode);
+        overridePendingTransition(R.anim.push_right_in, R.anim.push_left_out);
+    }
+
+    public void close() {
+        finish();
+    }
+
+
+    public void showToast(String msg) {
+        if (!isFinishing()) {
+            if (toast == null) {
+                toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
+            } else {
+                toast.setText(msg);
+            }
+
+            toast.show();
+        }
+    }
+
+    public void showToast(int res) {
+        showToast(getString(res));
+    }
+
+    public void showLoading() {
+        this.showLoading(null);
+    }
+
+    public void showLoading(String loading) {
+        if(loadingDialog == null) {
+            loadingDialog = new LoadingDialog(this);
+        }
+        loadingDialog.setLoading(loading);
+        if(!loadingDialog.isShowing()) {
+            loadingDialog.show();
+        }
+    }
+    public void hideLoading() {
+        if(loadingDialog != null && loadingDialog.isShowing()) {
+            loadingDialog.dismiss();
+        }
+    }
+
+    @Override
+    public Resources getResources() {
+        Resources resources = super.getResources();
+        Configuration newConfig = resources.getConfiguration();
+        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+        if (resources != null && newConfig.fontScale != 1) {
+            newConfig.fontScale = 1;
+            if (Build.VERSION.SDK_INT >= 17) {
+                Context configurationContext = createConfigurationContext(newConfig);
+                resources = configurationContext.getResources();
+                displayMetrics.scaledDensity = displayMetrics.density * newConfig.fontScale;
+            } else {
+//                resources.updateConfiguration(newConfig, displayMetrics);
+            }
+        }
+        return resources;
+    }
+}

+ 36 - 0
app/src/main/java/com/android/chmo/base/BaseApplication.java

@@ -0,0 +1,36 @@
+package com.android.chmo.base;
+
+import android.app.Application;
+import android.content.Context;
+import android.support.multidex.MultiDex;
+
+import org.xutils.x;
+
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public class BaseApplication extends Application {
+    private static BaseApplication mInstance;
+
+    public static Context getInstance() {
+        return mInstance;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mInstance = this;
+        x.Ext.init(this);
+        // 是否输出debug日志
+        x.Ext.setDebug(true);
+    }
+
+    @Override
+    protected void attachBaseContext(Context base) {
+        super.attachBaseContext(base);
+        MultiDex.install(this);
+    }
+
+}

+ 152 - 0
app/src/main/java/com/android/chmo/base/BaseFragment.java

@@ -0,0 +1,152 @@
+package com.android.chmo.base;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.chmo.R;
+
+import butterknife.ButterKnife;
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public abstract class BaseFragment extends Fragment {
+    private View mLayoutView;
+    public boolean isVisible;
+
+    /**
+     * 初始化布局
+     */
+    public abstract int getLayoutRes();
+
+    /**
+     * 初始化视图
+     */
+    public abstract void initView();
+
+    @Override
+    public Context getContext() {
+        return getBaseActivity().getContext();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        if (mLayoutView != null) {
+            ViewGroup parent = (ViewGroup) mLayoutView.getParent();
+            if (parent != null) {
+                parent.removeView(mLayoutView);
+            }
+        } else {
+            mLayoutView = getCreateView(inflater, container);
+            ButterKnife.bind(this, mLayoutView);
+            initView();     //初始化布局
+        }
+
+        return mLayoutView;
+    }
+
+
+
+    @Override
+    public void setUserVisibleHint(boolean isVisibleToUser) {
+        super.setUserVisibleHint(isVisibleToUser);
+        isVisible = isVisibleToUser;
+        if (isVisibleToUser) {
+            onVisible();
+        } else {
+            onInvisible();
+            System.gc();
+            System.runFinalization();
+        }
+    }
+
+    public void onVisible() {
+
+    }
+
+    public void  onInvisible(){
+
+    }
+
+    /**
+     * 获取Fragment布局文件的View
+     *
+     * @param inflater
+     * @param container
+     * @return
+     */
+    private View getCreateView(LayoutInflater inflater, ViewGroup container) {
+        return inflater.inflate(getLayoutRes(), container, false);
+    }
+
+    /**
+     * 获取当前Fragment状态
+     *
+     * @return true为正常 false为未加载或正在删除
+     */
+    private boolean getStatus() {
+        return (isAdded() && !isRemoving());
+    }
+
+    /**
+     * 获取Activity
+     *
+     * @return
+     */
+    public BaseActivity getBaseActivity() {
+        return (BaseActivity) getActivity();
+    }
+
+
+    public void showToast(String msg) {
+        if (getStatus()) {
+            getBaseActivity().showToast(msg);
+        }
+    }
+
+    public void showToast(int res) {
+        showToast(getString(res));
+    }
+
+    public void showLoading() {
+        getBaseActivity().showLoading();
+    }
+
+    public void showLoading(String msg) {
+        getBaseActivity().showLoading(msg);
+    }
+
+    public void hideLoading() {
+        getBaseActivity().hideLoading();
+    }
+
+
+    public void openPage(Class clazz) {
+        getBaseActivity().openPage(clazz);
+    }
+
+    public void openPage(Intent intent) {
+        getBaseActivity().openPage(intent);
+    }
+
+    public void openPageForResult(Intent intent, int requestCode) {
+        startActivityForResult(intent, requestCode);
+        getBaseActivity().overridePendingTransition(R.anim.push_right_in, R.anim.push_left_out);
+    }
+
+    public void close() {
+        getBaseActivity().close();
+    }
+
+}

+ 9 - 0
app/src/main/java/com/android/chmo/constant/Constants.java

@@ -0,0 +1,9 @@
+package com.android.chmo.constant;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class Constants {
+    public static final int PAGE_SIZE = 10;
+}

+ 37 - 0
app/src/main/java/com/android/chmo/db/CommDbHelper.java

@@ -0,0 +1,37 @@
+package com.android.chmo.db;
+
+
+import org.xutils.DbManager;
+
+/**
+ * Created by Administrator on 2016/9/21.
+ */
+public class CommDbHelper extends DBHelper {
+    private static CommDbHelper helper;
+
+    private CommDbHelper(){
+        super();
+    }
+
+    public synchronized static CommDbHelper get() {
+        if (null == helper) {
+            helper = new CommDbHelper();
+        }
+        return helper;
+    }
+
+    @Override
+    protected String getDbName() {
+        return "chmo.db";
+    }
+
+    @Override
+    protected int getDbVersion() {
+        return 1;
+    }
+
+    @Override
+    protected void onDbUpgrade(DbManager db, int oldVersion, int newVersion) {
+
+    }
+}

+ 79 - 0
app/src/main/java/com/android/chmo/db/DBHelper.java

@@ -0,0 +1,79 @@
+package com.android.chmo.db;
+
+import org.xutils.DbManager;
+import org.xutils.db.sqlite.WhereBuilder;
+import org.xutils.ex.DbException;
+import org.xutils.x;
+
+/**
+ * 数据库基类
+ */
+public abstract class DBHelper {
+    private DbManager db;
+
+    public DBHelper() {
+        DbManager.DaoConfig config = new DbManager.DaoConfig()
+                .setDbName(getDbName())
+                .setDbVersion(getDbVersion())
+                .setAllowTransaction(true)
+                .setDbOpenListener(new DbManager.DbOpenListener() {
+                    @Override
+                    public void onDbOpened(DbManager db) {
+                        // 开启WAL, 对写入加速提升巨大
+                        db.getDatabase().enableWriteAheadLogging();
+                    }
+                })
+                .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
+                    @Override
+                    public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
+                        onDbUpgrade(db, oldVersion, newVersion);
+                    }
+                });
+        db = x.getDb(config);
+    }
+
+    public DbManager getDbManager() {
+        return db;
+    }
+
+
+    protected abstract String getDbName();
+
+    protected abstract int getDbVersion();
+
+    protected abstract void onDbUpgrade(DbManager db, int oldVersion, int newVersion);
+
+    public void save(Object obj) {
+        try {
+            db.save(obj);
+        } catch (DbException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void saveOrUpdate(Object obj) {
+        try {
+            db.saveOrUpdate(obj);
+        } catch (DbException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void delete(Object obj) {
+        try {
+            db.delete(obj);
+        } catch (DbException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void delete(Class<?> obj, WhereBuilder where) {
+        try {
+            db.delete(obj, where);
+        } catch (DbException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}

+ 88 - 0
app/src/main/java/com/android/chmo/http/HttpApi.java

@@ -0,0 +1,88 @@
+package com.android.chmo.http;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.xutils.common.Callback;
+import org.xutils.http.HttpMethod;
+import org.xutils.http.RequestParams;
+import org.xutils.x;
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public class HttpApi {
+    public static final String BASE_URL = "http://118.190.49.85/thmodel/";
+
+//    public static final String BASE_URL = "http://118.190.49.85/thmodeltest/";
+
+
+    public static String getImgUrl(String path) {
+        if(TextUtils.isEmpty(path) || path.startsWith("http://")) {
+            return path;
+        }
+        return  BASE_URL + path;
+    }
+
+
+    public static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(BASE_URL);
+        return params;
+    }
+
+    public static Callback.Cancelable POST(RequestParams params,final RequestCallback callback) {
+        return request(HttpMethod.POST, params,callback);
+    }
+
+
+    public static Callback.Cancelable GET(RequestParams params, RequestCallback callback) {
+        return request(HttpMethod.GET, params,callback);
+    }
+
+
+
+    private static Callback.Cancelable request(HttpMethod method,RequestParams params, final RequestCallback callback) {
+        params.setMaxRetryCount(0);
+        Callback.Cancelable cancelable = x.http().request(method, params, new Callback.CommonCallback<String>() {
+            String result = null;
+            boolean isError = false;
+
+            @Override
+            public void onSuccess(String result) {
+                Log.i("HttpApi", "Success result : " + result);
+                if (null != result){
+                    this.result = result;
+                }
+            }
+
+            @Override
+            public void onError(Throwable ex, boolean isOnCallback) {
+                Log.e("HttpApi", "onError result : " + ex.toString());
+                isError = true;
+                if (null != callback) {
+                    callback.onFailure("请求失败,请稍后重试");
+                }
+            }
+
+            @Override
+            public void onCancelled(CancelledException cex) {
+            }
+
+            @Override
+            public void onFinished() {
+                // 不管成功或者失败最后都会回调该接口
+                if (!isError && this.result != null) {
+                    if (null != callback) {
+                        callback.onSuccess(result);
+                    }
+                }
+            }
+
+        });
+
+        return cancelable;
+    }
+}
+
+

+ 11 - 0
app/src/main/java/com/android/chmo/http/RequestCallback.java

@@ -0,0 +1,11 @@
+package com.android.chmo.http;
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public interface RequestCallback {
+    void onSuccess(String result);
+
+    void onFailure(String error);
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/ActivitiesListRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.ActivitiesInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class ActivitiesListRes extends Res {
+    public List<ActivitiesInfo> data;
+}

+ 11 - 0
app/src/main/java/com/android/chmo/http/response/AlipayRes.java

@@ -0,0 +1,11 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/10.
+ */
+
+public class AlipayRes extends Res {
+    public String data;
+    public String paypk;
+    public String outtradeno;
+}

+ 14 - 0
app/src/main/java/com/android/chmo/http/response/BannerRes.java

@@ -0,0 +1,14 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.BannerInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/16.
+ */
+
+public class BannerRes extends Res {
+    public List<BannerInfo> data;
+
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/BrokerListRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.BrokerInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class BrokerListRes extends Res {
+    public List<BrokerInfo> data;
+}

+ 10 - 0
app/src/main/java/com/android/chmo/http/response/CommentListRes.java

@@ -0,0 +1,10 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.CommentInfo;
+
+import java.util.List;
+
+
+public class CommentListRes extends Res {
+    public List<CommentInfo> data;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/FindListRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.FindInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class FindListRes extends Res {
+    public List<FindInfo> data;
+}

+ 10 - 0
app/src/main/java/com/android/chmo/http/response/LabelListRes.java

@@ -0,0 +1,10 @@
+package com.android.chmo.http.response;
+
+
+import com.android.chmo.model.LabelInfo;
+
+import java.util.List;
+
+public class LabelListRes extends Res {
+    public List<LabelInfo> data;
+}

+ 12 - 0
app/src/main/java/com/android/chmo/http/response/LoginRes.java

@@ -0,0 +1,12 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.UserInfo;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class LoginRes extends Res{
+    public UserInfo data;
+    public String desc;
+}

+ 22 - 0
app/src/main/java/com/android/chmo/http/response/ModelDetailRes.java

@@ -0,0 +1,22 @@
+package com.android.chmo.http.response;
+
+
+import com.android.chmo.model.ModelLabel;
+import com.android.chmo.model.ModelSkill;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class ModelDetailRes extends Res {
+    public List<ModelSkill> dogetprice;
+
+    public List<String> dogethonorname;
+
+    public Modelfigure dogetmodelfigure;
+
+    public class Modelfigure implements Serializable {
+        public List<ModelLabel> selffigure; // 自我评价
+        public List<ModelLabel> customfigure;
+        public List<ModelLabel> customimage;
+    }
+}

+ 11 - 0
app/src/main/java/com/android/chmo/http/response/ModelHonorRes.java

@@ -0,0 +1,11 @@
+package com.android.chmo.http.response;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/3.
+ */
+
+public class ModelHonorRes extends Res {
+    public List<String> data;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/ModelListRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.ModelInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class ModelListRes extends Res {
+    public List<ModelInfo> data;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/ModelSkillRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.ModelSkill;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/3.
+ */
+
+public class ModelSkillRes extends Res {
+    public List<ModelSkill> data;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/OrderListRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.OrderInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/4.
+ */
+
+public class OrderListRes extends Res {
+    public List<OrderInfo> data;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/OrderRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.OrderInfo;
+
+/**
+ * Created by Administrator on 2018/8/4.
+ */
+
+public class OrderRes extends Res {
+    public String orderpk;
+
+    public OrderInfo data;
+}

+ 10 - 0
app/src/main/java/com/android/chmo/http/response/PayOrderRes.java

@@ -0,0 +1,10 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/13.
+ */
+
+public class PayOrderRes extends Res{
+    public String desc;
+    public String orderstate;
+}

+ 9 - 0
app/src/main/java/com/android/chmo/http/response/PayRes.java

@@ -0,0 +1,9 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/10.
+ */
+
+public class PayRes extends Res {
+    public String coin_a;
+}

+ 9 - 0
app/src/main/java/com/android/chmo/http/response/PhotoRes.java

@@ -0,0 +1,9 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/7.
+ */
+
+public class PhotoRes extends Res {
+    public String img;
+}

+ 9 - 0
app/src/main/java/com/android/chmo/http/response/RegisterRes.java

@@ -0,0 +1,9 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class RegisterRes extends Res{
+
+}

+ 10 - 0
app/src/main/java/com/android/chmo/http/response/Res.java

@@ -0,0 +1,10 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by HP on 2018/8/1.
+ */
+
+public class Res {
+    public String msg;
+    public String value;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/VChatRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/9.
+ */
+
+public class VChatRes extends Res {
+    public String videopk;
+
+    public float coinfee; // 余额
+
+    public float coin;
+}

+ 13 - 0
app/src/main/java/com/android/chmo/http/response/VideoOrderRes.java

@@ -0,0 +1,13 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.ui.activity.model.VideoOrderInfo;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/20.
+ */
+
+public class VideoOrderRes extends Res {
+    public List<VideoOrderInfo> data;
+}

+ 10 - 0
app/src/main/java/com/android/chmo/http/response/VideoPriceRes.java

@@ -0,0 +1,10 @@
+package com.android.chmo.http.response;
+
+/**
+ * Created by Administrator on 2018/8/14.
+ */
+
+public class VideoPriceRes extends Res {
+    public String modelpk;
+    public float vprice;
+}

+ 16 - 0
app/src/main/java/com/android/chmo/http/response/ZoneListRes.java

@@ -0,0 +1,16 @@
+package com.android.chmo.http.response;
+
+import com.android.chmo.model.ModelZone;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/6.
+ */
+
+public class ZoneListRes extends Res {
+
+    public List<ModelZone> data;
+
+    public String hphoto;
+}

+ 74 - 0
app/src/main/java/com/android/chmo/http/service/ActivitiesService.java

@@ -0,0 +1,74 @@
+package com.android.chmo.http.service;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.constant.Constants;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.model.ActivitiesInfo;
+import com.android.chmo.model.LoginUser;
+
+import org.xutils.common.Callback;
+import org.xutils.http.RequestParams;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class ActivitiesService {
+
+    private static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "activity");
+        return params;
+    }
+
+    /**
+     *  活动列表
+     */
+    public static Callback.Cancelable getActivityList(int pageNo, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "dogetpartty");
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("index", pageNo+"");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE+"");
+
+        return HttpApi.GET(params, callback);
+    }
+
+    public static  Callback.Cancelable signIn(ActivitiesInfo info, String member, String contact, String count, String price, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doEnroll");
+        params.addQueryStringParameter("PK", ChmoApplication.getApp().getLoginUser().pk);
+        params.addQueryStringParameter("ParttyPK", info.pk);
+        params.addQueryStringParameter("people", member);
+        params.addQueryStringParameter("Tel", contact);
+        params.addQueryStringParameter("pCount", count);
+        params.addQueryStringParameter("Fee", price);
+
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     *  我参加的活动列表
+     */
+    public static Callback.Cancelable getMyActivities(int pageNo, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doqrypartty");
+        params.addQueryStringParameter("PK", user.pk);
+        params.addQueryStringParameter("index", pageNo+"");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE+"");
+        return HttpApi.GET(params, callback);
+    }
+
+
+    /**
+     *  我参加的活动列表
+     */
+    public static Callback.Cancelable getBanner(RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetBanner");
+        return HttpApi.GET(params, callback);
+    }
+}

+ 64 - 0
app/src/main/java/com/android/chmo/http/service/FindService.java

@@ -0,0 +1,64 @@
+package com.android.chmo.http.service;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.constant.Constants;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.model.LoginUser;
+
+import org.xutils.common.Callback;
+import org.xutils.http.RequestParams;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class FindService {
+
+    private static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "modelInfo");
+        return params;
+    }
+
+    /**
+     *  发现列表
+     */
+    public static Callback.Cancelable getFindList(String pk, int pageNo, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "findmodel");
+        params.addQueryStringParameter("MemberPk", pk);
+        params.addQueryStringParameter("index", pageNo+"");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE+"");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static  Callback.Cancelable getCommentList(String pk, int pageNo, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "findmodelprivatelimit");
+        params.addQueryStringParameter("privatePk", pk);
+        params.addQueryStringParameter("index", pageNo+"");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE+"");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static  Callback.Cancelable sendComment(String pk, String content, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doAddPrivateRecord");
+        params.addQueryStringParameter("PrivatePK", pk);
+        params.addQueryStringParameter("PK", user.pk);
+        params.addQueryStringParameter("RecordInfoPK", "0");
+        params.addQueryStringParameter("Intro", content);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static  Callback.Cancelable setGood(String pk,int type, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "likes");
+        params.addQueryStringParameter("privatePk", pk);
+        params.addQueryStringParameter("memberPk", user.pk);
+        params.addQueryStringParameter("type", type+"");
+        return HttpApi.GET(params, callback);
+    }
+}

+ 206 - 0
app/src/main/java/com/android/chmo/http/service/ModelService.java

@@ -0,0 +1,206 @@
+package com.android.chmo.http.service;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.constant.Constants;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.model.LoginUser;
+
+import org.xutils.common.Callback;
+import org.xutils.http.RequestParams;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class ModelService {
+    private static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "modelInfo");
+        return params;
+    }
+
+    /**
+     * 关注列表
+     */
+    public static Callback.Cancelable getFollowList(String pk, int pageNo, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetModelFan");
+        params.addQueryStringParameter("PK", pk);
+        params.addQueryStringParameter("index", pageNo + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 艺人列表
+     */
+    public static Callback.Cancelable getModelList(String search, int pageNo, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "dogetQueryModel");
+        params.addQueryStringParameter("LikeName", search);
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("index", pageNo + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 推荐列表
+     */
+    public static Callback.Cancelable getRecommedList(int pageNo, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "dogetmodel");
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("index", pageNo + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 经纪人列表
+     */
+    public static Callback.Cancelable getBrokerList(int pageNo, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doQryBroke");
+        params.addQueryStringParameter("index", pageNo + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 经纪人下的模特
+     */
+    public static Callback.Cancelable getBrokerModels(String brokerPK, int pageNo, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doQryModel");
+        params.addQueryStringParameter("BrokePK", brokerPK);
+        params.addQueryStringParameter("memberpk", brokerPK);
+        params.addQueryStringParameter("index", pageNo + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+        return HttpApi.GET(params, callback);
+    }
+
+
+    /**
+     * 获取模特信息
+     */
+    public static Callback.Cancelable getModelInfo(String modelPk, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doModelInfoByPk");
+        params.addQueryStringParameter("ModelPK", modelPk);
+        params.addQueryStringParameter("memberpk", user.pk);
+        return HttpApi.GET(params, callback);
+    }
+
+
+    public static Callback.Cancelable getModelDetailInfo(String modelPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "findModelAllInfo");
+        params.addQueryStringParameter("ModelPK", modelPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 获取模特荣誉信息
+     */
+    public static Callback.Cancelable getModelHonor(String modelPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetHonorName");
+        params.addQueryStringParameter("ModelPK", modelPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 获取模特技能信息
+     */
+    public static Callback.Cancelable getModelSkill(String modelPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetPrice");
+        params.addQueryStringParameter("ModelPK", modelPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 获取模特标签
+     */
+    public static Callback.Cancelable getModelLabel(String modelPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetModelFigure");
+        params.addQueryStringParameter("ModelPK", modelPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable getLabels(RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "dogetfigures");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable getAllSkills(RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doqryskillfigure");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable getModelByLabel(String labelPk, int pageNo, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doqryskillmodel");
+        params.addQueryStringParameter("SkillPK", labelPk);
+//        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("index", pageNo + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+        return HttpApi.GET(params, callback);
+    }
+
+
+    public static Callback.Cancelable setFollow(String modelPk, int type, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "attention");
+        params.addQueryStringParameter("memberPk", user.pk);
+        params.addQueryStringParameter("modelPk", modelPk);
+        params.addQueryStringParameter("type", type + "");
+        return HttpApi.GET(params, callback);
+    }
+
+
+    // 获取模特私密空间
+    public static Callback.Cancelable modelZone(String modelPk,int page, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetPrivate");
+        params.addQueryStringParameter("ModelPK", modelPk);
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("index", page + "");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE + "");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable goodModelZone(String pk, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doPraisePrivate");
+        params.addQueryStringParameter("PrivatePK", pk);
+        params.addQueryStringParameter("PK", user.pk);
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 获取模特视频单价
+     */
+    public static Callback.Cancelable getModelVideoPrice(String pk, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetModelVPrice");
+        params.addQueryStringParameter("memberpk", pk);
+        return HttpApi.GET(params, callback);
+    }
+
+
+}

+ 167 - 0
app/src/main/java/com/android/chmo/http/service/OrderService.java

@@ -0,0 +1,167 @@
+package com.android.chmo.http.service;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.constant.Constants;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.model.LoginUser;
+import com.android.chmo.model.ModelOrder;
+import com.android.chmo.utils.DateUtils;
+
+import org.xutils.common.Callback;
+import org.xutils.http.RequestParams;
+
+import java.util.Date;
+
+/**
+ * Created by Administrator on 2018/8/4.
+ */
+
+public class OrderService {
+    private static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "order");
+        return params;
+    }
+
+    /**
+     *  提交订单
+     */
+    public static Callback.Cancelable submitOrder(ModelOrder order,String workName,String contact,String phone,String workAddr,String mark, RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doPutOrder");
+        params.addQueryStringParameter("PK", user.pk);
+        params.addQueryStringParameter("ModelPK", order.model.modelpk);
+        params.addQueryStringParameter("BrokerPK", order.model.brokepk);
+        params.addQueryStringParameter("LederPK", "0");
+        params.addQueryStringParameter("ODate", DateUtils.formatHourDate(order.startTime));
+        params.addQueryStringParameter("SDate", DateUtils.formatHourDate(order.endTime));
+        params.addQueryStringParameter("SCount","" + order.hour);
+        params.addQueryStringParameter("SName",workName);
+        params.addQueryStringParameter("SPrice",order.skill.price);
+        params.addQueryStringParameter("coin",""+ String.valueOf(order.totalPrice));
+        params.addQueryStringParameter("OrderState","0");
+        params.addQueryStringParameter("intro",mark);
+        params.addQueryStringParameter("skillpk",order.skill.skillpk);
+        params.addQueryStringParameter("linkman", contact);
+        params.addQueryStringParameter("linkphone",phone);
+        params.addQueryStringParameter("addr", workAddr);
+        return HttpApi.GET(params, callback);
+    }
+
+
+    public static Callback.Cancelable getOrder(String orderPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetOrderInfo");
+        params.addQueryStringParameter("orderpk", orderPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable payOrder(String orderPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "domemberpayorder");
+        params.addQueryStringParameter("orderpk", orderPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable cancelOrder(String orderPk, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "domembercancelorder");
+        params.addQueryStringParameter("orderpk", orderPk);
+        return HttpApi.GET(params, callback);
+    }
+
+
+    public static Callback.Cancelable getOrderList(String state,int page, RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetOrder");
+        params.addQueryStringParameter("pk", user.pk);
+        params.addQueryStringParameter("state", state);
+        params.addQueryStringParameter("index", page+"");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE+"");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable getVideoOrder(int page, RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "getMemberVideoRecordOrder");
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("index", page+"");
+        params.addQueryStringParameter("size", Constants.PAGE_SIZE+"");
+        return HttpApi.GET(params, callback);
+    }
+
+
+
+    public static Callback.Cancelable beginVChat(String modelPk, RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "dobegvchat");
+        params.addQueryStringParameter("pk", user.pk);
+        params.addQueryStringParameter("modelpk", modelPk);
+        params.addQueryStringParameter("begdate", DateUtils.formatDateTime(new Date()));
+        params.addQueryStringParameter("hasanswer", "1");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable answerVChat(String modelPk, RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doansvchat");
+        params.addQueryStringParameter("videopk", "0");
+        params.addQueryStringParameter("pk", user.pk);
+        params.addQueryStringParameter("modelpk", modelPk);
+        params.addQueryStringParameter("begdate", DateUtils.formatDateTime(new Date()));
+        params.addQueryStringParameter("hasanswer", "1");
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable endVChat(String videoPk, int duration, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doendvchat");
+        params.addQueryStringParameter("videopk", videoPk);
+        params.addQueryStringParameter("duration", ""+duration);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable checkVChat(String videoPk, int duration, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "dovchattest");
+        params.addQueryStringParameter("videopk", videoPk);
+        params.addQueryStringParameter("duration", ""+duration);
+        return HttpApi.GET(params, callback);
+    }
+
+
+    /**
+     * 支付宝提交订单
+     * @return
+     */
+    public static Callback.Cancelable alipay(float money, RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params =  new RequestParams(HttpApi.BASE_URL + "pay");
+        params.addQueryStringParameter("action", "alipay");
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("totalamount", ""+money);
+        params.addQueryStringParameter("timeoutexpress", "3m");
+        params.addQueryStringParameter("body", "账户充值");
+        params.addQueryStringParameter("subject", "充值金额"+money);
+        return HttpApi.GET(params, callback);
+    }
+
+
+    /**
+     * 支付宝成功回调
+     */
+    public static Callback.Cancelable alipayResult(String payPk, String outtradeno, int result,RequestCallback callback) {
+        LoginUser user =  ChmoApplication.getApp().getLoginUser();
+        RequestParams params =  new RequestParams(HttpApi.BASE_URL + "pay");
+        params.addQueryStringParameter("action", "alipaycallback");
+        params.addQueryStringParameter("pk", payPk);
+        params.addQueryStringParameter("outtradeno", outtradeno);
+        params.addQueryStringParameter("result", result == 1 ? "success" : "fail");
+        return HttpApi.GET(params, callback);
+    }
+}

+ 31 - 0
app/src/main/java/com/android/chmo/http/service/PayService.java

@@ -0,0 +1,31 @@
+package com.android.chmo.http.service;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.model.LoginUser;
+
+import org.xutils.common.Callback;
+import org.xutils.http.RequestParams;
+
+/**
+ * Created by Administrator on 2018/8/6.
+ */
+
+public class PayService {
+    private static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "pay");
+        return params;
+    }
+
+    // 发红包
+    public static Callback.Cancelable sendRedPkg(String modelPk,String coin, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "giveRed");
+        params.addQueryStringParameter("ModelPk", modelPk);
+        params.addQueryStringParameter("MemberPk", user.pk);
+        params.addQueryStringParameter("coin", coin);
+        return HttpApi.GET(params, callback);
+    }
+}

+ 119 - 0
app/src/main/java/com/android/chmo/http/service/UserService.java

@@ -0,0 +1,119 @@
+package com.android.chmo.http.service;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.model.LoginUser;
+
+import org.xutils.common.Callback;
+import org.xutils.http.RequestParams;
+
+import java.io.File;
+
+/**
+ * Created by Administrator on 2018/8/1.
+ */
+
+public class UserService {
+    private static RequestParams getRequestParams() {
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "memberInfo");
+        return params;
+    }
+
+
+    public static Callback.Cancelable login(String mobile, String password, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doLogin");
+        params.addBodyParameter("mobile", mobile);
+        params.addBodyParameter("pass", password);
+        return HttpApi.POST(params, callback);
+    }
+
+    public static Callback.Cancelable getCode(String mobile,String codeStr, RequestCallback callback) {
+        RequestParams params = new RequestParams("http://sdk.entinfo.cn:8061/mdsmssend.ashx");
+        params.addQueryStringParameter("sn", "SDK-FHD-010-00328");
+        params.addQueryStringParameter("pwd", "54774CB6E781A142206F756B3E18142C");
+        params.addQueryStringParameter("mobile", mobile);
+        params.addQueryStringParameter("content", codeStr);
+        return HttpApi.GET(params, callback);
+    }
+
+
+    public static Callback.Cancelable register(String pet,String mobile, String password, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doRegister");
+        params.addBodyParameter("mobile", mobile);
+        params.addBodyParameter("pass", password);
+        params.addBodyParameter("pet", pet);
+
+        return HttpApi.GET(params, callback);
+    }
+
+
+    public static Callback.Cancelable getUser(RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        return getUserByPk(user.pk, callback);
+    }
+
+    public static Callback.Cancelable getUserByPk(String pk, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params =getRequestParams();
+        params.addQueryStringParameter("action", "getuserinfo");
+        params.addQueryStringParameter("PK", pk);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable modifyName(String name,RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params =getRequestParams();
+        params.addQueryStringParameter("action", "doPutPet");
+        params.addQueryStringParameter("PK", user.pk);
+        params.addQueryStringParameter("Pet",name);
+        return HttpApi.GET(params, callback);
+    }
+
+    public static Callback.Cancelable updateHead(String path,RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = new RequestParams(HttpApi.BASE_URL + "upload");
+        params.addBodyParameter("action", "hp");
+        params.addBodyParameter("memberpk", user.pk);
+        params.setMultipart(true);
+        params.addBodyParameter("file", new File(path));
+        return HttpApi.POST(params, callback);
+    }
+
+    public static Callback.Cancelable resetPwd(String mobile, String password, RequestCallback callback) {
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doGetPass");
+        params.addBodyParameter("mobile", mobile);
+        params.addBodyParameter("pass", password);
+
+        return HttpApi.GET(params, callback);
+    }
+
+
+    /**
+     * 屏蔽模特
+     */
+    public static Callback.Cancelable shieldModel(String modelPk, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "doDefriendModel");
+        params.addQueryStringParameter("memberpk", user.pk);
+        params.addQueryStringParameter("modelpk", modelPk);
+        return HttpApi.GET(params, callback);
+    }
+
+    /**
+     * 举报模特
+     */
+    public static Callback.Cancelable reportModel(String modelPk, String reason, RequestCallback callback) {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        RequestParams params = getRequestParams();
+        params.addQueryStringParameter("action", "report");
+        params.addQueryStringParameter("accuserpk", user.pk);
+        params.addQueryStringParameter("appelleepk", modelPk);
+        params.addQueryStringParameter("reason", reason);
+        return HttpApi.GET(params, callback);
+    }
+}

+ 10 - 0
app/src/main/java/com/android/chmo/http/service/messageService.java

@@ -0,0 +1,10 @@
+package com.android.chmo.http.service;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class messageService {
+
+
+}

+ 39 - 0
app/src/main/java/com/android/chmo/im/AVChatAction.java

@@ -0,0 +1,39 @@
+package com.android.chmo.im;
+
+import android.widget.Toast;
+
+import com.android.chmo.R;
+import com.android.chmo.app.VChatManager;
+import com.netease.nim.uikit.business.session.actions.BaseAction;
+import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
+import com.netease.nim.uikit.common.util.sys.NetworkUtil;
+import com.netease.nimlib.sdk.avchat.constant.AVChatType;
+
+
+/**
+ * Created by hzxuwen on 2015/6/12.
+ */
+public class AVChatAction extends BaseAction {
+    private AVChatType avChatType;
+
+    public AVChatAction(AVChatType avChatType) {
+        super(avChatType == AVChatType.AUDIO ? R.drawable.message_plus_audio_chat_selector : R.drawable.message_plus_video_chat_selector,
+                avChatType == AVChatType.AUDIO ? R.string.input_panel_audio_call : R.string.input_panel_video_call);
+        this.avChatType = avChatType;
+    }
+
+    @Override
+    public void onClick() {
+        if (NetworkUtil.isNetAvailable(getActivity())) {
+            startAudioVideoCall(avChatType);
+        } else {
+            Toast.makeText(getActivity(), R.string.network_is_not_available, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    /************************ 音视频通话 ***********************/
+
+    public void startAudioVideoCall(final AVChatType avChatType) {
+        VChatManager.call(getAccount(),UserInfoHelper.getUserDisplayName(getAccount()),avChatType.getValue());
+    }
+}

+ 71 - 0
app/src/main/java/com/android/chmo/im/IMManager.java

@@ -0,0 +1,71 @@
+package com.android.chmo.im;
+
+import android.util.Log;
+
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.model.LoginUser;
+import com.netease.nim.avchatkit.AVChatKit;
+import com.netease.nim.uikit.api.NimUIKit;
+import com.netease.nimlib.sdk.NIMClient;
+import com.netease.nimlib.sdk.RequestCallbackWrapper;
+import com.netease.nimlib.sdk.auth.LoginInfo;
+import com.netease.nimlib.sdk.uinfo.UserService;
+import com.netease.nimlib.sdk.uinfo.constant.UserInfoFieldEnum;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Administrator on 2018/8/8.
+ */
+
+public class IMManager {
+    private final static String TAG = "IMManager";
+    public static void login() {
+        LoginInfo info = ChmoApplication.getApp().imLoginInfo();
+        if(info == null){
+            return;
+        }
+        Log.i(TAG, "==================== IMLogin  ===============  "+ info.getAccount() + "   " + info.getToken());
+        NimUIKit.login(info, new com.netease.nimlib.sdk.RequestCallback<LoginInfo>() {
+
+            @Override
+            public void onSuccess(LoginInfo param) {
+                Log.i(TAG, "IMLogin onSuccess ===============  " + param.toString());
+                NimUIKit.loginSuccess(param.getAccount());
+                AVChatKit.setAccount(param.getAccount());
+                updateUser();
+            }
+
+            @Override
+            public void onFailed(int code) {
+                Log.e(TAG, "IMLogin onFailed ===============  " + code);
+            }
+
+            @Override
+            public void onException(Throwable exception) {
+                Log.e(TAG, "IMLogin onException ===============  " + exception.toString());
+            }
+        });
+    }
+
+    public static void updateUser() {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        Map<UserInfoFieldEnum, Object> fields = new HashMap<>(1);
+        fields.put(UserInfoFieldEnum.Name, user.pet);
+        fields.put(UserInfoFieldEnum.AVATAR, HttpApi.getImgUrl(user.hphoto));
+        NIMClient.getService(UserService.class).updateUserInfo(fields)
+                .setCallback(new RequestCallbackWrapper<Void>() {
+                    @Override
+                    public void onResult(int i, Void aVoid, Throwable throwable) {
+                    }
+                });
+    }
+
+
+    public static void logout() {
+        NimUIKit.logout();
+    }
+
+}

+ 208 - 0
app/src/main/java/com/android/chmo/im/SessionHelper.java

@@ -0,0 +1,208 @@
+package com.android.chmo.im;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+
+import com.android.chmo.im.holder.MsgViewHolderAVChat;
+import com.netease.nim.uikit.api.NimUIKit;
+import com.netease.nim.uikit.api.model.recent.RecentCustomization;
+import com.netease.nim.uikit.api.model.session.SessionCustomization;
+import com.netease.nim.uikit.api.wrapper.NimMessageRevokeObserver;
+import com.netease.nim.uikit.business.session.actions.BaseAction;
+import com.netease.nim.uikit.business.session.module.MsgForwardFilter;
+import com.netease.nim.uikit.business.session.module.MsgRevokeFilter;
+import com.netease.nim.uikit.common.util.sys.TimeUtil;
+import com.netease.nim.uikit.impl.customization.DefaultRecentCustomization;
+import com.netease.nimlib.sdk.NIMClient;
+import com.netease.nimlib.sdk.avchat.constant.AVChatRecordState;
+import com.netease.nimlib.sdk.avchat.constant.AVChatType;
+import com.netease.nimlib.sdk.avchat.model.AVChatAttachment;
+import com.netease.nimlib.sdk.msg.MsgService;
+import com.netease.nimlib.sdk.msg.MsgServiceObserve;
+import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
+import com.netease.nimlib.sdk.msg.constant.AttachStatusEnum;
+import com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum;
+import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
+import com.netease.nimlib.sdk.msg.model.IMMessage;
+import com.netease.nimlib.sdk.msg.model.LocalAntiSpamResult;
+import com.netease.nimlib.sdk.msg.model.RecentContact;
+import com.netease.nimlib.sdk.robot.model.RobotAttachment;
+
+import java.util.ArrayList;
+
+/**
+ * Created by Administrator on 2018/8/8.
+ */
+
+public class SessionHelper {
+    private static RecentCustomization recentCustomization;
+    private static SessionCustomization p2pCustomization;
+
+    public static final boolean USE_LOCAL_ANTISPAM = true;
+
+
+    public static void init() {
+        registerViewHolders();
+
+        registerMsgForwardFilter();
+        registerMsgRevokeFilter();
+        registerMsgRevokeObserver();
+
+        NimUIKit.setRecentCustomization(getRecentCustomization());
+        NimUIKit.setCommonP2PSessionCustomization(getP2pCustomization());
+    }
+
+    /**
+     * 消息转发过滤器
+     */
+    private static void registerMsgForwardFilter() {
+        NimUIKit.setMsgForwardFilter(new MsgForwardFilter() {
+            @Override
+            public boolean shouldIgnore(IMMessage message) {
+                if (message.getDirect() == MsgDirectionEnum.In
+                        && (message.getAttachStatus() == AttachStatusEnum.transferring
+                        || message.getAttachStatus() == AttachStatusEnum.fail)) {
+                    // 接收到的消息,附件没有下载成功,不允许转发
+                    return true;
+                } else if (message.getMsgType() == MsgTypeEnum.custom && message.getAttachment() != null) {
+                    // 白板消息和阅后即焚消息,红包消息 不允许转发
+                    return true;
+                } else if (message.getMsgType() == MsgTypeEnum.robot && message.getAttachment() != null && ((RobotAttachment) message.getAttachment()).isRobotSend()) {
+                    return true; // 如果是机器人发送的消息 不支持转发
+                }
+                return false;
+            }
+        });
+    }
+
+    /**
+     * 消息撤回过滤器
+     */
+    private static void registerMsgRevokeFilter() {
+        NimUIKit.setMsgRevokeFilter(new MsgRevokeFilter() {
+            @Override
+            public boolean shouldIgnore(IMMessage message) {
+                if (message.getAttachment() != null
+                        && (message.getAttachment() instanceof AVChatAttachment)) {
+                    // 视频通话消息和白板消息,红包消息 不允许撤回
+                    return true;
+                }
+                return false;
+            }
+        });
+    }
+    private static void registerMsgRevokeObserver() {
+        NIMClient.getService(MsgServiceObserve.class).observeRevokeMessage(new NimMessageRevokeObserver(), true);
+    }
+
+
+    private static RecentCustomization getRecentCustomization() {
+        if (recentCustomization == null) {
+            recentCustomization = new DefaultRecentCustomization() {
+                @Override
+                public String getDefaultDigest(RecentContact recent) {
+                    switch (recent.getMsgType()) {
+                        case avchat:
+                            MsgAttachment attachment = recent.getAttachment();
+                            AVChatAttachment avchat = (AVChatAttachment) attachment;
+                            if (avchat.getState() == AVChatRecordState.Missed && !recent.getFromAccount().equals(NimUIKit.getAccount())) {
+                                // 未接通话请求
+                                StringBuilder sb = new StringBuilder("[未接");
+                                if (avchat.getType() == AVChatType.VIDEO) {
+                                    sb.append("视频电话]");
+                                } else {
+                                    sb.append("音频电话]");
+                                }
+                                return sb.toString();
+                            } else if (avchat.getState() == AVChatRecordState.Success) {
+                                StringBuilder sb = new StringBuilder();
+                                if (avchat.getType() == AVChatType.VIDEO) {
+                                    sb.append("[视频电话]: ");
+                                } else {
+                                    sb.append("[音频电话]: ");
+                                }
+                                sb.append(TimeUtil.secToTime(avchat.getDuration()));
+                                return sb.toString();
+                            } else {
+                                if (avchat.getType() == AVChatType.VIDEO) {
+                                    return ("[视频电话]");
+                                } else {
+                                    return ("[音频电话]");
+                                }
+                            }
+                    }
+                    return super.getDefaultDigest(recent);
+                }
+            };
+        }
+
+        return recentCustomization;
+    }
+
+    // 定制化单聊界面。如果使用默认界面,返回null即可
+    private static SessionCustomization getP2pCustomization() {
+        if (p2pCustomization == null) {
+            p2pCustomization = new SessionCustomization() {
+                // 由于需要Activity Result, 所以重载该函数。
+                @Override
+                public void onActivityResult(final Activity activity, int requestCode, int resultCode, Intent data) {
+                    super.onActivityResult(activity, requestCode, resultCode, data);
+
+                }
+
+                @Override
+                public boolean isAllowSendMessage(IMMessage message) {
+                    return checkLocalAntiSpam(message);
+                }
+
+                @Override
+                public MsgAttachment createStickerAttachment(String category, String item) {
+                    return null;
+//                    return new StickerAttachment(category, item);
+                }
+            };
+
+
+            // 定制加号点开后可以包含的操作, 默认已经有图片,视频等消息了
+            ArrayList<BaseAction> actions = new ArrayList<>();
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+//                actions.add(new AVChatAction(AVChatType.AUDIO));
+                actions.add(new AVChatAction(AVChatType.VIDEO));
+            }
+            p2pCustomization.actions = actions;
+            p2pCustomization.withSticker = true;
+        }
+
+        return p2pCustomization;
+    }
+
+
+    private static boolean checkLocalAntiSpam(IMMessage message) {
+        if (!USE_LOCAL_ANTISPAM) {
+            return true;
+        }
+        LocalAntiSpamResult result = NIMClient.getService(MsgService.class).checkLocalAntiSpam(message.getContent(), "**");
+        int operator = result == null ? 0 : result.getOperator();
+
+        switch (operator) {
+            case 1: // 替换,允许发送
+                message.setContent(result.getContent());
+                return true;
+            case 2: // 拦截,不允许发送
+                return false;
+            case 3: // 允许发送,交给服务器
+                message.setClientAntiSpam(true);
+                return true;
+            case 0:
+            default:
+                break;
+        }
+
+        return true;
+    }
+
+    private static void registerViewHolders() {
+        NimUIKit.registerMsgItemViewHolder(AVChatAttachment.class, MsgViewHolderAVChat.class);
+    }
+}

+ 87 - 0
app/src/main/java/com/android/chmo/im/holder/MsgViewHolderAVChat.java

@@ -0,0 +1,87 @@
+package com.android.chmo.im.holder;
+
+import android.graphics.Color;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderBase;
+import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
+import com.netease.nim.uikit.common.util.sys.TimeUtil;
+import com.netease.nimlib.sdk.avchat.constant.AVChatType;
+import com.netease.nimlib.sdk.avchat.model.AVChatAttachment;
+
+
+/**
+ * Created by zhoujianghua on 2015/8/6.
+ */
+public class MsgViewHolderAVChat extends MsgViewHolderBase {
+
+    private ImageView typeImage;
+    private TextView statusLabel;
+
+    public MsgViewHolderAVChat(BaseMultiItemFetchLoadAdapter adapter) {
+        super(adapter);
+    }
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.nim_message_item_avchat;
+    }
+
+    @Override
+    protected void inflateContentView() {
+        typeImage = findViewById(R.id.message_item_avchat_type_img);
+        statusLabel = findViewById(R.id.message_item_avchat_state);
+    }
+
+    @Override
+    protected void bindContentView() {
+        if (message.getAttachment() == null) {
+            return;
+        }
+
+        layoutByDirection();
+
+        refreshContent();
+    }
+
+    private void layoutByDirection() {
+        AVChatAttachment attachment = (AVChatAttachment) message.getAttachment();
+
+        if (isReceivedMessage()) {
+            if (attachment.getType() == AVChatType.AUDIO) {
+                typeImage.setImageResource(R.drawable.avchat_left_type_audio);
+            } else {
+                typeImage.setImageResource(R.drawable.avchat_left_type_video);
+            }
+            statusLabel.setTextColor(context.getResources().getColor(R.color.color_grey_999999));
+        } else {
+            if (attachment.getType() == AVChatType.AUDIO) {
+                typeImage.setImageResource(R.drawable.avchat_right_type_audio);
+            } else {
+                typeImage.setImageResource(R.drawable.avchat_right_type_video);
+            }
+            statusLabel.setTextColor(Color.WHITE);
+        }
+    }
+
+    private void refreshContent() {
+        AVChatAttachment attachment = (AVChatAttachment) message.getAttachment();
+
+        String textString = "";
+        switch (attachment.getState()) {
+            case Success: //成功接听
+                textString = TimeUtil.secToTime(attachment.getDuration());
+                break;
+            case Missed: //未接听
+            case Rejected: //主动拒绝
+                textString = context.getString(R.string.avchat_no_pick_up);
+                break;
+            default:
+                break;
+        }
+
+        statusLabel.setText(textString);
+    }
+}

+ 103 - 0
app/src/main/java/com/android/chmo/im/location/ChmoLocationManager.java

@@ -0,0 +1,103 @@
+package com.android.chmo.im.location;
+
+import android.content.Context;
+import android.location.Address;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.amap.api.location.AMapLocationClient;
+import com.amap.api.location.AMapLocationClientOption;
+import com.amap.api.location.AMapLocationListener;
+import com.amap.api.services.core.LatLonPoint;
+import com.amap.api.services.geocoder.GeocodeSearch;
+import com.amap.api.services.geocoder.RegeocodeAddress;
+import com.amap.api.services.geocoder.RegeocodeQuery;
+
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/8.
+ */
+
+public class ChmoLocationManager{
+    private final String TAG = "ChmoLocationManager";
+    private Context mContext;
+    private Criteria criteria;
+    private AMapLocationClient client;
+
+    private AMapLocationListener locationListener;
+
+    public ChmoLocationManager(Context context, AMapLocationListener listener) {
+        mContext = context;
+        locationListener = listener;
+    }
+
+    public static boolean isLocationEnable(Context context) {
+        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+        Criteria cri = new Criteria();
+        cri.setAccuracy(Criteria.ACCURACY_COARSE);
+        cri.setAltitudeRequired(false);
+        cri.setBearingRequired(false);
+        cri.setCostAllowed(false);
+        String bestProvider = locationManager.getBestProvider(cri, true);
+        return !TextUtils.isEmpty(bestProvider);
+    }
+
+    public Location getLastKnownLocation() {
+        try {
+            if (criteria == null) {
+                criteria = new Criteria();
+                criteria.setAccuracy(Criteria.ACCURACY_COARSE);
+                criteria.setAltitudeRequired(false);
+                criteria.setBearingRequired(false);
+                criteria.setCostAllowed(false);
+            }
+            return client.getLastKnownLocation();
+        } catch (Exception e) {
+            Log.i(TAG, "get last known location failed: " + e.toString());
+        }
+        return null;
+    }
+
+    public void request() {
+        if (client == null) {
+            AMapLocationClientOption option = new AMapLocationClientOption();
+            option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
+            option.setInterval(30 * 1000);
+            option.setHttpTimeOut(10 * 1000);
+            client = new AMapLocationClient(mContext);
+            client.setLocationOption(option);
+            client.setLocationListener(locationListener);
+            client.startLocation();
+        }
+    }
+
+    public void stop() {
+        if (client != null) {
+            client.unRegisterLocationListener(locationListener);
+            client.stopLocation();
+            client.onDestroy();
+        }
+        client = null;
+    }
+
+    public RegeocodeAddress getLocationAddress(double latitude, double longitude) {
+        List<Address> list;
+        try {
+            GeocodeSearch search = new GeocodeSearch(mContext);
+            LatLonPoint point = new LatLonPoint(latitude, longitude);
+            RegeocodeQuery query = new RegeocodeQuery(point, 100, GeocodeSearch.AMAP);
+                RegeocodeAddress address = search.getFromLocation(query);
+                if (address != null && !TextUtils.isEmpty(address.getFormatAddress())) {
+                  return address;
+                }
+        } catch (Exception e) {
+        }
+
+        return null;
+    }
+
+}

+ 63 - 0
app/src/main/java/com/android/chmo/im/location/ChmoLocationProvider.java

@@ -0,0 +1,63 @@
+package com.android.chmo.im.location;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+
+import com.android.chmo.ui.activity.message.LocationMapActivity;
+import com.netease.nim.uikit.api.model.location.LocationProvider;
+import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialog;
+import com.netease.nim.uikit.common.util.log.LogUtil;
+
+/**
+ * Created by Administrator on 2018/8/8.
+ */
+
+public class ChmoLocationProvider implements LocationProvider {
+
+    @Override
+    public void requestLocation(final Context context, Callback callback) {
+        if (!ChmoLocationManager.isLocationEnable(context)) {
+            final EasyAlertDialog alertDialog = new EasyAlertDialog(context);
+            alertDialog.setMessage("位置服务未开启");
+            alertDialog.addNegativeButton("取消", EasyAlertDialog.NO_TEXT_COLOR, EasyAlertDialog.NO_TEXT_SIZE,
+                    new View.OnClickListener() {
+
+                        @Override
+                        public void onClick(View v) {
+                            alertDialog.dismiss();
+                        }
+                    });
+            alertDialog.addPositiveButton("设置", EasyAlertDialog.NO_TEXT_COLOR, EasyAlertDialog.NO_TEXT_SIZE,
+                    new View.OnClickListener() {
+
+                        @Override
+                        public void onClick(View v) {
+                            alertDialog.dismiss();
+                            Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+                            try {
+                                context.startActivity(intent);
+                            } catch (Exception e) {
+                                LogUtil.e("LOC", "start ACTION_LOCATION_SOURCE_SETTINGS error");
+                            }
+
+                        }
+                    });
+            alertDialog.show();
+            return;
+        }
+
+        LocationMapActivity.start(context, callback);
+    }
+
+    @Override
+    public void openMap(Context context, double longitude, double latitude, String address) {
+        Intent intent = new Intent(context, LocationMapActivity.class);
+        intent.putExtra("longitude", longitude);
+        intent.putExtra("latitude", latitude);
+        intent.putExtra("address",address);
+        context.startActivity(intent);
+    }
+
+
+}

+ 8 - 0
app/src/main/java/com/android/chmo/im/location/LocationInfo.java

@@ -0,0 +1,8 @@
+package com.android.chmo.im.location;
+
+/**
+ * Created by Administrator on 2018/8/8.
+ */
+
+public class LocationInfo {
+}

+ 84 - 0
app/src/main/java/com/android/chmo/mixpush/ChmoMixPushMessageHandler.java

@@ -0,0 +1,84 @@
+package com.android.chmo.mixpush;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.chmo.app.ChmoApplication;
+import com.netease.nim.avchatkit.AVChatKit;
+import com.netease.nim.uikit.common.util.log.LogUtil;
+import com.netease.nimlib.sdk.NimIntent;
+import com.netease.nimlib.sdk.mixpush.MixPushMessageHandler;
+import com.netease.nimlib.sdk.msg.MessageBuilder;
+import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
+import com.netease.nimlib.sdk.msg.model.IMMessage;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * Created by hzchenkang on 2016/11/10.
+ */
+
+public class ChmoMixPushMessageHandler implements MixPushMessageHandler {
+
+
+    public static final String PAYLOAD_SESSION_ID = "sessionID";
+    public static final String PAYLOAD_SESSION_TYPE = "sessionType";
+
+    // 对于华为推送,这个方法并不能保证一定会回调
+    @Override
+    public boolean onNotificationClicked(Context context, Map<String, String> payload) {
+
+        LogUtil.i(ChmoMixPushMessageHandler.class.getSimpleName(), "rev pushMessage payload " + payload);
+        Log.i("--wk--","onNotificationClicked --- " + payload);
+        String sessionId = payload.get(PAYLOAD_SESSION_ID);
+        String type = payload.get(PAYLOAD_SESSION_TYPE);
+        //
+        if (sessionId != null && type != null) {
+            int typeValue = Integer.valueOf(type);
+            ArrayList<IMMessage> imMessages = new ArrayList<>();
+            IMMessage imMessage = MessageBuilder.createEmptyMessage(sessionId, SessionTypeEnum.typeOfValue(typeValue), 0);
+            imMessages.add(imMessage);
+            Intent notifyIntent = new Intent();
+            notifyIntent.setComponent(initLaunchComponent(context));
+            notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+            notifyIntent.setAction(Intent.ACTION_VIEW);
+            notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须
+            notifyIntent.putExtra(NimIntent.EXTRA_NOTIFY_CONTENT, imMessages);
+
+            context.startActivity(notifyIntent);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private ComponentName initLaunchComponent(Context context) {
+        ComponentName launchComponent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent();
+        return launchComponent;
+    }
+
+    // 将音视频通知 Notification 缓存,清除所有通知后再次弹出 Notification,避免清除之后找不到打开正在进行音视频通话界面的入口
+    @Override
+    public boolean cleanMixPushNotifications(int pushType) {
+        Context context = ChmoApplication.getApp().getApplicationContext();
+        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+        if (manager != null) {
+            manager.cancelAll();
+            SparseArray<Notification> nos = AVChatKit.getNotifications();
+            if (nos != null) {
+                int key = 0;
+                for (int i = 0; i < nos.size(); i++) {
+                    key = nos.keyAt(i);
+                    manager.notify(key, nos.get(key));
+                }
+            }
+        }
+        return true;
+    }
+}

+ 44 - 0
app/src/main/java/com/android/chmo/mixpush/ChmoPushContentProvider.java

@@ -0,0 +1,44 @@
+package com.android.chmo.mixpush;
+
+import com.netease.nim.uikit.api.model.main.CustomPushContentProvider;
+import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
+import com.netease.nimlib.sdk.msg.model.IMMessage;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 示例:
+ * 1.自定义的推送文案
+ * 2.自定义推送 payload 实现特定的点击通知栏跳转行为{@link ChmoMixPushMessageHandler}
+ * <p>
+ * 如果自定义文案和payload,请开发者在各端发送消息时保持一致。
+ */
+
+public class ChmoPushContentProvider implements CustomPushContentProvider {
+
+    @Override
+    public String getPushContent(IMMessage message) {
+        return null;
+    }
+
+    @Override
+    public Map<String, Object> getPushPayload(IMMessage message) {
+        return getPayload(message);
+    }
+
+    private Map<String, Object> getPayload(IMMessage message) {
+        if (message == null) {
+            return null;
+        }
+        HashMap<String, Object> payload = new HashMap<>();
+        payload.put("sessionType", message.getSessionType().getValue());
+        if (message.getSessionType() == SessionTypeEnum.Team) {
+            payload.put("sessionID", message.getSessionId());
+        } else if (message.getSessionType() == SessionTypeEnum.P2P) {
+            payload.put("sessionID", message.getFromAccount());
+        }
+
+        return payload;
+    }
+}

+ 27 - 0
app/src/main/java/com/android/chmo/model/ActivitiesInfo.java

@@ -0,0 +1,27 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/1.
+ */
+
+public class ActivitiesInfo implements Serializable {
+    public String caption;
+    public String pic;
+    public String intro;
+    public String pk;
+    public String moprice;
+    public float meprice;
+    public String brprice;
+    public String endt;
+    public String beg;
+    public String term;
+    public String sbeg;
+    public String sendt;
+    public int issign;
+    public int signcount;
+    public int issigndate;
+
+
+}

+ 61 - 0
app/src/main/java/com/android/chmo/model/AliPayResult.java

@@ -0,0 +1,61 @@
+package com.android.chmo.model;
+
+import android.text.TextUtils;
+
+public class AliPayResult {
+    private String resultStatus;
+    private String result;
+    private String memo;
+
+    public AliPayResult(String rawResult) {
+
+        if (TextUtils.isEmpty(rawResult))
+            return;
+
+        String[] resultParams = rawResult.split(";");
+        for (String resultParam : resultParams) {
+            if (resultParam.startsWith("resultStatus")) {
+                resultStatus = gatValue(resultParam, "resultStatus");
+            }
+            if (resultParam.startsWith("result")) {
+                result = gatValue(resultParam, "result");
+            }
+            if (resultParam.startsWith("memo")) {
+                memo = gatValue(resultParam, "memo");
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "resultStatus={" + resultStatus + "};memo={" + memo
+                + "};result={" + result + "}";
+    }
+
+    private String gatValue(String content, String key) {
+        String prefix = key + "={";
+        return content.substring(content.indexOf(prefix) + prefix.length(),
+                content.lastIndexOf("}"));
+    }
+
+    /**
+     * @return the resultStatus
+     */
+    public String getResultStatus() {
+        return resultStatus;
+    }
+
+    /**
+     * @return the memo
+     */
+    public String getMemo() {
+        return memo;
+    }
+
+    /**
+     * @return the result
+     */
+    public String getResult() {
+        return result;
+    }
+}

+ 13 - 0
app/src/main/java/com/android/chmo/model/BannerInfo.java

@@ -0,0 +1,13 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/1.
+ */
+
+public class BannerInfo implements Serializable {
+    public String caption;
+    public String banner;
+    public String pic;
+}

+ 27 - 0
app/src/main/java/com/android/chmo/model/BrokerInfo.java

@@ -0,0 +1,27 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/1.
+ */
+
+public class BrokerInfo implements Serializable {
+    public String logo;
+    public String sex;
+    public String superpk;
+    public String outfit;
+    public String addr;
+    public List<String> photopk;
+    public String modelcount;
+    public String intro;
+    public String memberpk;
+    public String area;
+    public String pet;
+    public String name;
+    public String linkman;
+    public String brokepk;
+    public List<String> modelphoto;
+    public String linktype;
+}

+ 14 - 0
app/src/main/java/com/android/chmo/model/CommentInfo.java

@@ -0,0 +1,14 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+
+public class CommentInfo implements Serializable {
+    public String pet;
+    public String hphoto;
+    public String intro;
+    public String pk;
+    public String memberpk;
+    public String idate;
+    public String privatepk;
+}

+ 25 - 0
app/src/main/java/com/android/chmo/model/FindInfo.java

@@ -0,0 +1,25 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/1.
+ */
+
+public class FindInfo implements Serializable {
+    public String pet;
+    public String hphoto;
+    public String privatepk;
+    public String modelpk;
+    public String img;
+    public String peivateitempk;
+    public String pdate;
+    public String memberpk;
+    public String area;
+    public int likescount;
+    public int commentcount;
+    public int isattention;
+    public int islikes;
+    public int attentioncount;
+
+}

+ 9 - 0
app/src/main/java/com/android/chmo/model/LabelInfo.java

@@ -0,0 +1,9 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+
+public class LabelInfo implements Serializable {
+    public String name;
+    public String pk;
+}

+ 165 - 0
app/src/main/java/com/android/chmo/model/LoginUser.java

@@ -0,0 +1,165 @@
+package com.android.chmo.model;
+
+import org.xutils.db.annotation.Column;
+import org.xutils.db.annotation.Table;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+@Table(name = "LoginUser")
+public class LoginUser implements Serializable {
+
+    @Column(
+            name = "ID",
+            isId = true,
+            autoGen = true
+    )
+    private int id;
+
+    @Column(name = "pk")
+    public String pk;
+
+    @Column(name = "pet")
+    public String pet;
+
+    @Column(name = "phone")
+    public String phone;
+
+    @Column(name = "membtype")
+    public String membtype;
+
+    @Column(name = "token")
+    public String token; // 消息令牌
+
+    @Column(name = "age")
+    public String age;
+
+    @Column(name = "hphoto")
+    public String hphoto;
+
+    @Column(name = "photo")
+    public String photo;
+
+    @Column(name = "qrcode")
+    public String qrcode;
+
+    @Column(name = "coin_a")
+    public String coin_a;
+
+    @Column(name = "area")
+    public String area;
+
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getPk() {
+        return pk;
+    }
+
+    public void setPk(String pk) {
+        this.pk = pk;
+    }
+
+    public String getPet() {
+        return pet;
+    }
+
+    public void setPet(String pet) {
+        this.pet = pet;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getMembtype() {
+        return membtype;
+    }
+
+    public void setMembtype(String membtype) {
+        this.membtype = membtype;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public String getAge() {
+        return age;
+    }
+
+    public void setAge(String age) {
+        this.age = age;
+    }
+
+    public String getHphoto() {
+        return hphoto;
+    }
+
+    public void setHphoto(String hphoto) {
+        this.hphoto = hphoto;
+    }
+
+    public String getPhoto() {
+        return photo;
+    }
+
+    public void setPhoto(String photo) {
+        this.photo = photo;
+    }
+
+    public String getQrcode() {
+        return qrcode;
+    }
+
+    public void setQrcode(String qrcode) {
+        this.qrcode = qrcode;
+    }
+
+    public String getCoin_a() {
+        return coin_a;
+    }
+
+    public void setCoin_a(String coin_a) {
+        this.coin_a = coin_a;
+    }
+
+    public String getArea() {
+        return area;
+    }
+
+    public void setArea(String area) {
+        this.area = area;
+    }
+
+    public void setUser(UserInfo info) {
+        pk = info.pk;
+        phone = info.phone;
+        pet = info.pet;
+        hphoto = info.hphoto;
+        membtype = info.membtype;
+        token = info.token;
+        age = info.age;
+        photo = info.photo;
+        qrcode = info.qrcode;
+        coin_a = info.coin_a;
+        area = info.area;
+    }
+}

+ 50 - 0
app/src/main/java/com/android/chmo/model/ModelInfo.java

@@ -0,0 +1,50 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by Administrator on 2018/8/1.
+ */
+
+public class ModelInfo implements Serializable{
+    public String modelpk;
+    public String name;
+    public int isattention;
+    public String hphoto;
+    public String occupation;  // 工作
+    public String lname; //签名
+    public String hei; // 身高
+    public String wei; // 体重
+    public String bust; //三围
+    public String wai;
+    public String hip;
+    public int star;
+    public float vprice; // 视频价格
+    public int fcount; // 粉丝数
+    public List<ModelPhoto> modelphoto;
+    public int is_a; // 是否在线
+    public String ucount;
+    public String sex;
+    public String is_v;
+    public String tel;
+    public String areaname;
+    public String addr;
+    public String ratio_r;
+    public String stage;
+    public String ratio_s;
+    public String memberpk;
+    public String dcount;
+    public String shoe;
+    public String eye;
+    public int hair;
+    public String nominate;
+    public String bmemberpk;
+
+    public String ratio_v;
+    public String brokepk;
+    public String cardpk;
+
+    public String skillnames;
+
+}

+ 19 - 0
app/src/main/java/com/android/chmo/model/ModelLabel.java

@@ -0,0 +1,19 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/3.
+ */
+
+public class ModelLabel implements Serializable {
+    public String name;
+    public String pk;
+
+    public String memberpk;
+    public String pet;
+    public String hphoto;
+
+    public String figurepk;
+    public String figurecount;
+}

+ 18 - 0
app/src/main/java/com/android/chmo/model/ModelOrder.java

@@ -0,0 +1,18 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Created by Administrator on 2018/8/3.
+ */
+
+public class ModelOrder implements Serializable {
+    public ModelInfo model;
+    public ModelSkill skill;
+    public Date startTime;
+    public Date endTime;
+    public int hour;
+    public float totalPrice;
+    public String workName;
+}

+ 14 - 0
app/src/main/java/com/android/chmo/model/ModelPhoto.java

@@ -0,0 +1,14 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/2.
+ */
+
+public class ModelPhoto implements Serializable {
+    public String modelphotopk;
+    public String modelpk;
+    public String ordid;
+    public String photo;
+}

+ 16 - 0
app/src/main/java/com/android/chmo/model/ModelSkill.java

@@ -0,0 +1,16 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/3.
+ */
+
+public class ModelSkill implements Serializable {
+    public String name;
+    public String price;
+    public String unit;
+    public String modelpricepk;
+    public String skillpk;
+    public String skillphoto;
+}

+ 27 - 0
app/src/main/java/com/android/chmo/model/ModelVideo.java

@@ -0,0 +1,27 @@
+package com.android.chmo.model;
+
+import org.xutils.db.annotation.Column;
+import org.xutils.db.annotation.Table;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/13.
+ */
+
+@Table(name = "ModelVideo")
+public class ModelVideo implements Serializable {
+
+    @Column(
+            name = "ID",
+            isId = true,
+            autoGen = true
+    )
+    private int id;
+
+    @Column(name = "modelPk")
+    public String modelPk;
+
+    @Column(name = "vPrice")
+    public float vPrice;
+}

+ 39 - 0
app/src/main/java/com/android/chmo/model/ModelZone.java

@@ -0,0 +1,39 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+public class ModelZone implements Serializable {
+    public String privatepk;
+    public String intro;
+    public String pdate;
+    public int isditto;
+    public int islikes;
+    public int likeCount;
+    public int commentCount;
+
+    public List<Comment> recordinfo;
+    public List<Good> privateinfo;
+    public List<ZoneItem> iteminfo;
+
+
+    public class Comment implements Serializable{
+        public String recordinfopk;
+        public String memberpk;
+        public String idate;
+        public int isgood;
+        public String intro;
+    }
+
+    public class Good implements Serializable{
+        public String memberpk;
+        public String idate;
+    }
+
+    public class ZoneItem implements Serializable{
+        public String iteminfopk;
+        public String ftype;
+        public String url;
+    }
+}

+ 39 - 0
app/src/main/java/com/android/chmo/model/OrderInfo.java

@@ -0,0 +1,39 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/8/4.
+ */
+
+public class OrderInfo implements Serializable {
+    public String brokerpk;
+    public String linkphone;
+    public String orderstate;  // 0: 未付款  1: 已付款  2:客户取消  3:模特接单 4:模特取消  5:订单结算 6:超时对消
+    public String coin;
+    public String odate;
+    public String scount;
+    public String lederpk;
+    public String ordernumber;
+    public String skillpk;
+    public String addr;
+    public String sname;
+    public String intro;
+    public String ec;
+    public String memberpk;
+    public String name;
+    public String sprice;
+    public String linkman;
+    public String sdate;
+    public String hphoto;
+    public String pk;
+    public String modelhphoto;
+    public String modelpk;
+    public String model_memberpk;
+    public String modelpet;
+    public String modelstar;
+    public String skillname;
+
+
+
+}

+ 21 - 0
app/src/main/java/com/android/chmo/model/UserInfo.java

@@ -0,0 +1,21 @@
+package com.android.chmo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+public class UserInfo implements Serializable {
+    public String pk;
+    public String pet;
+    public String phone;
+    public String membtype;
+    public String token; // 消息令牌
+    public String age;
+    public String hphoto;
+    public String photo;
+    public String qrcode;
+    public String coin_a;
+    public String area;
+
+}

+ 89 - 0
app/src/main/java/com/android/chmo/receiver/VChatReceiver.java

@@ -0,0 +1,89 @@
+package com.android.chmo.receiver;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.chmo.app.VChatManager;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.VideoPriceRes;
+import com.android.chmo.http.service.ModelService;
+import com.google.gson.Gson;
+import com.netease.nim.avchatkit.common.activity.ActivityManager;
+import com.netease.nimlib.sdk.avchat.model.AVChatData;
+
+/**
+ * Created by Administrator on 2018/8/9.
+ */
+
+public class VChatReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if(action.equals("android.chmo.action.INCOMING")){ // 接收到视频
+            AVChatData data = (AVChatData)intent.getSerializableExtra("data");
+            String name = intent.getStringExtra("name");
+            inComing(data,name);
+        } else if(action.equals("android.chmo.action.BEGIN_VIDEO")) { // 视频已连接
+            String account = intent.getStringExtra("account");
+            beginVideo(account);
+        }else if(action.equals("android.chmo.action.END_VIDEO")) { // 视频结束
+            endVideo();
+        }
+    }
+
+
+    private void inComing(final AVChatData data, final String name) {
+
+        ModelService.getModelVideoPrice(data.getAccount(), new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                VideoPriceRes res = new Gson().fromJson(result,VideoPriceRes.class);
+                float vprice = 6;
+                if(res.msg.equals("success")) {
+                    vprice = res.vprice;
+                }
+                Activity activity = ActivityManager.getInstance().currentActivity();
+                VChatManager.getInstance().showPromptDialog(activity,vprice, new VChatManager.VChatCallback(){
+                    @Override
+                    public void startVChat() {
+                    }
+                });
+            }
+            @Override
+            public void onFailure(String error) {
+                Activity activity = ActivityManager.getInstance().currentActivity();
+                VChatManager.getInstance().showPromptDialog(activity,6, new VChatManager.VChatCallback(){
+                    @Override
+                    public void startVChat() {
+                    }
+                });
+            }
+        });
+
+
+    }
+
+    private  void beginVideo(String account) {
+        ModelService.getModelVideoPrice(account, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                VideoPriceRes res = new Gson().fromJson(result,VideoPriceRes.class);
+                if(res.msg.equals("success")) {
+                    VChatManager.getInstance().requestBegin(res.modelpk);
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+            }
+        });
+
+    }
+
+    private  void endVideo() {
+        VChatManager.getInstance().requestEnd();
+    }
+}

+ 130 - 0
app/src/main/java/com/android/chmo/ui/activity/GuideActivity.java

@@ -0,0 +1,130 @@
+package com.android.chmo.ui.activity;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+
+import com.android.chmo.R;
+import com.android.chmo.app.SpManager;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.ui.view.PageIndexView;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+/**
+ * Created by Administrator on 2018/7/31.
+ */
+
+public class GuideActivity extends BaseActivity {
+    private final int imageIds[]= new int[]{R.mipmap.guide1, R.mipmap.guide2,R.mipmap.guide3};
+
+    @BindView(R.id.pager)
+    ViewPager viewPager;
+    @BindView(R.id.index)
+    PageIndexView indexView;
+    @BindView(R.id.launch)
+    Button launchBtn;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_guide;
+    }
+
+    @Override
+    public void initView() {
+        indexView.setDefDrawable(R.drawable.index_point_uncheck);
+        indexView.setSelectedIndexDrawable(R.drawable.index_point_checked);
+
+        if (imageIds.length > 1) {
+            indexView.setCount(imageIds.length);
+            indexView.setCurIndex(0);
+            indexView.setVisibility(View.VISIBLE);
+        } else {
+            indexView.setVisibility(View.GONE);
+        }
+
+        viewPager.setAdapter(new ImagePagerAdapter(getSupportFragmentManager()));
+        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+                indexView.setCurIndex(position);
+                if(position == imageIds.length-1) {
+                    launchBtn.setVisibility(View.VISIBLE);
+                }else{
+                    launchBtn.setVisibility(View.GONE);
+                }
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+
+            }
+        });
+
+    }
+
+
+    @OnClick(R.id.launch)
+    public void launch() {
+        SpManager.getInstance().setBoolean("appStarted", true);
+        openPage(LoginActivity.class);
+        finish();
+    }
+
+
+
+    public static class ImageFragment extends Fragment {
+        private ImageView imageIV;
+        private int imageId;
+
+        public ImageFragment() {
+            super();
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                                 Bundle savedInstanceState) {
+            View view = inflater.inflate(R.layout.page_guide, container, false);
+            imageIV = (ImageView) view.findViewById(R.id.image);
+
+            imageId = getArguments().getInt("imageId");
+            imageIV.setImageResource(imageId);
+
+            return view;
+        }
+    }
+
+    private class ImagePagerAdapter extends FragmentPagerAdapter {
+        public ImagePagerAdapter(FragmentManager fm) {
+            super(fm);
+        }
+
+        @Override
+        public Fragment getItem(int position) {
+            Fragment fragment = Fragment.instantiate(getApplicationContext(),
+                    ImageFragment.class.getName());
+            Bundle args = new Bundle();
+            args.putInt("imageId", imageIds[position]);
+            fragment.setArguments(args);
+            return fragment;
+        }
+
+        @Override
+        public int getCount() {
+            return imageIds.length;
+        }
+    }
+}

+ 148 - 0
app/src/main/java/com/android/chmo/ui/activity/LoginActivity.java

@@ -0,0 +1,148 @@
+package com.android.chmo.ui.activity;
+
+import android.Manifest;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.widget.EditText;
+
+import com.android.chmo.R;
+import com.android.chmo.app.SpManager;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.LoginRes;
+import com.android.chmo.http.service.UserService;
+import com.android.chmo.im.IMManager;
+import com.android.chmo.model.LoginUser;
+import com.android.chmo.ui.activity.me.ForgetPwdActivity;
+import com.android.chmo.utils.CommonUtils;
+import com.android.chmo.utils.LoginUtils;
+import com.google.gson.Gson;
+import com.netease.nim.uikit.support.permission.MPermission;
+import com.netease.nim.uikit.support.permission.annotation.OnMPermissionDenied;
+import com.netease.nim.uikit.support.permission.annotation.OnMPermissionGranted;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+/**
+ * Created by Administrator on 2018/7/30.
+ */
+
+public class LoginActivity extends BaseActivity {
+
+    @BindView(R.id.phone)
+    EditText phoneEdit;
+    @BindView(R.id.password)
+    EditText passwordEdit;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_login;
+    }
+
+    @Override
+    public void initView() {
+        checkLocationPermission();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        String phone = SpManager.getInstance().getString("LoginPhone");
+        String password = SpManager.getInstance().getString("LoginPwd");
+
+        phoneEdit.setText(phone);
+        passwordEdit.setText(password);
+    }
+
+    @OnClick(R.id.login)
+    public void login() {
+        final String phone = phoneEdit.getText().toString();
+        final String password = passwordEdit.getText().toString();
+        if(TextUtils.isEmpty(phone)) {
+            showToast("请输入手机号");
+            return;
+        }
+
+        if(!CommonUtils.isPhone(phone)) {
+            showToast("手机号不正确");
+            return;
+        }
+
+        if(TextUtils.isEmpty(password)) {
+            showToast("请输入密码");
+            return;
+        }
+        showLoading("登录中...");
+        UserService.login(phone, password, new RequestCallback(){
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                LoginRes res = new Gson().fromJson(result, LoginRes.class);
+                if(res.data != null) {
+                    LoginUser user = new LoginUser();
+                    user.setUser(res.data);
+                    LoginUtils.saveLoginUser(user);
+                    SpManager.getInstance().setString("LoginPhone", phone);
+                    SpManager.getInstance().setString("LoginPwd", password);
+
+                    IMManager.login();
+                    openPage(MainActivity.class);
+                    finish();
+                }else {
+                    showToast(TextUtils.isEmpty(res.desc) ? "登录失败" : res.desc);
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("登录失败");
+            }
+        });
+
+    }
+
+    @OnClick(R.id.forgetPwd)
+    public void forgetPwd() {
+            openPage(ForgetPwdActivity.class);
+    }
+
+    @OnClick(R.id.go_register)
+    public void goRegister() {
+        openPage(RegisterActivity.class);
+    }
+
+    @OnClick(R.id.container)
+    public void containerClick() {
+        CommonUtils.closeKeybord(phoneEdit,this);
+    }
+
+
+
+    private void checkLocationPermission() {
+        MPermission.with(this)
+                .setRequestCode(20)
+                .permissions( new String[] {
+                        Manifest.permission.ACCESS_FINE_LOCATION,
+                        Manifest.permission.ACCESS_COARSE_LOCATION,
+                        Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS}).request();
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        MPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
+    }
+
+    @OnMPermissionGranted(20)
+    public void locationPermissionSuccess(){
+
+    }
+
+    @OnMPermissionDenied(20)
+    public void locationPermissionFailed(){
+        showToast("定位所需权限未授权");
+    }
+
+
+}

+ 190 - 0
app/src/main/java/com/android/chmo/ui/activity/MainActivity.java

@@ -0,0 +1,190 @@
+package com.android.chmo.ui.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.ui.fragment.BrokerFragment;
+import com.android.chmo.ui.fragment.FindFragment;
+import com.android.chmo.ui.fragment.HomeFragment;
+import com.android.chmo.ui.fragment.MeFragment;
+import com.android.chmo.ui.fragment.MessageFragment;
+import com.android.chmo.ui.view.NoSlideViewPager;
+import com.netease.nimlib.sdk.NIMClient;
+import com.netease.nimlib.sdk.msg.MsgService;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+public class MainActivity extends BaseActivity {
+    private final int FRAGMENT_HOME = 0;
+    private final int FRAGMENT_BROKER = 1;
+    private final int FRAGMENT_FIND = 2;
+    private final int FRAGMENT_MESSAGE = 3;
+    private final int FRAGMENT_ME = 4;
+
+    @BindView(R.id.pager)
+    NoSlideViewPager mPager;
+
+    @BindView(R.id.tab_home)
+    View tabHome;
+
+    @BindView(R.id.tab_broker)
+    View tabBroker;
+
+    @BindView(R.id.tab_message)
+    View tabMessage;
+
+    @BindView(R.id.tab_me)
+    View tabMe;
+
+    @BindView(R.id.find)
+    View findBtn;
+
+    @BindView(R.id.unread)
+    TextView unreadView;
+
+    private View curTab;
+
+    private int curFragment;
+
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_main;
+    }
+
+    @Override
+    public void initView() {
+        mPager.setOffscreenPageLimit(5);
+        mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
+        curTab = tabHome;
+        curTab.setSelected(true);
+
+        registerObserver(true);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        fillUnreadView();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        registerObserver(false);
+    }
+
+    @OnClick({R.id.tab_home, R.id.tab_broker, R.id.tab_message, R.id.tab_me, R.id.find})
+    public void onTabClick(View v) {
+        if (null != curTab) {
+            curTab.setSelected(false);
+        }
+        curTab = v;
+        curTab.setSelected(true);
+        switch (v.getId()) {
+            case R.id.tab_home:
+                curFragment = FRAGMENT_HOME;
+                break;
+            case R.id.tab_broker:
+                curFragment = FRAGMENT_BROKER;
+                break;
+            case R.id.tab_message:
+                curFragment = FRAGMENT_MESSAGE;
+                break;
+            case R.id.tab_me:
+                curFragment = FRAGMENT_ME;
+                break;
+            case R.id.find:
+                curFragment = FRAGMENT_FIND;
+                break;
+            default:
+                break;
+        }
+        mPager.setCurrentItem(curFragment, false);
+    }
+
+    private void fillUnreadView() {
+        int count =  NIMClient.getService(MsgService.class).getTotalUnreadCount();
+        if (count == 0) {
+            unreadView.setText("0");
+            unreadView.setVisibility(View.GONE);
+        }else {
+            unreadView.setVisibility(View.VISIBLE);
+            unreadView.setText(count > 9 ? "9+" : String.valueOf(count));
+        }
+    }
+
+    private void registerObserver(boolean register) {
+        if (register) {
+            registerReceiver(msgCountReceiver,new IntentFilter("com.android.chmo.REFRESH_MSG"));
+        }else {
+            unregisterReceiver(msgCountReceiver);
+        }
+    }
+
+    private BroadcastReceiver msgCountReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            fillUnreadView();
+        }
+    };
+
+    private class MyPagerAdapter extends FragmentPagerAdapter {
+
+        public MyPagerAdapter(FragmentManager fm) {
+            super(fm);
+        }
+
+        @Override
+        public Fragment getItem(int position) {
+            switch (position) {
+                case FRAGMENT_HOME:
+                    return Fragment.instantiate(getApplicationContext(),
+                            HomeFragment.class.getName());
+                case FRAGMENT_BROKER:
+                    return Fragment.instantiate(getApplicationContext(),
+                            BrokerFragment.class.getName());
+                case FRAGMENT_FIND:
+                    return Fragment.instantiate(getApplicationContext(),
+                            FindFragment.class.getName());
+                case FRAGMENT_MESSAGE:
+                    return Fragment.instantiate(getApplicationContext(),
+                            MessageFragment.class.getName());
+                case FRAGMENT_ME:
+                    return Fragment.instantiate(getApplicationContext(),
+                            MeFragment.class.getName());
+            }
+
+            throw new RuntimeException("undefine position:" + position);
+        }
+
+        @Override
+        public int getCount() {
+            return 5;
+        }
+    }
+
+
+    private long backPressTime = 0;
+    @Override
+    public void onBackPressed() {
+        long time = System.currentTimeMillis();
+        if((time-backPressTime) > 2000) {
+            backPressTime = time;
+            showToast("再按一次退出应用");
+            return;
+        }
+
+        super.onBackPressed();
+    }
+}

+ 197 - 0
app/src/main/java/com/android/chmo/ui/activity/RegisterActivity.java

@@ -0,0 +1,197 @@
+package com.android.chmo.ui.activity;
+
+import android.content.Intent;
+import android.text.TextUtils;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.app.SpManager;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.RegisterRes;
+import com.android.chmo.http.service.UserService;
+import com.android.chmo.ui.activity.me.ProtocolActivity;
+import com.android.chmo.utils.CodeUtils;
+import com.android.chmo.utils.CommonUtils;
+import com.android.chmo.utils.VerifyCodeCounter;
+import com.google.gson.Gson;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+/**
+ * Created by Administrator on 2018/7/31.
+ */
+
+public class RegisterActivity extends BaseActivity {
+
+    @BindView(R.id.nickName)
+    EditText nickNameEdit;
+    @BindView(R.id.phone)
+    EditText phoneEdit;
+    @BindView(R.id.password)
+    EditText passwordEdit;
+    @BindView(R.id.confirm_password)
+    EditText confirmPwdEdit;
+    @BindView(R.id.code)
+    EditText codeEdit;
+
+    @BindView(R.id.getCode)
+    TextView getCodeBtn;
+    @BindView(R.id.checkbox)
+    ImageView checkBox;
+
+    private boolean protocolCheck = false;
+
+    private VerifyCodeCounter codeCounter;
+
+    private String code = ChmoApplication.getApp().getCode();
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_register;
+    }
+
+    @Override
+    public void initView() {
+
+    }
+
+    @OnClick(R.id.getCode)
+    public void getCode() {
+        String phone = phoneEdit.getText().toString();
+        if(TextUtils.isEmpty(phone)) {
+            showToast("请输入手机号");
+            return;
+        }
+        if(!CommonUtils.isPhone(phone)) {
+            showToast("手机号不正确");
+            return;
+        }
+
+        code = CodeUtils.randomCode();
+        String codeStr = CodeUtils.getCodeStr(0,code);
+        showLoading();
+        UserService.getCode(phone,codeStr, new RequestCallback(){
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                ChmoApplication.getApp().setCode(code);
+                codeCounter = new VerifyCodeCounter(60000,1000,getCodeBtn);
+                codeCounter.start();
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("获取验证码失败");
+            }
+        });
+
+    }
+
+    @OnClick(R.id.register)
+    public void register() {
+        String nickName = nickNameEdit.getText().toString();
+        final String phone = phoneEdit.getText().toString();
+        final String password = passwordEdit.getText().toString();
+        String confirmPwd = confirmPwdEdit.getText().toString();
+        String code = codeEdit.getText().toString();
+        if(TextUtils.isEmpty(nickName)) {
+            showToast("请输入昵称");
+            return;
+        }
+
+        if(TextUtils.isEmpty(phone)) {
+            showToast("请输入手机号");
+            return;
+        }
+        if(!CommonUtils.isPhone(phone)) {
+            showToast("手机号不正确");
+            return;
+        }
+        if(TextUtils.isEmpty(password)){
+            showToast("请输入密码");
+            return;
+        }
+
+        if(password.length() < 6){
+            showToast("密码长度不少于6位");
+            return;
+        }
+        if(!password.equals(confirmPwd)) {
+            showToast("确认密码不一致");
+            return;
+        }
+        if(TextUtils.isEmpty(code)){
+            showToast("请输入验证码");
+            return;
+        }
+        if(!code.equals(this.code)) {
+            showToast("验证码不正确");
+            return;
+        }
+
+        if (!protocolCheck) {
+            showToast("请先阅读并同意“用户协议”和“隐私协议”");
+            return;
+        }
+
+        showLoading();
+        UserService.register(nickName, phone, password, new RequestCallback(){
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                RegisterRes res = new Gson().fromJson(result, RegisterRes.class);
+                if(res.msg.equals("fail")) {
+                    showToast(TextUtils.isEmpty(res.value) ? "注册失败" : res.value);
+                }else {
+                    //注册成功
+                    showToast("注册成功");
+                    SpManager.getInstance().setString("LoginPhone", phone);
+                    SpManager.getInstance().setString("LoginPwd", password);
+                    finish();
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("注册失败");
+            }
+        });
+
+    }
+
+
+
+    @OnClick(R.id.container)
+    public void containerClick() {
+        CommonUtils.closeKeybord(phoneEdit,this);
+    }
+
+    @OnClick(R.id.protocol)
+    public void checkProtocol() {
+        protocolCheck = !protocolCheck;
+        checkBox.setImageResource(protocolCheck ? R.mipmap.checked : R.mipmap.check);
+    }
+
+    @OnClick(R.id.user_protocol)
+    public void userProtocol() {
+        Intent intent = new Intent(this, ProtocolActivity.class);
+        intent.putExtra("title", "用户协议");
+        intent.putExtra("url", "file:///android_asset/user_protocol.html");
+        openPage(intent);
+    }
+
+    @OnClick(R.id.privacy_protocol)
+    public void privacyProtocol() {
+        Intent intent = new Intent(this, ProtocolActivity.class);
+        intent.putExtra("title", "隐私协议");
+        intent.putExtra("url", "file:///android_asset/privacy_protocol.html");
+        openPage(intent);
+    }
+}

+ 52 - 0
app/src/main/java/com/android/chmo/ui/activity/WelcomeActivity.java

@@ -0,0 +1,52 @@
+package com.android.chmo.ui.activity;
+
+import android.widget.ImageView;
+
+import com.android.chmo.R;
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.app.SpManager;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.im.IMManager;
+import com.android.chmo.model.LoginUser;
+
+import butterknife.BindView;
+
+/**
+ * Created by Administrator on 2018/7/31.
+ */
+
+public class WelcomeActivity extends BaseActivity {
+    @BindView(R.id.image)
+    ImageView imageView;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_welcome;
+    }
+
+    @Override
+    public void initView() {
+        imageView.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                ChmoApplication.isInit = true;
+                if(SpManager.getInstance().getBoolean("appStarted")) {
+                    LoginUser user = ChmoApplication.getApp().getLoginUser();
+                    if(null != user) {
+                        IMManager.login();
+                        openPage(MainActivity.class);
+                    } else {
+                        openPage(LoginActivity.class);
+                    }
+                } else {
+                    openPage(GuideActivity.class);
+                }
+
+                finish();
+            }
+        },ChmoApplication.isInit ? 100 : 1000);
+
+    }
+
+
+}

+ 78 - 0
app/src/main/java/com/android/chmo/ui/activity/activities/ActivitiesDetailActivity.java

@@ -0,0 +1,78 @@
+package com.android.chmo.ui.activity.activities;
+
+import android.content.Intent;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.model.ActivitiesInfo;
+import com.android.chmo.utils.PixelUtils;
+import com.android.chmo.utils.XUtilsImage;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+
+public class ActivitiesDetailActivity extends BaseActivity {
+    @BindView(R.id.image)
+    ImageView imageView;
+    @BindView(R.id.atitle)
+    TextView titleView;
+    @BindView(R.id.startTime)
+    TextView startTimeView;
+    @BindView(R.id.endTime)
+    TextView endTimeView;
+    @BindView(R.id.desc)
+    TextView descView;
+
+
+    @BindView(R.id.signBtn)
+    Button signBtn;
+
+    private ActivitiesInfo info;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_activities_detail;
+    }
+
+    @Override
+    public void initView() {
+        info = (ActivitiesInfo) getIntent().getSerializableExtra("data");
+
+        int width = PixelUtils.getWindowWidth();
+        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)imageView.getLayoutParams();
+        lp.width = width;
+        lp.height = width;
+        imageView.setLayoutParams(lp);
+        XUtilsImage.display(imageView, HttpApi.getImgUrl(info.pic), R.mipmap.def_img2);
+
+        titleView.setText(info.caption);
+        startTimeView.setText(info.beg);
+        endTimeView.setText(info.sendt);
+        descView.setText(info.intro);
+
+        if(info.issigndate == 1) {
+            signBtn.setBackgroundResource(R.drawable.pink_btn);
+            signBtn.setText("立即报名");
+        }else {
+            signBtn.setBackgroundResource(R.drawable.gray_btn);
+            signBtn.setText("已结束");
+        }
+    }
+
+    @OnClick(R.id.signBtn)
+    public void sign(){
+        if(info.issigndate != 1) {
+            return;
+        }
+
+        Intent intent = new Intent(this,SignInActivity.class);
+        intent.putExtra("data", info);
+        openPage(intent);
+    }
+}

+ 111 - 0
app/src/main/java/com/android/chmo/ui/activity/activities/BannerInfoActivity.java

@@ -0,0 +1,111 @@
+package com.android.chmo.ui.activity.activities;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.model.BannerInfo;
+import com.android.chmo.ui.view.LongImageView;
+import com.android.chmo.ui.view.TopBar;
+import com.android.chmo.utils.ImageUtils;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import butterknife.BindView;
+
+import static com.android.chmo.R.id.pic;
+
+/**
+ * Created by Administrator on 2018/8/15.
+ */
+
+public class BannerInfoActivity extends BaseActivity {
+    @BindView(R.id.topBar)
+    TopBar topBar;
+
+    @BindView(pic)
+    LongImageView imageView;
+
+    private BannerInfo banner;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_banner_info;
+    }
+
+    @Override
+    public void initView() {
+        banner = (BannerInfo) getIntent().getSerializableExtra("banner");
+
+        topBar.setTitle(banner.caption);
+
+        loadImage();
+    }
+
+
+    private void loadImage() {
+
+        final Handler handler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == 0) {
+                    showToast("加载失败");
+                }else {
+                    Bitmap bitmap = (Bitmap)msg.obj;
+                    imageView.setImage(bitmap);
+                }
+                hideLoading();
+            }
+        };
+        showLoading();
+        new Thread() {
+            @Override
+            public void run() {
+                try {
+                    String fileName = getFileName();
+
+                    Bitmap bitmap = ImageUtils.getBitmap(getContext(), fileName);
+                    if(null != bitmap) {
+                        Message msg = handler.obtainMessage(1);
+                        msg.obj = bitmap;
+                        handler.sendMessage(msg);
+                    }else {
+                        URL url = new URL(HttpApi.getImgUrl(banner.pic));
+                        InputStream inputStream=url.openStream();
+                        bitmap = BitmapFactory.decodeStream(inputStream);
+                        Message msg = handler.obtainMessage(1);
+                        msg.obj = bitmap;
+                        handler.sendMessage(msg);
+                        inputStream.close();
+
+                        ImageUtils.saveImage(getContext(),url.openStream(), fileName);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    handler.sendEmptyMessage(0);
+                }catch (OutOfMemoryError e) {
+                    System.gc();
+                    System.runFinalization();
+                    handler.sendEmptyMessage(0);
+                }
+
+            }
+        }.start();
+    }
+
+
+    private String getFileName() {
+        if(TextUtils.isEmpty(banner.pic)) {
+            return "";
+        }
+
+        String fileName = banner.pic.substring(banner.pic.lastIndexOf("/")+1);
+        return fileName;
+    }
+}

+ 123 - 0
app/src/main/java/com/android/chmo/ui/activity/activities/SignInActivity.java

@@ -0,0 +1,123 @@
+package com.android.chmo.ui.activity.activities;
+
+import android.text.TextUtils;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.Res;
+import com.android.chmo.http.service.ActivitiesService;
+import com.android.chmo.model.ActivitiesInfo;
+import com.android.chmo.utils.PixelUtils;
+import com.android.chmo.utils.XUtilsImage;
+import com.google.gson.Gson;
+
+import org.greenrobot.eventbus.EventBus;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+
+public class SignInActivity extends BaseActivity {
+
+    @BindView(R.id.image)
+    ImageView imageView;
+    @BindView(R.id.atitle)
+    TextView titleView;
+    @BindView(R.id.joinMember)
+    EditText joinMemberEdit;
+    @BindView(R.id.contact)
+    EditText contactEdit;
+    @BindView(R.id.count)
+    TextView countView;
+    @BindView(R.id.price)
+    TextView priceView;
+    @BindView(R.id.all_price)
+    TextView totalPriceView;
+    @BindView(R.id.instruction)
+    TextView instructionView;
+
+    private int count = 1;
+
+    private ActivitiesInfo info;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_sign_in;
+    }
+
+    @Override
+    public void initView() {
+        info = (ActivitiesInfo) getIntent().getSerializableExtra("data");
+
+        int width = PixelUtils.getWindowWidth();
+        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)imageView.getLayoutParams();
+        lp.width = width;
+        lp.height = width;
+        imageView.setLayoutParams(lp);
+        XUtilsImage.display(imageView, HttpApi.getImgUrl(info.pic), R.mipmap.def_img2);
+
+        titleView.setText(info.caption);
+        priceView.setText(info.meprice + "元/人");
+        totalPriceView.setText(info.meprice + "元");
+    }
+
+    @OnClick(R.id.add)
+    public void add(){
+        count++;
+        countView.setText(""+count);
+
+        totalPriceView.setText(info.meprice * count + "元");
+    }
+
+    @OnClick(R.id.dec)
+    public void dec(){
+        count--;
+        count = Math.max(1, count);
+        countView.setText(""+count);
+        totalPriceView.setText(info.meprice * count + "元");
+    }
+
+    @OnClick(R.id.signBtn)
+    public void sign(){
+        String joinMember = joinMemberEdit.getText().toString();
+        String contact = contactEdit.getText().toString();
+        String allPrice = String.valueOf(info.meprice * count);
+        if(TextUtils.isEmpty(joinMember)) {
+            showToast("请输入参加人员");
+            return;
+        }
+        if(TextUtils.isEmpty(contact)) {
+            showToast("请输入联系方式");
+            return;
+        }
+
+        showLoading("报名中...");
+        ActivitiesService.signIn(info, joinMember, contact, String.valueOf(count), allPrice, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                Res res = new Gson().fromJson(result,Res.class);
+                if(res.msg.equals("success")) {
+                    showToast("报名成功");
+                    EventBus.getDefault().post("signChange");
+                    finish();
+                }else {
+                    showToast("报名失败");
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("报名失败");
+            }
+        });
+
+    }
+}

+ 394 - 0
app/src/main/java/com/android/chmo/ui/activity/find/FindDetailActivity.java

@@ -0,0 +1,394 @@
+package com.android.chmo.ui.activity.find;
+
+import android.content.Intent;
+import android.graphics.Rect;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.constant.Constants;
+import com.android.chmo.http.HttpApi;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.CommentListRes;
+import com.android.chmo.http.response.ModelListRes;
+import com.android.chmo.http.response.Res;
+import com.android.chmo.http.service.FindService;
+import com.android.chmo.http.service.ModelService;
+import com.android.chmo.model.CommentInfo;
+import com.android.chmo.model.FindInfo;
+import com.android.chmo.model.ModelInfo;
+import com.android.chmo.ui.activity.model.ModelDetailActivity;
+import com.android.chmo.ui.adpater.CommentAdapter;
+import com.android.chmo.ui.view.RefreshListView;
+import com.android.chmo.utils.CommonUtils;
+import com.android.chmo.utils.DateUtils;
+import com.android.chmo.utils.PixelUtils;
+import com.android.chmo.utils.TimeUtils;
+import com.android.chmo.utils.XUtilsImage;
+import com.google.gson.Gson;
+import com.netease.nim.uikit.common.util.StatusBarUtil;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import butterknife.BindView;
+
+
+public class FindDetailActivity extends BaseActivity implements RefreshListView.RefreshListener {
+
+    @BindView(R.id.refreshList)
+    RefreshListView refreshListView;
+    @BindView(R.id.commentBottom)
+    View commentBottom;
+    @BindView(R.id.commentInput)
+    EditText commentEdit;
+
+
+    ImageView headView;
+    ImageView bigImage;
+    TextView nameView;
+    TextView addrView;
+    TextView timeView;
+
+    TextView goodNum;
+    ImageView goodIcon;
+    TextView commentNum;
+    TextView followText;
+    ImageView followIcon;
+
+    View emptyView;
+
+    private CommentAdapter commentAdapter;
+
+    private List<CommentInfo> mList = new ArrayList<>();
+
+    private FindInfo info;
+
+    private ModelInfo model;
+
+    private int pageNo = 1;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_find_detail;
+    }
+
+    @Override
+    public void initView() {
+        info = (FindInfo) getIntent().getSerializableExtra("data");
+        refreshListView.getListView().addHeaderView(initDetailView());
+        refreshListView.setRefreshListener(this);
+        commentAdapter = new CommentAdapter(this);
+        refreshListView.setAdapter(commentAdapter);
+
+        commentEdit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+            @Override
+            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+                if (actionId == EditorInfo.IME_ACTION_SEND) {
+                    sendComment();
+                    return true;
+                }
+                return false;
+            }
+        });
+        listenerKeybroad();
+
+        fillDetailView();
+
+        refreshListView.autoRefresh();
+
+        getModelInfo(info.modelpk);
+    }
+
+    private View initDetailView() {
+        View view = LayoutInflater.from(this).inflate(R.layout.find_detail_header, null);
+        headView = (ImageView) view.findViewById(R.id.head);
+        bigImage = (ImageView) view.findViewById(R.id.bigImg);
+        nameView = (TextView) view.findViewById(R.id.name);
+        addrView = (TextView) view.findViewById(R.id.address);
+        timeView = (TextView) view.findViewById(R.id.time);
+        goodNum = (TextView) view.findViewById(R.id.goodText);
+        commentNum = (TextView) view.findViewById(R.id.commentText);
+        followText = (TextView) view.findViewById(R.id.followText);
+        goodIcon = (ImageView) view.findViewById(R.id.goodIcon);
+        followIcon = (ImageView) view.findViewById(R.id.followIcon);
+        emptyView = view.findViewById(R.id.empty);
+
+        int imgWidth = PixelUtils.getWindowWidth() - 20;
+        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) bigImage.getLayoutParams();
+        lp.width = imgWidth;
+        lp.height = imgWidth;
+        bigImage.setLayoutParams(lp);
+
+        view.findViewById(R.id.goodBtn).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setGood();
+            }
+        });
+        view.findViewById(R.id.followBtn).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setFollow();
+            }
+        });
+        view.findViewById(R.id.commentBtn).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                CommonUtils.openKeybord(commentEdit, FindDetailActivity.this);
+            }
+        });
+
+
+        return view;
+    }
+
+    private void fillDetailView() {
+        nameView.setText(info.pet);
+        addrView.setText(info.area);
+        timeView.setText(getTimeStr(info.pdate));
+        goodNum.setText("点赞" + info.likescount);
+        commentNum.setText("评论" + info.commentcount);
+
+        goodIcon.setImageResource(info.islikes == 1 ? R.mipmap.gooded : R.mipmap.good);
+
+        XUtilsImage.display(bigImage, HttpApi.getImgUrl(info.img), R.mipmap.def_img2);
+        XUtilsImage.displayCircluar(headView, HttpApi.getImgUrl(info.hphoto), R.mipmap.def_head);
+        fillFollowBtn();
+        headView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(getContext(), ModelDetailActivity.class);
+                intent.putExtra("model", model);
+                intent.putExtra("modelPk", info.modelpk);
+                openPage(intent);
+            }
+        });
+    }
+
+    private void fillFollowBtn() {
+        if (info.isattention == 1) {
+            followIcon.setImageResource(R.mipmap.liked);
+            followText.setTextColor(getResources().getColor(R.color.pink));
+            followText.setText("已关注");
+        } else {
+            followIcon.setImageResource(R.mipmap.like);
+            followText.setTextColor(getResources().getColor(R.color.black));
+            followText.setText("关注");
+        }
+    }
+
+    private String getTimeStr(String time) {
+        Date date = DateUtils.parseDate(time);
+        return TimeUtils.friendlyTime(date.getTime() / 1000);
+    }
+
+
+    @Override
+    public void onRefresh() {
+        loadComment(1);
+    }
+
+    @Override
+    public void onLoadMore() {
+        loadComment(this.pageNo + 1);
+    }
+
+
+    private void getModelInfo(String modelPk) {
+        ModelService.getModelInfo(modelPk, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                ModelListRes res = new Gson().fromJson(result, ModelListRes.class);
+                if (res.data != null && res.data.size() > 0) {
+                    model = res.data.get(0);
+                } else {
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+            }
+        });
+    }
+
+
+    private void loadComment(final int page) {
+        FindService.getCommentList(info.privatepk, page, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                refreshListView.finishRefresh();
+                final CommentListRes res = new Gson().fromJson(result, CommentListRes.class);
+                if (res.data != null) {
+                    pageNo = page;
+                    if (page == 1) {
+                        mList.clear();
+                    }
+                    mList.addAll(res.data);
+                    commentAdapter.setList(mList);
+                    if (res.data.size() == Constants.PAGE_SIZE) {
+                        refreshListView.setEnableLoadMore(true);
+                    } else {
+                        refreshListView.setNoMoreData();
+                    }
+                }
+                emptyView.setVisibility(mList.size() == 0 ? View.VISIBLE : View.GONE);
+            }
+
+            @Override
+            public void onFailure(String error) {
+                refreshListView.finishRefresh();
+            }
+        });
+    }
+
+
+    private void setGood() {
+        showLoading();
+        final int type = info.islikes == 1 ? 2 : 1;
+        FindService.setGood(info.privatepk, type, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                Res res = new Gson().fromJson(result, Res.class);
+                if (res.msg.equals("success")) {
+                    info.islikes = type;
+                    if (type == 2) {
+                        info.likescount--;
+                    } else {
+                        info.likescount++;
+                    }
+                    goodNum.setText("点赞" + info.likescount);
+                    goodIcon.setImageResource(info.islikes == 1 ? R.mipmap.gooded : R.mipmap.good);
+                    EventBus.getDefault().post("findRefresh");
+                } else {
+                    showToast("操作失败");
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("操作失败");
+            }
+        });
+    }
+
+    private void setFollow() {
+        showLoading();
+        int type = info.isattention == 1 ? 2 : 1;
+        ModelService.setFollow(info.modelpk, type, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                Res res = new Gson().fromJson(result, Res.class);
+                if (res.msg.equals("success")) {
+                    info.isattention = info.isattention == 1 ? 0 : 1;
+                    fillFollowBtn();
+                    EventBus.getDefault().post("followChange");
+                } else {
+                    showToast(info.isattention == 1 ? "取消失败" : "关注失败");
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast(info.isattention == 1 ? "取消失败" : "关注失败");
+            }
+        });
+    }
+
+    private void sendComment() {
+        CommonUtils.closeKeybord(commentEdit, this);
+        String content = commentEdit.getText().toString();
+        if (TextUtils.isEmpty(content)) {
+            return;
+        }
+
+        showLoading();
+        FindService.sendComment(info.privatepk, content, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                Res res = new Gson().fromJson(result, Res.class);
+                if (res.msg.equals("success")) {
+                    onRefresh();
+                    info.commentcount++;
+                    commentNum.setText("评论" + info.commentcount);
+                    commentEdit.setText("");
+                    EventBus.getDefault().post("findRefresh");
+                } else {
+                    showToast("评论失败");
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("评论失败");
+            }
+        });
+    }
+
+    private void listenerKeybroad() {
+        final View rootView = getWindow().getDecorView();
+        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            int rootViewVisibleHeight;
+
+            @Override
+            public void onGlobalLayout() {
+                //获取当前根视图在屏幕上显示的大小
+                Rect r = new Rect();
+                rootView.getWindowVisibleDisplayFrame(r);
+
+                int visibleHeight = r.height();
+                if (rootViewVisibleHeight == 0) {
+                    rootViewVisibleHeight = visibleHeight;
+                    return;
+                }
+                //根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
+                if (rootViewVisibleHeight == visibleHeight) {
+                    return;
+                }
+
+                //根视图显示高度变小超过200,可以看作软键盘显示了
+                if (rootViewVisibleHeight - visibleHeight > 200) {
+                    // 键盘显示
+                    rootViewVisibleHeight = visibleHeight;
+                    // 设置输入框位置
+                    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) commentBottom.getLayoutParams();
+                    lp.bottomMargin = PixelUtils.getWindowHeight() - StatusBarUtil.getStatusBarHeight(getContext()) - rootViewVisibleHeight;
+                    commentBottom.setLayoutParams(lp);
+                    commentBottom.setVisibility(View.VISIBLE);
+                    commentEdit.setFocusable(true);
+                    commentEdit.setFocusableInTouchMode(true);
+                    commentEdit.requestFocus();
+                    return;
+                }
+
+                //根视图显示高度变大超过200,可以看作软键盘隐藏了
+                if (visibleHeight - rootViewVisibleHeight > 200) {
+                    // 键盘隐藏
+                    commentBottom.setVisibility(View.GONE);
+                    rootViewVisibleHeight = visibleHeight;
+                    return;
+                }
+
+            }
+        });
+    }
+}

+ 62 - 0
app/src/main/java/com/android/chmo/ui/activity/me/AboutActivity.java

@@ -0,0 +1,62 @@
+package com.android.chmo.ui.activity.me;
+
+import android.Manifest;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.widget.Toast;
+
+import com.android.chmo.R;
+import com.android.chmo.base.BaseActivity;
+import com.netease.nim.uikit.support.permission.MPermission;
+import com.netease.nim.uikit.support.permission.annotation.OnMPermissionDenied;
+import com.netease.nim.uikit.support.permission.annotation.OnMPermissionGranted;
+
+import butterknife.OnClick;
+
+/**
+ * Created by Administrator on 2018/8/20.
+ */
+
+public class AboutActivity extends BaseActivity {
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_about;
+    }
+
+    @Override
+    public void initView() {
+
+    }
+
+    @OnClick(R.id.call)
+    public void call() {
+        checkCallPermission();
+    }
+
+    public void checkCallPermission() {
+        MPermission.with(this)
+                .setRequestCode(30)
+                .permissions( new String[] {
+                        Manifest.permission.CALL_PHONE}).request();
+    }
+
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        MPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
+    }
+
+    @OnMPermissionGranted(30)
+    public void onCallPermissionSuccess(){
+        Intent intent = new Intent(Intent.ACTION_DIAL);
+        Uri data = Uri.parse("tel:15805170379");
+        intent.setData(data);
+        startActivity(intent);
+    }
+
+    @OnMPermissionDenied(30)
+    public void onCallPermissionFailed(){
+        Toast.makeText(getContext(), "拨号所需权限未授权", Toast.LENGTH_SHORT).show();
+    }
+}

+ 177 - 0
app/src/main/java/com/android/chmo/ui/activity/me/ForgetPwdActivity.java

@@ -0,0 +1,177 @@
+package com.android.chmo.ui.activity.me;
+
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.android.chmo.R;
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.app.SpManager;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.Res;
+import com.android.chmo.http.service.UserService;
+import com.android.chmo.utils.CodeUtils;
+import com.android.chmo.utils.CommonUtils;
+import com.android.chmo.utils.VerifyCodeCounter;
+import com.google.gson.Gson;
+
+import butterknife.BindView;
+import butterknife.OnClick;
+
+
+/**
+ * Created by Administrator on 2018/8/16.
+ */
+
+public class ForgetPwdActivity extends BaseActivity {
+    @BindView(R.id.phone_content)
+    View phoneContent;
+    @BindView(R.id.pwd_content)
+    View pwdContent;
+
+    @BindView(R.id.phone)
+    EditText phoneEdit;
+    @BindView(R.id.password)
+    EditText passwordEdit;
+    @BindView(R.id.confirm_password)
+    EditText confirmPwdEdit;
+    @BindView(R.id.code)
+    EditText codeEdit;
+
+    @BindView(R.id.getCode)
+    TextView getCodeBtn;
+
+    private VerifyCodeCounter codeCounter;
+
+    private String code = ChmoApplication.getApp().getCode();
+
+
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_forget_pwd;
+    }
+
+    @Override
+    public void initView() {
+
+    }
+
+
+    @OnClick(R.id.getCode)
+    public void getCode() {
+        String phone = phoneEdit.getText().toString();
+        if(TextUtils.isEmpty(phone)) {
+            showToast("请输入手机号");
+            return;
+        }
+        if(!CommonUtils.isPhone(phone)) {
+            showToast("手机号不正确");
+            return;
+        }
+
+        code = CodeUtils.randomCode();
+        String codeStr = CodeUtils.getCodeStr(1,code);
+        showLoading();
+        UserService.getCode(phone,codeStr, new RequestCallback(){
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                ChmoApplication.getApp().setCode(code);
+                codeCounter = new VerifyCodeCounter(60000,1000,getCodeBtn);
+                codeCounter.start();
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("获取验证码失败");
+            }
+        });
+    }
+
+    @OnClick(R.id.next)
+    public void next() {
+        final String phone = phoneEdit.getText().toString();
+        String code = codeEdit.getText().toString();
+        if(TextUtils.isEmpty(phone)) {
+            showToast("请输入手机号");
+            return;
+        }
+        if(!CommonUtils.isPhone(phone)) {
+            showToast("手机号不正确");
+            return;
+        }
+
+        if(TextUtils.isEmpty(code)){
+            showToast("请输入验证码");
+            return;
+        }
+        if(!code.equals(this.code)) {
+            showToast("验证码不正确");
+            return;
+        }
+
+        phoneContent.setVisibility(View.GONE);
+        pwdContent.setVisibility(View.VISIBLE);
+    }
+
+
+    @OnClick(R.id.submit)
+    public void submit() {
+        final String phone = phoneEdit.getText().toString();
+        final String password = passwordEdit.getText().toString();
+        String confirmPwd = confirmPwdEdit.getText().toString();
+        String code = codeEdit.getText().toString();
+
+
+        if(TextUtils.isEmpty(password)){
+            showToast("请输入密码");
+            return;
+        }
+
+        if(password.length() < 6){
+            showToast("密码长度不少于6位");
+            return;
+        }
+        if(!password.equals(confirmPwd)) {
+            showToast("确认密码不一致");
+            return;
+        }
+
+
+        showLoading();
+        UserService.resetPwd(phone, password, new RequestCallback(){
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                Res res = new Gson().fromJson(result, Res.class);
+                if(res.msg.equals("fail")) {
+                    showToast(TextUtils.isEmpty(res.value) ? "重置失败" : res.value);
+                }else {
+                    //注册成功
+                    showToast("重置成功");
+                    SpManager.getInstance().setString("LoginPhone", phone);
+                    SpManager.getInstance().setString("LoginPwd", "");
+                    finish();
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("重置失败");
+            }
+        });
+
+    }
+
+
+
+    @OnClick(R.id.container)
+    public void containerClick() {
+        CommonUtils.closeKeybord(phoneEdit,this);
+    }
+}

+ 77 - 0
app/src/main/java/com/android/chmo/ui/activity/me/ModifyNameActivity.java

@@ -0,0 +1,77 @@
+package com.android.chmo.ui.activity.me;
+
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.chmo.R;
+import com.android.chmo.app.ChmoApplication;
+import com.android.chmo.base.BaseActivity;
+import com.android.chmo.http.RequestCallback;
+import com.android.chmo.http.response.Res;
+import com.android.chmo.http.service.UserService;
+import com.android.chmo.model.LoginUser;
+import com.android.chmo.ui.view.TopBar;
+import com.google.gson.Gson;
+
+import butterknife.BindView;
+
+/**
+ * Created by Administrator on 2018/8/6.
+ */
+
+public class ModifyNameActivity extends BaseActivity {
+    @BindView(R.id.topBar)
+    TopBar topBar;
+
+    @BindView(R.id.input)
+    EditText editText;
+
+    @Override
+    protected int getContentResId() {
+        return R.layout.activity_modify_name;
+    }
+
+    @Override
+    public void initView() {
+        LoginUser user = ChmoApplication.getApp().getLoginUser();
+        editText.setText(user.pet);
+
+        topBar.setRightBtn("保存", new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                save();
+            }
+        });
+    }
+
+    public void save() {
+        String name = editText.getText().toString();
+        if(TextUtils.isEmpty(name)) {
+            showToast("请输入昵称");
+            return;
+        }
+
+        showLoading();
+        UserService.modifyName(name, new RequestCallback() {
+            @Override
+            public void onSuccess(String result) {
+                hideLoading();
+                Res res = new Gson().fromJson(result,Res.class);
+                if(res.msg.equals("success")) {
+                    showToast("修改成功");
+                    setResult(RESULT_OK);
+                    finish();
+                }else {
+                    showToast("修改失败");
+                }
+            }
+
+            @Override
+            public void onFailure(String error) {
+                hideLoading();
+                showToast("修改失败");
+            }
+        });
+    }
+}

Неке датотеке нису приказане због велике количине промена