Przeglądaj źródła

commit by xuling

lyn 7 lat temu
commit
3effb41cff
100 zmienionych plików z 3217 dodań i 0 usunięć
  1. 9 0
      .gitignore
  2. 20 0
      .idea/gradle.xml
  3. 33 0
      .idea/misc.xml
  4. 11 0
      .idea/modules.xml
  5. 12 0
      .idea/runConfigurations.xml
  6. 6 0
      .idea/vcs.xml
  7. 1 0
      TvSDK_Lib_Project/.gitignore
  8. 25 0
      TvSDK_Lib_Project/build.gradle
  9. BIN
      TvSDK_Lib_Project/libs/odin.jar
  10. BIN
      TvSDK_Lib_Project/libs/tv_pay_static.jar
  11. 17 0
      TvSDK_Lib_Project/proguard-rules.pro
  12. 16 0
      TvSDK_Lib_Project/src/main/AndroidManifest.xml
  13. BIN
      TvSDK_Lib_Project/src/main/res/drawable-hdpi/ic_launcher.png
  14. BIN
      TvSDK_Lib_Project/src/main/res/raw/odin_plugin_ability_1x0x3.apk
  15. BIN
      TvSDK_Lib_Project/src/main/res/raw/odin_plugin_tv_1x0x0.apk
  16. 11 0
      TvSDK_Lib_Project/src/main/res/values-v11/styles.xml
  17. 12 0
      TvSDK_Lib_Project/src/main/res/values-v14/styles.xml
  18. 5 0
      TvSDK_Lib_Project/src/main/res/values/strings.xml
  19. 20 0
      TvSDK_Lib_Project/src/main/res/values/styles.xml
  20. 1 0
      app/.gitignore
  21. 53 0
      app/build.gradle
  22. 86 0
      app/proguard-rules.pro
  23. BIN
      app/release/dudutoy.apk
  24. 1 0
      app/release/output.json
  25. 26 0
      app/src/androidTest/java/com/haochuan/djbl/ExampleInstrumentedTest.java
  26. 78 0
      app/src/main/AndroidManifest.xml
  27. 25 0
      app/src/main/java/com/haochuan/djbl/BasicFactory.java
  28. 312 0
      app/src/main/java/com/haochuan/djbl/CrashHandler.java
  29. 592 0
      app/src/main/java/com/haochuan/djbl/DjblMainActivity.java
  30. 66 0
      app/src/main/java/com/haochuan/djbl/ErrorDataViewModel.java
  31. 9 0
      app/src/main/java/com/haochuan/djbl/ErrorFactory.java
  32. 23 0
      app/src/main/java/com/haochuan/djbl/ErrorService.java
  33. 146 0
      app/src/main/java/com/haochuan/djbl/HuaweiPay.java
  34. 42 0
      app/src/main/java/com/haochuan/djbl/LocalStore.java
  35. 109 0
      app/src/main/java/com/haochuan/djbl/PayActivity.java
  36. 8 0
      app/src/main/java/com/haochuan/djbl/StringUtils.java
  37. 14 0
      app/src/main/java/com/haochuan/djbl/StyleData.java
  38. 44 0
      app/src/main/java/com/haochuan/djbl/TestUnsubscribe.java
  39. 22 0
      app/src/main/java/com/haochuan/djbl/ToyApplication.java
  40. 29 0
      app/src/main/java/com/haochuan/djbl/UrlManager.java
  41. 334 0
      app/src/main/java/com/haochuan/djbl/VideoEndDialog.java
  42. 26 0
      app/src/main/java/com/haochuan/djbl/VideoInfo.java
  43. 323 0
      app/src/main/java/com/haochuan/djbl/VideoPlayerActivity.java
  44. BIN
      app/src/main/res/drawable-hdpi/btn_icon_add_default.png
  45. BIN
      app/src/main/res/drawable-hdpi/btn_icon_add_selected.png
  46. BIN
      app/src/main/res/drawable-hdpi/btn_icon_continue.png
  47. BIN
      app/src/main/res/drawable-hdpi/btn_icon_out.png
  48. BIN
      app/src/main/res/drawable-hdpi/img_start_bg.jpg
  49. BIN
      app/src/main/res/drawable-hdpi/loading_icon.png
  50. BIN
      app/src/main/res/drawable-ldpi/btn_icon_add_default.png
  51. BIN
      app/src/main/res/drawable-ldpi/btn_icon_add_selected.png
  52. BIN
      app/src/main/res/drawable-ldpi/btn_icon_continue.png
  53. BIN
      app/src/main/res/drawable-ldpi/btn_icon_out.png
  54. BIN
      app/src/main/res/drawable-ldpi/img_start_bg.jpg
  55. BIN
      app/src/main/res/drawable-mdpi/btn_icon_add_default.png
  56. BIN
      app/src/main/res/drawable-mdpi/btn_icon_add_selected.png
  57. BIN
      app/src/main/res/drawable-mdpi/btn_icon_continue.png
  58. BIN
      app/src/main/res/drawable-mdpi/btn_icon_out.png
  59. BIN
      app/src/main/res/drawable-mdpi/img_start_bg.jpg
  60. BIN
      app/src/main/res/drawable-mdpi/loading_icon.png
  61. BIN
      app/src/main/res/drawable-xhdpi/btn_icon_add_default.png
  62. BIN
      app/src/main/res/drawable-xhdpi/btn_icon_add_selected.png
  63. BIN
      app/src/main/res/drawable-xhdpi/btn_icon_continue.png
  64. BIN
      app/src/main/res/drawable-xhdpi/btn_icon_out.png
  65. BIN
      app/src/main/res/drawable-xhdpi/img_start_bg.jpg
  66. BIN
      app/src/main/res/drawable-xhdpi/loading_icon.png
  67. BIN
      app/src/main/res/drawable-xxhdpi/btn_icon_add_default.png
  68. BIN
      app/src/main/res/drawable-xxhdpi/btn_icon_add_selected.png
  69. BIN
      app/src/main/res/drawable-xxhdpi/btn_icon_continue.png
  70. BIN
      app/src/main/res/drawable-xxhdpi/btn_icon_out.png
  71. BIN
      app/src/main/res/drawable-xxhdpi/img_start_bg.jpg
  72. BIN
      app/src/main/res/drawable-xxhdpi/loading_icon.png
  73. BIN
      app/src/main/res/drawable/djbl_icon.png
  74. BIN
      app/src/main/res/drawable/dudu_icon.jpg
  75. 28 0
      app/src/main/res/drawable/dudu_video_seek_progress.xml
  76. 170 0
      app/src/main/res/drawable/ic_launcher_background.xml
  77. 34 0
      app/src/main/res/drawable/ic_launcher_foreground.xml
  78. 5 0
      app/src/main/res/drawable/loading_animation.xml
  79. 7 0
      app/src/main/res/drawable/top_bar_back.xml
  80. 6 0
      app/src/main/res/drawable/video_end_btn_back.xml
  81. 7 0
      app/src/main/res/drawable/video_end_btn_back_focus.xml
  82. 5 0
      app/src/main/res/drawable/video_end_btn_back_normal.xml
  83. 8 0
      app/src/main/res/drawable/video_seek_thumb_normal.xml
  84. 13 0
      app/src/main/res/layout/activity_main.xml
  85. 22 0
      app/src/main/res/layout/activity_pay.xml
  86. 13 0
      app/src/main/res/layout/activity_test_unsubscribe.xml
  87. 20 0
      app/src/main/res/layout/activity_video_player.xml
  88. 102 0
      app/src/main/res/layout/dialog_video_end.xml
  89. 5 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  90. 5 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  91. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  92. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  93. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  94. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  95. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  96. 50 0
      app/src/main/res/values-hdpi/dimens.xml
  97. 50 0
      app/src/main/res/values-ldpi/dimens.xml
  98. 50 0
      app/src/main/res/values-mdpi-1280x720/dimens.xml
  99. 50 0
      app/src/main/res/values-mdpi-1920x1080/dimens.xml
  100. 0 0
      app/src/main/res/values-xhdpi/dimens.xml

+ 9 - 0
.gitignore

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

+ 20 - 0
.idea/gradle.xml

@@ -0,0 +1,20 @@
+<?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$/TvSDK_Lib_Project" />
+            <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/bdvideoplayer" />
+          </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>

+ 11 - 0
.idea/modules.xml

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

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/git" vcs="Git" />
+  </component>
+</project>

+ 1 - 0
TvSDK_Lib_Project/.gitignore

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

+ 25 - 0
TvSDK_Lib_Project/build.gradle

@@ -0,0 +1,25 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 27
+    buildToolsVersion "27.0.2"
+
+    defaultConfig {
+        minSdkVersion 15
+        targetSdkVersion 27
+        versionCode 1
+        versionName "1.0"
+
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile files('libs/tv_pay_static.jar')
+    compile files('libs/odin.jar')
+}

BIN
TvSDK_Lib_Project/libs/odin.jar


BIN
TvSDK_Lib_Project/libs/tv_pay_static.jar


+ 17 - 0
TvSDK_Lib_Project/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\sdk\android-sdk-windows/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 16 - 0
TvSDK_Lib_Project/src/main/AndroidManifest.xml

@@ -0,0 +1,16 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.huawei.digital.tvpay"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="17" />
+
+    <application
+        android:allowBackup="true"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+    </application>
+
+</manifest>

BIN
TvSDK_Lib_Project/src/main/res/drawable-hdpi/ic_launcher.png


BIN
TvSDK_Lib_Project/src/main/res/raw/odin_plugin_ability_1x0x3.apk


BIN
TvSDK_Lib_Project/src/main/res/raw/odin_plugin_tv_1x0x0.apk


+ 11 - 0
TvSDK_Lib_Project/src/main/res/values-v11/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 12 - 0
TvSDK_Lib_Project/src/main/res/values-v14/styles.xml

@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 5 - 0
TvSDK_Lib_Project/src/main/res/values/strings.xml

@@ -0,0 +1,5 @@
+<resources>
+
+    <string name="app_name">PaymentSDKAndroidlib</string>
+
+</resources>

+ 20 - 0
TvSDK_Lib_Project/src/main/res/values/styles.xml

@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>

+ 1 - 0
app/.gitignore

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

+ 53 - 0
app/build.gradle

