瀏覽代碼

init commit

lyn 7 年之前
當前提交
cb2e371e2a
共有 100 個文件被更改,包括 5232 次插入0 次删除
  1. 9 0
      .gitignore
  2. 18 0
      .idea/gradle.xml
  3. 33 0
      .idea/misc.xml
  4. 9 0
      .idea/modules.xml
  5. 12 0
      .idea/runConfigurations.xml
  6. 1 0
      app/.gitignore
  7. 55 0
      app/build.gradle
  8. 二進制
      app/libs/billing-release.aar
  9. 42 0
      app/proguard-rules.pro
  10. 二進制
      app/release/djbl109.apk
  11. 二進制
      app/release/djbl110.apk
  12. 二進制
      app/release/jxjdbl2.apk
  13. 1 0
      app/release/output.json
  14. 26 0
      app/src/androidTest/java/com/example/jxdjbl2/ExampleInstrumentedTest.java
  15. 59 0
      app/src/main/AndroidManifest.xml
  16. 8 0
      app/src/main/assets/DeviceInfo.ini
  17. 36 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/TvApplication.java
  18. 720 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/activity/CntvPlayerActivity.java
  19. 27 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/activity/DjblPayActivity.java
  20. 177 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/activity/LoginActivity.java
  21. 388 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/activity/MainActivity.java
  22. 174 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/activity/PayActivity.java
  23. 158 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/activity/VideoEndDialog.java
  24. 23 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/BannerItem.java
  25. 19 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/CheckQuery.java
  26. 20 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/CollectWatch.java
  27. 19 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/CommitJoinActivityResult.java
  28. 16 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/CreateOrderBackData.java
  29. 22 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/CreateQuery.java
  30. 14 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/CreateUserResult.java
  31. 14 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/DeviceInfoReturn.java
  32. 16 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/ErrorResult.java
  33. 21 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/H5Switch.java
  34. 19 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/JoinActivity.java
  35. 21 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/LoadingImage.java
  36. 15 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/SearchSingleSource.java
  37. 31 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/SingleSource.java
  38. 21 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/SourceDetail.java
  39. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/StyleData.java
  40. 31 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/StyleDetail.java
  41. 20 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/model/UserLogin.java
  42. 319 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/CrashHandler.java
  43. 48 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/FileUtil.java
  44. 152 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/HCQuery.java
  45. 412 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/LocalHttpRequest.java
  46. 82 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/LocalStore.java
  47. 163 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/OttLoginUtil.java
  48. 81 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/ScreenUtil.java
  49. 218 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/util/UrlManager.java
  50. 66 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CheckQueryViewModel.java
  51. 67 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CollectWatchViewModel.java
  52. 72 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CommitJoinActivityResultViewModel.java
  53. 71 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CommitSequenceIdViewModel.java
  54. 71 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CreateOrderViewModel.java
  55. 78 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CreateQueryViewModel.java
  56. 76 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CreateUserViewModel.java
  57. 66 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/DeviceInfoViewModel.java
  58. 69 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/ErrorDataViewModel.java
  59. 66 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/H5SwitchViewModel.java
  60. 68 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/JoinActivityViewModel.java
  61. 68 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/LoadingImageViewModel.java
  62. 73 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/SearchSingleSourceViewModel.java
  63. 76 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/UserLoginViewModel.java
  64. 25 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/BasicFactory.java
  65. 29 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CheckQueryFactory.java
  66. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CollectWatchFactory.java
  67. 11 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CommitJoinActivityResultFactory.java
  68. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CreateOrderFactory.java
  69. 29 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CreateQueryFactory.java
  70. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CreateUserFactory.java
  71. 11 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/DeviceInfoFactory.java
  72. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/ErrorFactory.java
  73. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/H5SwitchFactory.java
  74. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/JoinActivityFactory.java
  75. 11 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/LoadingImageFactory.java
  76. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/SingleSourceFactory.java
  77. 12 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/UserLoginFactory.java
  78. 20 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CheckQueryService.java
  79. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CollectWatchService.java
  80. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CommitJoinActivityResultService.java
  81. 16 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CreateOrderService.java
  82. 29 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CreateQueryService.java
  83. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CreateUserService.java
  84. 22 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/DeviceInfoService.java
  85. 26 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/ErrorService.java
  86. 15 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/H5SwitchService.java
  87. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/JoinActivityService.java
  88. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/LoadingImageService.java
  89. 16 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/SingleSourceService.java
  90. 17 0
      app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/UserLoginService.java
  91. 二進制
      app/src/main/jniLibs/VDS-2.4.6.jar
  92. 二進制
      app/src/main/jniLibs/adsdk.jar
  93. 二進制
      app/src/main/jniLibs/armeabi-v7a/libVDS.so
  94. 二進制
      app/src/main/jniLibs/armeabi-v7a/libadsdk.so
  95. 二進制
      app/src/main/jniLibs/armeabi-v7a/liblogsdk.so
  96. 二進制
      app/src/main/jniLibs/armeabi-v7a/libottlogin.so
  97. 二進制
      app/src/main/jniLibs/icntvplayersdk.jar
  98. 二進制
      app/src/main/jniLibs/logsdk.jar
  99. 二進制
      app/src/main/jniLibs/ottlogin.jar
  100. 0 0
      app/src/main/jniLibs/universal-image-loader-1.9.3.jar

+ 9 - 0
.gitignore

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

+ 18 - 0
.idea/gradle.xml

@@ -0,0 +1,18 @@
+<?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" />
+          </set>
+        </option>
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 33 - 0
.idea/misc.xml

@@ -0,0 +1,33 @@
+<?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="4">
+          <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="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+        </list>
+      </value>
+    </option>
+    <option name="myNotNulls">
+      <value>
+        <list size="4">
+          <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" />
+        </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>

+ 9 - 0
.idea/modules.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/JxDJBL2.iml" filepath="$PROJECT_DIR$/JxDJBL2.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.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

+ 55 - 0
app/build.gradle

@@ -0,0 +1,55 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 27
+    buildToolsVersion "27.0.2"
+    defaultConfig {
+        applicationId "com.guangzhou.haochuan.jxtv"
+        minSdkVersion 16
+        targetSdkVersion 27
+        versionCode 9
+        versionName "1.0.9"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        ndk {
+            abiFilters "armeabi-v7a"
+        }
+    }
+    buildTypes {
+        release {
+            minifyEnabled true
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+        debug {
+            debuggable true
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+repositories {
+    flatDir {
+        dirs 'libs'
+    }
+}
+
+dependencies {
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
+    compile(name: 'billing-release', ext: 'aar')
+    implementation 'com.android.support:appcompat-v7:27.0.2'
+    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
+    implementation files('src/main/jniLibs/adsdk.jar')
+    implementation files('src/main/jniLibs/icntvplayersdk.jar')
+    implementation files('src/main/jniLibs/logsdk.jar')
+    implementation files('src/main/jniLibs/ottlogin.jar')
+    implementation files('src/main/jniLibs/universal-image-loader-1.9.3.jar')
+    implementation files('src/main/jniLibs/VDS-2.4.6.jar')
+    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
+    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
+    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
+    implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
+    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
+    implementation 'com.android.volley:volley:1.1.0'
+    implementation 'com.github.bumptech.glide:glide:3.8.0'
+
+}

二進制
app/libs/billing-release.aar


+ 42 - 0
app/proguard-rules.pro

@@ -0,0 +1,42 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+-keepattributes Signature
+# Retain service method parameters.
+-keep interface * {
+    @retrofit2.http.* <methods>;
+}
+# Ignore annotation used for build tooling.
+-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
+
+-dontwarn okio.**
+-dontwarn com.squareup.okhttp3.**
+-keep class com.squareup.okhttp3.** { *; }
+-keep interface com.squareup.okhttp3.** { *; }
+-dontwarn javax.annotation.**
+
+#cntv
+-keep class tv.icntv.** { *; }
+-dontwarn tv.icntv.**
+
+#ystn
+-keep class com.ystgame.sdk.** { *; }
+-keep class com.istv.** { *; }

二進制
app/release/djbl109.apk


二進制
app/release/djbl110.apk


二進制
app/release/jxjdbl2.apk


+ 1 - 0
app/release/output.json

@@ -0,0 +1 @@
+[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":9},"path":"app-release.apk","properties":{"packageId":"com.guangzhou.haochuan.jxtv","split":"","minSdkVersion":"16"}}]

+ 26 - 0
app/src/androidTest/java/com/example/jxdjbl2/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.example.jxdjbl2;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() throws Exception {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.example.jxdjbl2", appContext.getPackageName());
+    }
+}

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

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.guangzhou.haochuan.jxtv">
+
+    <!-- app所需权限 -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_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.SEND_SMS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+    <!-- 未来电视所需权限 -->
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.GET_TASKS" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.REORDER_TASKS" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+
+    <application
+        android:name=".TvApplication"
+        android:allowBackup="true"
+        android:icon="@drawable/app_icon"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name=".activity.MainActivity"
+            android:hardwareAccelerated="true"
+            android:launchMode="singleTop"
+            android:process=":remote"
+            android:screenOrientation="landscape"></activity>
+        <activity
+            android:name=".activity.LoginActivity"
+            android:screenOrientation="landscape">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".activity.CntvPlayerActivity"
+            android:screenOrientation="landscape" />
+        <activity android:name=".activity.DjblPayActivity"
+            android:screenOrientation="landscape"></activity>
+    </application>
+
+</manifest>

+ 8 - 0
app/src/main/assets/DeviceInfo.ini

@@ -0,0 +1,8 @@
+[DEVICE]
+BootGuideServer=http://newtv.boot.ottcn.com:8080
+LoginType=1
+MacFile=/sys/class/efuse/mac_bt
+
+[LOG]
+; 1 日志开启  0 日志关闭
+LogOpen=1

+ 36 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/TvApplication.java

@@ -0,0 +1,36 @@
+package com.guangzhou.haochuan.jxtv;
+
+import android.app.Application;
+
+
+import com.guangzhou.haochuan.jxtv.util.CrashHandler;
+
+
+/**
+ * Created by yunhaipiaodi on 2017/9/13.
+ */
+
+public class TvApplication extends Application {
+    private static TvApplication instance;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        initCrashHandler();
+    }
+
+    private void initCrashHandler(){
+        CrashHandler crashHandler = CrashHandler.getInstance();
+        crashHandler.init(getApplicationContext());
+    }
+
+    // 单例模式中获取唯一的ExitApplication实例
+    public static TvApplication getInstance()
+    {   if(instance == null) {
+        instance = new TvApplication();
+        }
+        return instance;
+    }
+
+}

+ 720 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/activity/CntvPlayerActivity.java

@@ -0,0 +1,720 @@
+package com.guangzhou.haochuan.jxtv.activity;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+
+import com.guangzhou.haochuan.jxtv.R;
+import com.guangzhou.haochuan.jxtv.util.CrashHandler;
+import com.guangzhou.haochuan.jxtv.util.LocalStore;
+import com.guangzhou.haochuan.jxtv.util.OttLoginUtil;
+
+import java.util.LinkedHashMap;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import tv.icntv.been.IcntvPlayerInfo;
+import tv.icntv.icntvplayersdk.IcntvPlayer;
+import tv.icntv.icntvplayersdk.iICntvPlayInterface;
+
+public class CntvPlayerActivity extends Activity implements iICntvPlayInterface,
+        VideoEndDialog.OnClickListener{
+
+    private IcntvPlayer icntvPlayer = null;            //cntv播放器实例
+
+    private FrameLayout playerContainer;        //播放器容器
+
+    // 计时器
+    private Timer timer_pay;
+    private Timer timer_video_time;
+    private TimerTask task_video_timer;
+    private TimerTask task_pay;
+    //延迟执行滑动播放
+    private Timer delaySeekTimer;
+    private TimerTask delaySeekTimerTask;
+
+    //UI参数
+    private TextView videoTitle;                //视频标题
+    private ImageView loadingAnimation;         //加载动画
+    private FrameLayout loadingContainer;       //加载动画容器
+    private TextView payNotice;                 //提示计费文本
+    private ImageView playOrPause;              //暂停/播放按钮
+    private SeekBar seekBar;                    //播放进度条
+    private TextView currentTime;               //当前播放时间
+    private TextView duration;                  //视频时长
+    private RelativeLayout topBar;              //顶部栏
+    private RelativeLayout bottomBar;           //顶部栏
+
+    //控制参数
+    private int seekPercent = 1;                //视频跳跃百分比;
+    private int delayHiddenBarTime = 3000;      //延后隐藏操作条时间
+
+
+    private final String appId = "5aa0b1a82cf0a";         //未来电视视频播放ID
+    private final String fSource = "1018";                //日志数据来源
+
+    //上一个页面传过来的参数
+    private String videoSourceId = "";                      //素材ID
+    private String videoTitleValue = "";                         //素材标题
+    private String videoUrl = "";                           //素材播放地址
+    private String isFee = "";                              //该素材是否免费
+    private String examineId = "";                          //未来审核ID
+    private String examineStatus = "";                      //审核状态。10,通过;20,未通过;40,下架
+    private String examineType="";                       //审核类型
+
+    //退出菜单
+    private boolean showVideoEndDialog = false;
+
+    String TAG = "CntvPlayerActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_cntv_player);
+        //Toast.makeText(this,"uid:" + uId,Toast.LENGTH_SHORT).show();
+        getDataFromIntent();
+        initComponent();
+        showBarOnBeginPlay();
+        //String msg = OttLoginUtil.getInstance().getLoginStateMsg();
+        String deviceId = OttLoginUtil.getInstance().getDeviceId();
+        if(deviceId.isEmpty() || deviceId == null){
+           // Log.i(TAG,",重新初始化ott,msg:" + msg);
+            OttLoginUtil.getInstance().init(this, new OttLoginUtil.OnLoginListener() {
+                @Override
+                public void OnSuccess() {
+                    initPlayer();
+                }
+
+                @Override
+                public void onFail(String msg) {
+                    new AlertDialog.Builder(CntvPlayerActivity.this)
+                            .setMessage("抱歉!播放器初始化失败,点击'确定'退出当前播放")
+                            .setNegativeButton("确定", new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    playerRelease();
+                                    destroyPayTask();
+                                    CntvPlayerActivity.this.finish();
+                                }
+                            }).show();
+                }
+            });
+        }else{
+            initPlayer();
+        }
+
+    }
+
+
+    @Override
+    protected void onResume(){
+        super.onResume();
+        if(icntvPlayer != null){
+            if(!icntvPlayer.isPlaying()){
+                icntvPlayer.startVideo();
+            }
+        }
+    }
+
+    @Override
+    protected void onPause(){
+        super.onPause();
+        if(icntvPlayer != null){
+            if(icntvPlayer.isPlaying()){
+                icntvPlayer.pauseVideo();
+            }
+        }
+    }
+
+    @Override
+    protected void onStop(){
+        super.onStop();
+        playerRelease();
+        destroyPayTask();
+    }
+
+    private void getDataFromIntent(){
+        Intent intent = getIntent();
+        videoSourceId = intent.getStringExtra("sourceId");
+        videoTitleValue = intent.getStringExtra("title");
+        videoUrl = intent.getStringExtra("url");
+        isFee = intent.getStringExtra("isFee");
+        examineId = intent.getStringExtra("examineId");
+        examineStatus = intent.getStringExtra("examineStatus");
+        examineType = intent.getStringExtra("examineType");
+    }
+
+    //开场显示上下条,一段时间后隐藏
+    private void showBarOnBeginPlay(){
+        showBar();
+        new Thread(){
+            public void run(){
+                Looper.prepare();
+                new Handler().postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        CntvPlayerActivity.this.runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                hiddenBar();
+                            }
+                        });
+
+                    }
+                },delayHiddenBarTime);
+                Looper.loop();
+            }
+        }.start();
+    }
+
+    @Override
+    protected void onDestroy(){
+        //将全局参数赋值为null
+        videoSourceId = null;
+        videoTitle = null;
+
+        icntvPlayer = null;
+        playerContainer = null;
+        timer_pay = null;
+        timer_video_time = null;
+        task_video_timer = null;
+        task_pay = null;
+        delaySeekTimer = null;
+        delaySeekTimerTask = null;
+        videoTitle = null;
+        loadingAnimation = null;
+        loadingContainer = null;
+        payNotice = null;
+        playOrPause = null;
+        seekBar = null;
+        currentTime= null;
+        duration = null;
+        topBar = null;
+        bottomBar= null;
+
+        super.onDestroy();
+    }
+
+    private void initComponent(){
+        videoTitle = findViewById(R.id.title);
+        payNotice = findViewById(R.id.pay_notice);
+        playOrPause = findViewById(R.id.play_pause);
+        loadingAnimation = findViewById(R.id.loading_animation);
+        loadingContainer = findViewById(R.id.loading);
+        seekBar = findViewById(R.id.seek_bar);
+        currentTime = findViewById(R.id.time_current);
+        duration = findViewById(R.id.time_total);
+        topBar = findViewById(R.id.top_bar);
+        bottomBar = findViewById(R.id.bottom_bar);
+
+        playerContainer = findViewById(R.id.video_view);
+        videoTitle.setText(videoTitleValue);
+
+        if(isFee.equals("2")){
+            payNotice.setVisibility(View.VISIBLE);
+        }else if(isFee.equals("1")){
+            payNotice.setVisibility(View.INVISIBLE);
+        }
+        //开启加载动画
+        initLoadingAnimation();
+    }
+
+    private void initLoadingAnimation(){
+        loadingAnimation.setImageResource(R.drawable.tv_load_animation);
+        AnimationDrawable a = (AnimationDrawable)loadingAnimation.getDrawable();
+        a.start();
+    }
+
+   /* private void setPlayerData(){
+        new SearchSingleSourceViewModel(this,videoSourceId).addObserver(this);
+    }*/
+
+    private void initPlayer(){
+        try{
+            IcntvPlayerInfo icntvPlayerInfo = new IcntvPlayerInfo();    //播放器所需传入参数实例
+            icntvPlayerInfo.setPlayUrl(videoUrl);
+            icntvPlayerInfo.setApp_id(appId);
+            icntvPlayerInfo.setCheckType(examineType);
+            icntvPlayerInfo.setfSource(fSource);
+            icntvPlayerInfo.setProgramID(examineId);
+            icntvPlayerInfo.setDuration(0);      //还未实现,等待接口更新
+            icntvPlayerInfo.setPlayType("0");
+            Log.d(TAG,"初始化播放器");
+            if(icntvPlayer != null){
+                playerRelease();
+                icntvPlayer = null;
+            }
+            icntvPlayer = new IcntvPlayer(this, playerContainer, icntvPlayerInfo, this);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    private void showBar(){
+        topBar.setVisibility(View.VISIBLE);
+        bottomBar.setVisibility(View.VISIBLE);
+
+        initUpdatePlayTimeTask();
+    }
+
+    private void hiddenBar(){
+        topBar.setVisibility(View.GONE);
+        bottomBar.setVisibility(View.GONE);
+
+        destroyUpdatePlayTimeTask();
+    }
+
+    private void destroyPayTask(){
+        if(task_pay != null){
+            task_pay.cancel();
+        }
+    }
+
+    //更新当前播放时间
+    private void initUpdatePlayTimeTask(){
+        //启动更新视频进度任务
+        timer_video_time = new Timer();
+        task_video_timer = new TimerTask() {
+            @Override
+            public void run() {
+                if(icntvPlayer == null){
+                    return;
+                }
+
+                new Thread(){
+                    public void run(){
+                        Looper.prepare();
+                        new Handler().post(
+                                new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        CntvPlayerActivity.this.runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                //更新当前播放时间
+                                                String currentPlayTime = convertLongTimeToStr(icntvPlayer.getCurrentPosition());        //获得当前播放时间
+                                                currentTime.setText(currentPlayTime);
+                                            }
+                                        });
+                                    }
+                                }
+                        );
+                        Looper.loop();
+                    }
+                }.start();
+
+
+            }
+        };
+        timer_video_time.schedule(task_video_timer,0,1000);
+
+    }
+
+    private void destroyUpdatePlayTimeTask(){
+        if(task_video_timer != null){
+            task_video_timer.cancel();
+        }
+        timer_video_time.purge();
+    }
+
+    public  String convertLongTimeToStr(long time) {
+        int ss = 1000;
+        int mi = ss * 60;
+        int hh = mi * 60;
+
+        long hour = (time) / hh;
+        long minute = (time - hour * hh) / mi;
+        long second = (time - hour * hh - minute * mi) / ss;
+
+        String strHour = hour < 10 ? "0" + hour : "" + hour;
+        String strMinute = minute < 10 ? "0" + minute : "" + minute;
+        String strSecond = second < 10 ? "0" + second : "" + second;
+        if (hour > 0) {
+            return strHour + ":" + strMinute + ":" + strSecond;
+        } else {
+            return strMinute + ":" + strSecond;
+        }
+    }
+
+    public void playerRelease(){
+        destroyUpdatePlayTimeTask();
+        if(icntvPlayer == null){
+            return;
+        }
+        if(icntvPlayer.isPlaying()){
+            icntvPlayer.stopVideo();
+        }
+        icntvPlayer.release();
+    }
+
+
+    //重新播放
+    private void rePlay(){
+        playerRelease();
+        initPlayer();
+        showBarOnBeginPlay();
+        hasCompletion = false;
+    }
+
+
+    //播放/暂停
+    private void playOrPause(){
+        if(icntvPlayer == null){
+            return;
+        }
+        if(icntvPlayer.isPlaying()){
+            icntvPlayer.pauseVideo();
+            playOrPause.setImageResource(R.drawable.icon_play);
+            showBar();
+        }else{
+            icntvPlayer.startVideo();
+            playOrPause.setImageResource(R.drawable.icon_pause);
+            hiddenBar();
+        }
+    }
+
+    private void showVideoEndDialog(){
+        try{
+            VideoEndDialog videoEndDialog = new VideoEndDialog();
+            videoEndDialog.show(getFragmentManager(),"VideoEndDialog");
+            showVideoEndDialog = true;
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    //遥控事件
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_CENTER:      //播放/暂停
+                playOrPause();
+                return true;
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+                seekBack();
+                return true;
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                seekForward();
+                return true;
+            case KeyEvent.KEYCODE_BACK:      //到顶跳到相应tab
+                if(!showVideoEndDialog){
+                    showVideoEndDialog();
+                    //Toast.makeText(this,"显示VideoEndDialog",Toast.LENGTH_SHORT).show();
+                    return true;
+                }else{
+                    return false;
+                }
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                hiddenBar();
+                return true;
+        }
+        return false;
+    }
+
+
+    //当用户连续点击“前进”或者“后退时”,需要延时执行,好一次性滑动到目标位置
+    private void seekBack(){
+        if(icntvPlayer == null){
+            return;
+        }
+        showBar();
+        int backDistance = icntvPlayer.getDuration()*seekPercent/100;
+        int currentPosition = icntvPlayer.getCurrentPosition();
+        int seekPosition = currentPosition - backDistance;
+        seekBar.setProgress(seekPosition);
+        playerDelaySeek();
+        destroyUpdatePlayTimeTask();
+    }
+
+    private void seekForward(){
+        if(icntvPlayer == null){
+            return;
+        }
+        showBar();
+        int backDistance = icntvPlayer.getDuration()*seekPercent/100;
+        int currentPosition = icntvPlayer.getCurrentPosition();
+        int seekPosition = currentPosition + backDistance;
+        seekBar.setProgress(seekPosition);
+        playerDelaySeek();
+        destroyUpdatePlayTimeTask();
+    }
+
+
+
+    private void playerDelaySeek(){
+        delaySeekTimer = new Timer();
+        if(delaySeekTimerTask != null)
+        {
+            delaySeekTimerTask.cancel();
+        }
+        delaySeekTimer.purge();
+        delaySeekTimerTask = new TimerTask() {
+            @Override
+            public void run() {
+                new Thread(){
+                    public void run(){
+                        Looper.prepare();
+                        new Handler().post(
+                                new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        CntvPlayerActivity.this.runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                if(icntvPlayer == null){
+                                                    return;
+                                                }
+                                                int seekToPosition = seekBar.getProgress();
+                                                icntvPlayer.seekTo(seekToPosition);
+                                                initUpdatePlayTimeTask();
+                                                hiddenBar();
+                                            }
+                                        });
+                                    }
+                                });
+                        Looper.loop();
+                    }
+                }.start();
+            }
+        };
+        delaySeekTimer.schedule(delaySeekTimerTask,2000);
+    }
+
+    //视频事件
+    @Override
+    public void onPrepared(LinkedHashMap<String, String> linkedHashMap) {
+        loadingContainer.setVisibility(View.GONE);
+
+        //设置seekbar最大值
+        seekBar.setMax(icntvPlayer.getDuration());
+        seekBar.setProgress(0);
+
+        //设置视频时长显示
+        duration.setText(convertLongTimeToStr(icntvPlayer.getDuration()));
+
+        if(!LocalStore.getInstance().getIsVip(this)){
+            if(isFee.equals("2")){
+                initPayTimeTask();
+            }
+        }
+    }
+
+    //监控当前观看时间,弹出计费
+
+    private void initPayTimeTask(){
+        timer_pay = new Timer();
+        task_pay = new TimerTask() {
+            @Override
+            public void run() {
+                new Thread(){
+                    public void run(){
+                        Looper.prepare();
+                        new Handler().post(
+                                new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        //Toast.makeText(CntvPlayerActivity.this,"监控计费时间",Toast.LENGTH_SHORT).show();
+                                        if(icntvPlayer.getCurrentPosition()/1000 > 30){
+                                            //跳转到计费界面
+                                            CntvPlayerActivity.this.runOnUiThread(new Runnable() {
+                                                @Override
+                                                public void run() {
+                                                    playerRelease();
+                                                    //Toast.makeText(CntvPlayerActivity.this,"跳转计费页面",Toast.LENGTH_SHORT).show();
+                                                    setResult(3);
+                                                    destroyPayTask();
+                                                    CntvPlayerActivity.this.finish();
+                                                }
+                                            });
+                                        }
+                                    }
+                                });
+                        Looper.loop();
+                    }
+                }.start();
+
+            }
+        };
+        timer_pay.schedule(task_pay,0,1000);
+    }
+
+    private boolean hasCompletion = false;
+    @Override
+    public void onCompletion() {
+        showVideoEndDialog();
+    }
+
+
+    @Override
+    public void onBufferStart(String s) {
+        loadingContainer.setVisibility(View.VISIBLE);
+    }
+
+    @Override
+    public void onBufferEnd(String s) {
+        loadingContainer.setVisibility(View.GONE);
+    }
+
+    @Override
+    public void onError(int i, int i1, String s) {
+        new AlertDialog.Builder(this)
+                .setTitle("错误")
+                .setMessage("播放错误:" + s)
+                .setPositiveButton("确定",new DialogInterface.OnClickListener(){
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        CntvPlayerActivity.this.finish();
+                    }
+                }).show();
+        String cnTvError = "";
+        switch (i){
+            case 1001:
+                cnTvError = "未来电视播放错误. " + "错误类型:"
+                        + i + "; 错误值:" + i1 + "; 错误消息:" + "CDN视频源调度失败";
+                break;
+            case 123456:
+                cnTvError = "未来电视播放错误. " + "错误类型:"
+                        + i + "; 错误值:" + i1 + "; 错误消息:" + "SDK鉴权失败";
+                break;
+        }
+        CrashHandler.getInstance().saveCrashInfoToWeb(cnTvError);
+    }
+
+
+    @Override
+    public void onTimeout() {
+        new AlertDialog.Builder(this)
+                .setTitle("超时")
+                .setMessage("加载视频超时,点击“确定”返回")
+                .setPositiveButton("确定",new DialogInterface.OnClickListener(){
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        playerRelease();
+                        destroyPayTask();
+                        CntvPlayerActivity.this.finish();
+                    }
+                }).show();
+            Toast.makeText(this,"视频超时,退出",Toast.LENGTH_SHORT).show();
+        }
+
+
+
+  /*  @Override
+    public void update(Observable o, Object arg) {
+        if(o instanceof SearchSingleSourceViewModel){
+            SearchSingleSourceViewModel searchSingleSourceViewModel = (SearchSingleSourceViewModel)o;
+            searchSingleSource = searchSingleSourceViewModel.getSearchSingleSource();
+            if(searchSingleSource == null){
+                return;
+            }
+            setSearchSingleSource(searchSingleSource);
+        }
+    }*/
+
+
+    /*private void setSearchSingleSource(SearchSingleSource searchSingleSource){
+        if(searchSingleSource != null){
+            if(searchSingleSource.code == 0){
+                icntvPlayerInfo = new IcntvPlayerInfo();
+                SingleSource singleSource = searchSingleSource.data;
+                if(singleSource.isFee.equals("1")){
+                    isFee = false;
+                    payNotice.setVisibility(View.GONE);
+                }else if(singleSource.isFee.equals("2")){
+                    isFee = true;
+                }
+
+                if(!singleSource.examine.examineStatus.equals("10")){
+                    //未审核通过
+                    CrashHandler
+                            .getInstance()
+                            .saveCrashInfoToWeb("播放的视频,ID:"
+                                    + searchSingleSource.data.sourceId
+                                    +",未通过审核,状态ID;" + singleSource.examine.examineStatus);
+                    new AlertDialog.Builder(this)
+                            .setMessage("视频未通过审核,或已下架,返回!")
+                            .setNegativeButton("确定", new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    CntvPlayerActivity.this.finish();
+                                }
+                            }).show();
+                }
+                *//*Toast.makeText(this,"sourceId:" + singleSource.sourceId
+                +"审核ID:" + singleSource.examine.examineId
+                        + "审核状态:"+ singleSource.examine.examineStatus,Toast.LENGTH_LONG).show();*//*
+
+                try{
+                    icntvPlayerInfo.setPlayUrl(singleSource.videoUrl);
+                    icntvPlayerInfo.setApp_id(appId);
+                    icntvPlayerInfo.setCheckType(singleSource.examine.examineType);
+                    icntvPlayerInfo.setfSource(fSource);
+                    icntvPlayerInfo.setProgramID(singleSource.examine.examineId);
+                    icntvPlayerInfo.setDuration(singleSource.movieTime);      //还未实现,等待接口更新
+                    icntvPlayerInfo.setPlayType("0");
+                    if(icntvPlayer != null){
+                        playerRelease();
+                        icntvPlayer = null;
+                    }
+                    icntvPlayer = new IcntvPlayer(this, playerContainer, icntvPlayerInfo, this);
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+
+                //videoSourceId = searchSingleSource.data.sourceId;
+
+                recordWatchHistory(videoSourceId);
+            }else {
+                Toast.makeText(this,"当前视频未通过审核,请退出播放!",Toast.LENGTH_SHORT).show();
+            }
+        }else{
+            Toast.makeText(this,"未获得当前视频信息,请退出播放!",Toast.LENGTH_SHORT).show();
+        }
+    }*/
+
+   /* //记录播放记录
+    private void recordWatchHistory(String sourceId){
+        if(sourceId.isEmpty()){
+            return;
+        }
+
+        new CollectWatchViewModel(sourceId).addObserver(this);
+    }*/
+
+
+    @Override
+    public void onPlayCurrent() {
+        if(hasCompletion){
+            rePlay();
+        }
+    }
+
+    @Override
+    public void onExit() {
+        playerRelease();
+        destroyPayTask();
+        setResult(3);
+        this.finish();
+    }
+
+    @Override
+    public void onDismiss() {
+        showVideoEndDialog = false;
+    }
+
+}

+ 27 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/activity/DjblPayActivity.java

@@ -0,0 +1,27 @@
+package com.guangzhou.haochuan.jxtv.activity;
+
+import android.os.Bundle;
+
+import com.guangzhou.haochuan.jxtv.R;
+
+public class DjblPayActivity extends PayActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_djbl_pay);
+        monthPay();
+    }
+
+    @Override
+    protected void onPaySuccess(){
+        setResult(1);
+        this.finish();
+    }
+
+    @Override
+    protected void onPayFail(){
+        setResult(-1);
+        this.finish();
+    }
+}

+ 177 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/activity/LoginActivity.java