@@ -0,0 +1,53 @@
+apply plugin: 'com.android.application'
+
+android {
+    signingConfigs {
+        config {
+            keyAlias 'key0'
+            keyPassword '123456'
+            storeFile file('D:/android project/tianjin/TianjingDjbl/key/djbl.jks')
+            storePassword '123456'
+        }
+    }
+    compileSdkVersion 27
+    buildToolsVersion "27.0.2"
+    defaultConfig {
+        applicationId "com.haochuan.djbl2"
+        minSdkVersion 15
+        targetSdkVersion 27
+        versionCode 1
+        versionName "1.0.1"
+        ndk {
+            abiFilters "armeabi-v7a", "x86"
+        }
+
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+            signingConfig signingConfigs.config
+        }
+        debug {
+            debuggable true
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+            signingConfig signingConfigs.config
+        }
+    }
+}
+
+dependencies {
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
+    implementation project(':TvSDK_Lib_Project')
+    implementation project(':bdvideoplayer')
+    implementation 'com.android.support:appcompat-v7:27.0.2'
+    implementation 'com.android.support:support-v4:27.0.2'
+    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
+    implementation 'com.android.volley:volley:1.1.0'
+    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'
+}

+ 86 - 0
app/proguard-rules.pro

@@ -0,0 +1,86 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+-keep class com.huawei.tools.**{*;}
+-keep class com.huawei.ability.**{*;}
+-keep class org.kxml2.**{*;}
+-keep class org.xmlpull.**{*;}
+-keep class com.google.**{*;}
+-keep class org.tantalum.**{*;}
+-keep class android.**{*;}
+-keep class assets.**{*;}
+-keep class com.android.**{*;}
+-keep class java.**{*;}
+-keep class javax.**{*;}
+-keep class junit.**{*;}
+-keep class org.**{*;}
+-keep class res.**{*;}
+
+
+-keep public class * extends android.content.ContextWrapper
+-keep public class * extends com.odin.framework.foundation.BasePluginActivity
+-keep public class * extends com.odin.framework.foundation.BasePluginService
+
+-keep class com.odin.framework{*;}
+-keep class com.odin.framework.utils.FileUtil{*;}
+-keep class com.odin.framework.utils.StringUtil{*;}
+-keep class com.odin.framework.utils.ThreadUtil{*;}
+-keep class com.odin.framework.proxy.ProxyManager{*;}
+-keep class com.odin.framework.plugable.Logger{*;}
+-keep class com.odin.framework.foundation.Framework{*;}
+-keep class com.odin.framework.foundation.ExposedService{*;}
+-keep class com.odin.framework.foundation.PluginInfo{*;}
+
+-keep class com.odin.plugable.api.**{*;}
+-keep class com.sdk.plugable.ability.log.LogImpl{*;}
+
+-keepattributes InnerClasses
+
+#Dynamic R File
+-keep class com.huawei.digital.tv.R{*;}
+
+-keep class com.huawei.digital.tv.R$*{*;}
+
+#plugin_in R File
+-keep class com.odin_plugin.R{*;}
+
+-keep class com.haochuan.dudutoy.R{*;}
+-keep class com.haochuan.dudutoy.R$*{*;}
+
+
+
+
+-keep class com.shuyu.gsyvideoplayer.video.** { *; }
+-dontwarn com.shuyu.gsyvideoplayer.video.**
+-keep class com.shuyu.gsyvideoplayer.video.base.** { *; }
+-dontwarn com.shuyu.gsyvideoplayer.video.base.**
+-keep class com.shuyu.gsyvideoplayer.utils.** { *; }
+-dontwarn com.shuyu.gsyvideoplayer.utils.**
+-keep class tv.danmaku.ijk.** { *; }
+-dontwarn tv.danmaku.ijk.**
+
+-keep public class * extends android.view.View{
+    *** get*();
+    void set*(***);
+    public <init>(android.content.Context);
+    public <init>(android.content.Context, android.util.AttributeSet);
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}

BIN
app/release/dudutoy.apk


+ 1 - 0
app/release/output.json

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

+ 26 - 0
app/src/androidTest/java/com/haochuan/djbl/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.haochuan.djbl;
+
+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.haochuan.dudutoy", appContext.getPackageName());
+    }
+}

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

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.haochuan.djbl2">
+
+    <uses-sdk tools:overrideLibrary="com.shuyu.gsyvideoplayer,com.shuyu.gsyvideoplayer.ex_so,tv.danmaku.ijk.media.exo2,shuyu.com.androidvideocache" />
+
+    <!-- 计费权限 -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <application
+        android:name="com.haochuan.djbl.ToyApplication"
+        android:allowBackup="true"
+        android:icon="@drawable/djbl_icon"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:screenOrientation="landscape"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name="com.haochuan.djbl.DjblMainActivity"
+            android:hardwareAccelerated="true"
+            android:launchMode="singleTask"
+            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="com.haochuan.djbl.VideoPlayerActivity"
+            android:hardwareAccelerated="true"
+            android:screenOrientation="landscape"></activity>
+        <activity
+            android:name="com.haochuan.djbl.TestUnsubscribe"
+            android:screenOrientation="landscape"></activity>
+
+        <!-- 计费开始 -->
+        <activity
+            android:name="com.odin.framework.proxy.ProxyActivity"
+            android:configChanges="orientation|navigation|screenSize|keyboardHidden|keyboard"
+            android:exported="false"
+            android:screenOrientation="landscape"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="adjustPan"></activity>
+
+        <activity android:name="com.haochuan.djbl.PayActivity"
+            android:screenOrientation="landscape"
+            >
+
+        </activity>
+        <service
+            android:name="com.odin.framework.proxy.ProxyService1"
+            android:exported="false" />
+        <service
+            android:name="com.odin.framework.proxy.ProxyService2"
+            android:exported="false" />
+        <service
+            android:name="com.odin.framework.proxy.ProxyService3"
+            android:exported="false" />
+        <service
+            android:name="com.odin.framework.proxy.ProxyService4"
+            android:exported="false" />
+        <service
+            android:name="com.odin.framework.proxy.ProxyService5"
+            android:exported="false" />
+        <!-- 计费结束 -->
+
+    </application>
+
+</manifest>

+ 25 - 0
app/src/main/java/com/haochuan/djbl/BasicFactory.java

@@ -0,0 +1,25 @@
+package com.haochuan.djbl;
+
+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://202.99.114.74:56199/";
+    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();
+}

+ 312 - 0
app/src/main/java/com/haochuan/djbl/CrashHandler.java

@@ -0,0 +1,312 @@
+package com.haochuan.djbl;
+
+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 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());
+            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();
+
+
+
+        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;
+
+
+
+        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;
+    }
+}

+ 592 - 0
app/src/main/java/com/haochuan/djbl/DjblMainActivity.java