@@ -0,0 +1,177 @@
+package com.guangzhou.haochuan.jxtv.activity;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.widget.RelativeLayout;
+
+import com.guangzhou.haochuan.jxtv.util.FileUtil;
+import com.guangzhou.haochuan.jxtv.util.LocalStore;
+import com.guangzhou.haochuan.jxtv.util.OttLoginUtil;
+import com.guangzhou.haochuan.jxtv.R;
+import com.guangzhou.haochuan.jxtv.util.ScreenUtil;
+import com.ystgame.sdk.billing.api.GameInterface;
+import com.ystgame.sdk.billing.api.MonthAuthResult;
+
+import java.io.File;
+import java.util.Observable;
+import java.util.Observer;
+
+public class LoginActivity extends Activity {
+
+    //电信计费参数
+    private int appId = 252;             //唯一用户标识,在AndroidMainfest.xml里的Meta-Data里设置
+    private String appName = "电竞部落";
+    private String providerName = "广州浩传";       //内容提供商
+    private String serviceTel = "020-38468029";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+        init();
+        initYst();
+    }
+
+    private void init(){
+        RelativeLayout background = findViewById(R.id.back_image);
+        //设置背景图片
+        String path = FileUtil.getInstance().getLoadingImageSavePath(this, ScreenUtil.getInstance().getDpiType(this));
+        File file = new File(path);
+        if(file.exists()){
+            background.setBackground(Drawable.createFromPath(path));
+        }
+    }
+
+    private void initYst(){
+        LoginActivity.this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try{
+                    GameInterface.initializeApp(LoginActivity.this,appId,appName,providerName,serviceTel,new GameInterface.IAppUidCallback(){
+                        @Override
+                        public void onResult(int i, String s) {
+                            switch (i){
+                                case 0:
+                                    Log.d("Telecom","init success");
+                                    auth();
+                                    //Toast.makeText(TelecomPayActivity.this,"易视腾初始化成功",Toast.LENGTH_SHORT).show();
+                                    break;
+                                default:
+                                    new AlertDialog.Builder(LoginActivity.this)
+                                            .setTitle("错误")
+                                            .setMessage("初始化失败,点击'确定'退出" )
+                                            .setNegativeButton("确定", new DialogInterface.OnClickListener() {
+                                                @Override
+                                                public void onClick(DialogInterface dialog, int which) {
+                                                    LoginActivity.this.finish();
+                                                }
+                                            }).show();
+                                    break;
+                            }
+                        }
+                    });
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+
+    //包月鉴权(此函数还未用到,因为现在还是从后台获取用户是否包月状态,后续后台需要更改,再用)
+    protected void auth()
+    {
+        try{
+            // TODO Auto-generated method stub
+            GameInterface.monthAuth(this,new GameInterface.IAuthCallback()
+            {
+                @Override
+                public void onResult(final int code, final String msg)
+                {
+                    // TODO Auto-generated method stub
+                    switch(code)
+                    {
+                        case MonthAuthResult.AUTH_SUCCESS:
+                            //鉴权成功 用户已购买...
+                            LocalStore.getInstance().storeIsVip(LoginActivity.this,true);
+                            OttLogin();
+                            break;
+                        default:
+                            // 其他错误,服务器端处理请求失败
+                            LocalStore.getInstance().storeIsVip(LoginActivity.this,false);
+                            OttLogin();
+                            break;
+                    }
+
+                }
+            });
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+
+    private void OttLogin(){
+        OttLoginUtil.getInstance().init(this, new OttLoginUtil.OnLoginListener() {
+            @Override
+            public void OnSuccess() {
+                LocalStore.getInstance().storeLoginOrNot(LoginActivity.this,true);
+                //创建用户
+                String uId= String.valueOf(OttLoginUtil.getInstance().getDeviceId());
+                //Toast.makeText(LoginActivity.this,"uid:" + uId,Toast.LENGTH_SHORT).show();
+                if(uId.equals("0")){
+                    uId = "13";
+                }
+                LocalStore.getInstance().storeUserId(LoginActivity.this,uId);
+                String templateId = String.valueOf(OttLoginUtil.getInstance().getTemplateID());
+                String platformId = String.valueOf(OttLoginUtil.getInstance().getPlatformID());
+                String mac = String.valueOf(OttLoginUtil.getInstance().getMac());
+                LocalStore.getInstance().storeMac(LoginActivity.this,mac);
+                //new CreateUserViewModel(uId,templateId,platformId,mac).addObserver(LoginActivity.this);
+                delayTrans();
+            }
+
+            @Override
+            public void onFail(String msg) {
+                new AlertDialog.Builder(LoginActivity.this)
+                        .setTitle("错误")
+                        .setMessage("验证失败:" + msg + "\n" + "点击'确定'退出" )
+                        .setNegativeButton("确定", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                LoginActivity.this.finish();
+                            }
+                        }).show();
+                LocalStore.getInstance().storeLoginOrNot(LoginActivity.this,false);
+                //new CreateUserViewModel("","","","").addObserver(LoginActivity.this);
+                delayTrans();
+            }
+        });
+    }
+
+    private void delayTrans(){
+        new Thread(){
+            public void run(){
+                Looper.prepare();
+                new Handler().postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        Intent intent = new Intent(LoginActivity.this,MainActivity.class);
+                        LoginActivity.this.startActivity(intent);
+                        LoginActivity.this.finish();
+                    }
+                },2000);
+                Looper.loop();
+            }
+        }.start();
+    }
+
+}

+ 388 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/activity/MainActivity.java

@@ -0,0 +1,388 @@
+package com.guangzhou.haochuan.jxtv.activity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.webkit.JavascriptInterface;
+import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.ImageRequest;
+import com.android.volley.toolbox.Volley;
+import com.guangzhou.haochuan.jxtv.R;
+import com.guangzhou.haochuan.jxtv.model.H5Switch;
+import com.guangzhou.haochuan.jxtv.model.LoadingImage;
+import com.guangzhou.haochuan.jxtv.util.FileUtil;
+import com.guangzhou.haochuan.jxtv.util.LocalHttpRequest;
+import com.guangzhou.haochuan.jxtv.util.LocalStore;
+import com.guangzhou.haochuan.jxtv.util.ScreenUtil;
+import com.guangzhou.haochuan.jxtv.viewModel.DeviceInfoViewModel;
+import com.guangzhou.haochuan.jxtv.viewModel.H5SwitchViewModel;
+import com.guangzhou.haochuan.jxtv.viewModel.LoadingImageViewModel;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Observable;
+import java.util.Observer;
+
+public class MainActivity extends PayActivity {
+
+    String TAG = "MainActivity";
+    WebView webView;
+    int playerRequestCode = 2;
+    int payRequestCode = 2;
+
+    Boolean isPlaying = false;
+    FrameLayout container;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+        init();
+    }
+
+
+    @Override
+    protected void onActivityResult(int requestCode,int resultCode,Intent data){
+        super.onActivityResult(requestCode,resultCode,data);
+        onPlayerBack();
+        if(requestCode == playerRequestCode){
+            isPlaying = false;
+            if(resultCode ==3){
+               gotoPayActivity();
+            }
+        }else if(requestCode == payRequestCode){
+            onPayBack(resultCode);
+        }
+    }
+    
+    private void gotoPayActivity(){
+        Intent intent = new Intent(this,DjblPayActivity.class);
+        MainActivity.this.startActivityForResult(intent,payRequestCode);
+    }
+
+    private void init(){
+        container = findViewById(R.id.webview_container);
+        String url = "http://117.169.11.222:8000/h5v2/index.html";
+        webView = new WebView(this);
+        container.addView(webView,new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
+        webView.getSettings().setJavaScriptEnabled(true);
+        webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
+        webView.setWebChromeClient(new WebChromeClient() {
+            @Override
+            public void onProgressChanged(WebView view, int progress) {
+                MainActivity.this.setProgress(progress * 1000);
+            }
+        });
+        webView.setWebViewClient(new WebViewClient() {
+            @Override
+            public void onPageFinished(WebView view, String url)
+            {
+                super.onPageFinished(view, url);
+            }
+
+            @Override
+            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+                Toast.makeText(MainActivity.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
+            }
+        });
+        webView.addJavascriptInterface(new AndroidToJs(h5Result),"djbl2");
+        webView.loadUrl(url);
+
+        //下载loading图
+        new LoadingImageViewModel(ScreenUtil.getInstance().getDpiType(this)).addObserver(this);
+
+
+        //活动开关
+        if(!LocalStore.getInstance().getDeviceInfoSaved(this)){
+            new H5SwitchViewModel().addObserver(this);
+        }
+    }
+
+    String deviceId = "";
+    private void saveInfo(){
+        final LocalHttpRequest localHttpRequest = new LocalHttpRequest();
+
+        localHttpRequest.getUrls(this, new LocalHttpRequest.GetUrlsListener() {
+            @Override
+            public void onFinished() {
+                localHttpRequest.getParam1(MainActivity.this, new LocalHttpRequest.ResultListener() {
+                    @Override
+                    public void onResult(String result) {
+                        if(result != null){
+                            deviceId = result;
+                        }
+                        localHttpRequest.getParam2(MainActivity.this, new LocalHttpRequest.ResultListener() {
+                            @Override
+                            public void onResult(String result) {
+                                final String token = result ==null?"":result;
+                                localHttpRequest.getParam3(MainActivity.this, new LocalHttpRequest.ResultListener() {
+                                    @Override
+                                    public void onResult(String result) {
+                                        String phone = result;
+                                        int isVip = LocalStore.getInstance().getIsVip(MainActivity.this)?1:0;
+                                        String uId = LocalStore.getInstance().getUserId(MainActivity.this);
+                                        new DeviceInfoViewModel(deviceId,phone,token,isVip,uId);
+                                    }
+                                });
+                            }
+                        });
+                    }
+                });
+            }
+        });
+
+
+    }
+
+    //下载LoginActivity背景图
+    private void downloadLoadingImage(String imageUrl){
+        final String path = FileUtil.getInstance().getLoadingImageSavePath(this,ScreenUtil.getInstance().getDpiType(this));
+        File file = new File(path);
+        if(file.exists()){
+            file.delete();
+        }
+        Volley.newRequestQueue(this).add(new ImageRequest(imageUrl, new Response.Listener<Bitmap>() {
+            @Override
+            public void onResponse(Bitmap response) {
+                    saveImage(path,response);
+            }
+        },2000,2000,ImageView.ScaleType.CENTER, null,new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        }));
+    }
+
+    public void saveImage(String imagePath,Bitmap bmp) {
+        File file = new File(imagePath);
+        try {
+            FileOutputStream fos = new FileOutputStream(file);
+            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
+            fos.flush();
+            fos.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private H5Result h5Result = new H5Result() {
+        @Override
+        public void videoPlay(String url,String title,String sourceId,String isFee,String examineId,String examineStatus,String examineType) {
+            if(isPlaying){
+                return;
+            }
+            if(!examineStatus.equals("10")){
+                Toast.makeText(MainActivity.this,"视频未通过审核,或已下架",Toast.LENGTH_SHORT).show();
+                return;
+            }
+            Intent intent = new Intent(MainActivity.this,CntvPlayerActivity.class);
+            intent.putExtra("url",url);
+            intent.putExtra("title",title);
+            intent.putExtra("sourceId",sourceId);
+            intent.putExtra("isFee",isFee);
+            intent.putExtra("examineId",examineId);
+            intent.putExtra("examineStatus",examineStatus);
+            intent.putExtra("examineType",examineType);
+            MainActivity.this.startActivityForResult(intent,playerRequestCode);
+            isPlaying = true;
+        }
+    };
+
+    //将原生Toast包含在UI线程中
+    private void Toast(final Activity activity, final String msg){
+        activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(activity,msg,Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    //安卓交互类
+    public class AndroidToJs{
+        H5Result listener;
+        public AndroidToJs(H5Result h5Result){
+            this.listener = h5Result;
+        }
+
+        @JavascriptInterface
+        public void play(final String sourceId,final String title,final String url,final String isFee,String examineId,String examineStatus,String examineType){
+            listener.videoPlay(url,title,sourceId,isFee,examineId,examineStatus,examineType);
+
+        }
+
+        @JavascriptInterface
+        public void pay(){
+           gotoPayActivity();
+        }
+
+
+        @JavascriptInterface
+        public void appExit(){
+            MainActivity.this.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    MainActivity.this.finish();
+                }
+            });
+        }
+
+        @JavascriptInterface
+        public String getUser(){
+            return LocalStore.getInstance().getUserId(MainActivity.this);
+        }
+
+        @JavascriptInterface
+        public int  getVipState(){
+            boolean vipState = LocalStore.getInstance().getIsVip(MainActivity.this);
+            return vipState?1:-1;
+        }
+
+        @JavascriptInterface
+        public String getMac(){
+            return LocalStore.getInstance().getMac(MainActivity.this);
+        }
+
+        @JavascriptInterface
+        public int getVersionCode(){
+            try{
+                PackageInfo packageInfo = MainActivity.this.getPackageManager().getPackageInfo(MainActivity.this.getPackageName(),0);
+                return packageInfo.versionCode;
+            }catch (Exception e){
+                e.printStackTrace();
+                return 0;
+            }
+        }
+
+        @JavascriptInterface
+        public String getVersionName(){
+            try{
+                PackageInfo packageInfo = MainActivity.this.getPackageManager().getPackageInfo(MainActivity.this.getPackageName(),0);
+                return packageInfo.versionName;
+            }catch (Exception e){
+                e.printStackTrace();
+                return "";
+            }
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        onJsBack();
+    }
+
+    //调用js返回事件处理回调函数
+    private void onJsBack(){
+        final int version = Build.VERSION.SDK_INT;
+        if(version>18){
+            webView.evaluateJavascript("javascript:onBackEvent()", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String value) {
+                    //此处为 js 返回的结果
+                }
+            });
+        }else{
+            webView.loadUrl("javascript:onBackEvent()");
+        }
+    }
+
+    //播放器返回回调函数
+    private void onPlayerBack(){
+        final int version = Build.VERSION.SDK_INT;
+        if(version>18){
+            webView.evaluateJavascript("javascript:onPlayBackEvent()", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String value) {
+                    //此处为 js 返回的结果
+                }
+            });
+        }else{
+            webView.loadUrl("javascript:onPlayBackEvent()");
+        }
+    }
+
+    //js支付回调函数
+    private void onPayBack(int payResult){
+        final int version = Build.VERSION.SDK_INT;
+        if(version>18){
+            webView.evaluateJavascript("javascript:onPayResult(" + payResult + ")", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String value) {
+                    //此处为 js 返回的结果
+                }
+            });
+        }else{
+            webView.loadUrl("javascript:onPayResult(" + payResult + ")");
+        }
+    }
+
+    public interface H5Result {
+        public void videoPlay(String url,String title,String sourceId,
+                              String isFee,String examineId,String examineStatus,String examineType);
+    }
+
+
+    @Override
+    protected void onDestroy(){
+        if(webView != null){
+            webView.clearCache(true);
+            webView.clearFormData();
+            webView.clearMatches();
+            webView.clearSslPreferences();
+            webView.clearDisappearingChildren();
+            webView.clearHistory();
+            webView.clearAnimation();
+            webView.loadUrl("about:blank");
+            webView.removeAllViews();
+            webView.freeMemory();
+
+            webView = null;
+        }
+
+        if(container != null){
+            container = null;
+        }
+
+        super.onDestroy();
+    }
+
+    @Override
+    public void update(Observable o, Object arg) {
+        super.update(o,arg);
+        if(o instanceof LoadingImageViewModel){
+            LoadingImageViewModel loadingImageViewModel = (LoadingImageViewModel)o;
+            LoadingImage loadingImage = loadingImageViewModel.getLoadingImage();
+            if(loadingImage.code == 0){
+                downloadLoadingImage(loadingImage.data.imgUrl);
+            }
+        }if(o instanceof H5SwitchViewModel){
+            H5SwitchViewModel h5SwitchViewModel = (H5SwitchViewModel)o;
+            H5Switch h5Switch = h5SwitchViewModel.getH5Switch();
+            if(h5Switch.code == 0){
+                if(h5Switch.data.equipMessage == 100){
+                    saveInfo();
+                }
+            }
+        }
+    }
+}

+ 174 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/activity/PayActivity.java

@@ -0,0 +1,174 @@
+package com.guangzhou.haochuan.jxtv.activity;
+
+import android.app.Activity;
+import android.widget.Toast;
+
+import com.guangzhou.haochuan.jxtv.model.CreateOrderBackData;
+import com.guangzhou.haochuan.jxtv.model.H5Switch;
+import com.guangzhou.haochuan.jxtv.model.JoinActivity;
+import com.guangzhou.haochuan.jxtv.util.CrashHandler;
+import com.guangzhou.haochuan.jxtv.util.HCQuery;
+import com.guangzhou.haochuan.jxtv.util.LocalHttpRequest;
+import com.guangzhou.haochuan.jxtv.util.LocalStore;
+import com.guangzhou.haochuan.jxtv.viewModel.CreateOrderViewModel;
+import com.guangzhou.haochuan.jxtv.viewModel.H5SwitchViewModel;
+import com.guangzhou.haochuan.jxtv.viewModel.JoinActivityViewModel;
+import com.ystgame.sdk.billing.api.BillingResult;
+import com.ystgame.sdk.billing.api.GameInterface;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Random;
+
+/**
+ * Created by 浩传 on 2018/6/23.
+ */
+
+public class PayActivity extends Activity implements Observer{
+
+    protected void monthPay(){
+        //创建订单
+        String orderNo = getOrderNo();
+        String userId = LocalStore.getInstance().getUserId(this);
+        new CreateOrderViewModel(this,userId,orderNo).addObserver(this);
+    }
+
+    private String getOrderNo(){
+        //获取当前时间
+        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
+        String currentTime = df.format(new Date());
+
+        //获取时间戳
+        String time = String.valueOf(System.currentTimeMillis());
+
+        //生成8位随机数
+        String random = createRandomCharData(8);
+
+        return currentTime+ time + random;
+
+    }
+
+    private String createRandomCharData(int length)
+    {
+        StringBuilder sb=new StringBuilder();
+        Random randData=new Random();
+        int data=0;
+        for(int i=0;i<length;i++)
+        {
+            data=randData.nextInt(10);//仅仅会生成0~9
+            sb.append(data);
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public void update(Observable o, Object arg) {
+        if(o instanceof CreateOrderViewModel){
+            CreateOrderViewModel createOrderViewModel = (CreateOrderViewModel)o;
+            CreateOrderBackData createOrderBackData = createOrderViewModel.getCreateOrderData();
+            if(createOrderBackData.code == 0){       //成功
+                telecomPay(createOrderBackData.data);
+            }else{
+                Toast.makeText(this,"交易请求失败:" + createOrderBackData.msg, Toast.LENGTH_SHORT).show();
+                return;
+            }
+        }else if(o instanceof H5SwitchViewModel){
+            H5SwitchViewModel h5SwitchViewModel = (H5SwitchViewModel)o;
+            H5Switch h5Switch = h5SwitchViewModel.getH5Switch();
+            if(h5Switch.code == 0){
+                switch (h5Switch.data.powerOne){
+                    case -99:
+
+                        break;
+                    case 100:
+                        HCQuery hcQuery = new HCQuery();
+                        hcQuery.getPhone(PayActivity.this, new LocalHttpRequest.ResultListener() {
+                            @Override
+                            public void onResult(String result) {
+                                new JoinActivityViewModel(result).addObserver(PayActivity.this);
+                            }
+                        });
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }else if(o instanceof JoinActivityViewModel){
+            JoinActivityViewModel joinActivityViewModel = (JoinActivityViewModel)o;
+            JoinActivity joinActivity = joinActivityViewModel.getJoinActivity();
+            if(joinActivity.code == 0){
+                //LocalStore.getInstance().storeDeviceInfoSwitchCode(this,h5Switch.data.equipMessage);
+                switch (joinActivity.data.status){
+                    case -10:
+
+                        break;
+                    case 10:
+                        HCQuery hcQuery = new HCQuery();
+                        hcQuery.reQuery(PayActivity.this);
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    protected void telecomPay(final String paySn){
+        PayActivity.this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                GameInterface.doMonthBilling(PayActivity.this,paySn, new GameInterface.IMonthPayback()
+                {
+                    @Override
+                    public void onResult(final int code, String orderId, String msg)
+                    {
+                        switch (code)
+                        {
+                            case BillingResult.SUCCESS:
+                                LocalStore.getInstance().storeIsVip(PayActivity.this,true);
+                                onPaySuccess();
+                                break;
+                            case BillingResult.PROCESSING:
+                                LocalStore.getInstance().storeIsVip(PayActivity.this,false);
+                                onPayFail();
+                                new H5SwitchViewModel().addObserver(PayActivity.this);
+                                break;
+                            case BillingResult.FAILED:
+                                LocalStore.getInstance().storeIsVip(PayActivity.this,false);
+                                onPayFail();
+                                new H5SwitchViewModel().addObserver(PayActivity.this);
+                                break;
+                            case BillingResult.CANCELLED:
+                                LocalStore.getInstance().storeIsVip(PayActivity.this,false);
+                                onPayFail();
+                                new H5SwitchViewModel().addObserver(PayActivity.this);
+                                break;
+                            case BillingResult.CANCELLED_RETURN:
+                                LocalStore.getInstance().storeIsVip(PayActivity.this,false);
+                                onPayFail();
+                                new H5SwitchViewModel().addObserver(PayActivity.this);
+                                break;
+                            default:
+                                LocalStore.getInstance().storeIsVip(PayActivity.this,false);
+                                CrashHandler.getInstance().saveCrashInfoToWeb("易视腾计费失败:" + msg);
+                                onPayFail();
+                                new H5SwitchViewModel().addObserver(PayActivity.this);
+                                break;
+                        }
+                    }
+
+                });
+            }
+        });
+    }
+
+    protected void onPaySuccess(){
+
+    }
+
+    protected void onPayFail(){
+
+    }
+}

+ 158 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/activity/VideoEndDialog.java

@@ -0,0 +1,158 @@
+package com.guangzhou.haochuan.jxtv.activity;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.guangzhou.haochuan.jxtv.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+/**
+ * Created by yunhaipiaodi on 2017/10/13.
+ */
+
+public class VideoEndDialog extends DialogFragment{
+
+
+
+    private OnClickListener mListener;
+
+    private long  mLastClickTime = 0;
+
+
+    FrameLayout continueWatch;
+    FrameLayout exit;
+
+
+
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        this.setCancelable(false);
+        //Toast.makeText(getActivity(),"currentPos:" + currentPos + "; maxPos:" + maxPos,Toast.LENGTH_LONG).show();
+    }
+
+    @Override
+    public void onAttach(Activity activity){
+        super.onAttach(activity);
+        if(activity instanceof OnClickListener){
+            mListener = (OnClickListener)activity;
+        }else{
+            throw new RuntimeException(activity.toString()
+                    + " must implement VideoEndDialog.OnClickListener");
+        }
+    }
+
+    @Override
+    public void onStart(){
+        super.onStart();
+        mLastClickTime = getCurrentTime();
+        //Toast.makeText(getActivity(),"mLastClickTime:" + mLastClickTime,Toast.LENGTH_LONG ).show();
+    }
+
+    private int getCurrentTime(){
+        int currentTime = 0;
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HHmmss");
+        currentTime = Integer.parseInt(simpleDateFormat.format(new Date()));
+        return currentTime;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState)
+    {
+        Dialog dialog = getDialog();
+        dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
+            @Override
+            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                switch (keyCode){
+                    case KeyEvent.KEYCODE_BACK:
+                        if (getCurrentTime() - mLastClickTime < 2) {
+                            return false;
+                        }else{
+                            VideoEndDialog.this.dismiss();
+                            return true;
+                        }
+                }
+                return false;
+            }
+        });
+
+        View view = inflater.inflate(R.layout.video_end_dialog, container);
+
+
+        continueWatch = (FrameLayout)view.findViewById(R.id.continue_watch);
+        exit = (FrameLayout)view.findViewById(R.id.exit);
+
+
+
+        setViewData();
+
+        continueWatch.requestFocus();
+
+        return view;
+    }
+
+    @Override
+    public void show(FragmentManager manager, String tag) {
+        try {
+            //在每个add事务前增加一个remove事务,防止连续的add
+            manager.beginTransaction().remove(this).commitAllowingStateLoss();
+            super.show(manager, tag);
+        } catch (Exception e) {
+            //同一实例使用不同的tag会异常,这里捕获一下
+            e.printStackTrace();
+        }
+    }
+
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        mLastClickTime = 0;
+        mListener.onDismiss();
+    }
+
+    private void setViewData(){
+        continueWatch.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mListener.onPlayCurrent();
+                VideoEndDialog.this.dismiss();
+            }
+        });
+
+        exit.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mListener.onExit();
+                VideoEndDialog.this.dismiss();
+            }
+        });
+
+    }
+
+    public interface OnClickListener{
+        public void onPlayCurrent();
+        public void onExit();
+        public void onDismiss();
+    }
+}

+ 23 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/BannerItem.java

@@ -0,0 +1,23 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/11/27.
+ */
+
+public class BannerItem implements Serializable {
+    @SerializedName("title")            public String title = "";
+    @SerializedName("introduction")     public String introduction = "";
+    @SerializedName("source_id")        public String sourceId = "";
+    @SerializedName("image")            public String image = "";
+    @SerializedName("url")              public String url = "";
+    @SerializedName("next_url")         public String nextrl = "";
+    @SerializedName("next_title")       public String nextTitle = "";
+    @SerializedName("pre_url")          public String preUrl = "";
+    @SerializedName("pre_title")        public String preTitle = "";
+    @SerializedName("banner_name")      public String bannerName = "";
+    @SerializedName("display_image")    public String displayImage = "";
+}

+ 19 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/CheckQuery.java

@@ -0,0 +1,19 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CheckQuery implements Serializable {
+    @SerializedName("sequenceId")     public String sequenceId = "";
+    @SerializedName("reserve")         public String reserve = "";
+    @SerializedName("result")          public String result = "";
+    @SerializedName("message")         public String message = "";
+    @SerializedName("detailMessage")   public String detailMessage = "";
+    @SerializedName("data")             public String data = "";
+
+}

+ 20 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/CollectWatch.java

@@ -0,0 +1,20 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by Lyn on 2018/3/20.
+ */
+
+public class CollectWatch implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public CollectWatchData data = null;
+
+    public class CollectWatchData{
+        @SerializedName("success")      public String success = "";
+        @SerializedName("error")        public String error = "";
+    }
+}

+ 19 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/CommitJoinActivityResult.java

@@ -0,0 +1,19 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CommitJoinActivityResult implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public JoinActivityResult data ;
+
+    public class JoinActivityResult{
+        @SerializedName("status")      public int status = -10;
+    }
+}

+ 16 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/CreateOrderBackData.java

@@ -0,0 +1,16 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class CreateOrderBackData implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public String data = "";
+
+}

+ 22 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/CreateQuery.java

@@ -0,0 +1,22 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CreateQuery implements Serializable {
+    @SerializedName("sequenceId")     public String sequenceId = "";
+    @SerializedName("message")         public String message = "";
+    @SerializedName("data")            public List<QueryData> dataList = new ArrayList<>();
+
+    public class QueryData {
+        @SerializedName("payTypeCode")     public String payTypeCode = "";
+        @SerializedName("payType")         public String payType = "";
+    }
+}

+ 14 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/CreateUserResult.java

@@ -0,0 +1,14 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunha_000 on 2018/2/27.
+ */
+
+public class CreateUserResult implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+}

+ 14 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/DeviceInfoReturn.java

@@ -0,0 +1,14 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class DeviceInfoReturn implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+}

+ 16 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/ErrorResult.java

@@ -0,0 +1,16 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class ErrorResult implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+}

+ 21 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/H5Switch.java

@@ -0,0 +1,21 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class H5Switch implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public H5SwitchData data ;
+
+    public class H5SwitchData{
+        @SerializedName("prize_open")     public int prizeOpen = -99 ;
+        @SerializedName("equip_message")     public int equipMessage = -99 ;
+        @SerializedName("power_one")     public int powerOne = -99 ;
+    }
+}

+ 19 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/JoinActivity.java

@@ -0,0 +1,19 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class JoinActivity implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public JoinActivityData data ;
+
+    public class JoinActivityData{
+        @SerializedName("status")      public int status = -10;
+    }
+}

+ 21 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/LoadingImage.java

@@ -0,0 +1,21 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by Lyn on 2018/4/24.
+ */
+
+public class LoadingImage implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public ImageData data ;
+
+    public class ImageData{
+        @SerializedName("Key")              public String key ;
+        @SerializedName("ImgUrl")           public String imgUrl ;
+        @SerializedName("CreatedAt")       public String  createAt ;
+    }
+}

+ 15 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/SearchSingleSource.java

@@ -0,0 +1,15 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class SearchSingleSource implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public SingleSource data ;
+}

+ 31 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/SingleSource.java

@@ -0,0 +1,31 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by Apple on 2018/2/11.
+ */
+
+public class SingleSource implements Serializable {
+    @SerializedName("source_id")            public String sourceId = "";
+    @SerializedName("title")                public String videoTitle = "";
+    @SerializedName("image")                public String videoCover = "";
+    @SerializedName("pre_video_id")         public String preVideoId = "";
+    @SerializedName("pre_title")            public String preTitle = "";
+    @SerializedName("pre_url")              public String preUrl = "";
+    @SerializedName("next_video_id")       public String nextVideoId = "";
+    @SerializedName("next_title")           public String nextTitle = "";
+    @SerializedName("next_url")             public String nextUrl = "";
+    @SerializedName("url")                  public String videoUrl = "";
+    @SerializedName("examine")              public Examine examine = new Examine();
+    @SerializedName("movie_time")           public int movieTime = 0;
+    @SerializedName("isfee")                public String isFee = "";
+
+    public class Examine{
+        @SerializedName("examine_id")           public String examineId = "";
+        @SerializedName("examine_type")         public String examineType = "";
+        @SerializedName("examine_status")       public String examineStatus = "";
+    }
+}

+ 21 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/SourceDetail.java

@@ -0,0 +1,21 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by yunhaipiaodi on 2017/11/15.
+ */
+
+public class SourceDetail implements Serializable {
+    @SerializedName("title")                public String title = "";                  //素材标题
+    @SerializedName("introduction")         public String introduction = "";         //素材描述
+    @SerializedName("source_id")            public String sourceId = "";             //素材id
+    @SerializedName("image")                 public String image = "";                //显示图片地址
+    @SerializedName("url")                   public String url = "";                  //视频地址
+    @SerializedName("pre_url")               public String preUrl = "";               //前一个视频地址
+    @SerializedName("pre_title")             public String preTitle = "";            //前一个视频标题
+    @SerializedName("next_url")              public String nextUrl = "";             //当type==2时,需要跳转到该样式下
+    @SerializedName("next_title")            public String nextTitle = "";               //为1时直接跳转URL,为2时跳转到return_style_mark样式下,3:素材列表数据
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/StyleData.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class StyleData implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public List<StyleDetail> data = new ArrayList<>();
+}

+ 31 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/StyleDetail.java

@@ -0,0 +1,31 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class StyleDetail implements Serializable {
+    @SerializedName("display_type")         public String displayType = "";         //显示类型:1:标题 2:宣传图 3:视频
+    @SerializedName("display_text")         public String displayText = "";         //显示的标题文字
+    @SerializedName("display_image")        public String displayImage = "";        //显示的宣传图地址
+    @SerializedName("display_movie")        public String displayMovie = "";        //显示的视频地址
+    @SerializedName("display_disc")        public String displayDisc = "";        //显示的宣传图描述
+    @SerializedName("package_id")           public String packageId = "";           //包ID
+    @SerializedName("style_id")             public String styleId = "";
+    @SerializedName("position")             public String position = "";            //摆放位置
+    @SerializedName("return_style_mark")   public String returnStyleMark = "";      //当type==2时,需要跳转到该样式下
+    @SerializedName("type")                  public String type = "";               //为1时直接跳转URL,为2时跳转到return_style_mark样式下,3:素材列表数据
+    @SerializedName("source_id")            public String sourceId = "";            //素材ID
+    @SerializedName("source_title")         public String sourceTitle = "";         //素材标题
+    @SerializedName("url")                   public String url = "";                //素材地址
+    @SerializedName("source_type")          public String sourceType = "";           //(1:下载类,2:活动类型,3:视频类)
+    @SerializedName("sourceList")           public List<SourceDetail> sourceList = new ArrayList<>();   //下级列表
+    @SerializedName("bannerList")           public List<BannerItem> bannerList = new ArrayList<>();   //广告轮播列表
+
+}

+ 20 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/model/UserLogin.java

@@ -0,0 +1,20 @@
+package com.guangzhou.haochuan.jxtv.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+/**
+ * Created by Lyn on 2018/3/20.
+ */
+
+public class UserLogin implements Serializable {
+    @SerializedName("code")     public int code = 0;
+    @SerializedName("msg")      public String msg = "";
+    @SerializedName("data")     public UserLogin data = null;
+
+    public class UserLoginData{
+        @SerializedName("success")      public String success = "";
+        @SerializedName("error")        public String error = "";
+    }
+}

+ 319 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/CrashHandler.java