@@ -0,0 +1,592 @@
+package com.haochuan.djbl;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
+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.Toast;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+import com.android.volley.toolbox.Volley;
+import com.haochuan.djbl2.R;
+import com.odin.framework.plugable.Logger;
+import com.sdk.commplatform.entry.AuthResult;
+import com.sdk.commplatform.entry.ErrorCode;
+import com.sdk.commplatform.entry.PayResult;
+import com.sdk.commplatform.listener.CallbackListener;
+
+import org.json.JSONObject;
+
+public class DjblMainActivity extends Activity {
+
+    String TAG = "HuaweiPay";
+
+    private String userId="";
+    private WebView webview;
+
+    private String backUrl = "";
+    private String buyProductId="";
+
+    boolean enableLogger = false;
+
+    private void Logger(String msg){
+        if(enableLogger){
+            Log.d(TAG,msg);
+        }
+    }
+
+    private boolean isPlayPay =false;
+
+    private int requestPlayCode = 1;
+    private int requestPayCode =2;
+    private int responsePlayCode =3;
+
+    private H5Result h5Result = new H5Result() {
+        @Override
+        public void videoPlay(String url,String title,String uId,String sourceId) {
+            Intent intent = new Intent(DjblMainActivity.this,VideoPlayerActivity.class);
+            intent.putExtra("url",url);
+            intent.putExtra("title",title);
+            intent.putExtra("uId",uId);
+            intent.putExtra("sourceId",sourceId);
+            DjblMainActivity.this.startActivityForResult(intent,requestPlayCode);
+        }
+    };
+
+    private MyPayResult myPayResult = new MyPayResult() {
+        @Override
+        public void onSuccess() {
+            Toast("计费成功" );
+            Logger("计费成功");
+            authAfterPay();
+
+        }
+
+        @Override
+        public void onFail(String msg) {
+            Logger("计费失败:" + msg);
+            authAfterPay();
+        }
+    };
+
+    private void authAfterPay(){
+        final ProgressDialog dialog = new ProgressDialog(this);
+        dialog.setMessage("获取用户支付状态中,请稍后...");
+        dialog.setCancelable(false);
+
+        HuaweiPay.getInstance().authForMonth(new CallbackListener<AuthResult>() {
+            @Override
+            public void callback(int i, AuthResult authResult) {
+                if(i == ErrorCode.COM_PLATFORM_SUCCESS){
+                   new LocalStore(DjblMainActivity.this).saveIsVip(true);
+                }else{
+                    new LocalStore(DjblMainActivity.this).saveIsVip(false);
+                }
+                DjblMainActivity.this.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        dialog.dismiss();
+                    }
+                });
+                if(!isPlayPay){
+                    reloadUrl();
+                }else{
+                }
+
+            }
+        });
+    }
+
+    public static String replaceAccessTokenReg(String url, String name, String accessToken) {
+        url = url.replaceAll("(" + name + "=[^&]*)", name + "=" + accessToken);
+        return url;
+    }
+
+    private String transUrl(String url){
+        if(url.contains("is_vip=")){
+            url = replaceAccessTokenReg(url,"is_vip",new LocalStore(DjblMainActivity.this).getIsVip()?"true":"false");
+        }else{
+            url = url + "&is_vip=" + (new LocalStore(DjblMainActivity.this).getIsVip()?"true":"false");
+        }
+        if(!url.contains("uid=")){
+            url = url+ "&uid=" + userId;
+        }
+
+        return url;
+    }
+
+    private void reloadUrl(){
+        this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                String url = transUrl(DjblMainActivity.this.backUrl);
+                webview.loadUrl(url);
+            }
+        });
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode,int resultCode,final Intent data){
+        super.onActivityResult(requestCode,resultCode,data);
+        if(requestCode == requestPlayCode){
+            onJsFresh();
+            if(resultCode == responsePlayCode){
+                Log.d(TAG,"视频跳转计费");
+                isPlayPay = true;
+                gotoPayActivity(userId,buyProductId);
+            }
+        }else if(requestCode == requestPayCode){
+            onJsFresh();
+            authAfterPay();
+        }
+
+    }
+
+    private void gotoPayActivity(String userId,String buyProductId){
+        Intent intent = new Intent(this,PayActivity.class);
+        intent.putExtra("userId",userId);
+        intent.putExtra("buyProductId",buyProductId);
+        startActivityForResult(intent,requestPayCode);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        FrameLayout frameLayout = findViewById(R.id.webview_container);
+        webview = new WebView(this);
+        frameLayout.addView(webview,new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
+        webview.setVisibility(View.INVISIBLE);
+        prepare();
+
+    }
+
+    public void saveLoginUser(String userId){
+        String requestUrl = "http://202.99.114.74:56199/index.php?m=Home&c=DuduApi&a=addUser"
+                    + "&uid=" + userId
+                    + "&UserToken=dudutoken"
+                    +"&originId" + 2;
+        RequestQueue queue = Volley.newRequestQueue(this);
+        queue.add(new JsonObjectRequest(Request.Method.GET, requestUrl, null, new Response.Listener<JSONObject>() {
+            @Override
+            public void onResponse(JSONObject response) {
+
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        }));
+    }
+
+
+
+    private void loadH5Url(){
+        String url = "http://202.99.114.74:56251/h5v2/tribeapp_test/index.html?is_vip=%s&uid=%s";
+        url = String.format(url,new LocalStore(DjblMainActivity.this).getIsVip(),userId);
+        webview.getSettings().setJavaScriptEnabled(true);
+        webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
+        webview.setWebChromeClient(new WebChromeClient() {
+            @Override
+            public void onProgressChanged(WebView view, int progress) {
+                DjblMainActivity.this.setProgress(progress * 1000);
+            }
+        });
+        webview.setWebViewClient(new WebViewClient() {
+            @Override
+            public void onPageFinished(WebView view, String url)
+            {
+                super.onPageFinished(view, url);
+                webview.setVisibility(View.VISIBLE);
+            }
+
+            @Override
+            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+                Toast("Oh no! ");
+            }
+        });
+        webview.addJavascriptInterface(new AndroidToJs(h5Result,myPayResult),"H5Play");
+        webview.loadUrl(url);
+
+    }
+
+    private void prepare(){
+        HuaweiPay.getInstance().init(this, new CallbackListener<Integer>()
+        {
+            @Override
+            public void callback(final int paramInt, final Integer paramT)
+            {
+                switch (paramInt){
+                    case ErrorCode.COM_PLATFORM_SUCCESS:
+                        //Toast("初始化成功");
+                        HuaweiPay.getInstance().authForMonth(new CallbackListener<AuthResult>() {
+                            @Override
+                            public void callback(int i, AuthResult authResult) {
+                                switch (i){
+                                    case ErrorCode.COM_PLATFORM_SUCCESS:
+                                        new LocalStore(DjblMainActivity.this).saveIsVip(true);
+                                        if(authResult!=null){
+                                            Toast(authResult.description);
+                                            Log.i(TAG,authResult.description);
+                                        }
+                                        runH5();
+                                        break;
+                                    case ErrorCode.COM_PLATFORM_ERROR_PARAM:
+                                        new LocalStore(DjblMainActivity.this).saveIsVip(false);
+                                        if(authResult!=null){
+                                            getBuyProductId(authResult);
+                                        }
+                                        runH5();
+                                        Log.i(TAG,"参数错误,description:" + authResult.description);
+                                        break;
+                                    case ErrorCode.COM_PLATFORM_ERROR_UNKNOWN:
+                                        new LocalStore(DjblMainActivity.this).saveIsVip(false);
+                                        if(authResult!=null){
+                                            getBuyProductId(authResult);
+                                        }
+                                        runH5();
+                                        Log.i(TAG,"SDK未初始化及其它错误,description:" + authResult.description);
+                                        break;
+                                    default:
+                                        new LocalStore(DjblMainActivity.this).saveIsVip(false);
+                                        if(authResult!=null){
+                                            getBuyProductId(authResult);
+                                        }
+                                        runH5();
+                                        Log.i(TAG,"其他错误,description:" + authResult.description);
+                                        break;
+                                }
+                            }
+                        });
+                        userId = HuaweiPay.getInstance().getUserId();
+                        saveLoginUser(userId);
+                        new LocalStore(DjblMainActivity.this).saveUserId(userId);
+                        break;
+                    case ErrorCode.COM_PLATFORM_ERROR_ONLINE_CHECK_FAILURE:
+                        Log.i(TAG,"无网络");
+                        CrashHandler.getInstance().saveCrashInfoToWeb("初始化失败,无网络");
+                        onInitFail();
+                        break;
+                    case ErrorCode.COM_PLATFORM_ERROR_FORCE_CLOSE:
+                        Log.i(TAG,"初始化异常,强制退出");
+                        CrashHandler.getInstance().saveCrashInfoToWeb("初始化异常,强制退出");
+                        onInitFail();
+                        break;
+                    case ErrorCode.COM_PLATFORM_ERROR_TIME_OUT:
+                        //Toast(DjblMainActivity.this,"网络超时:" + paramInt);
+                        Log.i(TAG,"网络超时");
+                        CrashHandler.getInstance().saveCrashInfoToWeb("初始化失败,网络超时");
+                        onInitFail();
+                        break;
+                    default:
+                        Log.i(TAG,"其他错误:" + paramInt);
+                        CrashHandler.getInstance().saveCrashInfoToWeb("初始化失败,其他错误:" + paramInt);
+                        onInitFail();
+                        break;
+                }
+            }
+        });
+    }
+
+
+    private void onInitFail(){
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                new AlertDialog.Builder(DjblMainActivity.this)
+                        .setMessage("初始化失败,点击'确定'退出")
+                        .setPositiveButton("确定",new DialogInterface.OnClickListener(){
+
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                DjblMainActivity.this.finish();
+                            }
+                        }).show();
+            }
+        });
+
+    }
+
+    private void getBuyProductId(@NonNull AuthResult authResult){
+        if(authResult.productInfos.length>0){
+            buyProductId = authResult.productInfos[0].productId;
+            Log.d(TAG," buyProductId:" + buyProductId);
+            //Toast("计费产品ID:" + buyProductId);
+       }else{
+            CrashHandler.getInstance().saveCrashInfoToWeb("计费失败,未检测到产品列表,用户ID:" + userId);
+            Toast("没有检测到产品列表,不能发起计费!");
+        }
+
+    }
+
+    private void monthPay(){
+        Logger("开始计费");
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                HuaweiPay.getInstance().payForMonth(DjblMainActivity.this,userId,buyProductId,new CallbackListener<PayResult>()
+                {
+                    @Override
+                    public void callback(final int arg0, PayResult arg1)
+                    {
+                        switch(arg0){
+                            case ErrorCode.COM_PLATFORM_SUCCESS:
+                       /* Log.i(TAG,"计费成功,用户ID:" + arg1.getUin()
+                                +";流水号:" + arg1.getConsumeStreamId() + ";商户收入:" + arg1.getShare());*/
+                                Log.d(TAG,"鉴权成功");
+                                myPayResult.onSuccess();
+                                break;
+                            case ErrorCode.COM_PLATFORM_ERROR_PARAM:
+                                myPayResult.onFail("参数错误");
+                                break;
+                            case ErrorCode.COM_PLATFORM_ERROR_UNKNOWN:
+                                myPayResult.onFail("SDK未初始化及其它错误,tradeStatus:" + arg1.getTradeStatus());
+                                break;
+                            case ErrorCode.COM_PLATFORM_ERROR_PAY_CANCEL:
+                                myPayResult.onFail("用户取消" + arg1.getTradeStatus());
+                                break;
+                            default:
+                                myPayResult.onFail("计费未知错误:" + arg0);
+                                break;
+                        }
+                        if (null != arg1)
+                        {
+                            Logger.d(TAG, "unipayExt PayResult : "+ arg1);
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    private void runH5(){
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                loadH5Url();
+            }
+        });
+    }
+
+
+
+    private void Toast(final String msg){
+        DjblMainActivity.this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(DjblMainActivity.this,msg,Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    public class AndroidToJs{
+        H5Result listener;
+        MyPayResult payResult;
+        public AndroidToJs(H5Result h5Result,MyPayResult payResult){
+            this.listener = h5Result;
+            this.payResult = payResult;
+        }
+
+        @JavascriptInterface
+        public void play(final String url,final String title,final String sourceId){
+            listener.videoPlay(url,title,userId,sourceId);
+        }
+
+        @JavascriptInterface
+        public void pay(String backUrl){
+            //Toast.makeText(DjblMainActivity.this,"开始计费",Toast.LENGTH_SHORT).show();
+            Log.d(TAG,"限时订购计费");
+            DjblMainActivity.this.backUrl = backUrl;
+            gotoPayActivity(userId,buyProductId);
+        }
+
+        @JavascriptInterface
+        public int getScreenWidth(){
+            return getWindowManager().getDefaultDisplay().getWidth();
+        }
+
+        @JavascriptInterface
+        public void exit(){
+            //todo run in ui thread
+            DjblMainActivity.this.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    new AlertDialog.Builder(DjblMainActivity.this)
+                            .setMessage("确认退出!")
+                            .setPositiveButton("继续观看", new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+
+                                }
+                            }).setNegativeButton("立即退出", new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            DjblMainActivity.this.finish();
+                        }
+                    }).show();
+                }
+            });
+
+        }
+
+        @JavascriptInterface
+        public void jsAuth(){
+            HuaweiPay.getInstance().authForMonth(new CallbackListener<AuthResult>() {
+                @Override
+                public void callback(int i, AuthResult authResult) {
+                    if(i == ErrorCode.COM_PLATFORM_SUCCESS){
+                        onAuthResult(1);
+                    }else{
+                        onAuthResult(-1);
+                    }
+                }
+            });
+        }
+
+        @JavascriptInterface
+        public int  getVipState(){
+            boolean vipState = new LocalStore(DjblMainActivity.this).getIsVip();
+            return vipState?1:-1;
+        }
+
+        @JavascriptInterface
+        public String getUserId(){
+            String userId = new LocalStore(DjblMainActivity.this).getUserId();
+            return userId;
+        }
+    }
+
+    @Override
+    protected void onDestroy(){
+        //清空所有Cookie
+        CookieSyncManager.createInstance(this);  //Create a singleton CookieSyncManager within a context
+        CookieManager cookieManager = CookieManager.getInstance(); // the singleton CookieManager instance
+        cookieManager.removeAllCookie();// Removes all cookies.
+        CookieSyncManager.getInstance().sync(); // forces sync manager to sync now
+
+        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.setWebChromeClient(null);
+            webview.setWebViewClient(null);
+            webview.getSettings().setJavaScriptEnabled(false);
+            webview.clearCache(true);
+            webview = null;
+        }
+
+        HuaweiPay.getInstance().onDestroy();
+        super.onDestroy();
+
+    }
+
+    @Override
+    public void onBackPressed() {
+        onJsBack();
+    }
+
+    private void onJsBack(){
+        final int version = Build.VERSION.SDK_INT;
+        if(version>18){
+            webview.evaluateJavascript("javascript:onBack()", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String value) {
+                    //此处为 js 返回的结果
+                }
+            });
+        }else{
+            webview.loadUrl("javascript:onBack()");
+        }
+    }
+
+    private void onJsFresh(){
+        final int version = Build.VERSION.SDK_INT;
+        if(version>18){
+            webview.evaluateJavascript("javascript:myrefresh()", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String value) {
+                    //此处为 js 返回的结果
+                }
+            });
+        }else{
+            webview.loadUrl("javascript:myrefresh()");
+        }
+    }
+
+    private void onPlayBackPay(){
+        final int version = Build.VERSION.SDK_INT;
+        if(version>18){
+            webview.evaluateJavascript("javascript:onPlayBackPay()", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String value) {
+                    //此处为 js 返回的结果
+                }
+            });
+        }else{
+            webview.loadUrl("javascript:onPlayBackPay()");
+        }
+    }
+
+
+    private void onAuthResult(final int i){
+        DjblMainActivity.this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final int version = Build.VERSION.SDK_INT;
+                String script = "javascript:onAuthResult(" + i +")";
+                if(version>18){
+                    webview.evaluateJavascript(script, new ValueCallback<String>() {
+                        @Override
+                        public void onReceiveValue(String value) {
+                            //此处为 js 返回的结果
+                        }
+                    });
+                }else{
+                    webview.loadUrl(script);
+                }
+            }
+        });
+
+    }
+
+    public interface H5Result {
+        public void videoPlay(String url,String title,String uId,String sourceId);
+    }
+
+    public interface MyPayResult{
+        public void onSuccess();
+        public void onFail(String msg);
+    }
+}
+
+