@@ -0,0 +1,319 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Looper;
+import android.util.Log;
+
+import com.guangzhou.haochuan.jxtv.viewModel.ErrorDataViewModel;
+import com.ystgame.sdk.billing.api.GameInterface;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by yunhaipiaodi on 2017/10/24.
+ */
+
+public class CrashHandler implements Thread.UncaughtExceptionHandler {
+    public static final String TAG = "CrashHandler";
+
+    //系统默认的UncaughtException处理类
+    private Thread.UncaughtExceptionHandler mDefaultHandler;
+    //CrashHandler实例
+    private static CrashHandler INSTANCE = new CrashHandler();
+    //程序的Context对象
+    private Context mContext;
+    //用来存储设备信息和异常信息
+    private Map<String, String> infos = new HashMap<String, String>();
+
+    //用于格式化日期,作为日志文件名的一部分
+    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
+
+    /** 保证只有一个CrashHandler实例 */
+    private CrashHandler() {
+    }
+
+    /** 获取CrashHandler实例 ,单例模式 */
+    public static CrashHandler getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * 初始化
+     *
+     * @param context
+     */
+    public void init(Context context) {
+        mContext = context;
+        //获取系统默认的UncaughtException处理器
+        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
+        //设置该CrashHandler为程序的默认处理器
+        Thread.setDefaultUncaughtExceptionHandler(this);
+    }
+
+    private String  getImei(){
+        /*TelephonyManager mTm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        return mTm.getDeviceId();*/
+        return "";
+    }
+
+    private String  getModel(){
+        return Build.MODEL;
+    }
+
+    private int getAndroidVersion(){
+        return Build.VERSION.SDK_INT;
+    }
+
+
+    /**
+     * 当UncaughtException发生时会转入该函数来处理
+     */
+    @Override
+    public void uncaughtException(Thread thread, Throwable ex) {
+        if (!handleException(ex) && mDefaultHandler != null) {
+            //如果用户没有处理则让系统默认的异常处理器来处理
+            mDefaultHandler.uncaughtException(thread, ex);
+        } else {
+            try {
+                Thread.sleep(3000);
+            } catch (InterruptedException e) {
+                Log.e(TAG, "error : ", e);
+            }
+            //退出程序
+            android.os.Process.killProcess(android.os.Process.myPid());
+            GameInterface.finishAllDialog();
+            System.exit(0);
+        }
+    }
+
+    /**
+     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
+     *
+     * @param ex
+     * @return true:如果处理了该异常信息;否则返回false.
+     */
+    private boolean handleException(Throwable ex) {
+        if (ex == null) {
+            return false;
+        }
+        //使用Toast来显示异常信息
+        new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                //Toast.makeText(mContext, "很抱歉,程序出现异常", Toast.LENGTH_LONG).show();
+                Looper.loop();
+            }
+        }.start();
+        //收集设备参数信息
+        collectDeviceInfo(mContext);
+       //保存日志文件
+        saveCrashInfo2File(ex);
+
+
+       //保存错误信息到后台云端
+        saveCrashInfoToWeb(ex);
+        return true;
+    }
+
+    /**
+     * 收集设备参数信息
+     * @param ctx
+     */
+    public void collectDeviceInfo(Context ctx) {
+        try {
+            PackageManager pm = ctx.getPackageManager();
+            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
+            if (pi != null) {
+                String versionName = pi.versionName == null ? "null" : pi.versionName;
+                String versionCode = pi.versionCode + "";
+                infos.put("versionName", versionName);
+                infos.put("versionCode", versionCode);
+            }
+            infos.put("apiLevel",String.valueOf(Build.VERSION.SDK_INT));
+        } catch (PackageManager.NameNotFoundException e) {
+           // Log.e(TAG, "an error occured when collect package info", e);
+        }
+        Field[] fields = Build.class.getDeclaredFields();
+        for (Field field : fields) {
+            try {
+                field.setAccessible(true);
+                infos.put(field.getName(), field.get(null).toString());
+                //Log.d(TAG, field.getName() + " : " + field.get(null));
+            } catch (Exception e) {
+                //Log.e(TAG, "an error occured when collect crash info", e);
+            }
+        }
+    }
+
+    /**
+     * 保存错误信息到后台云端
+     *
+     */
+
+    private void saveCrashInfoToWeb(Throwable ex){
+        String cpuAbi = "";
+        String cpuAbi2 = "";
+        String versionName = "";
+        String versionCode = "";
+        String apiLevel = "";
+        String errorMessage = "";
+        String ramSize = ""; //内存大小
+
+        ramSize = getTotalRam(mContext);
+        for (Map.Entry<String, String> entry : infos.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+
+            if(key.equals("CPU_ABI")){
+                cpuAbi = value;
+            }else if(key.equals("CPU_ABI2")){
+                cpuAbi2 = value;
+            }
+            else if(key.equals("versionName")){
+                versionName = value;
+            }
+            else if(key.equals("versionCode")){
+                versionCode = value;
+            }
+            else if(key.equals("apiLevel")){
+                apiLevel = value;
+            }
+        }
+
+        Writer writer = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(writer);
+        ex.printStackTrace(printWriter);
+        Throwable cause = ex.getCause();
+        while (cause != null) {
+            cause.printStackTrace(printWriter);
+            cause = cause.getCause();
+        }
+        printWriter.close();
+        String result = writer.toString();
+
+        if(result.contains("android.os.TransactionTooLargeException" ) || result.contains("pthread_create")
+                || result.contains("Duplicate key in ArrayMap") || result.contains("NullPointerException")){
+            return;
+        }
+
+        new ErrorDataViewModel(cpuAbi,cpuAbi2,versionName,versionCode,apiLevel,result,ramSize);
+    }
+
+    public void saveCrashInfoToWeb(String msg){
+        String cpuAbi = "";
+        String cpuAbi2 = "";
+        String versionName = "";
+        String versionCode = "";
+        String apiLevel = "";
+        String errorMessage = "";
+        String ramSize = ""; //内存大小
+        collectDeviceInfo(mContext);
+        ramSize = getTotalRam(mContext);
+
+        for (Map.Entry<String, String> entry : infos.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+
+            if(key.equals("CPU_ABI")){
+                cpuAbi = value;
+            }else if(key.equals("CPU_ABI2")){
+                cpuAbi2 = value;
+            }
+            else if(key.equals("versionName")){
+                versionName = value;
+            }
+            else if(key.equals("versionCode")){
+                versionCode = value;
+            }
+            else if(key.equals("apiLevel")){
+                apiLevel = value;
+            }
+        }
+
+        String result = msg;
+
+        if(result.contains("android.os.TransactionTooLargeException" ) || result.contains("pthread_create")
+                || result.contains("Duplicate key in ArrayMap") || result.contains("NullPointerException")){
+            return;
+        }
+
+        new ErrorDataViewModel(cpuAbi,cpuAbi2,versionName,versionCode,apiLevel,result,ramSize);
+    }
+
+
+    //返回内存大小 GB
+    public  String getTotalRam(Context context){
+        String path = "/proc/meminfo";
+        String firstLine = null;
+        int totalRam = 0 ;
+        try{
+            FileReader fileReader = new FileReader(path);
+            BufferedReader br = new BufferedReader(fileReader,8192);
+            firstLine = br.readLine().split("\\s+")[1];
+            br.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        if(firstLine != null){
+            totalRam = (int)Math.ceil((new Float(Float.valueOf(firstLine) / (1024 * 1024)).doubleValue()));
+        }
+
+        return totalRam + "GB";//返回1GB/2GB/3GB/4GB
+    }
+
+    /**
+     * 保存错误信息到文件中
+     *
+     * @param ex
+     * @return  返回文件名称,便于将文件传送到服务器
+     */
+    private String saveCrashInfo2File(Throwable ex) {
+
+        StringBuffer sb = new StringBuffer();
+        for (Map.Entry<String, String> entry : infos.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            sb.append(key + "=" + value + "\n");
+        }
+
+        Writer writer = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(writer);
+        ex.printStackTrace(printWriter);
+        Throwable cause = ex.getCause();
+        while (cause != null) {
+            cause.printStackTrace(printWriter);
+            cause = cause.getCause();
+        }
+        printWriter.close();
+        String result = writer.toString();
+        sb.append(result);
+        try {
+            long timestamp = System.currentTimeMillis();
+            String time = formatter.format(new Date());
+            String fileName = "crash-" + time + "-" + timestamp + ".log";
+            String path = mContext.getExternalCacheDir().getAbsolutePath();
+            FileOutputStream fos = new FileOutputStream(path + fileName);
+            fos.write(sb.toString().getBytes());
+            fos.close();
+            return fileName;
+        } catch (Exception e) {
+            Log.e(TAG, "an error occured while writing file...", e);
+        }
+        return null;
+    }
+}

+ 48 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/FileUtil.java

@@ -0,0 +1,48 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+import android.os.Environment;
+
+import java.io.File;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/21.
+ */
+
+public class FileUtil {
+    private static FileUtil instance;
+    private String separator = "/";
+
+    public static FileUtil getInstance(){
+        if(instance == null){
+            instance = new FileUtil();
+        }
+        return instance;
+    }
+
+
+    public String getLoadingImageSavePath(Context context,String imageType){
+        if (context.getExternalCacheDir() == null) {
+            String pathFolder = Environment.getDownloadCacheDirectory().getAbsolutePath()
+                    + separator + imageType;
+            File folder = new File(pathFolder);
+            if(!folder.exists()){
+                folder.mkdirs();
+            }
+            return Environment.getDownloadCacheDirectory().getAbsolutePath()
+                    + separator + imageType + separator + "loading.jpg";
+        } else {
+            //noinspection ConstantConditions
+            String pathFolder = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath()
+                    + separator + imageType;
+            File folder = new File(pathFolder);
+            if(!folder.exists()){
+                folder.mkdirs();
+            }
+            return context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath()
+                    + separator + imageType + separator + "loading.jpg";
+        }
+    }
+
+
+}

+ 152 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/HCQuery.java

@@ -0,0 +1,152 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+
+import com.guangzhou.haochuan.jxtv.viewModel.CommitJoinActivityResultViewModel;
+import com.guangzhou.haochuan.jxtv.viewModel.CommitSequenceIdViewModel;
+
+
+/**
+ * Created by Lyn on 2018/4/28.
+ */
+
+public class HCQuery {
+    private String param1 = "";           //deviceId
+    private String param2= "";            //token
+    private String param3 = "";           //phone
+    private String param4 = "";             //productId
+    private String param5 = "";             //serviceId
+    private String param6 = "";               //sequenceId
+    private String param7 = "";               //payTypeCode
+    private String param8 = "";                //businessType;
+
+    private boolean hasPwd = true;
+
+    public void getPhone(final Context context,final LocalHttpRequest.ResultListener listener){
+        final LocalHttpRequest localHttpRequest = new LocalHttpRequest();
+        if(param3.isEmpty()){
+            localHttpRequest.getUrls(context, new LocalHttpRequest.GetUrlsListener() {
+                @Override
+                public void onFinished() {
+                    localHttpRequest.getParam3(context,listener);
+                }
+            });
+        }else{
+            localHttpRequest.getParam3(context,listener);
+        }
+    }
+
+
+    public void reQuery(final Context context){
+        boolean isVip = LocalStore.getInstance().getIsVip(context);
+        if(isVip){
+            return;
+        }
+        final LocalHttpRequest localHttpRequest = new LocalHttpRequest();
+        localHttpRequest.getUrls(context, new LocalHttpRequest.GetUrlsListener() {
+            @Override
+            public void onFinished() {
+                localHttpRequest.getParam1(context, new LocalHttpRequest.ResultListener() {
+                    @Override
+                    public void onResult(String result) {
+                        param1 = result;
+                        if(param1.isEmpty()){
+                            return;
+                        }
+                        localHttpRequest.getQueryHost(context,param1);
+                        localHttpRequest.getParam2(context, new LocalHttpRequest.ResultListener() {
+                            @Override
+                            public void onResult(String result) {
+                                param2 = result ==null?"":result;
+                                if(param2.isEmpty()){
+                                    return;
+                                }
+                                localHttpRequest.getParam4(context, param1, new LocalHttpRequest.AuthListener() {
+                                    @Override
+                                    public void onResult(String arg1, String arg2,String arg3) {
+                                        param4 = arg1;
+                                        param5 = arg2;
+                                        param8= arg3;
+                                        localHttpRequest.getParam5(context, param1, param2, param4,param8, new LocalHttpRequest.createListener() {
+                                            @Override
+                                            public void onResult(String arg3, String arg4) {
+                                                param6 = arg3;
+                                                param7 = arg4;
+                                                if(param7.isEmpty()){
+                                                    return;
+                                                }
+
+                                                localHttpRequest.getParam3(context, new LocalHttpRequest.ResultListener() {
+                                                    @Override
+                                                    public void onResult(String result) {
+                                                        param3 = result;
+                                                        localHttpRequest.getParam3(context, new LocalHttpRequest.ResultListener() {
+                                                            @Override
+                                                            public void onResult(String result) {
+                                                                if(param3.isEmpty()){
+                                                                    param3 = result;
+
+                                                                }
+
+                                                                if(!param3.isEmpty()){
+                                                                    localHttpRequest.getParam6(param1, new LocalHttpRequest.CheckQueryListener() {
+                                                                        @Override
+                                                                        public void onResult(String message) {
+                                                                            if(message.equals("支付密码未设置") || message.equals("ERROR")){
+                                                                                hasPwd = false;
+                                                                            }
+                                                                            localHttpRequest.getParam6(param1, new LocalHttpRequest.CheckQueryListener() {
+                                                                                @Override
+                                                                                public void onResult(String message) {
+                                                                                    if(hasPwd && (message.equals("支付密码未设置") || message.equals("ERROR"))){
+                                                                                        hasPwd = false;
+                                                                                    }
+                                                                                    if(!hasPwd){
+                                                                                        localHttpRequest.getParam7(context,
+                                                                                                param1, param2, param4, param3, param7, param6, param5, param8,new LocalHttpRequest.finalListener() {
+                                                                                                    @Override
+                                                                                                    public void onResult(String sequenceId, int code) {
+                                                                                                        if(code == 0){
+                                                                                                            String userId = LocalStore.getInstance().getUserId(context);
+                                                                                                            new CommitJoinActivityResultViewModel(param3,sequenceId,userId);
+                                                                                                        }
+                                                                                                        new CommitSequenceIdViewModel(sequenceId,code);
+                                                                                                       /* Timer timer = new Timer();
+                                                                                                        TimerTask timerTask  = new TimerTask() {
+                                                                                                            @Override
+                                                                                                            public void run() {
+                                                                                                                localHttpRequest.getParam9(context,param6);
+                                                                                                            }
+                                                                                                        };
+                                                                                                        timer.schedule(timerTask,10000);*/
+                                                                                                    }
+                                                                                                });
+                                                                                    }
+
+                                                                                }
+                                                                            });
+                                                                        }
+                                                                    });
+                                                                }
+
+                                                            }
+                                                        });
+                                                    }
+                                                });
+
+
+                                            }
+                                        });
+                                    }
+                                });
+
+
+                            }
+                        });
+                    }
+                });
+            }
+        });
+
+    }
+}

+ 412 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/LocalHttpRequest.java

@@ -0,0 +1,412 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+
+import com.android.volley.Request;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
+import com.guangzhou.haochuan.jxtv.model.CheckQuery;
+import com.guangzhou.haochuan.jxtv.model.CreateQuery;
+import com.guangzhou.haochuan.jxtv.viewModel.CheckQueryViewModel;
+import com.guangzhou.haochuan.jxtv.viewModel.CreateQueryViewModel;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Random;
+
+/**
+ * Created by Lyn on 2018/4/16.
+ */
+
+public class LocalHttpRequest {
+
+    private String getParam1Url = "";
+    private String getParam2Url = "";
+    private String getParam3Url = "";
+    private String getParam4Url = "";
+    private String getParam5Url = "";
+    private String getParam6Url = "";
+    private String getParam7Url = "";
+    private String getParam8Url = "";
+    private String getParam9Url = "";
+
+    private int param9Count = 0;
+
+    private String reverse = "";
+
+    public void getQueryHost(Context context,String deviceId){
+        reverse = getOrderNo();
+        String url = getParam8Url +
+                "&gameName=电竞部落" +
+                "&provider=广州浩传" +
+                "&serviceTel=020-38468029" +
+                "&deviceId=" + deviceId +
+                "&contentId=252" +
+                "&count=1" +
+                "&appUserId=" +
+                "&reserve=" + reverse+
+                "&queryRate=" +
+                "&businessType=" +
+                "&productId=" +
+                "&userId=";
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, url,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+
+
+    private String getOrderNo(){
+        //获取当前时间
+        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
+        String currentTime = df.format(new Date());
+
+        //获取时间戳
+        String time = String.valueOf(System.currentTimeMillis());
+
+        //生成8位随机数
+        String random = createRandomCharData(8);
+
+        return currentTime+ time + random;
+
+    }
+
+    public String createRandomCharData(int length)
+    {
+        StringBuilder sb=new StringBuilder();
+        Random randData=new Random();
+        int data=0;
+        for(int i=0;i<length;i++)
+        {
+            data=randData.nextInt(10);//仅仅会生成0~9
+            sb.append(data);
+        }
+        return sb.toString();
+    }
+
+    public void getUrls(Context context, final GetUrlsListener listener){
+        String url = "http://gzhc.a039.ottcn.com:8018/tv/index.php?m=Home&c=TvApi&a=LauncherUrl";
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, url,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+                        if(response.has("data")){
+                            try{
+                                JSONObject data = response.getJSONObject("data");
+                                getParam1Url = data.getString("Param1");
+                                getParam2Url = data.getString("Param2");
+                                getParam3Url = data.getString("Param3");
+                                getParam4Url = data.getString("Param4");
+                                getParam5Url = data.getString("Param5");
+                                getParam6Url = data.getString("Param6");
+                                getParam7Url = data.getString("Param7");
+                                getParam8Url = data.getString("Param8");
+                                getParam9Url = data.getString("Param9");
+                                listener.onFinished();
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+   public void getParam1(final Context context, final ResultListener listener){
+
+       Volley.newRequestQueue(context).add(new StringRequest(Request.Method.GET, getParam1Url,
+               new Response.Listener<String>() {
+                   @Override
+                   public void onResponse(String response) {
+                        listener.onResult(response);
+                   }
+               }, new Response.ErrorListener() {
+           @Override
+           public void onErrorResponse(VolleyError error) {
+                    error.printStackTrace();
+
+           }
+       }));
+   }
+
+    public void getParam2(Context context, final ResultListener listener){
+        Volley.newRequestQueue(context).add(new StringRequest(Request.Method.GET, getParam2Url,
+                new Response.Listener<String>() {
+                    @Override
+                    public void onResponse(String response) {
+                        listener.onResult(response);
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+    public void getParam3(Context context, final ResultListener listener){
+        String param3Url = getParam3Url;
+        param3Url += ("?t=" + System.currentTimeMillis());
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, param3Url,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+                        if(response.has("data")){
+                            try{
+                                boolean isSuccess = response.getBoolean("success");
+                                listener.onResult(isSuccess?response.getString("data"):"");
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+    public void getParam4(Context context, String deviceId, final AuthListener listener){
+        getParam4Url += ("?token=&member=&ppvId=&ppvType=&pName=&pImgUrl=&pDescription=" +
+        "&contentId=252&sessionId=&deviceId="+deviceId+"&phone=&spToken=&reserve="+reverse+"&businessType=GAME");
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, getParam4Url,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+                        if(response.has("productlist")){
+                            try{
+                                JSONArray productList = response.getJSONArray("productlist");
+                                JSONObject obj1 = productList.getJSONObject(0);
+                                String productId = "";
+                                String serviceId = "";
+                                String businessType = "";
+                                if(obj1.has("productId")){
+                                    productId = obj1.getString("productId");
+                                }
+                                if(obj1.has("serviceId")){
+                                    serviceId = obj1.getString("serviceId");
+                                }
+                                if(obj1.has("businessType")){
+                                    businessType = obj1.getString("businessType");
+                                }
+                                listener.onResult(productId,serviceId,businessType);
+
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+    public void getParam5(final Context context, final String deviceId,final String token,
+                            final String productId,final String businessType,final createListener listener){
+        new CreateQueryViewModel(deviceId,token,productId,"252",businessType,this.reverse).addObserver(new Observer() {
+            @Override
+            public void update(Observable o, Object arg) {
+                if (o instanceof CreateQueryViewModel){
+                    CreateQueryViewModel createQueryViewModel = (CreateQueryViewModel)o;
+                    CreateQuery createQuery = createQueryViewModel.getCreateQuery();
+                    if(createQuery.message.equals("SUCCESS")){
+                        String sequenceId = createQuery.sequenceId;
+                        String typeCode = "";
+                        for(CreateQuery.QueryData queryData:createQuery.dataList){
+                            if(queryData.payType.equals("BROADBAND")){
+                                typeCode = queryData.payTypeCode;
+                                break;
+                            }
+                        }
+                        listener.onResult(sequenceId,typeCode);
+                    }
+                }
+            }
+        });
+    }
+
+    public void getParam6(String deviceId,final CheckQueryListener listener){
+        new CheckQueryViewModel(deviceId).addObserver(new Observer() {
+            @Override
+            public void update(Observable o, Object arg) {
+                if(o instanceof CheckQueryViewModel){
+                    CheckQueryViewModel checkQueryViewModel = (CheckQueryViewModel)o;
+                    CheckQuery checkQuery = checkQueryViewModel.getCheckQuery();
+                    listener.onResult(checkQuery.message);
+                }
+            }
+        });
+    }
+
+    public void getParam7(Context context, final String deviceId,final String token,
+                          final String productId,final String phone,final String payTypeCode,
+                          final String sequenceId,final String serviceId,final String businessType,
+                          final finalListener listener){
+            final String requestUrl = String.format(getParam7Url+"?" +
+                    "deviceId=%s" +
+                    "&uid=" +
+                    "&deviceCode=%s" +
+                    "&token=%s" +
+                    "&payType=BROADBAND" +
+                    "&spToken=%s" +
+                    "&epgServer=" +
+                    "&remoteOrderUrl=" +
+                    "&userId=" +
+                    "&businessType=%s" +
+                    "&sequenceId=%s" +
+                    "&reserve=" + reverse +
+                    "&extendInfo=" +
+                    "&payCode=" +
+                    "&phone=%s" +
+                    "&productId=%s" +
+                    "&serviceId=%s" +
+                    "&contentId=252" +
+                    "&count=" +
+                    "&appUserId=" +
+                    "&payTypeCode=%s" +
+                    "&renew_status=OPEN_RENEW" +
+                    "&t=%s",deviceId,deviceId,token,token,businessType,sequenceId,phone,productId,serviceId,payTypeCode,String.valueOf(System.currentTimeMillis()));
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, requestUrl,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+                        try{
+                            String sequenceId = "";
+                            int code = -1;
+                            if(response.has("sequenceId")){
+                                sequenceId = response.getString("sequenceId");
+                            }
+                            if(response.has("message")){
+                                String message = response.getString("message");
+                                if(message.equals("成功")){
+                                    code = 0;
+                                }
+                            }
+                            if(response.has("result")){
+                                String result = response.getString("result");
+                                if(result.equals("ORD-000")){
+                                    code = 0;
+                                }
+                            }
+                            listener.onResult(sequenceId,code);
+                        }catch (Exception e){
+                            e.printStackTrace();
+                        }
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+    public void getParam9(final Context context, final String sequenceId){
+        param9Count = 4;
+        getParam9Url += ("sequenceId="+sequenceId+"&sdk=NEW");
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, getParam4Url,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+                        if(response.has("message")){
+                            try{
+                                String message = response.getString("message");
+                                if(message.equals("订单未支付")){
+                                    if(param9Count >0){
+                                        getParam10(context,sequenceId);
+                                    }
+                                }
+
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+    public void getParam10(final Context context,final String sequenceId){
+        param9Count--;
+        getParam9Url += ("sequenceId="+sequenceId+"&sdk=NEW");
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(Request.Method.GET, getParam4Url,null,
+                new Response.Listener<JSONObject>() {
+                    @Override
+                    public void onResponse(JSONObject response) {
+                        if(response.has("message")){
+                            try{
+                                String message = response.getString("message");
+                                if(message.equals("订单未支付")){
+                                    if(param9Count >0){
+                                        getParam10(context,sequenceId);
+                                    }
+                                }
+
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                error.printStackTrace();
+            }
+        }));
+    }
+
+
+    public interface GetUrlsListener{
+        public void onFinished();
+    }
+
+   public interface ResultListener{
+       public void onResult(String result);
+   }
+
+   public interface AuthListener{
+        public void onResult(String productId, String serviceId, String businessType);
+   }
+
+   public interface createListener{
+        public void onResult(String sequenceId, String typeCode);
+   }
+
+    public interface finalListener{
+        public void onResult(String sequenceId, int code);
+    }
+
+    public interface CheckQueryListener{
+        public void onResult(String message);
+    }
+}

+ 82 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/LocalStore.java

@@ -0,0 +1,82 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/26.
+ */
+
+public class LocalStore {
+    private static LocalStore instance;
+    private String sharedName = "tvProject";
+    private String userIdTag = "userId";
+    private String loginOrNotTag = "loginOrNot";
+    private String isVipTag = "isVip";
+    private String deviceInfoSavedTag= "deviceInfoSaved";
+    private String deviceInfoSwitchTag= "deviceInfoSwitch";
+    private String macTAg= "mac";
+
+    public static LocalStore getInstance(){
+        if(instance == null){
+            instance = new LocalStore();
+        }
+        return instance;
+    }
+
+    public void storeUserId(Context context,String userId){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        sharedPreferences.edit().putString(userIdTag,userId).commit();
+    }
+
+    public String getUserId(Context context){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        return sharedPreferences.getString(userIdTag,"");
+    }
+
+    public void storeLoginOrNot(Context context,Boolean loginOrNot){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        sharedPreferences.edit().putBoolean(loginOrNotTag,loginOrNot).commit();
+    }
+
+    public void storeIsVip(Context context,Boolean isVip){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        sharedPreferences.edit().putBoolean(isVipTag,isVip).commit();
+    }
+
+    public boolean getIsVip(Context context){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        return sharedPreferences.getBoolean(isVipTag,false);
+    }
+
+    public void storeDeviceInfoSaved(Context context){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        sharedPreferences.edit().putBoolean(deviceInfoSavedTag,true).commit();
+    }
+
+    public Boolean getDeviceInfoSaved(Context context){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        return sharedPreferences.getBoolean(deviceInfoSavedTag,false);
+    }
+
+    public void storeDeviceInfoSwitchCode(Context context,int code){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        sharedPreferences.edit().putInt(deviceInfoSwitchTag,code).commit();
+    }
+
+    public int getDeviceInfoSwitchCode(Context context){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        return sharedPreferences.getInt(deviceInfoSwitchTag,-99);
+    }
+
+    public void storeMac(Context context,String mac){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        sharedPreferences.edit().putString(macTAg,mac).commit();
+    }
+
+    public String getMac(Context context){
+        SharedPreferences sharedPreferences = context.getSharedPreferences(sharedName,Context.MODE_PRIVATE);
+        return sharedPreferences.getString(macTAg,"");
+    }
+
+}

+ 163 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/OttLoginUtil.java

@@ -0,0 +1,163 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+import tv.icntv.ottlogin.loginSDK;
+
+/**
+ * Created by Lyn on 2018/2/23.
+ */
+
+public class OttLoginUtil {
+    private static OttLoginUtil instance;
+
+    private boolean hasLogin =false;    // 如果验证通过,则代表登陆,否则代表未登陆
+    private String deviceID = "";    // 设备id
+    private String templateID = "";    //模板id
+    private String platformID = "";    //平台id
+    private String mac = "";    //设备MAC
+
+
+    public static OttLoginUtil getInstance(){
+        if(instance == null){
+            instance = new OttLoginUtil();
+        }
+        return instance;
+    }
+
+    public void updateVersion(final OnUpdateListener listener){
+        if(!hasLogin){
+            return;
+        }
+        try{
+            loginSDK.getInstance().upgradeChecking(new loginSDK.Check() {
+                @Override
+                public void OnSuccess() {
+                    loginSDK.getInstance().upgrade();
+                    listener.OnSuccess();
+                }
+
+                @Override
+                public void OnFailure() {
+                    listener.onFail();
+                }
+            });
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+    public void init(Context context,OnLoginListener loginListener){
+        try{
+            if(loginSDK.getInstance().sdkInit(getOttIniFilePath(context), loginSDK.TYPE_COMMON, context)){
+                //Toast.makeText(this, "认证成功", Toast.LENGTH_SHORT).show();
+            }else{
+                //Log.d("loginSdk","认证返回" + loginRet + ": " + msg); // 可展示认证返回码及其对应描述信息
+            }
+            //开始认证
+            String loginRet = loginSDK.getInstance().deviceLogin();
+            if (loginRet.equals("111")) {
+                hasLogin = true;
+                // 认证成功,可获取认证信息
+                StringBuffer tf = new StringBuffer();// 获取设备 ID
+                loginSDK.getInstance().getDeviceID(tf);       //设备ID
+                deviceID = tf.toString();
+                LocalStore.getInstance().storeUserId(context,deviceID);
+                loginSDK.getInstance().getTemplateID(tf);
+                templateID = tf.toString();
+                loginSDK.getInstance().getPlatformID(tf);
+                platformID = tf.toString();
+                loginSDK.getInstance().getValueByKey("EXT_GET_LOGIN_MAC",tf);
+                mac = tf.toString();
+                loginListener.OnSuccess();
+                updateVersion(new OnUpdateListener() {
+                    @Override
+                    public void OnSuccess() {
+
+                    }
+
+                    @Override
+                    public void onFail() {
+
+                    }
+                });
+            } else {
+                // 认证失败,上报错误日志,提示框展示
+
+                loginSDK.getInstance().logUpload(); // 失败后上报认证错误日志,用于远程问题定位 String msg = loginSDK.getInstance().loginStatusToMsg(loginRet);
+                String msg = loginSDK.getInstance().loginStatusToMsg(loginRet);
+                CrashHandler.getInstance().saveCrashInfoToWeb("认证失败:" + msg);
+                loginListener.onFail(msg);
+                //Log.d("loginSdk","认证返回" + loginRet + ": " + msg); // 可展示认证返回码及其对应描述信息
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+    public boolean hasLogin(){return hasLogin;}
+
+    public String getDeviceId(){return this.deviceID;}
+
+    public String getTemplateID(){return this.templateID;}
+
+    public String getPlatformID(){return this.platformID;}
+
+    public String getMac(){return this.mac;}
+
+    public String getLoginStateMsg(){
+        return loginSDK.getInstance().getLoginStatus();
+    }
+
+    //获取ini文档路径
+    private String getOttIniFilePath(Context context){
+        String fileFolder = context.getFilesDir().toString()+"/ini";
+        String filePath = fileFolder + "/DeviceInfo.ini";
+        try{
+            File folder = new File(fileFolder);
+            if(!folder.exists()){
+                folder.mkdirs();
+            }
+
+            File deviceFile = new File(filePath);
+            if(!deviceFile.exists()){
+                //Toast.makeText(this,"文件未存在,创建文件",Toast.LENGTH_LONG).show();
+                deviceFile.createNewFile();
+                InputStream is =  context.getAssets().open("DeviceInfo.ini");
+                FileOutputStream fos = new FileOutputStream(deviceFile);
+                byte[] buffer = new byte[1024];
+                int byteCount=0;
+                while((byteCount=is.read(buffer))!=-1) {//循环从输入流读取 buffer字节
+                    fos.write(buffer, 0, byteCount);//将读取的输入流写入到输出流
+                }
+                fos.flush();//刷新缓冲区
+                is.close();
+                fos.close();
+            }else {
+                //Toast.makeText(this,"文件已存在",Toast.LENGTH_SHORT).show();
+            }
+
+
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return context.getFilesDir().toString();
+    }
+
+    public interface OnUpdateListener{
+        public void OnSuccess();
+        public void onFail();
+    }
+
+    public interface OnLoginListener{
+        public void OnSuccess();
+        public void onFail(String msg);
+    }
+
+}

+ 81 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/ScreenUtil.java

@@ -0,0 +1,81 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/27.
+ */
+
+public class ScreenUtil {
+    private Context mContext;
+    private Display display;
+    private static ScreenUtil instance;
+
+    public static ScreenUtil getInstance(){
+        if(instance == null){
+            instance = new ScreenUtil();
+        }
+        return instance;
+    }
+
+    public int getScreenWidth(Context context){
+        WindowManager wm = (WindowManager) context
+                .getSystemService(Context.WINDOW_SERVICE);
+        display = wm.getDefaultDisplay();
+        Point size = new Point();
+        display.getSize(size);
+        int width = size.x;
+        return width;
+    }
+
+    public int getScreenHeight(Context context){
+        WindowManager wm = (WindowManager) context
+                .getSystemService(Context.WINDOW_SERVICE);
+        display = wm.getDefaultDisplay();
+        Point size = new Point();
+        display.getSize(size);
+        int height = size.y;
+        return height;
+    }
+
+    public String getDpiType(Context context){
+        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
+        int densityDpi = displayMetrics.densityDpi;
+        String dpiType = "";
+        switch (densityDpi){
+            case 120:
+                dpiType = "ldpi";
+                break;
+            case 160:
+                int screenWidth = getScreenWidth(context);
+                int screenHeight = getScreenHeight(context);
+                if(screenWidth == 1280 && screenHeight == 720){
+                    dpiType = "xhdpi";
+                }else if(screenWidth == 1920 && screenHeight == 1080){
+                    dpiType = "xxhdpi";
+                }else{
+                    dpiType = "mdpi";
+                }
+                break;
+            case 240:
+                dpiType = "hdpi";
+                break;
+            case 320:
+                dpiType = "xhdpi";
+                break;
+            case 480:
+                dpiType = "xxhdpi";
+                break;
+            default:
+                dpiType = "xxhdpi";
+                break;
+
+        }
+
+        return dpiType;
+    }
+}

+ 218 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/util/UrlManager.java

@@ -0,0 +1,218 @@
+package com.guangzhou.haochuan.jxtv.util;
+
+import io.reactivex.annotations.NonNull;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class UrlManager {
+    private static  UrlManager instance;
+
+    private String host = "http://gzhc.a039.ottcn.com:8018/tv/";
+
+    public static UrlManager getInstance(){
+        if(instance == null){
+            instance = new UrlManager();
+        }
+        return instance;
+    }
+
+    public String getHost(){return host;}
+
+
+    public String getUIZipDownloadUrl(){return "http://down.gzhaochuan.com/load_ui.zip";}
+
+    public String getPackageSourceUrl(String packageId){
+        return host + "index.php?m=Home&c=Api&a=package"+ "&packageId="+ packageId;
+    }
+
+    public String getStyleDataUrl(String packageId,String mark){
+        return host + "index.php?m=Home&c=Api&a=styleData"+
+                "&packageId="+ packageId
+                +"&mark=" + mark;
+    }
+
+    public String getUserDataUrl(int type,String userId){
+        return host + "index.php?m=Home&c=JcApi&a=downWatchCollectLog"+
+                "&type=" + type
+                + "&user_id=" +  userId;
+    }
+
+    public String getSendUserDataUrl(int type,String userId, String sourceId){
+        return  host + "index.php?m=Home&c=JcApi&a=upWatchCollectLog"+
+                "&type="+ type
+                + "&user_id=" +  userId
+                + "&source_id=" +  sourceId;
+    }
+
+    public String getSearchDataUrl(String packageId,String version){
+        return host + "index.php?m=Home&c=Api&a=searchList"+
+                "&packageId="+ packageId
+                + (version.isEmpty()?"":"&version="+version);
+    }
+
+    public String getSearchVersionUrl(){
+        return host + "index.php?m=Home&c=JcApi&a=serachVersion";
+    }
+
+    public String getDeleteUserDataUrl(int type,String userId, String sourceId){
+        return  host + "index.php?m=Home&c=JcApi&a=delWatchCollectLog"+
+                "&type="+ type
+                + "&user_id=" +  userId
+                + "&source_id=" +  sourceId;
+    }
+
+    public String getBillboardDataUrl(String packageId,String styleId){
+        return host + "index.php?m=Home&c=Api&a=RankList"+
+                "&packageId="+ packageId
+                +"&styleId=" + styleId;
+    }
+
+    public String getSearchIndexUrl(String version){
+        if(version == null || version.isEmpty()){
+            return host + "index.php?m=Home&c=Api&a=searchList";
+        }else{
+            return host + "index.php?m=Home&c=Api&a=searchList&version=" + version;
+        }
+    }
+
+    public String getVersionUrl(String packageId,int uploadType){
+        return host + "index.php?m=Home&c=Api&a=uploadVersion"+
+                "&packageId="+ packageId
+                +"&upload_type="+ uploadType;
+    }
+
+    public String getVersionTestUrl(String packageId,int uploadType){
+        return host + "index.php?m=Home&c=Api&a=uploadVersion_test"+
+                "&packageId="+ packageId
+                +"&upload_type="+ uploadType;
+    }
+
+
+    public String getSearchResultById(@NonNull String sourceId){
+        return host + "index.php?m=Home&c=Api&a=searchSource&sourceId="+ sourceId;
+    }
+
+    public String getUserInfoUrl(String userId){
+        return host + "index.php?m=Home&c=Api&a=userDate"+
+                "&user_id=" + userId;
+    }
+
+    public String getCreateOrderUrl(String userId, String orderNo){
+        return host + "index.php?m=Home&c=JcApi&a=CreatOrder"+
+                "&paySn="+ orderNo
+                +"&uid=" + userId;
+    }
+
+    public String getSourceDataUrl(String sourceId){
+        return host + "index.php?m=Home&c=Api&a=searchSource"+
+                "&sourceId="+ sourceId;
+    }
+
+    public String getLikeDataUrl(String packageId){
+        return host + "index.php?m=Home&c=Api&a=h5guess"+
+                "&packageId="+ packageId;
+    }
+
+    public String getHuYaShowStateUrl(String packageId){
+        return host + "index.php?m=Home&c=Api&a=packageConfig"+
+                "&packageId="+ packageId;
+    }
+
+    public String getHuYaApkUrl(){
+        return "http://yydl.duowan.com/mobile/kiwi-androidtv/2.2.0/kiwi-2.2.0-shipin.apk";
+    }
+
+    public String getSingleSource(String sourceId){
+        return host+"index.php?m=Home&c=Api&a=searchSource&sourceId="+sourceId;
+    }
+
+    public String getSecondaryUrl(String mark){
+        return host+"index.php?m=Home&c=Api&a=Xqdata&mark="+mark;
+    }
+
+    public String getSecondaryTabUrl(String tabId,String tabType,String mark){
+        return host+"index.php?m=Home&c=Api&a=XqTabData&tab_id="+tabId
+                + "&tab_type="+ tabType
+                + "&mark="+ tabType;
+    }
+
+    public String getCreateUserUrl(String uId,String templateId,
+                                   String platformId,String mac){
+        return host+"index.php?m=Home&c=jcApi&a=addUser&uid=" + uId
+                + "&template_id=" + templateId
+                + "&platform_id=" + platformId
+                + "&mac=" + mac;
+    }
+
+    public String getCheckCollectUrl(String uId,String sourceId){
+        return host+"index.php?m=Home&c=JcApi&a=isCollect&user_id=" + uId
+                + "&source_id=" + sourceId;
+    }
+
+    public String getUserLoginUrl(String uId,int versionCode,String versionName){
+        return host+"index.php?m=Home&c=jcApi&a=userLogin"
+                + "&uid=" + uId + "&version_code=" + versionCode
+                + "&version_name=" + versionName;
+    }
+
+    public String getWatchCollectUrl(String sourceId){
+        return host+"index.php?m=Home&c=JcApi&a=watchsource"
+                + "&source_id=" + sourceId;
+
+    }
+
+    public String getFreeAreaUrl(){
+        return host+"index.php?m=Home&c=JcApi&a=feeStyleList";
+    }
+
+    public String getFreeAreaListUrl(String styleId){
+        return host+"index.php?m=Home&c=JcApi&a=feeStyleSource" + "&style_id=" + styleId;
+    }
+
+    public String getH5Address(){
+        return host + "h5/special/20180329/index.html";
+    }
+
+    public String getUpdateOrderUrl(String paySn,String orderId,int status){
+        return host+"index.php?m=Home&c=JcApi&a=androidOnNotify"
+                + "&paySn=" + paySn
+                + "&orderId=" + orderId
+                + "&status=" + status;
+    }
+
+    public String getLoadingImage(String imageType){
+        return host+"index.php?m=Home&c=Api&a=AndroidImage"
+                + "&key=" + imageType;
+    }
+
+    public String getH5SwitchUrl(){
+        return host+"index.php?m=Home&c=Api&a=act_config";
+    }
+
+    public String getCommitSequenceIdUrl(String sequenceId, int code){
+        return host+"index.php?m=Home&c=Api&a=AndroidSequenceId"
+                +"&SequenceId=" + sequenceId
+                +"&resultCode=" + code;
+    }
+
+    public String getRecordBillingUrl(String userId, int isBilling,String device_id){
+        return host+"index.php?m=Home&c=AndroidApi&a=UserBilling"
+                +"&uid=" + userId
+                +"&isMonthBilling=" + isBilling
+                +"&device_id=" + device_id;
+    }
+
+    public String getJoinActivityUrl(String phoneNo){
+        return host + "index.php?m=Home&c=AndroidApi&a=joinActivity"+
+                "&phone="+ phoneNo;
+    }
+
+    public String getCommitJoinActivityUrl(String phoneNo,String sequenceId,String userId){
+        return host + "index.php?m=Home&c=AndroidApi&a=activityNum"+
+                "&phone="+ phoneNo+
+                "&sequenceId="+ sequenceId+
+                "&uid="+ userId;
+    }
+}

+ 66 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CheckQueryViewModel.java

@@ -0,0 +1,66 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.CheckQuery;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CheckQueryFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CheckQueryViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CheckQuery checkQuery;
+    private String deviceId;
+
+
+    public CheckQueryViewModel(String deviceId){
+        this.deviceId = deviceId;
+        fetchCreateQueryData();
+    }
+
+    private void fetchCreateQueryData() {
+        compositeDisposable.add( new CheckQueryFactory().create()
+                .getObservable(deviceId,deviceId,String.valueOf(System.currentTimeMillis()))
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CheckQuery>() {
+                    @Override
+                    public void accept(@NonNull CheckQuery source) throws Exception {
+                        setCheckQueryData(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCheckQueryData(CheckQuery source){
+        this.checkQuery = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CheckQuery getCheckQuery(){return this.checkQuery;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 67 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CollectWatchViewModel.java

@@ -0,0 +1,67 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.CollectWatch;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CollectWatchFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class CollectWatchViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CollectWatch collectWatch;
+    private String sourceId = "";
+
+    public CollectWatchViewModel(String sourceId){
+        this.sourceId = sourceId;
+        fetchCollectWatch();
+    }
+
+    private void fetchCollectWatch() {
+        String requestUrl = UrlManager.getInstance().getWatchCollectUrl(sourceId);
+
+        compositeDisposable.add( new CollectWatchFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CollectWatch>() {
+                    @Override
+                    public void accept(@NonNull CollectWatch source) throws Exception {
+                        setCollectWatchData(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCollectWatchData(CollectWatch source){
+        this.collectWatch = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CollectWatch getCollectWatch(){return this.collectWatch;}
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 72 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CommitJoinActivityResultViewModel.java

@@ -0,0 +1,72 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.CommitJoinActivityResult;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CommitJoinActivityResultFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CommitJoinActivityResultViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CommitJoinActivityResult commitJoinActivityResult;
+    private String phoneNo;
+    private String sequenceId;
+    private String userId;
+
+    public CommitJoinActivityResultViewModel(String phoneNo,String sequenceId,String userId){
+        this.phoneNo = phoneNo;
+        this.sequenceId = sequenceId;
+        this.userId = userId;
+        fetchCommitJoinActivityResult();
+    }
+
+    private void fetchCommitJoinActivityResult() {
+        String requestUrl = UrlManager.getInstance().getCommitJoinActivityUrl(phoneNo,sequenceId,userId);
+
+        compositeDisposable.add( new CommitJoinActivityResultFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CommitJoinActivityResult>() {
+                    @Override
+                    public void accept(@NonNull CommitJoinActivityResult source) throws Exception {
+                        setCommitJoinActivityResult(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCommitJoinActivityResult(CommitJoinActivityResult source){
+        this.commitJoinActivityResult = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CommitJoinActivityResult getCommitJoinActivityResult(){return this.commitJoinActivityResult;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 71 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CommitSequenceIdViewModel.java

@@ -0,0 +1,71 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+
+import com.guangzhou.haochuan.jxtv.model.CollectWatch;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CollectWatchFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CommitSequenceIdViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CollectWatch collectWatch;
+    private String sequenceId;
+    private int code;
+
+    public CommitSequenceIdViewModel(String sequenceId, int code){
+        this.sequenceId = sequenceId;
+        this.code = code;
+        fetchBillboardData();
+    }
+
+    private void fetchBillboardData() {
+        String requestUrl = UrlManager.getInstance().getCommitSequenceIdUrl(sequenceId,code);
+
+        compositeDisposable.add( new CollectWatchFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CollectWatch>() {
+                    @Override
+                    public void accept(@NonNull CollectWatch source) throws Exception {
+                        setCollectWatch(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCollectWatch(CollectWatch source){
+        this.collectWatch= source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CollectWatch getCollectWatch(){return this.collectWatch;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 71 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CreateOrderViewModel.java

@@ -0,0 +1,71 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+import android.content.Context;
+
+import com.guangzhou.haochuan.jxtv.model.CreateOrderBackData;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CreateOrderFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class CreateOrderViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CreateOrderBackData createOrderBackData;
+    private String userId = "";
+    private String orderNo = "";
+    private String mark;
+
+    public CreateOrderViewModel(Context context, String userId, String orderNo){
+        this.userId = userId;
+        this.orderNo = orderNo;
+        fetchStyleData();
+    }
+
+    private void fetchStyleData() {
+        String requestUrl = UrlManager.getInstance().getCreateOrderUrl(userId,orderNo);
+
+        compositeDisposable.add( new CreateOrderFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CreateOrderBackData>() {
+                    @Override
+                    public void accept(@NonNull CreateOrderBackData source) throws Exception {
+                        setCreateOrderData(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCreateOrderData(CreateOrderBackData source){
+        this.createOrderBackData = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CreateOrderBackData getCreateOrderData(){return this.createOrderBackData;}
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 78 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CreateQueryViewModel.java

@@ -0,0 +1,78 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.CreateQuery;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CreateQueryFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CreateQueryViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CreateQuery createQuery;
+    private String deviceId;
+    private String token;
+    private String productId;
+    private String contentId;
+    private String businessType;
+    private String reverse;
+
+    public CreateQueryViewModel(String deviceId, String token,
+                                String productId, String contentId,
+                                String businessType, String reverse){
+        this.deviceId = deviceId;
+        this.token = token;
+        this.productId = productId;
+        this.contentId = contentId;
+        this.businessType = businessType;
+        this.reverse = reverse;
+        fetchCreateQueryData();
+    }
+
+    private void fetchCreateQueryData() {
+
+        compositeDisposable.add( new CreateQueryFactory().create()
+                .getObservable(deviceId,"","",token,token,productId,contentId,businessType,"",this.reverse,String.valueOf(System.currentTimeMillis()))
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CreateQuery>() {
+                    @Override
+                    public void accept(@NonNull CreateQuery source) throws Exception {
+                        setCreateQueryData(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCreateQueryData(CreateQuery source){
+        this.createQuery = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CreateQuery getCreateQuery(){return this.createQuery;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 76 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/CreateUserViewModel.java

@@ -0,0 +1,76 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.CreateUserResult;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.CreateUserFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class CreateUserViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private CreateUserResult createUserResult;
+    private String uId;
+    private String templateId;
+    private String platformId;
+    private String mac;
+
+    public CreateUserViewModel(String uId,
+                               String templateId,
+                               String platformId,
+                               String mac){
+        this.uId = uId;
+        this.templateId = templateId;
+        this.platformId = platformId;
+        this.mac = mac;
+        fetchStyleData();
+    }
+
+    private void fetchStyleData() {
+        String requestUrl = UrlManager.getInstance().getCreateUserUrl(uId,templateId,platformId,mac);
+
+        compositeDisposable.add( new CreateUserFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<CreateUserResult>() {
+                    @Override
+                    public void accept(@NonNull CreateUserResult source) throws Exception {
+                        setCreateUserResult(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setCreateUserResult(CreateUserResult source){
+        this.createUserResult = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public CreateUserResult getCreateUserResult(){return this.createUserResult;}
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 66 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/DeviceInfoViewModel.java

@@ -0,0 +1,66 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+import com.guangzhou.haochuan.jxtv.model.DeviceInfoReturn;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.DeviceInfoFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class DeviceInfoViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    String deviceId;
+    String phone;
+    String token;
+    int isVip;
+    String uId;
+
+    public DeviceInfoViewModel(String deviceId,
+                               String phone,
+                               String token,
+                               int isVip, String uId){
+        this.deviceId = deviceId;
+        this.phone = phone;
+        this.token = token;
+        this.isVip = isVip;
+        this.uId = uId;
+        fetchDeviceInfo();
+    }
+
+    private void fetchDeviceInfo() {
+
+        compositeDisposable.add( new DeviceInfoFactory().create()
+                .getObservable(deviceId,phone,token,isVip,uId)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<DeviceInfoReturn>() {
+                    @Override
+                    public void accept(@NonNull DeviceInfoReturn source) throws Exception {
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 69 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/ErrorDataViewModel.java

@@ -0,0 +1,69 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+import com.guangzhou.haochuan.jxtv.model.ErrorResult;
+import com.guangzhou.haochuan.jxtv.model.StyleData;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.ErrorFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class ErrorDataViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    String cpuAbi;
+    String cpuAbi2;
+    String versionName;
+    String versionCode;
+    String apiLevel;
+    String errorMessage;
+    String ramSize;
+
+    public ErrorDataViewModel(String cpuAbi, String cpuAbi2, String versionName,
+                              String versionCode, String apiLevel, String errorMessage, String ramSize){
+        this.cpuAbi = cpuAbi;
+        this.cpuAbi2 = cpuAbi2;
+        this.versionName = versionName;
+        this.versionCode = versionCode;
+        this.apiLevel = apiLevel;
+        this.errorMessage = errorMessage;
+        this.ramSize = ramSize;
+        fetchErrorData();
+    }
+
+    private void fetchErrorData() {
+
+        compositeDisposable.add( new ErrorFactory().create()
+                .getObservable(cpuAbi,cpuAbi2,versionName,versionCode,apiLevel,errorMessage,ramSize)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<ErrorResult>() {
+                    @Override
+                    public void accept(@NonNull ErrorResult source) throws Exception {
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 66 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/H5SwitchViewModel.java

@@ -0,0 +1,66 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.H5Switch;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.H5SwitchFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class H5SwitchViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private H5Switch h5Switch;
+
+    public H5SwitchViewModel(){
+        fetchH5Switch();
+    }
+
+    private void fetchH5Switch() {
+        String requestUrl = UrlManager.getInstance().getH5SwitchUrl();
+
+        compositeDisposable.add( new H5SwitchFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<H5Switch>() {
+                    @Override
+                    public void accept(@NonNull H5Switch source) throws Exception {
+                        setH5Switch(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setH5Switch(H5Switch source){
+        this.h5Switch =source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public H5Switch getH5Switch(){return this.h5Switch;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 68 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/JoinActivityViewModel.java

@@ -0,0 +1,68 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.JoinActivity;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.JoinActivityFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class JoinActivityViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private JoinActivity joinActivity;
+    private String phoneNo;
+
+    public JoinActivityViewModel(String phoneNo){
+        this.phoneNo = phoneNo;
+        fetchJoinActivityData();
+    }
+
+    private void fetchJoinActivityData() {
+        String requestUrl = UrlManager.getInstance().getJoinActivityUrl(phoneNo);
+
+        compositeDisposable.add( new JoinActivityFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<JoinActivity>() {
+                    @Override
+                    public void accept(@NonNull JoinActivity source) throws Exception {
+                        setJoinActivity(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setJoinActivity(JoinActivity source){
+        this.joinActivity = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public JoinActivity getJoinActivity(){return this.joinActivity;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 68 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/LoadingImageViewModel.java

@@ -0,0 +1,68 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+
+import com.guangzhou.haochuan.jxtv.model.LoadingImage;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.LoadingImageFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class LoadingImageViewModel extends Observable {
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private LoadingImage loadingImage;
+    private String imageType;
+
+    public LoadingImageViewModel(String imageType){
+        this.imageType = imageType;
+        fetchLoadingImage();
+    }
+
+    private void fetchLoadingImage() {
+        String requestUrl = UrlManager.getInstance().getLoadingImage(imageType);
+
+        compositeDisposable.add( new LoadingImageFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<LoadingImage>() {
+                    @Override
+                    public void accept(@NonNull LoadingImage source) throws Exception {
+                        setLoadingImage(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setLoadingImage(LoadingImage source){
+        this.loadingImage = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public LoadingImage getLoadingImage(){return this.loadingImage;}
+
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 73 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/SearchSingleSourceViewModel.java

@@ -0,0 +1,73 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+import android.content.Context;
+
+
+import com.guangzhou.haochuan.jxtv.model.SearchSingleSource;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.SingleSourceFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class SearchSingleSourceViewModel extends Observable {
+    private Context mContext;
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private SearchSingleSource searchSingleSource;
+    private String sourceId;
+
+    public SearchSingleSourceViewModel(Context context, String sourceId){
+        this.mContext = context;
+        this.sourceId = sourceId;
+        fetchBillboardData();
+    }
+
+    private void fetchBillboardData() {
+        String requestUrl = UrlManager.getInstance().getSingleSource(sourceId);
+
+        compositeDisposable.add( new SingleSourceFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<SearchSingleSource>() {
+                    @Override
+                    public void accept(@NonNull SearchSingleSource source) throws Exception {
+                        setSearchSingleSource(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setSearchSingleSource(SearchSingleSource source){
+        this.searchSingleSource= source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public SearchSingleSource getSearchSingleSource(){return this.searchSingleSource;}
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+        mContext = null;
+    }
+
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 76 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/viewModel/UserLoginViewModel.java

@@ -0,0 +1,76 @@
+package com.guangzhou.haochuan.jxtv.viewModel;
+
+import android.content.Context;
+
+
+import com.guangzhou.haochuan.jxtv.model.UserLogin;
+import com.guangzhou.haochuan.jxtv.util.UrlManager;
+import com.guangzhou.haochuan.jxtv.web.retrofitFactory.UserLoginFactory;
+
+import java.util.Observable;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Consumer;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class UserLoginViewModel extends Observable {
+    private Context mContext;
+    private CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private UserLogin userLogin;
+    private String userId = "";
+    private int versionCode;
+    private String versionName;
+
+    public UserLoginViewModel(Context context, String userId, int versionCode, String versionName){
+        this.mContext = context;
+        this.userId = userId;
+        this.versionCode = versionCode;
+        this.versionName = versionName;
+        fetchStyleData();
+    }
+
+    private void fetchStyleData() {
+        String requestUrl = UrlManager.getInstance().getUserLoginUrl(userId,versionCode,versionName);
+
+        compositeDisposable.add( new UserLoginFactory().create()
+                .getObservable(requestUrl)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<UserLogin>() {
+                    @Override
+                    public void accept(@NonNull UserLogin source) throws Exception {
+                        setUserLoginData(source);
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        throwable.printStackTrace();
+                    }
+                }));
+    }
+
+    public void setUserLoginData(UserLogin source){
+        this.userLogin = source;
+        setChanged();
+        notifyObservers();
+    }
+
+    public UserLogin getUserLoginData(){return this.userLogin;}
+
+    public void reset(){
+        unSubscribeFromObservable();
+        compositeDisposable = null;
+        mContext = null;
+    }
+    private void unSubscribeFromObservable() {
+        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
+            compositeDisposable.dispose();
+        }
+    }
+}

+ 25 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/BasicFactory.java

@@ -0,0 +1,25 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+/**
+ * Created by yunhaipiaodi on 2017/8/2.
+ */
+
+public class BasicFactory {
+    protected String baseUrl = "http://gzhc.a039.ottcn.com:8018/tv/";
+    protected Retrofit retrofit = new Retrofit.Builder()
+            .baseUrl(baseUrl)
+            .client(new OkHttpClient.Builder()
+                    .connectTimeout(10, TimeUnit.SECONDS)
+                    .writeTimeout(10, TimeUnit.SECONDS)
+                    .readTimeout(10, TimeUnit.SECONDS).build())
+            .addConverterFactory(GsonConverterFactory.create())
+            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+            .build();
+}

+ 29 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CheckQueryFactory.java

@@ -0,0 +1,29 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.CheckQueryService;
+
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CheckQueryFactory {
+    protected String baseUrl = "http://223.82.137.201:8080/yst-ord-api//";
+    protected Retrofit retrofit = new Retrofit.Builder()
+            .baseUrl(baseUrl)
+            .client(new OkHttpClient.Builder()
+                    .connectTimeout(10, TimeUnit.SECONDS)
+                    .writeTimeout(10, TimeUnit.SECONDS)
+                    .readTimeout(10, TimeUnit.SECONDS).build())
+            .addConverterFactory(GsonConverterFactory.create())
+            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+            .build();
+    public CheckQueryService create(){return retrofit.create(CheckQueryService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CollectWatchFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.CollectWatchService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class CollectWatchFactory extends BasicFactory {
+    public CollectWatchService create(){return super.retrofit.create(CollectWatchService.class);}
+}

+ 11 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CommitJoinActivityResultFactory.java

@@ -0,0 +1,11 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.CommitJoinActivityResultService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CommitJoinActivityResultFactory extends BasicFactory {
+    public CommitJoinActivityResultService create(){return super.retrofit.create(CommitJoinActivityResultService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CreateOrderFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.CreateOrderService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class CreateOrderFactory extends BasicFactory {
+    public CreateOrderService create(){return super.retrofit.create(CreateOrderService.class);}
+}

+ 29 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CreateQueryFactory.java

@@ -0,0 +1,29 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.CreateQueryService;
+
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CreateQueryFactory {
+    protected String baseUrl = "http://223.82.137.201:8080/yst-ord-api//";
+    protected Retrofit retrofit = new Retrofit.Builder()
+            .baseUrl(baseUrl)
+            .client(new OkHttpClient.Builder()
+                    .connectTimeout(10, TimeUnit.SECONDS)
+                    .writeTimeout(10, TimeUnit.SECONDS)
+                    .readTimeout(10, TimeUnit.SECONDS).build())
+            .addConverterFactory(GsonConverterFactory.create())
+            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+            .build();
+    public CreateQueryService create(){return retrofit.create(CreateQueryService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/CreateUserFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.CreateUserService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class CreateUserFactory extends BasicFactory {
+    public CreateUserService create(){return super.retrofit.create(CreateUserService.class);}
+}

+ 11 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/DeviceInfoFactory.java

@@ -0,0 +1,11 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.DeviceInfoService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class DeviceInfoFactory extends BasicFactory {
+    public DeviceInfoService create(){return super.retrofit.create(DeviceInfoService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/ErrorFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.ErrorService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class ErrorFactory extends BasicFactory {
+    public ErrorService create(){return super.retrofit.create(ErrorService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/H5SwitchFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.H5SwitchService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class H5SwitchFactory extends BasicFactory {
+    public H5SwitchService create(){return super.retrofit.create(H5SwitchService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/JoinActivityFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.JoinActivityService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class JoinActivityFactory extends BasicFactory {
+    public JoinActivityService create(){return super.retrofit.create(JoinActivityService.class);}
+}

+ 11 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/LoadingImageFactory.java

@@ -0,0 +1,11 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.LoadingImageService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class LoadingImageFactory extends BasicFactory {
+    public LoadingImageService create(){return super.retrofit.create(LoadingImageService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/SingleSourceFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.SingleSourceService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public class SingleSourceFactory extends BasicFactory {
+    public SingleSourceService create(){return super.retrofit.create(SingleSourceService.class);}
+}

+ 12 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitFactory/UserLoginFactory.java

@@ -0,0 +1,12 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitFactory;
+
+
+import com.guangzhou.haochuan.jxtv.web.retrofitService.UserLoginService;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public class UserLoginFactory extends BasicFactory {
+    public UserLoginService create(){return super.retrofit.create(UserLoginService.class);}
+}

+ 20 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CheckQueryService.java

@@ -0,0 +1,20 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+import com.guangzhou.haochuan.jxtv.model.CheckQuery;
+
+import io.reactivex.Observable;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface CheckQueryService {
+    @POST("order/checkPwdExisted")
+    @FormUrlEncoded
+    public  Observable<CheckQuery> getObservable(@Field("deviceId") String deviceId,
+                                                 @Field("deviceCode") String deviceCode,
+                                                 @Field("t") String time);
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CollectWatchService.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.CollectWatch;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public interface CollectWatchService {
+    @GET
+    public Observable<CollectWatch> getObservable(@Url String url);
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CommitJoinActivityResultService.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.CommitJoinActivityResult;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface CommitJoinActivityResultService {
+    @GET
+    public Observable<CommitJoinActivityResult> getObservable(@Url String url);
+}

+ 16 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CreateOrderService.java

@@ -0,0 +1,16 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+import com.guangzhou.haochuan.jxtv.model.CreateOrderBackData;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public interface CreateOrderService {
+    @GET
+    public Observable<CreateOrderBackData> getObservable(@Url String url);
+}

+ 29 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CreateQueryService.java

@@ -0,0 +1,29 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.CreateQuery;
+
+import io.reactivex.Observable;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface CreateQueryService {
+    @POST("order/create")
+    @FormUrlEncoded
+    public  Observable<CreateQuery> getObservable(@Field("deviceId") String deviceId,
+                                                  @Field("uid") String uid,
+                                                  @Field("phone") String phone,
+                                                  @Field("token") String token,
+                                                  @Field("spToken") String spToken,
+                                                  @Field("productId") String productId,
+                                                  @Field("contentId") String contentId,
+                                                  @Field("businessType") String businessType,
+                                                  @Field("extendInfo") String extendInfo,
+                                                  @Field("reserve") String reserve,
+                                                  @Field("t") String time);
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/CreateUserService.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.CreateUserResult;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface CreateUserService {
+    @GET
+    public Observable<CreateUserResult> getObservable(@Url String url);
+}

+ 22 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/DeviceInfoService.java

@@ -0,0 +1,22 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+import com.guangzhou.haochuan.jxtv.model.DeviceInfoReturn;
+
+import io.reactivex.Observable;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface DeviceInfoService {
+    @POST("index.php?m=Home&c=TvApi&a=putDevicePhone")
+    @FormUrlEncoded
+    public  Observable<DeviceInfoReturn> getObservable(@Field("device_id") String deviceId,
+                                                       @Field("phone_no") String phoneNo,
+                                                       @Field("token") String token,
+                                                       @Field("is_vip") int isVip,
+                                                       @Field("user_id") String uId);
+}

+ 26 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/ErrorService.java

@@ -0,0 +1,26 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.ErrorResult;
+import com.guangzhou.haochuan.jxtv.model.StyleData;
+
+import io.reactivex.Observable;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface ErrorService {
+        @POST("index.php?m=Home&c=Api&a=addError")
+    @FormUrlEncoded
+    public  Observable<ErrorResult> getObservable(@Field("cpu_abi") String cpuAbi,
+                                                  @Field("cpu_abi2") String cpuAbi2,
+                                                  @Field("version_name") String versionName,
+                                                  @Field("version_code") String versionCode,
+                                                  @Field("api_level") String apiLevel,
+                                                  @Field("error_message") String errorMessage,
+                                                  @Field("ram_size") String ramSize);
+}

+ 15 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/H5SwitchService.java

@@ -0,0 +1,15 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+import com.guangzhou.haochuan.jxtv.model.H5Switch;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface H5SwitchService {
+    @GET
+    public Observable<H5Switch> getObservable(@Url String url);
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/JoinActivityService.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.JoinActivity;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface JoinActivityService {
+    @GET
+    public Observable<JoinActivity> getObservable(@Url String url);
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/LoadingImageService.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.LoadingImage;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface LoadingImageService {
+    @GET
+    public Observable<LoadingImage> getObservable(@Url String url);
+}

+ 16 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/SingleSourceService.java

@@ -0,0 +1,16 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+import com.guangzhou.haochuan.jxtv.model.SearchSingleSource;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/22.
+ */
+
+public interface SingleSourceService {
+    @GET
+    public Observable<SearchSingleSource> getObservable(@Url String url);
+}

+ 17 - 0
app/src/main/java/com/guangzhou/haochuan/jxtv/web/retrofitService/UserLoginService.java

@@ -0,0 +1,17 @@
+package com.guangzhou.haochuan.jxtv.web.retrofitService;
+
+
+import com.guangzhou.haochuan.jxtv.model.UserLogin;
+
+import io.reactivex.Observable;
+import retrofit2.http.GET;
+import retrofit2.http.Url;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/20.
+ */
+
+public interface UserLoginService {
+    @GET
+    public Observable<UserLogin> getObservable(@Url String url);
+}

二進制
app/src/main/jniLibs/VDS-2.4.6.jar


二進制
app/src/main/jniLibs/adsdk.jar


二進制
app/src/main/jniLibs/armeabi-v7a/libVDS.so


二進制
app/src/main/jniLibs/armeabi-v7a/libadsdk.so


二進制
app/src/main/jniLibs/armeabi-v7a/liblogsdk.so


二進制
app/src/main/jniLibs/armeabi-v7a/libottlogin.so


二進制
app/src/main/jniLibs/icntvplayersdk.jar


二進制
app/src/main/jniLibs/logsdk.jar


二進制
app/src/main/jniLibs/ottlogin.jar


+ 0 - 0
app/src/main/jniLibs/universal-image-loader-1.9.3.jar


部分文件因文件數量過多而無法顯示