+ 66 - 0
app/src/main/java/com/haochuan/djbl/ErrorDataViewModel.java

@@ -0,0 +1,66 @@
+package com.haochuan.djbl;
+
+
+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<StyleData>() {
+                    @Override
+                    public void accept(@NonNull StyleData 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();
+        }
+    }
+}

+ 9 - 0
app/src/main/java/com/haochuan/djbl/ErrorFactory.java

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

+ 23 - 0
app/src/main/java/com/haochuan/djbl/ErrorService.java

@@ -0,0 +1,23 @@
+package com.haochuan.djbl;
+
+
+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<StyleData> 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);
+}

+ 146 - 0
app/src/main/java/com/haochuan/djbl/HuaweiPay.java

@@ -0,0 +1,146 @@
+package com.haochuan.djbl;
+import android.content.Context;
+
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+import com.android.volley.toolbox.Volley;
+import com.sdk.commplatform.Commplatform;
+import com.sdk.commplatform.entry.AppInfo;
+import com.sdk.commplatform.entry.AuthResult;
+import com.sdk.commplatform.entry.CyclePayment;
+import com.sdk.commplatform.entry.PayResult;
+import com.sdk.commplatform.listener.CallbackListener;
+
+import org.json.JSONObject;
+
+import java.util.Random;
+
+/**
+ * Created by Lyn on 2018/6/4.
+ */
+
+public class HuaweiPay {
+    private String appKey="hcjf";
+    private String appId="hcdjbl";
+    private String authProductId="hcdjblby025@201";
+    private String authContentId="hcdjblby025";
+    private String productId="1";
+    private String thirdAppId="1";
+    private String thirdAppName="电竞部落";
+    private String thirdAppPkgName="com.haochuan.djbl2";
+    private String notifyUrl="http://202.99.114.74:56251/notify.php";
+
+    private static HuaweiPay instance;
+
+    public static HuaweiPay getInstance(){
+        if(instance == null){
+            instance = new HuaweiPay();
+        }
+        return instance;
+    }
+
+    public static String getRandomCharAndNumr(Integer length) {
+        String str = "";
+        Random random = new Random();
+        for (int i = 0; i < length; i++) {
+            boolean b = random.nextBoolean();
+            if (b) { // 字符串
+                // int choice = random.nextBoolean() ? 65 : 97; 取得65大写字母还是97小写字母
+                str += (char) (65 + random.nextInt(26));// 取得大写字母
+            } else { // 数字
+                str += String.valueOf(random.nextInt(10));
+            }
+        }
+        return str;
+    }
+
+    private CyclePayment getBuyInfo(String tradeNo)
+    {//校验商品信息
+        CyclePayment buyInfo = new CyclePayment();
+        buyInfo.setTradeNo(tradeNo);
+        buyInfo.setThirdAppId(thirdAppId);
+        buyInfo.setThirdAppName(thirdAppName);
+        buyInfo.setThirdAppPkgname(thirdAppPkgName);
+        buyInfo.setNotifyURL(notifyUrl);
+        buyInfo.setNote("");
+        buyInfo.setUnsubNotifyURL("http://202.99.114.74:56251/index.php?m=Home&c=Order&a=unsubscribeNotify");
+        return buyInfo;
+    }
+
+
+    //计费sdk初始化
+    public void init(Context context,CallbackListener<Integer> listener){
+        thirdAppPkgName = context.getPackageName();
+        AppInfo appInfo = new AppInfo();
+        appInfo.setAppId(appId);// 应用ID
+        appInfo.setAppKey(appKey);// 应用Key
+        appInfo.setCtx(context);
+        appInfo.setVersionCheckStatus(0);
+        Commplatform.getInstance().Init(0,
+                appInfo,
+                listener);
+    }
+
+    //包月鉴权
+    public void authForMonth(CallbackListener<AuthResult> listener){
+            Commplatform.getInstance().authPermission(authProductId,"2",authContentId,listener);
+    }
+
+    //获取用户Id
+    public String getUserId(){
+        return Commplatform.getInstance().getLoginUin();
+    }
+
+    private void getTradeNo(Context context,String userId,final GetTradeNoListener listener){
+        String url = String.format("http://202.99.114.74:56199/index.php?m=Home&c=Api&a=CreatOrder&uid=%s",userId);
+        Volley.newRequestQueue(context).add(new JsonObjectRequest(url, null, new Response.Listener<JSONObject>() {
+            @Override
+            public void onResponse(JSONObject response) {
+                    if(response.has("data")){
+                        try{
+                            listener.onResult(response.getString("data"));
+                        }catch (Exception e){
+                            listener.onResult("");
+                            e.printStackTrace();
+                        }
+                    }
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                listener.onResult("");
+                error.printStackTrace();
+            }
+        }));
+    }
+
+    //包月计费
+    public void payForMonth(final Context context,String userId,final String buyProductId,final CallbackListener<PayResult> listener)
+    {
+        getTradeNo(context, userId, new GetTradeNoListener() {
+            @Override
+            public void onResult(String tradeNo) {
+                CyclePayment buyInfo = getBuyInfo(tradeNo);
+                buyInfo.setProductId(buyProductId);
+                Commplatform.getInstance().subsPay(buyInfo,
+                        context,
+                        listener);
+            }
+        });
+    }
+
+    //取消订购
+    public void unSubscribe(Context context,String tradeNo,CallbackListener<PayResult> payListener){
+        Commplatform.getInstance().cancelCyclePay(tradeNo,context,payListener);
+    }
+
+    //销毁sdk
+    public void onDestroy(){
+        Commplatform.getInstance().destroy();
+    }
+
+    public interface GetTradeNoListener{
+        public void onResult(String tradeNo);
+    }
+}

+ 42 - 0
app/src/main/java/com/haochuan/djbl/LocalStore.java

@@ -0,0 +1,42 @@
+package com.haochuan.djbl;
+
+import android.content.Context;
+
+/**
+ * Created by 浩传 on 2018/6/22.
+ */
+
+public class LocalStore {
+    Context context;
+    String shareName = "duduToy";
+    String isVipTag = "isVip";
+    String userIdTag = "userId";
+
+    public LocalStore(Context context){
+        this.context = context;
+    }
+
+    public void saveIsVip(boolean isVip){
+        context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .edit()
+                .putBoolean(isVipTag,isVip)
+                .commit();
+    }
+
+    public boolean getIsVip(){
+       return context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+               .getBoolean(isVipTag,false);
+    }
+
+    public void saveUserId(String userId){
+        context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .edit()
+                .putString(userIdTag,userId)
+                .commit();
+    }
+
+    public String getUserId(){
+        return context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .getString(userIdTag,"");
+    }
+}

+ 109 - 0
app/src/main/java/com/haochuan/djbl/PayActivity.java

@@ -0,0 +1,109 @@
+package com.haochuan.djbl;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.haochuan.djbl2.R;
+import com.sdk.commplatform.entry.ErrorCode;
+import com.sdk.commplatform.entry.PayResult;
+import com.sdk.commplatform.listener.CallbackListener;
+
+public class PayActivity extends Activity {
+    String userId = "";
+    String buyProductId = "";
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_pay);
+        userId = getIntent().getStringExtra("userId");
+        buyProductId = getIntent().getStringExtra("buyProductId");
+        monthPay();
+    }
+
+    private void prepare(){
+        HuaweiPay.getInstance().init(this, new CallbackListener<Integer>()
+        {
+            @Override
+            public void callback(final int paramInt, final Integer paramT)
+            {
+                switch (paramInt){
+                    case ErrorCode.COM_PLATFORM_SUCCESS:
+                        //Toast("初始化成功");
+                        monthPay();
+                        break;
+                    case ErrorCode.COM_PLATFORM_ERROR_ONLINE_CHECK_FAILURE:
+                        break;
+                    case ErrorCode.COM_PLATFORM_ERROR_FORCE_CLOSE:
+                        break;
+                    case ErrorCode.COM_PLATFORM_ERROR_TIME_OUT:
+
+                        break;
+                    default:
+
+                        break;
+                }
+            }
+        });
+    }
+
+    private void Toast(final String msg){
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(PayActivity.this,msg,Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    private void monthPay(){
+        Log.d("HuaweiPay","开始计费,userId:" + userId + "; buyProductId:" + buyProductId);
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                HuaweiPay.getInstance().payForMonth(PayActivity.this,userId,buyProductId,new CallbackListener<PayResult>()
+                {
+                    @Override
+                    public void callback(final int arg0, PayResult arg1)
+                    {
+                        switch(arg0){
+                            case ErrorCode.COM_PLATFORM_SUCCESS:
+                       /* Log.i(TAG,"计费成功,用户ID:" + arg1.getUin()
+                                +";流水号:" + arg1.getConsumeStreamId() + ";商户收入:" + arg1.getShare());*/
+                                Toast("订购成功" );
+                                paySuccessResult();
+                                break;
+                            case ErrorCode.COM_PLATFORM_ERROR_PARAM:
+                                payFailResult();
+                                break;
+                            case ErrorCode.COM_PLATFORM_ERROR_UNKNOWN:
+                                payFailResult();
+                                break;
+                            case ErrorCode.COM_PLATFORM_ERROR_PAY_CANCEL:
+                                payFailResult();
+                                break;
+                            default:
+                                payFailResult();
+                                break;
+                        }
+                        if (null != arg1)
+                        {
+
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+   private void paySuccessResult(){
+       new LocalStore(this).saveIsVip(true);
+       finish();
+   }
+
+    private void payFailResult(){
+        new LocalStore(this).saveIsVip(false);
+        finish();
+    }
+}

+ 8 - 0
app/src/main/java/com/haochuan/djbl/StringUtils.java

@@ -0,0 +1,8 @@
+package com.haochuan.djbl;
+
+/**
+ * Created by 浩传 on 2018/6/7.
+ */
+
+class StringUtils {
+}

+ 14 - 0
app/src/main/java/com/haochuan/djbl/StyleData.java

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

+ 44 - 0
app/src/main/java/com/haochuan/djbl/TestUnsubscribe.java

@@ -0,0 +1,44 @@
+package com.haochuan.djbl;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+
+import com.haochuan.djbl2.R;
+import com.sdk.commplatform.entry.ErrorCode;
+import com.sdk.commplatform.entry.PayResult;
+import com.sdk.commplatform.listener.CallbackListener;
+
+public class TestUnsubscribe extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_test_unsubscribe);
+        Button unSubscribe = findViewById(R.id.unsubscribe);
+
+        unSubscribe.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+               HuaweiPay.getInstance().unSubscribe(TestUnsubscribe.this, "B702207712043108", new CallbackListener<PayResult>() {
+                    @Override
+                    public void callback(int i, PayResult payResult) {
+                        if(i == ErrorCode.COM_PLATFORM_SUCCESS){
+                            TestUnsubscribe.this.runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    Toast.makeText(TestUnsubscribe.this,"取消订购平台已受理",Toast.LENGTH_SHORT).show();
+                                }
+                            });
+                        }else{
+                            Log.i("TestUnsubscribe","取消订购失败:" + i);
+                        }
+                    }
+                });
+            }
+        });
+    }
+}

+ 22 - 0
app/src/main/java/com/haochuan/djbl/ToyApplication.java

@@ -0,0 +1,22 @@
+package com.haochuan.djbl;
+
+import android.app.Application;
+
+/**
+ * Created by 浩传 on 2018/7/2.
+ */
+
+public class ToyApplication extends Application {
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        initCrashHandler();
+    }
+
+    private void initCrashHandler(){
+        CrashHandler crashHandler = CrashHandler.getInstance();
+        crashHandler.init(getApplicationContext());
+    }
+}

+ 29 - 0
app/src/main/java/com/haochuan/djbl/UrlManager.java

@@ -0,0 +1,29 @@
+package com.haochuan.djbl;
+
+/**
+ * Created by Lyn on 2018/5/30.
+ */
+
+public class UrlManager {
+    private String host = "http://202.99.114.74:56199/";
+
+    public String getCollectedStateUrl(String uId,String sourceId){
+        return host + "index.php?m=Home&c=DuduApi&a=isCollect"
+                + "&uid=" + uId
+                +"&source_id=" + sourceId;
+    }
+
+    public String addCollectedStateUrl(String uId,String sourceId,int type){
+        return host + "index.php?m=Home&c=DuduApi&a=upWatchCollectLog"
+                + "&type=" + type
+                + "&uid=" + uId
+                +"&source_id=" + sourceId;
+    }
+
+    public String cancelCollectedStateUrl(String uId,String sourceId,int type){
+        return host + "index.php?m=Home&c=DuduApi&a=delWatchCollectLog"
+                + "&type=" + type
+                + "&uid=" + uId
+                +"&source_id=" + sourceId;
+    }
+}

+ 334 - 0
app/src/main/java/com/haochuan/djbl/VideoEndDialog.java

@@ -0,0 +1,334 @@
+package com.haochuan.djbl;
+
+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.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+import com.android.volley.toolbox.Volley;
+import com.haochuan.djbl2.R;
+
+import org.json.JSONObject;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+/**
+ * Created by yunhaipiaodi on 2017/10/13.
+ */
+
+public class VideoEndDialog extends DialogFragment{
+
+    private static String PARAM1 = "uid";
+    private static String PARAM2 = "sourceId";
+    private static String PARAM3 = "isComplete";
+
+    private String uId = "";
+    private String sourceId = "";
+    private Boolean isComplete = false;
+
+    private OnClickListener mListener;
+    private RequestQueue queue;
+
+    private LinearLayout collectContainer;
+    private ImageView collectIcon;
+    private TextView collectTitle;
+
+    private long  mLastClickTime = 0;
+
+    public static VideoEndDialog getInstance(String uId,String sourceId,Boolean isComplete){
+        VideoEndDialog videoEndDialog = new VideoEndDialog();
+        Bundle bundle = new Bundle();
+        bundle.putString(PARAM1,uId);
+        bundle.putString(PARAM2,sourceId);
+        bundle.putBoolean(PARAM3,isComplete);
+        videoEndDialog.setArguments(bundle);
+        return videoEndDialog;
+    }
+
+
+    @Override
+    public void onAttach(Activity activity){
+        super.onAttach(activity);
+        queue = Volley.newRequestQueue(activity);
+        if(activity instanceof OnClickListener){
+            mListener = (OnClickListener)activity;
+        }else{
+            throw new RuntimeException(activity.toString()
+                    + " must implement VideoEndDialog.OnClickListener");
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        this.setCancelable(false);
+        uId = getArguments().getString(PARAM1);
+        sourceId = getArguments().getString(PARAM2);
+        isComplete = getArguments().getBoolean(PARAM3);
+    }
+
+    @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.dialog_video_end, container);
+        LinearLayout continueBtn = view.findViewById(R.id.continue_play);
+        collectContainer = view.findViewById(R.id.collect_video);
+        LinearLayout exitBtn = view.findViewById(R.id.exit_play);
+        collectIcon = view.findViewById(R.id.collect_icon);
+        collectTitle = view.findViewById(R.id.collect_title);
+
+        if(isComplete){
+            continueBtn.setVisibility(View.GONE);
+        }
+
+        getCollectState(new OnCollectListener(){
+
+            @Override
+            public void onCollected(boolean result) {
+                if(result){     //已经收藏
+                    collectSet();
+                    collectContainer.setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            cancelCollectStateToWeb();
+                        }
+                    });
+                }else{          //未收藏
+                    noCollectSet();
+                    collectContainer.setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            addCollectStateToWeb();
+                        }
+                    });
+                }
+            }
+        });
+
+        continueBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                VideoEndDialog.this.dismiss();
+                mListener.onContinuePlay();
+            }
+        });
+
+        exitBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mListener.onExit();
+            }
+        });
+
+        continueBtn.requestFocus();
+        return view;
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        if(mListener!=null){
+            mListener.onDismiss();
+        }
+    }
+
+    //没收藏时的设置
+    private void noCollectSet(){
+        collectTitle.setText("加入收藏");
+        collectTitle.setTextColor(getActivity().getResources().getColor(R.color.video_end_text_color));
+        collectIcon.setImageResource(R.drawable.btn_icon_add_default);
+    }
+
+    //已收藏时的设置
+    private void collectSet(){
+        collectTitle.setText("取消收藏");
+        collectTitle.setTextColor(getActivity().getResources().getColor(R.color.video_end_text_color));
+        collectIcon.setImageResource(R.drawable.btn_icon_add_selected);
+    }
+
+    public void getCollectState(final OnCollectListener listener ){
+        final String requestUrl = new UrlManager().getCollectedStateUrl(uId,sourceId);
+        queue.add(new JsonObjectRequest(Request.Method.GET, requestUrl, null, new Response.Listener<JSONObject>() {
+            @Override
+            public void onResponse(JSONObject response) {
+                if(response.has("code")){
+                    try{
+                        int code = response.getInt("code");
+                        switch (code){
+                            case 1:
+                                listener.onCollected(false);
+                                break;
+                            case 2:
+                                listener.onCollected(true);
+                                break;
+                            default:
+                                listener.onCollected(false);
+                                break;
+                        }
+                    }catch (Exception e){
+                        listener.onCollected(false);
+                        e.printStackTrace();
+                    }
+
+                }
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        }));
+    }
+
+    private void addCollectStateToWeb(){
+        final String requestUrl = new UrlManager().addCollectedStateUrl(uId,sourceId,2);
+        queue.add(new JsonObjectRequest(Request.Method.GET, requestUrl, null, new Response.Listener<JSONObject>() {
+            @Override
+            public void onResponse(JSONObject response) {
+                if(response.has("code")){
+                    try{
+                        int code = response.getInt("code");
+                        if(code == 0){
+                            collectSet();
+                            collectContainer.setOnClickListener(new View.OnClickListener() {
+                                @Override
+                                public void onClick(View v) {
+                                    cancelCollectStateToWeb();
+                                }
+                            });
+                        }else{
+                            Toast.makeText(getActivity(),"收藏失败",Toast.LENGTH_SHORT).show();
+                        }
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+
+                }
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        }));
+    }
+
+    private void cancelCollectStateToWeb(){
+        final String requestUrl = new UrlManager().cancelCollectedStateUrl(uId,sourceId,2);
+        queue.add(new JsonObjectRequest(Request.Method.GET, requestUrl, null, new Response.Listener<JSONObject>() {
+            @Override
+            public void onResponse(JSONObject response) {
+                if(response.has("code")){
+                    try{
+                        int code = response.getInt("code");
+                        if(code == 0){
+                            noCollectSet();
+                            collectContainer.setOnClickListener(new View.OnClickListener() {
+                                @Override
+                                public void onClick(View v) {
+                                    addCollectStateToWeb();
+                                }
+                            });
+                        }else{
+                            Toast.makeText(getActivity(),"取消收藏失败",Toast.LENGTH_SHORT).show();
+                        }
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+
+                }
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        }));
+    }
+
+    @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 onDestroy(){
+        collectContainer= null;
+        collectIcon = null;
+        collectTitle = null;
+        super.onDestroy();
+    }
+
+    public interface OnCollectListener{
+        public void onCollected(boolean result);
+    }
+
+    public interface OnClickListener{
+        public void onExit();
+        public void onDismiss();
+        public void onContinuePlay();
+    }
+
+}

+ 26 - 0
app/src/main/java/com/haochuan/djbl/VideoInfo.java

@@ -0,0 +1,26 @@
+package com.haochuan.djbl;
+
+import com.boredream.bdvideoplayer.bean.IVideoInfo;
+
+/**
+ * Created by 浩传 on 2018/7/26.
+ */
+
+public class VideoInfo implements IVideoInfo {
+    private String title;
+    private String videoPath;
+
+    public VideoInfo(String title,String videoPath){
+        this.title =title;
+        this.videoPath = videoPath;
+    }
+    @Override
+    public String getVideoTitle() {
+        return title;
+    }
+
+    @Override
+    public String getVideoPath() {
+        return videoPath;
+    }
+}

+ 323 - 0
app/src/main/java/com/haochuan/djbl/VideoPlayerActivity.java

@@ -0,0 +1,323 @@
+package com.haochuan.djbl;
+
+import android.app.Activity;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.KeyEvent;
+import android.widget.Toast;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.JsonObjectRequest;
+import com.android.volley.toolbox.Volley;
+import com.boredream.bdvideoplayer.BDVideoView;
+import com.haochuan.djbl2.R;
+
+import org.json.JSONObject;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class VideoPlayerActivity extends Activity implements VideoEndDialog.OnClickListener,BDVideoView.BdPlayerListener{
+
+    String uId = "";
+    String sourceId = "";
+
+    private boolean showVideoEndDialog = false;
+    BDVideoView bdVideoView;
+
+
+    private int seekPercent = 5;
+
+    private Timer timer_pay;
+    private TimerTask task_pay;
+
+    String TAG = "VideoPlayerActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_video_player);
+        String url = getIntent().getStringExtra("url");
+        String title = getIntent().getStringExtra("title");
+        uId = getIntent().getStringExtra("uId");
+        sourceId = getIntent().getStringExtra("sourceId");
+       /* url = "http://202.99.114.93/88888891/16/20171229/269788225/269788225.ts";
+        title = "小小战士";*/
+        bdVideoView = findViewById(R.id.bd_player);
+        bdVideoView.setActivity(this);
+        VideoInfo info = new VideoInfo(title,url);
+
+        bdVideoView.startPlayVideo(info);
+
+        bdVideoView.setBdPlayerListener(this);
+
+        /*duduPlayer.setUp(url, false,title);
+        duduPlayer.clickStartIcon();
+
+        duduPlayer.setOnCompleteListener(new DuduPlayer.OnCompleteListener() {
+            @Override
+            public void onComplete() {
+                new Handler().postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        VideoPlayerActivity.this.runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                showVideoEndDialogComplete();
+                            }
+                        });
+                    }
+                },1000);
+
+            }
+        });*/
+        //addHistoryToWeb();
+
+        if(!new LocalStore(this).getIsVip()){
+            initPayTimeTask();
+            Toast.makeText(this,"您还不是会员,您只可以试看30秒视频!并且不能快进",Toast.LENGTH_LONG).show();
+        }
+    }
+
+
+    private void addHistoryToWeb(){
+        final String requestUrl = new UrlManager().addCollectedStateUrl(uId,sourceId,1);
+        RequestQueue queue = Volley.newRequestQueue(this);
+        queue.add(new JsonObjectRequest(Request.Method.GET, requestUrl, null, new Response.Listener<JSONObject>() {
+            @Override
+            public void onResponse(JSONObject response) {
+
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        }));
+    }
+
+    //遥控事件
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_CENTER:      //播放/暂停
+                playOrPause();
+                return true;
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+                if(bdVideoView.canSeek()){
+                    seekBack();
+                }else{
+                    Toast.makeText(VideoPlayerActivity.this,"视频准备中,暂时不能拖动快进",Toast.LENGTH_SHORT).show();
+                }
+                return true;
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                //seekForward();
+                if(bdVideoView.canSeek()){
+                    seekForward();
+                }else{
+                    Toast.makeText(VideoPlayerActivity.this,"视频准备中,暂时不能拖动快进",Toast.LENGTH_SHORT).show();
+                }
+                return true;
+            case KeyEvent.KEYCODE_BACK:      //到顶跳到相应tab
+               /* duduPlayer.pause();*/
+               bdVideoView.pause();
+                if(!showVideoEndDialog){
+                    if(Build.VERSION.SDK_INT> 15){
+                        showVideoEndDialog();
+                    }else{
+                        VideoPlayerActivity.this.finish();
+                    }
+                    //Toast.makeText(this,"显示VideoEndDialog",Toast.LENGTH_SHORT).show();
+                    return true;
+                }else{
+                    return false;
+                }
+        }
+        return false;
+    }
+
+    private void playOrPause(){
+        bdVideoView.playOrPause();
+    }
+
+    private void seekBack(){
+        if(!new LocalStore(this).getIsVip()){
+            return;
+        }
+        int seekCount = bdVideoView.getDuration()*seekPercent/100;
+        int position = 0;
+        if(bdVideoView.getCurrentPositionWhenPlaying() - seekCount > 0) {
+            position = (bdVideoView.getCurrentPositionWhenPlaying() - seekCount) * 1000/ bdVideoView.getDuration();
+        }
+        if(position<= 0){
+            return;
+        }
+        bdVideoView.seek(position);
+    }
+
+    private void seekForward(){
+        if(!new LocalStore(this).getIsVip()){
+            return;
+        }
+        int seekCount = bdVideoView.getDuration()*seekPercent/100;
+        int position = bdVideoView.getDuration();
+        if(bdVideoView.getCurrentPositionWhenPlaying() + seekCount <= bdVideoView.getDuration()) {
+            position = (bdVideoView.getCurrentPositionWhenPlaying() + seekCount) *1000/ bdVideoView.getDuration();
+        }
+        if(position>=1000){
+            return;
+        }
+        bdVideoView.seek(position);
+    }
+
+
+    private void showVideoEndDialog(){
+        try{
+            VideoEndDialog videoEndDialog =  VideoEndDialog.getInstance(uId,sourceId,false);
+            videoEndDialog.show(getFragmentManager(),"VideoEndDialog");
+            showVideoEndDialog = true;
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    private void showVideoEndDialogComplete(){
+        try{
+            VideoEndDialog videoEndDialog =  VideoEndDialog.getInstance(uId,sourceId,true);
+            videoEndDialog.show(getFragmentManager(),"VideoEndDialog");
+            showVideoEndDialog = true;
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    //非会员视频播放到30秒
+    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();
+                                        int pos = bdVideoView.getCurrentPositionWhenPlaying();
+                                        if(pos/1000 > 30){
+                                            //跳转到计费界面
+                                            VideoPlayerActivity.this.runOnUiThread(new Runnable() {
+                                                @Override
+                                                public void run() {
+                                                    setResult(3);
+                                                    VideoPlayerActivity.this.finish();
+                                                }
+                                            });
+                                        }
+                                    }
+                                });
+                        Looper.loop();
+                    }
+                }.start();
+
+            }
+        };
+        timer_pay.schedule(task_pay,0,1000);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        if(bdVideoView != null){
+            bdVideoView.onStart();
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+       /* if(duduPlayer != null){
+            duduPlayer.pause();
+        }*/
+
+    }
+
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        /*if(duduPlayer != null){
+            duduPlayer.play();
+        }*/
+
+    }
+
+    @Override
+    protected void onStop(){
+        super.onStop();
+        if(bdVideoView != null){
+            bdVideoView.onStop();
+        }
+        this.finish();
+    }
+
+    @Override
+    protected void onDestroy() {
+       /* duduPlayer.setVideoAllCallBack(null);
+        GSYVideoManager.releaseAllVideos();
+        duduPlayer.onDestroy();
+
+        duduPlayer = null;*/
+
+       if(bdVideoView != null){
+           bdVideoView.onDestroy();
+       }
+        if(timer_pay != null){
+            timer_pay.cancel();
+        }
+        if(task_pay != null){
+            task_pay.cancel();
+        }
+        task_pay = null;
+        timer_pay = null;
+        super.onDestroy();
+    }
+
+    @Override
+    public void onExit() {
+        this.finish();
+    }
+
+    @Override
+    public void onDismiss() {
+        showVideoEndDialog = false;
+       /* if(duduPlayer!=null){
+            duduPlayer.play();
+        }*/
+        if(bdVideoView != null){
+            bdVideoView.play();
+        }
+    }
+
+    @Override
+    public void onContinuePlay() {
+       /* if(duduPlayer != null){
+            duduPlayer.play();
+        }*/
+        if(bdVideoView != null){
+            bdVideoView.play();
+        }
+    }
+
+    @Override
+    public void onComplete() {
+        showVideoEndDialogComplete();
+    }
+}

BIN
app/src/main/res/drawable-hdpi/btn_icon_add_default.png


BIN
app/src/main/res/drawable-hdpi/btn_icon_add_selected.png


BIN
app/src/main/res/drawable-hdpi/btn_icon_continue.png


BIN
app/src/main/res/drawable-hdpi/btn_icon_out.png


BIN
app/src/main/res/drawable-hdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-hdpi/loading_icon.png


BIN
app/src/main/res/drawable-ldpi/btn_icon_add_default.png


BIN
app/src/main/res/drawable-ldpi/btn_icon_add_selected.png


BIN
app/src/main/res/drawable-ldpi/btn_icon_continue.png


BIN
app/src/main/res/drawable-ldpi/btn_icon_out.png


BIN
app/src/main/res/drawable-ldpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-mdpi/btn_icon_add_default.png


BIN
app/src/main/res/drawable-mdpi/btn_icon_add_selected.png


BIN
app/src/main/res/drawable-mdpi/btn_icon_continue.png


BIN
app/src/main/res/drawable-mdpi/btn_icon_out.png


BIN
app/src/main/res/drawable-mdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-mdpi/loading_icon.png


BIN
app/src/main/res/drawable-xhdpi/btn_icon_add_default.png


BIN
app/src/main/res/drawable-xhdpi/btn_icon_add_selected.png


BIN
app/src/main/res/drawable-xhdpi/btn_icon_continue.png


BIN
app/src/main/res/drawable-xhdpi/btn_icon_out.png


BIN
app/src/main/res/drawable-xhdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-xhdpi/loading_icon.png


BIN
app/src/main/res/drawable-xxhdpi/btn_icon_add_default.png


BIN
app/src/main/res/drawable-xxhdpi/btn_icon_add_selected.png


BIN
app/src/main/res/drawable-xxhdpi/btn_icon_continue.png


BIN
app/src/main/res/drawable-xxhdpi/btn_icon_out.png


BIN
app/src/main/res/drawable-xxhdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-xxhdpi/loading_icon.png


BIN
app/src/main/res/drawable/djbl_icon.png


BIN
app/src/main/res/drawable/dudu_icon.jpg


+ 28 - 0
app/src/main/res/drawable/dudu_video_seek_progress.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/background">
+        <shape>
+            <solid android:color="#FFD8D8D8"/>
+            <size android:height="@dimen/progress_back_height"/>
+            <corners android:radius="@dimen/progress_back_radius"/>
+        </shape>
+    </item>
+    <item android:id="@android:id/secondaryProgress">
+        <clip>
+            <shape>
+                <solid android:color="@color/style_color"/>
+                <size android:height="@dimen/progress_back_height"/>
+                <corners android:radius="@dimen/progress_back_radius"/>
+            </shape>
+        </clip>
+    </item>
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <solid android:color="#FFFFF0C6"/>
+                <size android:height="@dimen/progress_back_height"/>
+                <corners android:radius="@dimen/progress_back_radius"/>
+            </shape>
+        </clip>
+    </item>
+</layer-list>

+ 170 - 0
app/src/main/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillColor="#26A69A"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+</vector>

Plik diff jest za duży
+ 34 - 0
app/src/main/res/drawable/ic_launcher_foreground.xml


+ 5 - 0
app/src/main/res/drawable/loading_animation.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/loading_1" android:duration="300"/>
+    <item android:drawable="@drawable/loading_2" android:duration="300"/>
+</animation-list>

+ 7 - 0
app/src/main/res/drawable/top_bar_back.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:startColor="#ff000000"
+        android:endColor="#00000000"
+        android:angle="270"/>
+</shape>

+ 6 - 0
app/src/main/res/drawable/video_end_btn_back.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/video_end_btn_back_focus"  android:state_focused="true"/>
+    <item android:drawable="@drawable/video_end_btn_back_normal"  android:state_focused="false"/>
+    <item android:drawable="@drawable/video_end_btn_back_normal"/>
+</selector>

+ 7 - 0
app/src/main/res/drawable/video_end_btn_back_focus.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/video_end_btn_back"/>
+    <corners android:radius="@dimen/end_btn_back_radius"/>
+    <stroke android:color="#FFFFF0C6"
+        android:width="@dimen/end_btn_back_select_stroke_width"/>
+</shape>

+ 5 - 0
app/src/main/res/drawable/video_end_btn_back_normal.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/video_end_btn_back"/>
+    <corners android:radius="@dimen/end_btn_back_radius"/>
+</shape>

+ 8 - 0
app/src/main/res/drawable/video_seek_thumb_normal.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape android:shape="oval"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FFFFF0C6" />
+    <size
+        android:height="@dimen/video_seek_thumb_height"
+        android:width="@dimen/video_seek_thumb_height" />
+</shape>

+ 13 - 0
app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/webview_container"
+    android:background="@drawable/img_start_bg"
+    tools:context="com.haochuan.djbl.DjblMainActivity">
+
+
+
+</FrameLayout>

+ 22 - 0
app/src/main/res/layout/activity_pay.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.haochuan.djbl.PayActivity">
+
+    <ImageView
+        android:layout_width="@dimen/loading_image_width"
+        android:layout_height="@dimen/loading_image_width"
+        android:layout_centerInParent="true"
+        android:id="@+id/logo"
+        android:src="@drawable/loading_icon"/>
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/logo"
+        android:layout_marginTop="@dimen/loading_text_margin_top"
+        android:text="计费跳转中..."/>
+</RelativeLayout>

+ 13 - 0
app/src/main/res/layout/activity_test_unsubscribe.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.guangzhou.haochuan.jxtv.activity.TestUnsubscribe">
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/unsubscribe"
+        android:text="取消订购"
+        android:layout_gravity="center"/>
+</FrameLayout>

+ 20 - 0
app/src/main/res/layout/activity_video_player.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/video_container"
+    android:orientation="horizontal"
+    tools:context="com.haochuan.djbl.VideoPlayerActivity">
+
+    <com.boredream.bdvideoplayer.BDVideoView
+        android:id="@+id/bd_player"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+    </com.boredream.bdvideoplayer.BDVideoView>
+
+
+</RelativeLayout>

+ 102 - 0
app/src/main/res/layout/dialog_video_end.xml

@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minWidth="1000dp"
+    android:minHeight="1000dp">
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="center"
+        android:gravity="center_horizontal">
+
+        <LinearLayout
+            android:layout_width="@dimen/end_btn_back_width"
+            android:layout_height="@dimen/end_btn_back_height"
+            android:id="@+id/continue_play"
+            android:layout_marginEnd="0dp"
+            android:layout_marginStart="0dp"
+            android:background="@drawable/video_end_btn_back"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+            android:focusable="true"
+            android:clickable="true"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent">
+            <ImageView
+                android:layout_width="@dimen/icon_size"
+                android:layout_height="@dimen/icon_size"
+                android:src="@drawable/btn_icon_continue"
+                android:layout_marginLeft="@dimen/end_btn_back_icon_margin_left"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/end_btn_back_text_margin_left"
+                android:textColor="#FFE6FBFF"
+                android:textSize="@dimen/time_text_size"
+                android:text="继续播放"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="@dimen/end_btn_back_width"
+            android:layout_height="@dimen/end_btn_back_height"
+            android:background="@drawable/video_end_btn_back"
+            android:id="@+id/collect_video"
+            android:orientation="horizontal"
+            android:layout_marginTop="@dimen/end_btn_back_margin_top"
+            android:gravity="center_vertical"
+            android:focusable="true"
+            android:clickable="true"
+            android:visibility="gone"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/continue_play">
+            <ImageView
+                android:layout_width="@dimen/icon_size"
+                android:layout_height="@dimen/icon_size"
+                android:src="@drawable/btn_icon_add_default"
+                android:id="@+id/collect_icon"
+                android:layout_marginLeft="@dimen/end_btn_back_icon_margin_left"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/collect_title"
+                android:layout_marginLeft="@dimen/end_btn_back_text_margin_left"
+                android:textColor="#FFE6FBFF"
+                android:textSize="@dimen/time_text_size"
+                android:text="加入收藏"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="@dimen/end_btn_back_width"
+            android:layout_height="@dimen/end_btn_back_height"
+            android:id="@+id/exit_play"
+            android:background="@drawable/video_end_btn_back"
+            android:orientation="horizontal"
+            android:layout_marginTop="@dimen/end_btn_back_margin_top"
+            android:gravity="center_vertical"
+            android:focusable="true"
+            android:clickable="true"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/collect_video">
+            <ImageView
+                android:layout_width="@dimen/icon_size"
+                android:layout_height="@dimen/icon_size"
+                android:src="@drawable/btn_icon_out"
+                android:layout_marginLeft="@dimen/end_btn_back_icon_margin_left"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/end_btn_back_text_margin_left"
+                android:textColor="#FFE6FBFF"
+                android:textSize="@dimen/time_text_size"
+                android:text="退出播放"/>
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>

+ 5 - 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

+ 5 - 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 50 - 0
app/src/main/res/values-hdpi/dimens.xml

@@ -0,0 +1,50 @@
+<resources>
+    <dimen name="icon_size">33.333332dp</dimen>
+
+    <!--top bar-->
+    <dimen name="top_bar_height">80.0dp</dimen>
+    <dimen name="top_bar_title_margin_left">40.0dp</dimen>
+    <dimen name="top_bar_title_text_size">32.0dp</dimen>
+    <dimen name="top_bar_title_container_width">702.6667dp</dimen>
+
+    <dimen name="top_bar_icon1_margin_left">742.6667dp</dimen>
+    <dimen name="top_bar_explainItem_margin_left">40.0dp</dimen>
+    <dimen name="top_bar_explain_margin_left">23.333334dp</dimen>
+    <dimen name="top_bar_icon_between">6.6666665dp</dimen>
+
+    <!--bottom bar-->
+    <dimen name="bottom_bar_height">93.333336dp</dimen>
+    <dimen name="play_btn_margin_left">36.666668dp</dimen>
+    <dimen name="seek_bar_margin_left">22.666666dp</dimen>
+    <dimen name="time_margin_left">26.666666dp</dimen>
+    <dimen name="time_text_size">18.666666dp</dimen>
+
+
+
+    <!--player progress-->
+    <dimen name="progress_back_height">5.3333335dp</dimen>
+    <dimen name="progress_back_radius">66.666664dp</dimen>
+    <dimen name="video_seek_thumb_height">16.0dp</dimen>
+    <dimen name="video_seek_thumb_padding_left">16.0dp</dimen>
+
+    <!--video end-->
+    <dimen name="end_btn_back_width">240.0dp</dimen>
+    <dimen name="end_btn_back_height">80.0dp</dimen>
+    <dimen name="end_btn_back_radius">5.3333335dp</dimen>
+    <dimen name="end_btn_back1_margin_top">181.33333dp</dimen>
+    <dimen name="end_btn_back_margin_top">13.333333dp</dimen>
+    <dimen name="end_btn_back_icon_margin_left">62.666668dp</dimen>
+    <dimen name="end_btn_back_text_margin_left">7.3333335dp</dimen>
+    <dimen name="end_btn_back_select_stroke_width">2.6666667dp</dimen>
+
+    <!--video loading-->
+    <dimen name="loading_width">300.0dp</dimen>
+    <dimen name="loading_height">53.333332dp</dimen>
+    <dimen name="loading_text_size">24.0dp</dimen>
+    <dimen name="loading_text_margin_top">19.333334dp</dimen>
+
+    <!--loading page-->
+    <dimen name="loading_image_width">253.33dp</dimen>
+    <dimen name="loading_image_height">200dp</dimen>
+    <dimen name="loading_page_text_margin_top">26dp</dimen>
+</resources>

+ 50 - 0
app/src/main/res/values-ldpi/dimens.xml

@@ -0,0 +1,50 @@
+<resources>
+    <dimen name="icon_size">66.666664dp</dimen>
+
+    <!--top bar-->
+    <dimen name="top_bar_height">160.0dp</dimen>
+    <dimen name="top_bar_title_margin_left">80.0dp</dimen>
+    <dimen name="top_bar_title_text_size">64.0dp</dimen>
+    <dimen name="top_bar_title_container_width">1405.3334dp</dimen>
+
+    <dimen name="top_bar_icon1_margin_left">1485.3334dp</dimen>
+    <dimen name="top_bar_explainItem_margin_left">80.0dp</dimen>
+    <dimen name="top_bar_explain_margin_left">46.666668dp</dimen>
+    <dimen name="top_bar_icon_between">13.333333dp</dimen>
+
+    <!--bottom bar-->
+    <dimen name="bottom_bar_height">186.66667dp</dimen>
+    <dimen name="play_btn_margin_left">73.333336dp</dimen>
+    <dimen name="seek_bar_margin_left">45.333332dp</dimen>
+    <dimen name="time_margin_left">53.333332dp</dimen>
+    <dimen name="time_text_size">37.333332dp</dimen>
+
+
+
+    <!--player progress-->
+    <dimen name="progress_back_height">10.666667dp</dimen>
+    <dimen name="progress_back_radius">133.33333dp</dimen>
+    <dimen name="video_seek_thumb_height">32.0dp</dimen>
+    <dimen name="video_seek_thumb_padding_left">32.0dp</dimen>
+
+    <!--video end-->
+    <dimen name="end_btn_back_width">480.0dp</dimen>
+    <dimen name="end_btn_back_height">160.0dp</dimen>
+    <dimen name="end_btn_back_radius">10.666667dp</dimen>
+    <dimen name="end_btn_back1_margin_top">362.66666dp</dimen>
+    <dimen name="end_btn_back_margin_top">26.666666dp</dimen>
+    <dimen name="end_btn_back_icon_margin_left">125.333336dp</dimen>
+    <dimen name="end_btn_back_text_margin_left">14.666667dp</dimen>
+    <dimen name="end_btn_back_select_stroke_width">5.3333335dp</dimen>
+
+    <!--video loading-->
+    <dimen name="loading_width">600.0dp</dimen>
+    <dimen name="loading_height">106.666664dp</dimen>
+    <dimen name="loading_text_size">48.0dp</dimen>
+    <dimen name="loading_text_margin_top">38.666668dp</dimen>
+
+    <!--loading page-->
+    <dimen name="loading_image_width">506.67dp</dimen>
+    <dimen name="loading_image_height">400dp</dimen>
+    <dimen name="loading_page_text_margin_top">52dp</dimen>
+</resources>

+ 50 - 0
app/src/main/res/values-mdpi-1280x720/dimens.xml

@@ -0,0 +1,50 @@
+<resources>
+    <dimen name="icon_size">33.333332dp</dimen>
+
+    <!--top bar-->
+    <dimen name="top_bar_height">80.0dp</dimen>
+    <dimen name="top_bar_title_margin_left">40.0dp</dimen>
+    <dimen name="top_bar_title_text_size">32.0dp</dimen>
+    <dimen name="top_bar_title_container_width">702.6667dp</dimen>
+
+    <dimen name="top_bar_icon1_margin_left">742.6667dp</dimen>
+    <dimen name="top_bar_explainItem_margin_left">40.0dp</dimen>
+    <dimen name="top_bar_explain_margin_left">23.333334dp</dimen>
+    <dimen name="top_bar_icon_between">6.6666665dp</dimen>
+
+    <!--bottom bar-->
+    <dimen name="bottom_bar_height">93.333336dp</dimen>
+    <dimen name="play_btn_margin_left">36.666668dp</dimen>
+    <dimen name="seek_bar_margin_left">22.666666dp</dimen>
+    <dimen name="time_margin_left">26.666666dp</dimen>
+    <dimen name="time_text_size">18.666666dp</dimen>
+
+
+
+    <!--player progress-->
+    <dimen name="progress_back_height">5.3333335dp</dimen>
+    <dimen name="progress_back_radius">66.666664dp</dimen>
+    <dimen name="video_seek_thumb_height">16.0dp</dimen>
+    <dimen name="video_seek_thumb_padding_left">16.0dp</dimen>
+
+    <!--video end-->
+    <dimen name="end_btn_back_width">240.0dp</dimen>
+    <dimen name="end_btn_back_height">80.0dp</dimen>
+    <dimen name="end_btn_back_radius">5.3333335dp</dimen>
+    <dimen name="end_btn_back1_margin_top">181.33333dp</dimen>
+    <dimen name="end_btn_back_margin_top">13.333333dp</dimen>
+    <dimen name="end_btn_back_icon_margin_left">62.666668dp</dimen>
+    <dimen name="end_btn_back_text_margin_left">7.3333335dp</dimen>
+    <dimen name="end_btn_back_select_stroke_width">2.6666667dp</dimen>
+
+    <!--video loading-->
+    <dimen name="loading_width">300.0dp</dimen>
+    <dimen name="loading_height">53.333332dp</dimen>
+    <dimen name="loading_text_size">24.0dp</dimen>
+    <dimen name="loading_text_margin_top">19.333334dp</dimen>
+
+    <!--loading page-->
+    <dimen name="loading_image_width">380dp</dimen>
+    <dimen name="loading_image_height">300dp</dimen>
+    <dimen name="loading_page_text_margin_top">39dp</dimen>
+</resources>

+ 50 - 0
app/src/main/res/values-mdpi-1920x1080/dimens.xml

@@ -0,0 +1,50 @@
+<resources>
+    <dimen name="icon_size">50.0dp</dimen>
+
+    <!--top bar-->
+    <dimen name="top_bar_height">120.0dp</dimen>
+    <dimen name="top_bar_title_margin_left">60.0dp</dimen>
+    <dimen name="top_bar_title_text_size">48.0dp</dimen>
+    <dimen name="top_bar_title_container_width">1054.0dp</dimen>
+
+    <dimen name="top_bar_icon1_margin_left">1114.0dp</dimen>
+    <dimen name="top_bar_explainItem_margin_left">60.0dp</dimen>
+    <dimen name="top_bar_explain_margin_left">35.0dp</dimen>
+    <dimen name="top_bar_icon_between">10.0dp</dimen>
+
+    <!--bottom bar-->
+    <dimen name="bottom_bar_height">140.0dp</dimen>
+    <dimen name="play_btn_margin_left">55.0dp</dimen>
+    <dimen name="seek_bar_margin_left">34.0dp</dimen>
+    <dimen name="time_margin_left">40.0dp</dimen>
+    <dimen name="time_text_size">28.0dp</dimen>
+
+
+
+    <!--player progress-->
+    <dimen name="progress_back_height">8.0dp</dimen>
+    <dimen name="progress_back_radius">100.0dp</dimen>
+    <dimen name="video_seek_thumb_height">24.0dp</dimen>
+    <dimen name="video_seek_thumb_padding_left">24.0dp</dimen>
+
+    <!--video end-->
+    <dimen name="end_btn_back_width">360.0dp</dimen>
+    <dimen name="end_btn_back_height">120.0dp</dimen>
+    <dimen name="end_btn_back_radius">8.0dp</dimen>
+    <dimen name="end_btn_back1_margin_top">272.0dp</dimen>
+    <dimen name="end_btn_back_margin_top">20.0dp</dimen>
+    <dimen name="end_btn_back_icon_margin_left">94.0dp</dimen>
+    <dimen name="end_btn_back_text_margin_left">11.0dp</dimen>
+    <dimen name="end_btn_back_select_stroke_width">4.0dp</dimen>
+
+    <!--video loading-->
+    <dimen name="loading_width">450.0dp</dimen>
+    <dimen name="loading_height">80.0dp</dimen>
+    <dimen name="loading_text_size">36.0dp</dimen>
+    <dimen name="loading_text_margin_top">29.0dp</dimen>
+
+    <!--loading page-->
+    <dimen name="loading_image_width">126.67dp</dimen>
+    <dimen name="loading_image_height">100dp</dimen>
+    <dimen name="loading_page_text_margin_top">13dp</dimen>
+</resources>

+ 0 - 0
app/src/main/res/values-xhdpi/dimens.xml


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików