Przeglądaj źródła

添加半袋米相关代码

zengjiebin 8 lat temu
rodzic
commit
5cc3161df2
100 zmienionych plików z 18912 dodań i 3 usunięć
  1. 8 0
      .idea/gradle.xml
  2. 2 0
      .idea/modules.xml
  3. 136 1
      app/build.gradle
  4. BIN
      app/libs/Bbnpay.jar
  5. BIN
      app/libs/FileDownloader-1.0.0.aar
  6. BIN
      app/libs/SocialSDK_QQ_Simplify.jar
  7. BIN
      app/libs/SocialSDK_Sina_Simplify.jar
  8. BIN
      app/libs/SocialSDK_WeChat_Simplify.jar
  9. BIN
      app/libs/alipaySdk-20170922.jar
  10. BIN
      app/libs/appstoreutils.aar
  11. BIN
      app/libs/fastjson-1.2.28.jar
  12. BIN
      app/libs/jackson-core-2.2.1.jar
  13. BIN
      app/libs/jackson-dataformat-xml-2.1.2.jar
  14. BIN
      app/libs/umeng_shareboard_widget.jar
  15. BIN
      app/libs/umeng_social_api.jar
  16. BIN
      app/libs/umeng_social_net.jar
  17. BIN
      app/libs/umeng_social_shareboard.jar
  18. BIN
      app/libs/umeng_social_shareview.jar
  19. BIN
      app/libs/umeng_social_tool.jar
  20. BIN
      app/libs/view-release.aar
  21. 176 2
      app/src/main/AndroidManifest.xml
  22. 77 0
      app/src/main/java/com/googlecode/protobuf/format/AbstractCharBasedFormatter.java
  23. 97 0
      app/src/main/java/com/googlecode/protobuf/format/CouchDBFormat.java
  24. 41 0
      app/src/main/java/com/googlecode/protobuf/format/FormatFactory.java
  25. 630 0
      app/src/main/java/com/googlecode/protobuf/format/HtmlFormat.java
  26. 1209 0
      app/src/main/java/com/googlecode/protobuf/format/JavaPropsFormat.java
  27. 1513 0
      app/src/main/java/com/googlecode/protobuf/format/JsonFormat.java
  28. 568 0
      app/src/main/java/com/googlecode/protobuf/format/JsonJacksonFormat.java
  29. 156 0
      app/src/main/java/com/googlecode/protobuf/format/ProtobufFormatter.java
  30. 72 0
      app/src/main/java/com/googlecode/protobuf/format/util/HexUtils.java
  31. 439 0
      app/src/main/java/com/googlecode/protobuf/format/util/TextUtils.java
  32. 311 0
      app/src/main/java/com/kfzs/duanduan/ActAccountManage.java
  33. 374 0
      app/src/main/java/com/kfzs/duanduan/ActAuth.java
  34. 427 0
      app/src/main/java/com/kfzs/duanduan/ActDownloadMgr.java
  35. 240 0
      app/src/main/java/com/kfzs/duanduan/ActDuJiaShouFa.java
  36. 121 0
      app/src/main/java/com/kfzs/duanduan/ActFeedback.java
  37. 639 0
      app/src/main/java/com/kfzs/duanduan/ActGameCertification.java
  38. 479 0
      app/src/main/java/com/kfzs/duanduan/ActGameDetails.java
  39. 48 0
      app/src/main/java/com/kfzs/duanduan/ActGategoryRank.java
  40. 183 0
      app/src/main/java/com/kfzs/duanduan/ActGift.java
  41. 666 0
      app/src/main/java/com/kfzs/duanduan/ActLogin.java
  42. 543 0
      app/src/main/java/com/kfzs/duanduan/ActMain.java
  43. 301 0
      app/src/main/java/com/kfzs/duanduan/ActNewGameBook.java
  44. 350 0
      app/src/main/java/com/kfzs/duanduan/ActPersonPage.java
  45. 84 0
      app/src/main/java/com/kfzs/duanduan/ActPicturesEnlarge.java
  46. 671 0
      app/src/main/java/com/kfzs/duanduan/ActRegist.java
  47. 601 0
      app/src/main/java/com/kfzs/duanduan/ActSearch.java
  48. 218 0
      app/src/main/java/com/kfzs/duanduan/ActSetting.java
  49. 112 0
      app/src/main/java/com/kfzs/duanduan/ActSimple.java
  50. 331 0
      app/src/main/java/com/kfzs/duanduan/ActSplash.java
  51. 67 0
      app/src/main/java/com/kfzs/duanduan/ActTest.java
  52. 428 0
      app/src/main/java/com/kfzs/duanduan/ActUser.java
  53. 367 0
      app/src/main/java/com/kfzs/duanduan/ActWeb.java
  54. 331 0
      app/src/main/java/com/kfzs/duanduan/BaseCompatActivity.java
  55. 236 0
      app/src/main/java/com/kfzs/duanduan/BaseCompatFragment.java
  56. 79 0
      app/src/main/java/com/kfzs/duanduan/CompatActivity.java
  57. 79 0
      app/src/main/java/com/kfzs/duanduan/G.java
  58. 303 0
      app/src/main/java/com/kfzs/duanduan/KFZSApp.java
  59. 334 0
      app/src/main/java/com/kfzs/duanduan/PicBottomSheetActivity.java
  60. 88 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpCommonRecy.java
  61. 96 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpCoupon.java
  62. 63 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpFgtAppDetailBbs.java
  63. 70 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpFgtAppDetailNewGame.java
  64. 221 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpFragmentRank.java
  65. 97 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpGameBook.java
  66. 212 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpMainPageGift.java
  67. 681 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpMainPageRecy.java
  68. 169 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpMainStartService.java
  69. 144 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpSearchGame.java
  70. 169 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpSearchGift.java
  71. 84 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpSearchNewGame.java
  72. 119 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpSearchRecord.java
  73. 86 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpSearchTest.java
  74. 69 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpSearchViewPager.java
  75. 50 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpViewPagerDetail.java
  76. 46 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpViewPagerMainPage.java
  77. 91 0
      app/src/main/java/com/kfzs/duanduan/adp/AdpVipCoupon.java
  78. 69 0
      app/src/main/java/com/kfzs/duanduan/adp/BaseAdpterWithDownBtn.java
  79. 451 0
      app/src/main/java/com/kfzs/duanduan/adp/ClassificationAdapter.java
  80. 128 0
      app/src/main/java/com/kfzs/duanduan/adp/ClassificationGridviewAdapter.java
  81. 141 0
      app/src/main/java/com/kfzs/duanduan/adp/DownloadMgrAdapter.java
  82. 67 0
      app/src/main/java/com/kfzs/duanduan/adp/FilterWindowAdapter.java
  83. 77 0
      app/src/main/java/com/kfzs/duanduan/adp/ManagementAccountAdapter.java
  84. 53 0
      app/src/main/java/com/kfzs/duanduan/adp/UserSelfInfoShowAdapter.java
  85. 31 0
      app/src/main/java/com/kfzs/duanduan/adp/ViewPagerFragmentAdapter.java
  86. 110 0
      app/src/main/java/com/kfzs/duanduan/bean/BaseMsg.java
  87. 72 0
      app/src/main/java/com/kfzs/duanduan/bean/BorrowPlayIntegral.java
  88. 61 0
      app/src/main/java/com/kfzs/duanduan/bean/CateGameBean.java
  89. 34 0
      app/src/main/java/com/kfzs/duanduan/bean/CateGameList.java
  90. 23 0
      app/src/main/java/com/kfzs/duanduan/bean/CompareResult.java
  91. 87 0
      app/src/main/java/com/kfzs/duanduan/bean/ContactBean.java
  92. 130 0
      app/src/main/java/com/kfzs/duanduan/bean/DownloadStatus.java
  93. 313 0
      app/src/main/java/com/kfzs/duanduan/bean/Game.java
  94. 184 0
      app/src/main/java/com/kfzs/duanduan/bean/GiftItem.java
  95. 89 0
      app/src/main/java/com/kfzs/duanduan/bean/GiftList.java
  96. 45 0
      app/src/main/java/com/kfzs/duanduan/bean/GuessYouLike.java
  97. 40 0
      app/src/main/java/com/kfzs/duanduan/bean/KFIntentKeys.java
  98. 57 0
      app/src/main/java/com/kfzs/duanduan/bean/NewGameRecommend.java
  99. 48 0
      app/src/main/java/com/kfzs/duanduan/bean/QueryCondition.java
  100. 0 0
      app/src/main/java/com/kfzs/duanduan/bean/RecyleObj.java

+ 8 - 0
.idea/gradle.xml

@@ -5,6 +5,14 @@
       <GradleProjectSettings>
         <option name="distributionType" value="DEFAULT_WRAPPED" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/datashare" />
+            <option value="$PROJECT_DIR$/view" />
+          </set>
+        </option>
         <option name="resolveModulePerSourceSet" value="false" />
       </GradleProjectSettings>
     </option>

+ 2 - 0
.idea/modules.xml

@@ -3,7 +3,9 @@
   <component name="ProjectModuleManager">
     <modules>
       <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
+      <module fileurl="file://$PROJECT_DIR$/datashare/datashare.iml" filepath="$PROJECT_DIR$/datashare/datashare.iml" />
       <module fileurl="file://$PROJECT_DIR$/small_sheep_android.iml" filepath="$PROJECT_DIR$/small_sheep_android.iml" />
+      <module fileurl="file://$PROJECT_DIR$/view/view.iml" filepath="$PROJECT_DIR$/view/view.iml" />
     </modules>
   </component>
 </project>

+ 136 - 1
app/build.gradle

@@ -14,7 +14,7 @@ android {
         multiDexEnabled true
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         ndk {
-            abiFilters 'armeabi' , 'x86'//, 'armeabi-v7a', 'x86_64', 'arm64-v8a'
+            abiFilters "armeabi-v7a", 'x86'//, 'armeabi-v7a', 'x86_64', 'arm64-v8a'
         }
         jackOptions {
             enabled true
@@ -34,6 +34,20 @@ android {
         }
 
     }
+
+    lintOptions {
+        abortOnError false
+        disable 'MissingTranslation'
+    }
+
+    dexOptions {
+        preDexLibraries = false
+        javaMaxHeapSize "4g"
+    }
+    packagingOptions {
+
+        exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
+    }
     buildTypes {
         release {
             minifyEnabled false
@@ -44,6 +58,75 @@ android {
             signingConfig signingConfigs.config
         }
     }
+    productFlavors.all { flavor ->
+        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: "${flavor.name}",
+                                       DUANDUAN_GRAPH     : "${flavor.name}",
+                                       DUANDUAN_DATASHARE : "${flavor.name}",
+        ]
+    }
+    productFlavors {
+        bandaimitest {
+            applicationId "com.sheep.jiuyan.samllsheep.test"
+            manifestPlaceholders = [UMENG_CHANNEL_VALUE   : "bandaimitest",
+                                    DUANDUAN_GRAPH        : "bandaimitest",
+                                    DUANDUAN_DATASHARE    : "bandaimitest",
+                                    UMENG_APPKEY          : "58dc9509aed17959a3001bff",
+                                    JPUSH_PKGNAME : applicationId,
+                                    JPUSH_APPKEY : "b8b5adf7d70d0c904d46d04c",
+                                    JPUSH_CHANNEL : "developer-default",
+                                    WX_ENTRY_ACTIVITY     : "com.kfzs.duanduan.bandaimi.wxapi.WXEntryActivity",
+                                    REACT_ACTIVITY_ACTION     : "com.kfzs.duanduan.bandaimi.jumpToReactActivity",
+                                    DUANDUAN_GAME_CATEGORY: "android.intent.category.LAUNCHER"]
+            buildConfigField "String", "DUANDUAN_DATASHARE", '"bandaimitest"'
+            buildConfigField "String", "DUANDUAN_GRAPH", '"bandaimitest"'
+            buildConfigField "boolean", "KF_DEBUG", 'true'
+//            buildConfigField "String", "API_DOMAIN", '"10.8.210.229:8081"'
+//            buildConfigField "String", "RN_DOMAIN", '"10.8.210.229:8070"'
+            buildConfigField "String", "API_DOMAIN", '"test.bdmapp.kfzs.com"'
+            buildConfigField "String", "RN_DOMAIN", '"test.shopapi.bandaimi.com"'
+//            buildConfigField "String", "API_DOMAIN", '"10.8.210.229:8081"'
+            buildConfigField "String", "JFSC_DOMAIN", '"http://10.8.210.190:8080/"'//积分商城
+            buildConfigField "String", "CAPTCHA_DOMAIN", '"captcha.kuaifazs.com"'
+            buildConfigField "String", "umeng_appkey", '"58dc9509aed17959a3001bff"'
+            buildConfigField "String", "WX_APPID", '"wx1af78a79dd7d4a45"'
+            buildConfigField "String", "WX_APPSECRET", '"f183b5e8c4a5f91a9ce23bacb5094b1d"'
+            buildConfigField "String", "WB_APPID", '"285907821"'
+            buildConfigField "String", "WB_APPSECRET", '"771a81389c60bcedd1a517dbe65977d6"'
+            buildConfigField "String", "DUANDUAN_GAME_CATEGORY", '"android.intent.category.LAUNCHER"'
+            signingConfig signingConfigs.config
+        }
+        bandaimi {
+            applicationId "com.sheep.jiuyan.samllsheep"
+//            applicationId "com.kfzs.duanduan.bandaimi"
+            manifestPlaceholders = [UMENG_CHANNEL_VALUE   : "bandaimi",
+                                    DUANDUAN_GRAPH        : "bandaimi",
+                                    DUANDUAN_DATASHARE    : "bandaimi",
+                                    UMENG_APPKEY          : "58dc9509aed17959a3001bff",
+                                    JPUSH_PKGNAME : applicationId,
+                                    JPUSH_APPKEY : "b8b5adf7d70d0c904d46d04c",
+                                    JPUSH_CHANNEL : "developer-default",
+                                    WX_ENTRY_ACTIVITY     : "com.kfzs.duanduan.bandaimi.wxapi.WXEntryActivity",
+                                    REACT_ACTIVITY_ACTION     : "com.kfzs.duanduan.bandaimi.jumpToReactActivity",
+                                    DUANDUAN_GAME_CATEGORY: "android.intent.category.LAUNCHER"]
+            buildConfigField "String", "DUANDUAN_DATASHARE", '"bandaimi"'
+            buildConfigField "String", "DUANDUAN_GRAPH", '"bandaimi"'
+            buildConfigField "boolean", "KF_DEBUG", 'false'
+            buildConfigField "String", "API_DOMAIN", '"app.bandai.yunduanzs.cn"'
+            buildConfigField "String", "RN_DOMAIN", '"shopapi.bandaimi.com"'
+            buildConfigField "String", "JFSC_DOMAIN", '"http://jf.bandaimi.com/"'//积分商城
+//            buildConfigField "String", "API_DOMAIN", '"app.bdmoem.kfzs.com"'
+//            buildConfigField "String", "RN_DOMAIN", '"shopapi.bdmoem.kfzs.com"'
+//            buildConfigField "String", "JFSC_DOMAIN", '"http://jf.bdmoem.kfzs.com/"'//积分商城
+            buildConfigField "String", "CAPTCHA_DOMAIN", '"captcha.kuaifazs.com"'
+            buildConfigField "String", "umeng_appkey", '"58dc9509aed17959a3001bff"'
+            buildConfigField "String", "WX_APPID", '"wx1af78a79dd7d4a45"'
+            buildConfigField "String", "WX_APPSECRET", '"f183b5e8c4a5f91a9ce23bacb5094b1d"'
+            buildConfigField "String", "WB_APPID", '"285907821"'
+            buildConfigField "String", "WB_APPSECRET", '"771a81389c60bcedd1a517dbe65977d6"'
+            buildConfigField "String", "DUANDUAN_GAME_CATEGORY", '"android.intent.category.LAUNCHER"'
+            signingConfig signingConfigs.config
+        }
+    }
 }
 
 repositories {
@@ -115,4 +198,56 @@ dependencies {
     //fast json
     compile 'com.alibaba:fastjson:+'
 
+    //添加半袋米相关
+//    compile 'com.jakewharton:butterknife:8.1.0'
+//    annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0'
+    compile(name: 'appstoreutils', ext: 'aar')
+    compile project(':view')
+//    compile(name: 'view-release', ext: 'aar')
+
+    //极光推送两个
+    compile 'cn.jiguang.sdk:jpush:3.0.8'
+    // 此处以JPush 3.0.3 版本为例。
+    compile 'cn.jiguang.sdk:jcore:1.1.6'
+    // 此处以JCore 1.1.1 版本为例。
+    compile 'com.google.code.gson:gson:2.8.1'
+
+    //    compile 'com.android.support:design:24.2.0'
+    compile 'com.flipboard:bottomsheet-core:1.5.3'
+    compile 'com.flipboard:bottomsheet-commons:1.5.3'
+    //    compile 'org.greenrobot:greendao:3.2.0'
+    compile 'com.google.protobuf:protobuf-java:3.2.0'
+    compile 'com.umeng.analytics:analytics:6.0.9'
+    compile(name: 'com.kfzs.safe', ext: 'aar')
+    compile(name: 'FileDownloader-1.0.0', ext: 'aar')
+    compile 'org.greenrobot:eventbus:3.0.0'
+    compile 'com.yalantis:ucrop:2.2.0'
+    //    compile files('libs/SocialSDK_QQ_Simplify.jar')
+    compile files('libs/SocialSDK_Sina_Simplify.jar')
+    compile files('libs/SocialSDK_WeChat_Simplify.jar')
+    compile files('libs/umeng_shareboard_widget.jar')
+    compile files('libs/umeng_social_api.jar')
+    compile files('libs/umeng_social_net.jar')
+    compile files('libs/umeng_social_shareboard.jar')
+    compile files('libs/umeng_social_shareview.jar')
+    compile files('libs/umeng_social_tool.jar')
+    compile 'com.zhy:okhttputils:2.6.2'
+    compile files('libs/alipaySdk-20170922.jar')
+    compile 'com.github.bumptech.glide:glide:3.5.2'
+    compile 'jp.wasabeef:glide-transformations:2.0.2'
+    compile 'com.nineoldandroids:library:2.4.0'
+    compile 'cn.bingoogolapple:bga-banner:2.1.7@aar'
+    compile 'mdl.sinlov.android:log:0.0.2'
+    //    compile 'com.kf.framework:kf-utils:latest.integration@aar'
+    compile 'com.kf.framework:kf-utils:1.4.5@aar'
+    //    compile 'com.kf.framework:volleyplus:latest.integration@aar'
+    compile 'com.kf.framework:volleyplus:1.4.5@aar'
+    compile 'com.android.support:support-annotations:23.1.1'
+    compile 'com.android.support:recyclerview-v7:27.1.0'
+    compile 'io.reactivex:rxandroid:1.2.1'
+    compile 'io.reactivex:rxjava:1.1.6'
+    compile 'top.zibin:Luban:1.0.9'
+    compile project(':datashare')
+    compile files('libs/jackson-core-2.2.1.jar')
+    compile files('libs/jackson-dataformat-xml-2.1.2.jar')
 }

BIN
app/libs/Bbnpay.jar


BIN
app/libs/FileDownloader-1.0.0.aar


BIN
app/libs/SocialSDK_QQ_Simplify.jar


BIN
app/libs/SocialSDK_Sina_Simplify.jar


BIN
app/libs/SocialSDK_WeChat_Simplify.jar


BIN
app/libs/alipaySdk-20170922.jar


BIN
app/libs/appstoreutils.aar


BIN
app/libs/fastjson-1.2.28.jar


BIN
app/libs/jackson-core-2.2.1.jar


BIN
app/libs/jackson-dataformat-xml-2.1.2.jar


BIN
app/libs/umeng_shareboard_widget.jar


BIN
app/libs/umeng_social_api.jar


BIN
app/libs/umeng_social_net.jar


BIN
app/libs/umeng_social_shareboard.jar


BIN
app/libs/umeng_social_shareview.jar


BIN
app/libs/umeng_social_tool.jar


BIN
app/libs/view-release.aar


+ 176 - 2
app/src/main/AndroidManifest.xml

@@ -225,9 +225,183 @@
         </service>
 
         <!--友盟start-->
-        <meta-data android:value="xx" android:name="UMENG_APPKEY"/>
-        <meta-data android:value="xxx" android:name="UMENG_CHANNEL"/>
+        <meta-data
+            android:name="DUANDUAN_GRAPH"
+            android:value="${DUANDUAN_GRAPH}" />
+
+        <meta-data
+            android:name="DUANDUAN_DATASHARE"
+            android:value="${DUANDUAN_DATASHARE}" />
+
+        <meta-data
+            android:name="UMENG_CHANNEL"
+            android:value="${UMENG_CHANNEL_VALUE}" />
+        <meta-data
+            android:name="UMENG_APPKEY"
+            android:value="${UMENG_APPKEY}"/>
         <!--友盟end-->
+
+        <!--半袋米首页-->
+        <activity
+            android:name="com.kfzs.duanduan.ActMain"
+            android:configChanges="keyboardHidden|screenSize|orientation"
+            android:exported="true"
+            android:hardwareAccelerated="true"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateHidden">
+            <category android:name="android.intent.category.DEFAULT" />
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name="com.kfzs.duanduan.ActSimple"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActSearch"
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustNothing" />
+        <activity
+            android:name="com.kfzs.duanduan.ActGameDetails"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActLogin"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActRegist"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActDuJiaShouFa"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActPicturesEnlarge"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActGift"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActPersonPage"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActFeedback"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActNewGameBook"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.ActGategoryRank"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.mine.GiftpackListActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name="com.kfzs.duanduan.mine.VoucherListActivity"
+            android:screenOrientation="portrait" />
+
+        <activity
+            android:name="com.kfzs.duanduan.ActWeb"
+            android:hardwareAccelerated="true"
+            android:screenOrientation="portrait" />
+
+
+        <activity
+            android:name="com.kfzs.duanduan.ActDownloadMgr"
+            android:hardwareAccelerated="false"
+            android:screenOrientation="portrait" />
+
+        <service
+            android:name="com.kfzs.duanduan.services.KFDownloadServices"
+            android:exported="false" />
+
+        <activity
+            android:name="com.kfzs.duanduan.ActUser"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:launchMode="singleTask"
+            android:parentActivityName="com.kfzs.duanduan.ActMain"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateHidden">
+            <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="com.kfzs.duanduan.ActMain" />
+        </activity>
+
+        <activity
+            android:name="com.kfzs.duanduan.ActAuth"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateHidden" />
+
+        <activity
+            android:name="com.kfzs.duanduan.ActTest"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:hardwareAccelerated="false"
+            android:label="测试Act"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateHidden">
+            <!--<intent-filter>-->
+            <!--<action android:name="android.intent.action.MAIN" />-->
+            <!--<category android:name="android.intent.category.LAUNCHER" />-->
+            <!--</intent-filter>-->
+        </activity>
+
+        <activity
+            android:name="com.kfzs.duanduan.ActAccountManage"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateHidden" />
+
+        <!--android:hardwareAccelerated="false"-->
+        <activity
+            android:name="com.kfzs.duanduan.ActGameCertification"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:exported="true"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />
+        <activity
+            android:name="com.kfzs.duanduan.view.GameCertificationActivity"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:exported="true"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme"
+            android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />
+
+        <activity
+            android:name="com.yalantis.ucrop.UCropActivity"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:screenOrientation="portrait"
+            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
+        <activity
+            android:name="com.umeng.socialize.editorpage.ShareActivity"
+            android:excludeFromRecents="true"
+            android:theme="@style/Theme.UMDefault" />
+
+
+        <provider
+            android:name="com.kfzs.duanduan.data.graph.provider.KFZSProvider"
+            android:authorities="com.kfzs.duanduan.data.graph.provider.${DUANDUAN_GRAPH}"
+            android:exported="true" />
+
+
+        <receiver android:name="com.kfzs.duanduan.oem.AppAddOrdelReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.PACKAGE_ADDED" />
+                <action android:name="android.intent.action.PACKAGE_REMOVED" />
+                <action android:name="android.intent.action.PACKAGE_REPLACED" />
+
+                <data android:scheme="package" />
+            </intent-filter>
+        </receiver>
     </application>
 
 

+ 77 - 0
app/src/main/java/com/googlecode/protobuf/format/AbstractCharBasedFormatter.java

@@ -0,0 +1,77 @@
+/**
+ * Copyright 2000-2011 NeuStar, Inc. All rights reserved.
+ * NeuStar, the Neustar logo and related names and logos are registered
+ * trademarks, service marks or tradenames of NeuStar, Inc. All other
+ * product names, company names, marks, logos and symbols may be trademarks
+ * of their respective owners.
+ */
+
+package com.googlecode.protobuf.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.Message;
+import com.google.protobuf.Message.Builder;
+import com.google.protobuf.UnknownFieldSet;
+import com.googlecode.protobuf.format.ProtobufFormatter.ParseException;
+import com.googlecode.protobuf.format.util.TextUtils;
+
+public abstract class AbstractCharBasedFormatter extends ProtobufFormatter {
+
+	@Override
+	public void print(Message message, OutputStream output, Charset cs)
+			throws IOException {
+		OutputStreamWriter writer = new OutputStreamWriter(output, cs);
+		print(message, writer);
+		writer.flush();
+	}
+	
+	abstract public void print(Message message, Appendable output) throws IOException;
+
+
+	@Override
+	public void print(UnknownFieldSet fields, OutputStream output, Charset cs)
+			throws IOException {
+		OutputStreamWriter writer = new OutputStreamWriter(output, cs);
+		print(fields, writer);
+		writer.flush();
+	}
+	
+	abstract public void print(UnknownFieldSet fields, Appendable output) throws IOException;
+
+	@Override
+	public void merge(InputStream input, Charset cs, 
+			ExtensionRegistry extensionRegistry, Builder builder) throws IOException {
+		InputStreamReader reader = new InputStreamReader(input, cs);
+		merge(reader, extensionRegistry, builder);
+	}
+	
+	
+	abstract public void merge(CharSequence input, ExtensionRegistry extensionRegistry,
+            Builder builder) throws IOException;
+	
+	/**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     */
+    public void merge(Readable input,
+    		ExtensionRegistry extensionRegistry,
+    		Builder builder) throws IOException {
+        // Read the entire input to a String then parse that.
+
+        // If StreamTokenizer were not quite so crippled, or if there were a kind
+        // of Reader that could read in chunks that match some particular regex,
+        // or if we wanted to write a custom Reader to tokenize our stream, then
+        // we would not have to read to one big String. Alas, none of these is
+        // the case. Oh well.
+
+		merge(TextUtils.toStringBuilder(input), extensionRegistry, builder);
+    }
+}

+ 97 - 0
app/src/main/java/com/googlecode/protobuf/format/CouchDBFormat.java

@@ -0,0 +1,97 @@
+package com.googlecode.protobuf.format;
+
+
+import java.io.IOException;
+
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: aantonov
+ * Date: Mar 16, 2010
+ * Time: 4:06:05 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class CouchDBFormat extends JsonFormat {
+
+    /**
+     * Outputs a textual representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public void print(final Message message, Appendable output) throws IOException {
+        CouchDBGenerator generator = new CouchDBGenerator(output);
+        generator.print("{");
+        print(message, generator);
+        generator.print("}");
+    }
+
+    /**
+     * Outputs a textual representation of {@code fields} to {@code output}.
+     */
+    public void print(final UnknownFieldSet fields, Appendable output) throws IOException {
+        CouchDBGenerator generator = new CouchDBGenerator(output);
+        generator.print("{");
+        printUnknownFields(fields, generator);
+        generator.print("}");
+    }
+
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     */
+    public void merge(CharSequence input,
+                             ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws ParseException {
+        Tokenizer tokenizer = new Tokenizer(input);
+
+        // Based on the state machine @ http://json.org/
+
+        tokenizer.consume("{"); // Needs to happen when the object starts.
+        while (!tokenizer.tryConsume("}")) { // Continue till the object is done
+            mergeField(tokenizer, extensionRegistry, builder);
+        }
+    }
+
+    protected static class Tokenizer extends JsonFormat.Tokenizer {
+
+        /**
+         * Construct a tokenizer that parses tokens from the given text.
+         */
+        public Tokenizer(CharSequence text) {
+            super(text);
+        }
+
+        @Override
+        public String consumeIdentifier() throws ParseException {
+            String id = super.consumeIdentifier();
+            if ("_id".equals(id)) {
+                return "id";
+            } else if ("_rev".equals(id)) {
+                return "rev";
+            }
+            return id;
+        }
+    }
+
+    protected static class CouchDBGenerator extends JsonGenerator {
+
+        public CouchDBGenerator(Appendable output) {
+            super(output);
+        }
+
+        @Override
+        public void print(CharSequence text) throws IOException {
+            if ("id".equals(text)) {
+                super.print("_id");
+            } else if ("rev".equals(text)) {
+                super.print("_rev");
+            } else {
+                super.print(text);
+            }
+        }
+    }
+}

+ 41 - 0
app/src/main/java/com/googlecode/protobuf/format/FormatFactory.java

@@ -0,0 +1,41 @@
+/**
+ * Copyright 2000-2011 NeuStar, Inc. All rights reserved.
+ * NeuStar, the Neustar logo and related names and logos are registered
+ * trademarks, service marks or tradenames of NeuStar, Inc. All other
+ * product names, company names, marks, logos and symbols may be trademarks
+ * of their respective owners.
+ */
+
+package com.googlecode.protobuf.format;
+
+public class FormatFactory {
+	
+	public FormatFactory() {}
+	
+	public enum Formatter {
+		COUCHDB (CouchDBFormat.class),
+		HTML (HtmlFormat.class),
+		JAVA_PROPS (JavaPropsFormat.class),
+		JSON (JsonFormat.class),
+		JSON_JACKSON (JsonJacksonFormat.class);
+
+		private Class<? extends ProtobufFormatter> formatterClass;
+		Formatter(Class<? extends ProtobufFormatter> formatterClass) {
+			this.formatterClass = formatterClass;
+		}
+		protected Class<? extends ProtobufFormatter> getFormatterClass() {
+			return formatterClass;
+		}
+	}
+	
+	
+	public ProtobufFormatter createFormatter(Formatter formatter) {
+		try {
+			return formatter.getFormatterClass().newInstance();
+		} catch (InstantiationException e) {
+			throw new RuntimeException(e);
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}

+ 630 - 0
app/src/main/java/com/googlecode/protobuf/format/HtmlFormat.java

@@ -0,0 +1,630 @@
+package com.googlecode.protobuf.format;
+/* 
+    Copyright (c) 2009, Orbitz World Wide
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+    are permitted provided that the following conditions are met:
+
+        * Redistributions of source code must retain the above copyright notice, 
+          this list of conditions and the following disclaimer.
+        * Redistributions in binary form must reproduce the above copyright notice, 
+          this list of conditions and the following disclaimer in the documentation 
+          and/or other materials provided with the distribution.
+        * Neither the name of the Orbitz World Wide nor the names of its contributors 
+          may be used to endorse or promote products derived from this software 
+          without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.Message;
+import com.google.protobuf.Message.Builder;
+import com.google.protobuf.UnknownFieldSet;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import static com.googlecode.protobuf.format.util.TextUtils.*;
+
+
+/**
+ * Provide ascii html formatting support for proto2 instances.
+ * <p>
+ * (c) 2009-10 Orbitz World Wide. All Rights Reserved.
+ * 
+ * @author eliran.bivas@gmail.com Eliran Bivas
+ * @version $HtmlFormat.java Mar 12, 2009 4:00:33 PM$
+ */
+public final class HtmlFormat extends AbstractCharBasedFormatter {
+
+    private static final String META_CONTENT = "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />";
+    private static final String MAIN_DIV_STYLE = "color: black; font-size: 14px; font-family: sans-serif; font-weight: bolder; margin-bottom: 10px;";
+    private static final String FIELD_NAME_STYLE = "font-weight: bold; color: #669966;font-size: 14px; font-family: sans-serif;";
+    private static final String FIELD_VALUE_STYLE = "color: #3300FF;font-size: 13px; font-family: sans-serif;";
+
+    
+    public void print(final Message message, Appendable output) throws IOException {
+    	HtmlGenerator generator = new HtmlGenerator(output);
+        printTitle(message, generator);
+        print(message, generator);
+        generator.print("</body></html>");
+    }
+    
+	public void print(final UnknownFieldSet fields, Appendable output) throws IOException {
+		HtmlGenerator generator = new HtmlGenerator(output);
+        generator.print("<html>");
+        generator.print(META_CONTENT);
+        generator.print("</head><body>");
+        printUnknownFields(fields, generator);
+        generator.print("</body></html>");
+	}
+	
+	@Override
+	public void merge(CharSequence input, ExtensionRegistry extensionRegistry,
+			Builder builder) throws IOException {
+		throw new UnsupportedOperationException();
+	}
+    
+
+    private void printTitle(final Message message, final HtmlGenerator generator) throws IOException {
+        generator.print("<html><head>");
+        generator.print(META_CONTENT);
+        generator.print("<title>");
+        generator.print(message.getDescriptorForType().getFullName());
+        generator.print("</title></head><body>");
+        generator.print("<div style=\"");
+        generator.print(MAIN_DIV_STYLE);
+        generator.print("\">message : ");
+        generator.print(message.getDescriptorForType().getFullName());
+        generator.print("</div>");
+    }
+
+
+    private void print(Message message, HtmlGenerator generator) throws IOException {
+
+        for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
+            printField(field.getKey(), field.getValue(), generator);
+        }
+        printUnknownFields(message.getUnknownFields(), generator);
+    }
+
+    public void printField(FieldDescriptor field, Object value, HtmlGenerator generator) throws IOException {
+
+        if (field.isRepeated()) {
+            // Repeated field. Print each element.
+            for (Object element : (List<?>) value) {
+                printSingleField(field, element, generator);
+            }
+        } else {
+            printSingleField(field, value, generator);
+        }
+    }
+
+    private void printSingleField(FieldDescriptor field,
+                                         Object value,
+                                         HtmlGenerator generator) throws IOException {
+        if (field.isExtension()) {
+            generator.print("[<span style=\"");
+            generator.print(FIELD_NAME_STYLE);
+            generator.print("\">");
+            // We special-case MessageSet elements for compatibility with proto1.
+            if (field.getContainingType().getOptions().getMessageSetWireFormat()
+                            && (field.getType() == FieldDescriptor.Type.MESSAGE) && (field.isOptional())
+                            // object equality
+                            && (field.getExtensionScope() == field.getMessageType())) {
+                generator.print(field.getMessageType().getFullName());
+            } else {
+                generator.print(field.getFullName());
+            }
+            generator.print("</span>]");
+        } else {
+            generator.print("<span style=\"");
+            generator.print(FIELD_NAME_STYLE);
+            generator.print("\">");
+            if (field.getType() == FieldDescriptor.Type.GROUP) {
+                // Groups must be serialized with their original capitalization.
+                generator.print(field.getMessageType().getName());
+            } else {
+                generator.print(field.getName());
+            }
+            generator.print("</span>");
+        }
+
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            generator.print(" <span style=\"color: red;\">{</span><br/>");
+            generator.indent();
+        } else {
+            generator.print(": ");
+        }
+
+        printFieldValue(field, value, generator);
+
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            generator.outdent();
+            generator.print("<span style=\"color: red;\">}</span>");
+        }
+        generator.print("<br/>");
+    }
+
+    private void printFieldValue(FieldDescriptor field, Object value, HtmlGenerator generator) throws IOException {
+        generator.print("<span style=\"");
+        generator.print(FIELD_VALUE_STYLE);
+        generator.print("\">");
+        switch (field.getType()) {
+            case INT32:
+            case INT64:
+            case SINT32:
+            case SINT64:
+            case SFIXED32:
+            case SFIXED64:
+            case FLOAT:
+            case DOUBLE:
+            case BOOL:
+                // Good old toString() does what we want for these types.
+                generator.print(value.toString());
+                break;
+
+            case UINT32:
+            case FIXED32:
+                generator.print(unsignedToString((Integer) value));
+                break;
+
+            case UINT64:
+            case FIXED64:
+                generator.print(unsignedToString((Long) value));
+                break;
+
+            case STRING:
+                generator.print("\"");
+                generator.print(value.toString());
+                generator.print("\"");
+                break;
+
+            case BYTES: {
+                generator.print("\"");
+                generator.print(escapeBytes((ByteString) value));
+                generator.print("\"");
+                break;
+            }
+
+            case ENUM: {
+                generator.print(((EnumValueDescriptor) value).getName());
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+                print((Message) value, generator);
+                break;
+        }
+        generator.print("</span>");
+    }
+
+    private void printUnknownFields(UnknownFieldSet unknownFields, HtmlGenerator generator) throws IOException {
+        for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
+            UnknownFieldSet.Field field = entry.getValue();
+
+            for (long value : field.getVarintList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(unsignedToString(value));
+                generator.print("<br/>");
+            }
+            for (int value : field.getFixed32List()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(String.format((Locale) null, "0x%08x", value));
+                generator.print("<br/>");
+            }
+            for (long value : field.getFixed64List()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(String.format((Locale) null, "0x%016x", value));
+                generator.print("<br/>");
+            }
+            for (ByteString value : field.getLengthDelimitedList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": \"");
+                generator.print(escapeBytes(value));
+                generator.print("\"<br/>");
+            }
+            for (UnknownFieldSet value : field.getGroupList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(" <span style=\"color: red;\">{</span><br/>");
+                generator.indent();
+                printUnknownFields(value, generator);
+                generator.outdent();
+                generator.print("<span style=\"color: red;\">}</span><br/>");
+            }
+        }
+    }
+
+    
+
+    /**
+     * An inner class for writing text to the output stream.
+     */
+    static private final class HtmlGenerator {
+
+        Appendable output;
+        boolean atStartOfLine = true;
+
+        public HtmlGenerator(Appendable output) {
+            this.output = output;
+        }
+
+        /**
+         * Indent text by two spaces. After calling Indent(), two spaces will be inserted at the
+         * beginning of each line of text. Indent() may be called multiple times to produce deeper
+         * indents.
+         * 
+         * @throws IOException
+         */
+        public void indent() throws IOException {
+            print("<div style=\"margin-left: 25px\">");
+        }
+
+        /**
+         * Reduces the current indent level by two spaces, or crashes if the indent level is zero.
+         * 
+         * @throws IOException
+         */
+        public void outdent() throws IOException {
+            print("</div>");
+        }
+
+        /**
+         * Print text to the output stream.
+         */
+        public void print(CharSequence text) throws IOException {
+            int size = text.length();
+            int pos = 0;
+
+            for (int i = 0; i < size; i++) {
+                if (text.charAt(i) == '\n') {
+                    write("<br/>", i - pos + 1);
+                    pos = i + 1;
+                    atStartOfLine = true;
+                }
+            }
+            write(text.subSequence(pos, size), size - pos);
+        }
+
+        private void write(CharSequence data, int size) throws IOException {
+            if (size == 0) {
+                return;
+            }
+            if (atStartOfLine) {
+                atStartOfLine = false;
+            }
+            output.append(data);
+        }
+    }
+
+    // =================================================================
+    // Utility functions
+    //
+    // Some of these methods are package-private because Descriptors.java uses
+    // them.
+
+    /**
+     * Escapes bytes in the format used in protocol buffer text format, which is the same as the
+     * format used for C string literals. All bytes that are not printable 7-bit ASCII characters
+     * are escaped, as well as backslash, single-quote, and double-quote characters. Characters for
+     * which no defined short-hand escape sequence is defined will be escaped using 3-digit octal
+     * sequences.
+     */
+    static String escapeBytes(ByteString input) {
+        StringBuilder builder = new StringBuilder(input.size());
+        for (int i = 0; i < input.size(); i++) {
+            byte b = input.byteAt(i);
+            switch (b) {
+                // Java does not recognize \a or \v, apparently.
+                case 0x07:
+                    builder.append("\\a");
+                    break;
+                case '\b':
+                    builder.append("\\b");
+                    break;
+                case '\f':
+                    builder.append("\\f");
+                    break;
+                case '\n':
+                    builder.append("\\n");
+                    break;
+                case '\r':
+                    builder.append("\\r");
+                    break;
+                case '\t':
+                    builder.append("\\t");
+                    break;
+                case 0x0b:
+                    builder.append("\\v");
+                    break;
+                case '\\':
+                    builder.append("\\\\");
+                    break;
+                case '\'':
+                    builder.append("\\\'");
+                    break;
+                case '"':
+                    builder.append("\\\"");
+                    break;
+                default:
+                    if (b >= 0x20) {
+                        builder.append((char) b);
+                    } else {
+                        builder.append('\\');
+                        builder.append((char) ('0' + ((b >>> 6) & 3)));
+                        builder.append((char) ('0' + ((b >>> 3) & 7)));
+                        builder.append((char) ('0' + (b & 7)));
+                    }
+                    break;
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Un-escape a byte sequence as escaped using
+     * {@link #escapeBytes(com.googlecode.protobuf.format.ByteString)}. Two-digit hex escapes (starting with
+     * "\x") are also recognized.
+     */
+    static ByteString unescapeBytes(CharSequence input) throws InvalidEscapeSequence {
+        byte[] result = new byte[input.length()];
+        int pos = 0;
+        for (int i = 0; i < input.length(); i++) {
+            char c = input.charAt(i);
+            if (c == '\\') {
+                if (i + 1 < input.length()) {
+                    ++i;
+                    c = input.charAt(i);
+                    if (isOctal(c)) {
+                        // Octal escape.
+                        int code = digitValue(c);
+                        if ((i + 1 < input.length()) && isOctal(input.charAt(i + 1))) {
+                            ++i;
+                            code = code * 8 + digitValue(input.charAt(i));
+                        }
+                        if ((i + 1 < input.length()) && isOctal(input.charAt(i + 1))) {
+                            ++i;
+                            code = code * 8 + digitValue(input.charAt(i));
+                        }
+                        result[pos++] = (byte) code;
+                    } else {
+                        switch (c) {
+                            case 'a':
+                                result[pos++] = 0x07;
+                                break;
+                            case 'b':
+                                result[pos++] = '\b';
+                                break;
+                            case 'f':
+                                result[pos++] = '\f';
+                                break;
+                            case 'n':
+                                result[pos++] = '\n';
+                                break;
+                            case 'r':
+                                result[pos++] = '\r';
+                                break;
+                            case 't':
+                                result[pos++] = '\t';
+                                break;
+                            case 'v':
+                                result[pos++] = 0x0b;
+                                break;
+                            case '\\':
+                                result[pos++] = '\\';
+                                break;
+                            case '\'':
+                                result[pos++] = '\'';
+                                break;
+                            case '"':
+                                result[pos++] = '\"';
+                                break;
+
+                            case 'x':
+                                // hex escape
+                                int code = 0;
+                                if ((i + 1 < input.length()) && isHex(input.charAt(i + 1))) {
+                                    ++i;
+                                    code = digitValue(input.charAt(i));
+                                } else {
+                                    throw new InvalidEscapeSequence("Invalid escape sequence: '\\x' with no digits");
+                                }
+                                if ((i + 1 < input.length()) && isHex(input.charAt(i + 1))) {
+                                    ++i;
+                                    code = code * 16 + digitValue(input.charAt(i));
+                                }
+                                result[pos++] = (byte) code;
+                                break;
+
+                            default:
+                                throw new InvalidEscapeSequence("Invalid escape sequence: '\\" + c
+                                                                + "'");
+                        }
+                    }
+                } else {
+                    throw new InvalidEscapeSequence("Invalid escape sequence: '\\' at end of string.");
+                }
+            } else {
+                result[pos++] = (byte) c;
+            }
+        }
+
+        return ByteString.copyFrom(result, 0, pos);
+    }
+
+    /**
+     * Thrown by {@link JsonFormat#unescapeBytes} and {@link JsonFormat#unescapeText} when an
+     * invalid escape sequence is seen.
+     */
+    static class InvalidEscapeSequence extends IOException {
+
+        private static final long serialVersionUID = 1L;
+
+        public InvalidEscapeSequence(String description) {
+            super(description);
+        }
+    }
+
+    /**
+     * Like {@link #escapeBytes(com.googlecode.protobuf.format.ByteString)}, but escapes a text string.
+     * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped individually as a
+     * 3-digit octal escape. Yes, it's weird.
+     */
+    static String escapeText(String input) {
+        return escapeBytes(ByteString.copyFromUtf8(input));
+    }
+
+    /**
+     * Un-escape a text string as escaped using {@link #escapeText(String)}. Two-digit hex escapes
+     * (starting with "\x") are also recognized.
+     */
+    static String unescapeText(String input) throws InvalidEscapeSequence {
+        return unescapeBytes(input).toStringUtf8();
+    }
+
+
+    /**
+     * Parse a 32-bit signed integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively.
+     */
+    static int parseInt32(String text) throws NumberFormatException {
+        return (int) parseInteger(text, true, false);
+    }
+
+    /**
+     * Parse a 32-bit unsigned integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively. The result is coerced to a (signed) {@code int}
+     * when returned since Java has no unsigned integer type.
+     */
+    static int parseUInt32(String text) throws NumberFormatException {
+        return (int) parseInteger(text, false, false);
+    }
+
+    /**
+     * Parse a 64-bit signed integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively.
+     */
+    static long parseInt64(String text) throws NumberFormatException {
+        return parseInteger(text, true, true);
+    }
+
+    /**
+     * Parse a 64-bit unsigned integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively. The result is coerced to a (signed) {@code long}
+     * when returned since Java has no unsigned long type.
+     */
+    static long parseUInt64(String text) throws NumberFormatException {
+        return parseInteger(text, false, true);
+    }
+
+    private static long parseInteger(String text, boolean isSigned, boolean isLong) throws NumberFormatException {
+        int pos = 0;
+
+        boolean negative = false;
+        if (text.startsWith("-", pos)) {
+            if (!isSigned) {
+                throw new NumberFormatException("Number must be positive: " + text);
+            }
+            ++pos;
+            negative = true;
+        }
+
+        int radix = 10;
+        if (text.startsWith("0x", pos)) {
+            pos += 2;
+            radix = 16;
+        } else if (text.startsWith("0", pos)) {
+            radix = 8;
+        }
+
+        String numberText = text.substring(pos);
+
+        long result = 0;
+        if (numberText.length() < 16) {
+            // Can safely assume no overflow.
+            result = Long.parseLong(numberText, radix);
+            if (negative) {
+                result = -result;
+            }
+
+            // Check bounds.
+            // No need to check for 64-bit numbers since they'd have to be 16 chars
+            // or longer to overflow.
+            if (!isLong) {
+                if (isSigned) {
+                    if ((result > Integer.MAX_VALUE) || (result < Integer.MIN_VALUE)) {
+                        throw new NumberFormatException("Number out of range for 32-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if ((result >= (1L << 32)) || (result < 0)) {
+                        throw new NumberFormatException("Number out of range for 32-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            }
+        } else {
+            BigInteger bigValue = new BigInteger(numberText, radix);
+            if (negative) {
+                bigValue = bigValue.negate();
+            }
+
+            // Check bounds.
+            if (!isLong) {
+                if (isSigned) {
+                    if (bigValue.bitLength() > 31) {
+                        throw new NumberFormatException("Number out of range for 32-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if (bigValue.bitLength() > 32) {
+                        throw new NumberFormatException("Number out of range for 32-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            } else {
+                if (isSigned) {
+                    if (bigValue.bitLength() > 63) {
+                        throw new NumberFormatException("Number out of range for 64-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if (bigValue.bitLength() > 64) {
+                        throw new NumberFormatException("Number out of range for 64-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            }
+
+            result = bigValue.longValue();
+        }
+
+        return result;
+    }
+}

Plik diff jest za duży
+ 1209 - 0
app/src/main/java/com/googlecode/protobuf/format/JavaPropsFormat.java


Plik diff jest za duży
+ 1513 - 0
app/src/main/java/com/googlecode/protobuf/format/JsonFormat.java


+ 568 - 0
app/src/main/java/com/googlecode/protobuf/format/JsonJacksonFormat.java

@@ -0,0 +1,568 @@
+package com.googlecode.protobuf.format;
+/* 
+   Copyright (c) 2011 NeuStar, Inc. All Rights Reserved.
+
+   Redistribution and use in source and binary forms, with or without modification, 
+    are permitted provided that the following conditions are met:
+
+        * Redistributions of source code must retain the above copyright notice, 
+          this list of conditions and the following disclaimer.
+        * Redistributions in binary form must reproduce the above copyright notice, 
+          this list of conditions and the following disclaimer in the documentation 
+          and/or other materials provided with the distribution.
+        * Neither the name of the NeuStar, Inc. nor the names of its contributors 
+          may be used to endorse or promote products derived from this software 
+          without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+import static com.googlecode.protobuf.format.util.TextUtils.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.*;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+import com.googlecode.protobuf.format.util.TextUtils;
+
+/**
+ * Provide ascii text parsing and formatting support for proto2 instances. The implementation
+ * largely follows google/protobuf/text_format.cc.
+ * <p>
+ * (c) 2011 Neustar, Inc. All Rights Reserved.
+ *
+ * @author jeffrey.damick@neustar.biz Jeffrey Damick
+ *         Based on the original code by:
+ * @author eliran.bivas@gmail.com Eliran Bivas
+ * @author aantonov@orbitz.com Alex Antonov
+ *         <p>
+ * @author wenboz@google.com Wenbo Zhu
+ * @author kenton@google.com Kenton Varda
+ */
+public class JsonJacksonFormat extends ProtobufFormatter {
+    private static JsonFactory jsonFactory = new JsonFactory();
+    private static final long MAX_UINT_VALUE = (((long) Integer.MAX_VALUE) << 1) + 1;
+    private static final BigInteger MAX_ULONG_VALUE =
+            BigInteger.valueOf(Long.MAX_VALUE).shiftLeft(1).add(BigInteger.ONE);
+
+    /**
+     * Outputs a Smile representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public void print(final Message message, OutputStream output, Charset cs) throws IOException {
+        JsonGenerator generator = createGenerator(output);
+    	print(message, generator);
+    	generator.close();
+    }
+
+    /**
+     * Outputs a Smile representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public void print(Message message, JsonGenerator generator) throws IOException {
+    	generator.writeStartObject();
+    	printMessage(message, generator);
+        generator.writeEndObject();
+        generator.flush();
+    }
+
+    /**
+     * Outputs a Smile representation of {@code fields} to {@code output}.
+     */
+    public void print(final UnknownFieldSet fields, OutputStream output, Charset cs) throws IOException {
+    	JsonGenerator generator = createGenerator(output);
+    	generator.writeStartObject();
+    	printUnknownFields(fields, generator);
+        generator.writeEndObject();
+        generator.close();
+    }
+
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     * @throws IOException
+     */
+    public void merge(InputStream input, Charset cs,
+    		ExtensionRegistry extensionRegistry, Message.Builder builder) throws IOException {
+
+    	JsonParser parser = jsonFactory.createJsonParser(input);
+    	merge(parser, extensionRegistry, builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     * @throws IOException
+     */
+    public void merge(JsonParser parser,
+    						 ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws IOException {
+
+        JsonToken token = parser.nextToken();
+        if (token.equals(JsonToken.START_OBJECT)) {
+        	token = parser.nextToken();
+        }
+        while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+        	mergeField(parser, extensionRegistry, builder);
+        	token = parser.nextToken();
+        }
+
+        // Test to make sure the tokenizer has reached the end of the stream.
+        if (parser.nextToken() != null) {
+            throw new RuntimeException("Expecting the end of the stream, but there seems to be more data!  Check the input for a valid JSON format.");
+        }
+    }
+
+
+
+    protected JsonGenerator createGenerator(OutputStream output) throws IOException {
+    	JsonGenerator generator = jsonFactory.createJsonGenerator(output, JsonEncoding.UTF8);
+    	generator.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
+    	return generator;
+    }
+
+
+    protected void printMessage(Message message, JsonGenerator generator) throws IOException {
+
+        for (Iterator<Map.Entry<FieldDescriptor, Object>> iter = message.getAllFields().entrySet().iterator(); iter.hasNext();) {
+            Map.Entry<FieldDescriptor, Object> field = iter.next();
+            printField(field.getKey(), field.getValue(), generator);
+        }
+        printUnknownFields(message.getUnknownFields(), generator);
+    }
+
+    public void printField(FieldDescriptor field, Object value, JsonGenerator generator) throws IOException {
+
+        printSingleField(field, value, generator);
+    }
+
+    private void printSingleField(FieldDescriptor field,
+                                         Object value,
+                                         JsonGenerator generator) throws IOException {
+        if (field.isExtension()) {
+            // We special-case MessageSet elements for compatibility with proto1.
+            if (field.getContainingType().getOptions().getMessageSetWireFormat()
+                && (field.getType() == FieldDescriptor.Type.MESSAGE) && (field.isOptional())
+                // object equality
+                && (field.getExtensionScope() == field.getMessageType())) {
+                generator.writeFieldName(field.getMessageType().getFullName());
+            } else {
+            	// extensions will have '.' in them, while normal fields wont..
+            	generator.writeFieldName(field.getFullName());
+            }
+        } else {
+            if (field.getType() == FieldDescriptor.Type.GROUP) {
+                // Groups must be serialized with their original capitalization.
+                generator.writeFieldName(field.getMessageType().getName());
+            } else {
+                generator.writeFieldName(field.getName());
+            }
+        }
+
+        // Done with the name, on to the value
+        if (field.isRepeated()) {
+            // Repeated field. Print each element.
+            generator.writeStartArray();
+            for (Iterator<?> iter = ((List<?>) value).iterator(); iter.hasNext();) {
+                printFieldValue(field, iter.next(), generator);
+            }
+            generator.writeEndArray();
+        } else {
+            printFieldValue(field, value, generator);
+        }
+    }
+
+    private void printFieldValue(FieldDescriptor field, Object value, JsonGenerator generator) throws IOException {
+    	// TODO: look at using field.getType().getJavaType(), to simplify this..
+    	switch (field.getType()) {
+            case INT32:
+            case SINT32:
+            case SFIXED32:
+            	generator.writeNumber((Integer)value);
+            	break;
+
+            case INT64:
+            case SINT64:
+            case SFIXED64:
+            	generator.writeNumber((Long)value);
+            	break;
+
+            case FLOAT:
+            	generator.writeNumber((Float)value);
+            	break;
+
+            case DOUBLE:
+            	generator.writeNumber((Double)value);
+            	break;
+
+            case BOOL:
+                // Good old toString() does what we want for these types.
+                generator.writeBoolean((Boolean)value);
+                break;
+
+            case UINT32:
+            case FIXED32:
+                //generator.writeNumber(Integer.toUnsignedLong((Integer)value));
+                generator.writeNumber(Long.parseLong(value.toString()));
+                break;
+
+            case UINT64:
+            case FIXED64:
+                generator.writeNumber(unsignedLong((Long) value));
+                break;
+
+            case STRING:
+            	generator.writeString((String) value);
+                break;
+
+            case BYTES: {
+            	// Here we break with JsonFormat - since there is an issue with non-utf8 bytes..
+            	generator.writeBinary(((ByteString)value).toByteArray());
+                break;
+            }
+
+            case ENUM: {
+            	generator.writeString(((EnumValueDescriptor) value).getName());
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+            	generator.writeStartObject();
+                printMessage((Message) value, generator);
+                generator.writeEndObject();
+                break;
+        }
+    }
+
+    protected void printUnknownFields(UnknownFieldSet unknownFields, JsonGenerator generator) throws IOException {
+        for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
+            UnknownFieldSet.Field field = entry.getValue();
+
+            generator.writeArrayFieldStart(entry.getKey().toString());
+            for (long value : field.getVarintList()) {
+                generator.writeNumber(value);
+            }
+            for (int value : field.getFixed32List()) {
+                generator.writeNumber(value);
+            }
+            for (long value : field.getFixed64List()) {
+                generator.writeNumber(value);
+            }
+            for (ByteString value : field.getLengthDelimitedList()) {
+            	// here we break with the JsonFormat to support non-utf8 bytes
+            	generator.writeBinary(value.toByteArray());
+            }
+            for (UnknownFieldSet value : field.getGroupList()) {
+                generator.writeStartObject();
+                printUnknownFields(value, generator);
+                generator.writeEndObject();
+            }
+            generator.writeEndArray();
+        }
+    }
+
+
+
+    // =================================================================
+    // Parsing
+
+
+    /**
+     * Parse a single field from {@code parser} and merge it into {@code builder}. If a ',' is
+     * detected after the field ends, the next field will be parsed automatically
+     * @throws IOException
+     * @throws JsonParseException
+     */
+    protected void mergeField(JsonParser parser,
+                                   ExtensionRegistry extensionRegistry,
+                                   Message.Builder builder) throws JsonParseException, IOException {
+        FieldDescriptor field = null;
+        Descriptor type = builder.getDescriptorForType();
+        boolean unknown = false;
+        ExtensionRegistry.ExtensionInfo extension = null;
+        JsonToken token = parser.getCurrentToken();
+
+        if (token != null) {
+            String name = parser.getCurrentName();
+
+            if (name.contains(".")) {
+            	// should be an extension
+            	extension = extensionRegistry.findExtensionByName(name);
+                if (extension == null) {
+                    throw new RuntimeException("Extension \""
+                    		+ name + "\" not found in the ExtensionRegistry.");
+                } else if (extension.descriptor.getContainingType() != type) {
+                    throw new RuntimeException("Extension \"" + name
+                    		+ "\" does not extend message type \""
+                    		+ type.getFullName() + "\".");
+                }
+
+            	field = extension.descriptor;
+            } else {
+            	field = type.findFieldByName(name);
+            }
+
+            // Group names are expected to be capitalized as they appear in the
+            // .proto file, which actually matches their type names, not their field
+            // names.
+            if (field == null) {
+                // Explicitly specify US locale so that this code does not break when
+                // executing in Turkey.
+                String lowerName = name.toLowerCase(Locale.US);
+                field = type.findFieldByName(lowerName);
+                // If the case-insensitive match worked but the field is NOT a group,
+                if ((field != null) && (field.getType() != FieldDescriptor.Type.GROUP)) {
+                    field = null;
+                }
+            }
+            // Again, special-case group names as described above.
+            if ((field != null) && (field.getType() == FieldDescriptor.Type.GROUP)
+                && !field.getMessageType().getName().equals(name)
+                && !field.getMessageType().getFullName().equalsIgnoreCase(name) /* extension */) {
+                field = null;
+            }
+
+            // Last try to lookup by field-index if 'name' is numeric,
+            // which indicates a possible unknown field
+            if (field == null && TextUtils.isDigits(name)) {
+                field = type.findFieldByNumber(Integer.parseInt(name));
+                unknown = true;
+            }
+
+            // no throwing exceptions if field not found, since it could be a different version.
+            if (field == null) {
+            	UnknownFieldSet.Builder unknownsBuilder = UnknownFieldSet.newBuilder();
+            	handleMissingField(name, parser, extensionRegistry, unknownsBuilder);
+            	builder.setUnknownFields(unknownsBuilder.build());
+            }
+        }
+
+        if (field != null) {
+        	token = parser.nextToken();
+
+            boolean array = token.equals(JsonToken.START_ARRAY);
+
+            if (array) {
+            	token = parser.nextToken();
+                while (!token.equals(JsonToken.END_ARRAY)) {
+                    handleValue(parser, extensionRegistry, builder, field, extension, unknown);
+                    token = parser.nextToken();
+                }
+            } else {
+                handleValue(parser, extensionRegistry, builder, field, extension, unknown);
+            }
+        }
+    }
+
+    private void handleMissingField(String fieldName, JsonParser parser,
+                                           ExtensionRegistry extensionRegistry,
+                                           UnknownFieldSet.Builder builder) throws IOException {
+
+        JsonToken token = parser.nextToken();
+        if (token.equals(JsonToken.START_OBJECT)) {
+            // Message structure
+        	token = parser.nextToken(); // skip name
+        	while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+                handleMissingField(fieldName, parser, extensionRegistry, builder);
+                token = parser.nextToken(); // get } or field name
+            }
+        } else if (token.equals(JsonToken.START_ARRAY)) {
+            // Collection
+            do {
+                handleMissingField(fieldName, parser, extensionRegistry, builder);
+                token = parser.getCurrentToken(); // got value or ]
+            } while (token != null && !token.equals(JsonToken.END_ARRAY));
+        } else {
+            // Primitive value
+        	// NULL, INT, BOOL, STRING
+        	// nothing to do..
+        }
+    }
+
+    private void handleValue(JsonParser parser,
+                                    ExtensionRegistry extensionRegistry,
+                                    Message.Builder builder,
+                                    FieldDescriptor field,
+                                    ExtensionRegistry.ExtensionInfo extension,
+                                    boolean unknown) throws IOException {
+
+        Object value = null;
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            value = handleObject(parser, extensionRegistry, builder, field, extension, unknown);
+        } else {
+            value = handlePrimitive(parser, field);
+        }
+        if (value != null) {
+            if (field.isRepeated()) {
+                builder.addRepeatedField(field, value);
+            } else {
+                builder.setField(field, value);
+            }
+        }
+    }
+
+    private Object handlePrimitive(JsonParser parser, FieldDescriptor field) throws IOException {
+        Object value = null;
+
+        JsonToken token = parser.getCurrentToken();
+
+        if (token.equals(JsonToken.VALUE_NULL)) {
+            return value;
+        }
+
+        switch (field.getType()) {
+            case INT32:
+            case SINT32:
+            case SFIXED32:
+            	value = parser.getIntValue();
+                break;
+
+            case INT64:
+            case SINT64:
+            case SFIXED64:
+            	value = parser.getLongValue();
+                break;
+
+            case UINT32:
+            case FIXED32:
+            	long valueLong = parser.getLongValue();
+            	if (valueLong < 0 || valueLong > MAX_UINT_VALUE) {
+            		throw new NumberFormatException("Number must be positive: " + valueLong);
+            	}
+            	value = (int) valueLong;
+                break;
+
+            case UINT64:
+            case FIXED64:
+            	BigInteger valueBigInt = parser.getBigIntegerValue();
+                // valueBigInt < 0 || valueBigInt > MAX_ULONG_VALUE
+            	if (valueBigInt.compareTo(BigInteger.ZERO) == -1 || valueBigInt.compareTo(MAX_ULONG_VALUE) == 1) {
+            		throw new NumberFormatException("Number must be positive: " + valueBigInt);
+            	}
+            	value = valueBigInt.longValue();
+                break;
+
+            case FLOAT:
+            	value = parser.getFloatValue();
+                break;
+
+            case DOUBLE:
+            	value = parser.getDoubleValue();
+                break;
+
+            case BOOL:
+            	value = parser.getBooleanValue();
+                break;
+
+            case STRING:
+            	value = parser.getText();
+                break;
+
+            case BYTES:
+            	value = ByteString.copyFrom(parser.getBinaryValue());
+                break;
+
+            case ENUM: {
+                EnumDescriptor enumType = field.getEnumType();
+                if (token.equals(JsonToken.VALUE_NUMBER_INT)) {
+                    int number = parser.getIntValue();
+                    value = enumType.findValueByNumber(number);
+                    if (value == null) {
+                        throw new RuntimeException("Enum type \""
+                        		+ enumType.getFullName()
+                        		+ "\" has no value with number "
+                        		+ number + ".");
+                    }
+                } else {
+                    String id = parser.getText();
+                    value = enumType.findValueByName(id);
+                    if (value == null) {
+                    	throw new RuntimeException("Enum type \""
+                    			+ enumType.getFullName()
+                    			+ "\" has no value named \""
+                    			+ id + "\".");
+                    }
+                }
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+                throw new RuntimeException("Can't get here.");
+        }
+        return value;
+    }
+
+
+    private Object handleObject(JsonParser parser,
+                                       ExtensionRegistry extensionRegistry,
+                                       Message.Builder builder,
+                                       FieldDescriptor field,
+                                       ExtensionRegistry.ExtensionInfo extension,
+                                       boolean unknown) throws IOException {
+
+        Message.Builder subBuilder;
+        if (extension == null) {
+            subBuilder = builder.newBuilderForField(field);
+        } else {
+            subBuilder = extension.defaultInstance.newBuilderForType();
+        }
+
+        JsonToken token = parser.getCurrentToken();
+        if (JsonToken.VALUE_NULL == token) {
+            return null;
+        }
+
+        if (unknown) {
+        	ByteString data = ByteString.copyFrom(parser.getBinaryValue());
+            try {
+                subBuilder.mergeFrom(data);
+                return subBuilder.build();
+            } catch (InvalidProtocolBufferException e) {
+                throw new RuntimeException("Failed to build " + field.getFullName() + " from " + data);
+            }
+        }
+
+        //token = parser.nextToken();
+        if (token.equals(JsonToken.START_OBJECT)) {
+	        token = parser.nextToken();
+	        while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+	            mergeField(parser, extensionRegistry, subBuilder);
+	            token = parser.nextToken();
+	        }
+        }
+        return subBuilder.build();
+    }
+
+}

+ 156 - 0
app/src/main/java/com/googlecode/protobuf/format/ProtobufFormatter.java

@@ -0,0 +1,156 @@
+/**
+ * Copyright 2000-2011 NeuStar, Inc. All rights reserved.
+ * NeuStar, the Neustar logo and related names and logos are registered
+ * trademarks, service marks or tradenames of NeuStar, Inc. All other
+ * product names, company names, marks, logos and symbols may be trademarks
+ * of their respective owners.
+ */
+
+package com.googlecode.protobuf.format;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+import com.googlecode.protobuf.format.JavaPropsFormat.ParseException;
+
+public abstract class ProtobufFormatter {
+    private Charset defaultCharset = Charset.defaultCharset();
+
+    /**
+     * Set the default character set to use for input / output data streams
+     * @param cs the character set to use by default, when unspecified
+     */
+    public void setDefaultCharset(Charset cs) {
+        defaultCharset = cs;
+    }
+    
+    /**
+     * Get the default character set to use for input / output streams
+     * @return the character set to use by default, when unspecified
+     */
+    public Charset getDefaultCharset() {
+        return defaultCharset;
+    }
+	
+	/**
+	 * @see print(Message, OutputStream, Charset)
+	 * @param message the protobuf message to format
+	 * @param output the stream to write the formatted message using the default charset
+	 * @throws IOException
+	 */
+	public void print(final Message message, OutputStream output) throws IOException {
+		print(message, output, defaultCharset);
+	}
+	
+	/**
+	 * Outputs a textual representation of the Protocol Message supplied into
+	 * the parameter output. (This representation is the new version of the
+	 * classic "ProtocolPrinter" output from the original Protocol Buffer system)
+	 * 
+	 * @param message the protobuf message to format
+	 * @param output the stream to write the formatted message
+	 * @param cs the character set to use
+	 * @throws IOException
+	 */
+	abstract public void print(final Message message, OutputStream output, Charset cs) throws IOException;
+
+	
+	/**
+	 * @see print(UnknownFieldSet, OutputStream, Charset)
+	 * @param fields unknown fields to format
+	 * @param output output the stream to write the formatted message using the default charset
+	 * @throws IOException
+	 */
+	public void print(final UnknownFieldSet fields, OutputStream output) throws IOException {
+		print(fields, output, defaultCharset);
+	}
+
+	/**
+	 * @param fields unknown fields to format
+	 * @param output output the stream to write the formatted message
+	 * @param cs the character set to use
+	 * @throws IOException
+	 */
+	abstract public void print(final UnknownFieldSet fields, OutputStream output, Charset cs) throws IOException;
+	
+
+	/**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+	public String printToString(final Message message) {
+		try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            print(message, out, defaultCharset);
+            out.flush();
+            return out.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+	}
+	
+	/**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+	public String printToString(final UnknownFieldSet fields) {
+		try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            print(fields, out, defaultCharset);
+            out.flush();
+            return out.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+	}
+	
+	/**
+     * Thrown when parsing an invalid text format message.
+     */
+    public static class ParseException extends IOException {
+    	private static final long serialVersionUID = 1L;
+
+		public ParseException(String message) {
+            super(message);
+        }
+    }
+	
+	
+	/**
+	 * Parse a text-format message from {@code input} and merge the contents
+	 * into {@code builder}.
+	 */
+	abstract public void merge(final InputStream input, Charset cs,
+			ExtensionRegistry extensionRegistry, 
+			final Message.Builder builder) throws IOException;
+
+	
+	/**
+	 * Parse a text-format message from {@code input} and merge the contents
+	 * into {@code builder}.
+	 */
+	public void merge(final InputStream input, Charset cs, 
+			final Message.Builder builder) throws IOException {
+		
+		merge(input, cs, ExtensionRegistry.getEmptyRegistry(), builder);
+	}
+	
+	public void merge(final InputStream input, 
+			final Message.Builder builder) throws IOException {
+		
+		merge(input, defaultCharset, 
+				ExtensionRegistry.getEmptyRegistry(), builder);
+	}
+	
+	public void merge(final InputStream input,
+			ExtensionRegistry extensionRegistry, 
+			final Message.Builder builder) throws IOException {
+		merge(input, defaultCharset, extensionRegistry, builder);
+	}
+}

+ 72 - 0
app/src/main/java/com/googlecode/protobuf/format/util/HexUtils.java

@@ -0,0 +1,72 @@
+/* 
+	Copyright (c) 2009, protobuf-java-format
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, 
+	are permitted provided that the following conditions are met:
+
+		* Redistributions of source code must retain the above copyright notice, 
+		  this list of conditions and the following disclaimer.
+		* Redistributions in binary form must reproduce the above copyright notice, 
+		  this list of conditions and the following disclaimer in the documentation 
+		  and/or other materials provided with the distribution.
+		* Neither the name of the protobuf-java-format nor the names of its contributors 
+		  may be used to endorse or promote products derived from this software 
+		  without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+	A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+	OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package com.googlecode.protobuf.format.util;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Provide hex utility for converting bytes to hex string
+ * <p>
+ * (c) 2009-10 protobuf-java-format. All Rights Reserved.
+ *
+ * @author eliran.bivas@gmail.com Eliran Bivas
+ *         <p>
+ *         Based on the original code by:
+ * 		   http://rgagnon.com/javadetails/java-0596.html
+ */
+public final class HexUtils {
+
+	static final byte[] HEX_CHARS = { (byte) '0', (byte) '1', (byte) '2',
+			(byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
+			(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
+			(byte) 'd', (byte) 'e', (byte) 'f' };
+	
+	public static String getHexString(byte raw, int minLength) {
+		byte[] hex = new byte[2];
+		int index = 0;
+		int v = raw & 0xFF;
+		hex[index++] = HEX_CHARS[v >>> 4];
+		hex[index++] = HEX_CHARS[v & 0xF];
+		try {
+			String hexString = new String(hex, "ASCII");
+			StringBuilder builder = new StringBuilder();
+			if ( hexString.length() < minLength) {
+				int hexLength = minLength - hexString.length();
+				while ( hexLength > 0) {
+					builder.append('0');
+					hexLength--;
+				}
+			}
+			return builder.append(hexString).toString();
+		} catch (UnsupportedEncodingException e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+}

+ 439 - 0
app/src/main/java/com/googlecode/protobuf/format/util/TextUtils.java

@@ -0,0 +1,439 @@
+/**
+ * Copyright 2000-2011 NeuStar, Inc. All rights reserved.
+ * NeuStar, the Neustar logo and related names and logos are registered
+ * trademarks, service marks or tradenames of NeuStar, Inc. All other
+ * product names, company names, marks, logos and symbols may be trademarks
+ * of their respective owners.
+ */
+
+package com.googlecode.protobuf.format.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.regex.Pattern;
+
+import com.google.protobuf.ByteString;
+
+/**
+ * Utilities for coercing types
+ * largely follows google/protobuf/text_format.cc.
+ */
+public class TextUtils {
+    private static final Pattern DOUBLE_INFINITY = 
+            Pattern.compile("-?inf(inity)?", Pattern.CASE_INSENSITIVE);
+    private static final Pattern FLOAT_INFINITY = 
+          Pattern.compile("-?inf(inity)?f?", Pattern.CASE_INSENSITIVE);
+    private static final Pattern FLOAT_NAN = 
+          Pattern.compile("nanf?", Pattern.CASE_INSENSITIVE);
+    private static final Pattern DIGITS = 
+            Pattern.compile("[0-9]", Pattern.CASE_INSENSITIVE);
+    
+	/**
+     * Convert an unsigned 64-bit integer to a string.
+     */
+	 public static String unsignedToString(final long value) {
+        if (value >= 0) {
+            return Long.toString(value);
+        } else {
+            // Pull off the most-significant bit so that BigInteger doesn't think
+            // the number is negative, then set it again using setBit().
+            return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL).setBit(63).toString();
+        }
+    }
+	 
+    /**
+     * Convert an unsigned 32-bit integer to a string.
+     */
+    public static String unsignedToString(final int value) {
+        if (value >= 0) {
+            return Integer.toString(value);
+        } else {
+            return Long.toString((value) & 0x00000000FFFFFFFFL);
+        }
+    }
+
+    /**
+     * Convert an unsigned 64-bit integer to a {@link BigInteger}.
+     */
+    public static BigInteger unsignedLong(long value) {
+        if (value < 0) {
+            // Pull off the most-significant bit so that BigInteger doesn't think
+            // the number is negative, then set it again using setBit().
+            return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL).setBit(63);
+        }
+        return BigInteger.valueOf(value);
+    }
+
+    /** 
+     * Is this a hex digit? 
+     */
+    public static boolean isHex(final char c) {
+      return ('0' <= c && c <= '9') ||
+             ('a' <= c && c <= 'f') ||
+             ('A' <= c && c <= 'F');
+    }
+    
+    /** 
+     * Is this an octal digit? 
+     */
+    public static boolean isOctal(final char c) {
+      return '0' <= c && c <= '7';
+    }
+
+    /**
+     * Interpret a character as a digit (in any base up to 36) and return the
+     * numeric value.  This is like {@code Character.digit()} but we don't accept
+     * non-ASCII digits.
+     */
+    public static int digitValue(final char c) {
+      if ('0' <= c && c <= '9') {
+        return c - '0';
+      } else if ('a' <= c && c <= 'z') {
+        return c - 'a' + 10;
+      } else {
+        return c - 'A' + 10;
+      }
+    }
+    
+    public static boolean isDigits(final String text) {
+        return DIGITS.matcher(text).matches();
+    }
+    
+    private static final int BUFFER_SIZE = 4096;
+
+    // TODO(chrisn): See if working around java.io.Reader#read(CharBuffer)
+    // overhead is worthwhile
+    public static StringBuilder toStringBuilder(Readable input) throws IOException {
+        StringBuilder text = new StringBuilder();
+        CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
+        while (true) {
+            int n = input.read(buffer);
+            if (n == -1) {
+                break;
+            }
+            buffer.flip();
+            text.append(buffer, 0, n);
+        }
+        return text;
+    }
+    
+    public static InputStream toInputStream(String input) {
+    	return toInputStream(input, Charset.defaultCharset());
+    }
+    
+    public static InputStream toInputStream(String input, Charset cs) {
+        return new ByteArrayInputStream(input.getBytes(cs));
+    }
+    
+    
+    
+    /**
+     * If the next token is a double and return its value.
+     * Otherwise, throw a {@link NumberFormatException}.
+     */
+    public static double parseDouble(final String text) throws NumberFormatException {
+      // We need to parse infinity and nan separately because
+      // Double.parseDouble() does not accept "inf", "infinity", or "nan".
+      if (DOUBLE_INFINITY.matcher(text).matches()) {
+        final boolean negative = text.startsWith("-");
+        return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+      }
+      if (text.equalsIgnoreCase("nan")) {
+        return Double.NaN;
+      }
+
+      final double result = Double.parseDouble(text);
+      return result;
+    }
+
+    /**
+     * Parse a float and return its value.
+     * Otherwise, throw a {@link NumberFormatException}.
+     */
+    public static float parseFloat(final String text) throws NumberFormatException {
+      // We need to parse infinity and nan separately because
+      // Float.parseFloat() does not accept "inf", "infinity", or "nan".
+      if (FLOAT_INFINITY.matcher(text).matches()) {
+        final boolean negative = text.startsWith("-");
+        return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
+      }
+      if (FLOAT_NAN.matcher(text).matches()) {
+        return Float.NaN;
+      }
+
+      final float result = Float.parseFloat(text);
+      return result;
+    }
+    
+    /**
+     * Parse a boolean and return its value.
+     * Otherwise, throw a {@link IllegalArgumentException}.
+     */
+    public static boolean parseBoolean(final String text) throws IllegalArgumentException {
+      if (text.equalsIgnoreCase("true") || text.equalsIgnoreCase("t") ||
+              text.equals("1")) {
+        return true;
+      } else if (text.equalsIgnoreCase("false") || text.equalsIgnoreCase("f") ||
+              text.equals("0")) {
+        return false;
+      } else {
+        throw new IllegalArgumentException("Expected \"true\" or \"false\".");
+      }
+    }
+
+    
+    /**
+     * Parse a 32-bit signed integer from the text.  Unlike the Java standard
+     * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+     * and "0" to signify hexidecimal and octal numbers, respectively.
+     */
+    public static int parseInt32(final String text) throws NumberFormatException {
+      return (int) parseInteger(text, true, false);
+    }
+
+    /**
+     * Parse a 32-bit unsigned integer from the text.  Unlike the Java standard
+     * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+     * and "0" to signify hexidecimal and octal numbers, respectively.  The
+     * result is coerced to a (signed) {@code int} when returned since Java has
+     * no unsigned integer type.
+     */
+    public static int parseUInt32(final String text) throws NumberFormatException {
+      return (int) parseInteger(text, false, false);
+    }
+
+    /**
+     * Parse a 64-bit signed integer from the text.  Unlike the Java standard
+     * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+     * and "0" to signify hexidecimal and octal numbers, respectively.
+     */
+    public static long parseInt64(final String text) throws NumberFormatException {
+      return parseInteger(text, true, true);
+    }
+
+    /**
+     * Parse a 64-bit unsigned integer from the text.  Unlike the Java standard
+     * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+     * and "0" to signify hexidecimal and octal numbers, respectively.  The
+     * result is coerced to a (signed) {@code long} when returned since Java has
+     * no unsigned long type.
+     */
+    public static long parseUInt64(final String text) throws NumberFormatException {
+      return parseInteger(text, false, true);
+    }
+
+    public static long parseInteger(final String text,
+            final boolean isSigned, final boolean isLong) throws NumberFormatException {
+      int pos = 0;
+
+      boolean negative = false;
+      if (text.startsWith("-", pos)) {
+        if (!isSigned) {
+          throw new NumberFormatException("Number must be positive: " + text);
+        }
+        ++pos;
+        negative = true;
+      }
+
+      int radix = 10;
+      if (text.startsWith("0x", pos)) {
+        pos += 2;
+        radix = 16;
+      } else if (text.startsWith("0", pos)) {
+        radix = 8;
+      }
+
+      final String numberText = text.substring(pos);
+
+      long result = 0;
+      if (numberText.length() < 16) {
+        // Can safely assume no overflow.
+        result = Long.parseLong(numberText, radix);
+        if (negative) {
+          result = -result;
+        }
+
+        // Check bounds.
+        // No need to check for 64-bit numbers since they'd have to be 16 chars
+        // or longer to overflow.
+        if (!isLong) {
+          if (isSigned) {
+            if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
+              throw new NumberFormatException(
+                "Number out of range for 32-bit signed integer: " + text);
+            }
+          } else {
+            if (result >= (1L << 32) || result < 0) {
+              throw new NumberFormatException(
+                "Number out of range for 32-bit unsigned integer: " + text);
+            }
+          }
+        }
+      } else {
+        BigInteger bigValue = new BigInteger(numberText, radix);
+        if (negative) {
+          bigValue = bigValue.negate();
+        }
+
+        // Check bounds.
+        if (!isLong) {
+          if (isSigned) {
+            if (bigValue.bitLength() > 31) {
+              throw new NumberFormatException(
+                "Number out of range for 32-bit signed integer: " + text);
+            }
+          } else {
+            if (bigValue.bitLength() > 32) {
+              throw new NumberFormatException(
+                "Number out of range for 32-bit unsigned integer: " + text);
+            }
+          }
+        } else {
+          if (isSigned) {
+            if (bigValue.bitLength() > 63) {
+              throw new NumberFormatException(
+                "Number out of range for 64-bit signed integer: " + text);
+            }
+          } else {
+            if (bigValue.bitLength() > 64) {
+              throw new NumberFormatException(
+                "Number out of range for 64-bit unsigned integer: " + text);
+            }
+          }
+        }
+
+        result = bigValue.longValue();
+      }
+
+      return result;
+    }
+    
+    /**
+     * Escapes bytes in the format used in protocol buffer text format, which is the same as the
+     * format used for C string literals. All bytes that are not printable 7-bit ASCII characters
+     * are escaped, as well as backslash, single-quote, and double-quote characters. Characters for
+     * which no defined short-hand escape sequence is defined will be escaped using 3-digit octal
+     * sequences.
+     */
+    public static String escapeBytes(final ByteString input) {
+        final StringBuilder builder = new StringBuilder(input.size());
+        for (int i = 0; i < input.size(); i++) {
+          final byte b = input.byteAt(i);
+          switch (b) {
+            // Java does not recognize \a or \v, apparently.
+            case 0x07: builder.append("\\a" ); break;
+            case '\b': builder.append("\\b" ); break;
+            case '\f': builder.append("\\f" ); break;
+            case '\n': builder.append("\\n" ); break;
+            case '\r': builder.append("\\r" ); break;
+            case '\t': builder.append("\\t" ); break;
+            case 0x0b: builder.append("\\v" ); break;
+            case '\\': builder.append("\\\\"); break;
+            case '\'': builder.append("\\\'"); break;
+            case '"' : builder.append("\\\""); break;
+            default:
+              // Note:  Bytes with the high-order bit set should be escaped.  Since
+              //   bytes are signed, such bytes will compare less than 0x20, hence
+              //   the following line is correct.
+              if (b >= 0x20) {
+                builder.append((char) b);
+              } else {
+                builder.append('\\');
+                builder.append((char) ('0' + ((b >>> 6) & 3)));
+                builder.append((char) ('0' + ((b >>> 3) & 7)));
+                builder.append((char) ('0' + (b & 7)));
+              }
+              break;
+          }
+        }
+        return builder.toString();
+    }
+    
+    /**
+     * Un-escape a byte sequence as escaped using
+     * {@link #escapeBytes(ByteString)}.  Two-digit hex escapes (starting with
+     * "\x") are also recognized.
+     */
+    public static ByteString unescapeBytes(final CharSequence charString) {
+      // First convert the Java characater sequence to UTF-8 bytes.
+      ByteString input = ByteString.copyFromUtf8(charString.toString());
+      // Then unescape certain byte sequences introduced by ASCII '\\'.  The valid
+      // escapes can all be expressed with ASCII characters, so it is safe to
+      // operate on bytes here.
+      //
+      // Unescaping the input byte array will result in a byte sequence that's no
+      // longer than the input.  That's because each escape sequence is between
+      // two and four bytes long and stands for a single byte.
+      final byte[] result = new byte[input.size()];
+      int pos = 0;
+      for (int i = 0; i < input.size(); i++) {
+        byte c = input.byteAt(i);
+        if (c == '\\') {
+          if (i + 1 < input.size()) {
+            ++i;
+            c = input.byteAt(i);
+            if (isOctal((char)c)) {
+              // Octal escape.
+              int code = digitValue((char) c);
+              if (i + 1 < input.size() && isOctal((char) input.byteAt(i + 1))) {
+                ++i;
+                code = code * 8 + digitValue((char) input.byteAt(i));
+              }
+              if (i + 1 < input.size() && isOctal((char) input.byteAt(i + 1))) {
+                ++i;
+                code = code * 8 + digitValue((char) input.byteAt(i));
+              }
+              // TODO: Check that 0 <= code && code <= 0xFF.
+              result[pos++] = (byte)code;
+            } else {
+              switch (c) {
+                case 'a' : result[pos++] = 0x07; break;
+                case 'b' : result[pos++] = '\b'; break;
+                case 'f' : result[pos++] = '\f'; break;
+                case 'n' : result[pos++] = '\n'; break;
+                case 'r' : result[pos++] = '\r'; break;
+                case 't' : result[pos++] = '\t'; break;
+                case 'v' : result[pos++] = 0x0b; break;
+                case '\\': result[pos++] = '\\'; break;
+                case '\'': result[pos++] = '\''; break;
+                case '"' : result[pos++] = '\"'; break;
+
+                case 'x':
+                  // hex escape
+                  int code = 0;
+                  if (i + 1 < input.size() && isHex((char) input.byteAt(i + 1))) {
+                    ++i;
+                    code = digitValue((char) input.byteAt(i));
+                  } else {
+                    throw new IllegalArgumentException(
+                        "Invalid escape sequence: '\\x' with no digits");
+                  }
+                  if (i + 1 < input.size() && isHex((char) input.byteAt(i + 1))) {
+                    ++i;
+                    code = code * 16 + digitValue((char) input.byteAt(i));
+                  }
+                  result[pos++] = (byte)code;
+                  break;
+
+                default:
+                  throw new IllegalArgumentException(
+                      "Invalid escape sequence: '\\" + (char)c + '\'');
+              }
+            }
+          } else {
+            throw new IllegalArgumentException(
+                "Invalid escape sequence: '\\' at end of string.");
+          }
+        } else {
+          result[pos++] = c;
+        }
+      }
+
+      return ByteString.copyFrom(result, 0, pos);
+    }
+
+}

+ 311 - 0
app/src/main/java/com/kfzs/duanduan/ActAccountManage.java

@@ -0,0 +1,311 @@
+package com.kfzs.duanduan;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.StringRes;
+import android.support.design.widget.AppBarLayout;
+import android.support.v4.widget.NestedScrollView;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.kfzs.duanduan.data.graph.KFZSUserHelper;
+import com.kfzs.duanduan.data.graph.provider.user.UserBean;
+import com.kfzs.duanduan.event.AccountManagementEvent;
+import com.kfzs.duanduan.event.ReStartEvent;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.kfzs.duanduan.utils.sys.HomeListenByBroadcast;
+import com.kfzs.duanduan.fragment.ManagementAccountFragment;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import mdl.sinlov.android.log.ALog;
+
+public class ActAccountManage extends BaseCompatActivity {
+    public static final int JOB_FINISH_SELF_BY_ERROR = -2;
+    public static final int JOB_FINISH_SELF_BY_SUCCESS = -1;
+    public static final int JOB_CHANGE_TITLE = 1;
+    public static final int JOB_CODE_LOGIN = 2;
+    public static final int JOB_NEW_ACCOUNT = 3;
+    public static final int JOB_NEW_ACCOUNT_SUCCESS = 4;
+    public static final int JOB_REPLACE_HEAD_ACCOUNT = 5;
+    public static final int JOB_CHANGE_ACCOUNT_SHOW_LIST = 6;
+    public static final int JOB_CHANGE_ACCOUNT_BY_CHECK = 7;
+    public static final int JOB_CHANGE_ACCOUNT_CERTIFICATION = 8;
+    public static final int JOB_CHANGE_ACCOUNT_CERTIFICATION_SUCCESS = 9;
+    public static final int JOB_CHANGE_ACCOUNT_CERTIFICATION_CHECK = 10;
+    public static final int JOB_NEW_ACCOUNT_CERTIFICATION = 11;
+    public static final int JOB_REMOVE_ACCOUNT = 12;
+    public static final int JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD_CHECK = 13;
+    public static final int JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD = 14;
+    public static final int JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD_SUCCESS = 15;
+    public static final String KEY_SKIP_JOB_CODE = ActAccountManage.class.getCanonicalName() + ".job";
+    public static final String KEY_CHANGE_ACCOUNT_BY_ACTION = "key:change:account:by:action";
+    public static final String EXTRAS_NEED_GET_TOKEN = "extras:act:game:certification:need:get:token:string";
+    public static final String EXTRAS_NEED_GET_UID = "extras:act:game:certification:need:get:uid:string";
+    public static final String EXTRAS_NEED_GET_NICKNAME = "extras:act:game:certification:need:get:nickname:string";
+    public static final String EXTRAS_NEED_GET_OPENID = "extras:act:game:certification:need:get:openid:string";
+    @BindView(R.id.fl_act_management_account_replace_fgt)
+    FrameLayout flActManagementAccountReplaceFgt;
+    @BindView(R.id.nsv_content_management_account)
+    NestedScrollView nsvContentManagementAccount;
+
+    private String titleString = "";
+    private Bundle extras;
+    private HomeListenByBroadcast homeListenByBroadcast;
+    public boolean isCertification = false;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        homeListenByBroadcast = new HomeListenByBroadcast(this);
+        EventBus.getDefault().register(this);
+        setContentView(R.layout.activity_management_account);
+
+        ButterKnife.bind(this);
+        TitleBarUtils.getInstance().setTitleFinish(this)
+                .setTitle(this, getString(R.string.title_management_activity_account));
+        initListeners();
+        extras = getIntent().getExtras();
+        if (extras != null) {
+            int skipCode = extras.getInt(KEY_SKIP_JOB_CODE, 0);
+            AccountManagementEvent event = new AccountManagementEvent();
+            event.setSkipCode(skipCode);
+            filterSkipJobByCode(event);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        homeListenByBroadcast.start();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        homeListenByBroadcast.stop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+    private void filterSkipJobByCode(final AccountManagementEvent accountManagementEvent) {
+        int skipCode = accountManagementEvent.getSkipCode();
+        ALog.i("accountManagementEvent skipCode: " + skipCode);
+        switch (skipCode) {
+            case JOB_CHANGE_TITLE:
+                setActionBarTitle(accountManagementEvent.getTitleID());
+                break;
+            case JOB_FINISH_SELF_BY_ERROR:
+                ALog.d("error: " + accountManagementEvent.getMsg());
+                showToast(accountManagementEvent.getMsg());
+                ActAccountManage.this.finish();
+                break;
+            case JOB_FINISH_SELF_BY_SUCCESS:
+                ALog.d("success: " + accountManagementEvent.getMsg());
+                showToast(accountManagementEvent.getMsg());
+                ActAccountManage.this.finish();
+                break;
+            case JOB_CODE_LOGIN:
+                Bundle loginBundle = new Bundle();
+                loginBundle.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_LOGIN);
+                skip2Activity(ActAuth.class, loginBundle);
+                ActAccountManage.this.finish();
+                break;
+            case JOB_CHANGE_ACCOUNT_SHOW_LIST:
+                Bundle caShowList = new Bundle(extras);
+                caShowList.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_DEFAULT);
+                replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), caShowList, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CHANGE_ACCOUNT_BY_CHECK:
+                Bundle changeAccountByCheck = new Bundle(extras);
+                changeAccountByCheck.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REPLACE_HEAD);
+                changeAccountByCheck.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, accountManagementEvent.getNewUid());
+                replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), changeAccountByCheck, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CHANGE_ACCOUNT_CERTIFICATION:
+                isCertification = true;
+                Bundle changeAccountCModeBundle = new Bundle(extras);
+                changeAccountCModeBundle.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REPLACE_HEAD_CERTIFICATION);
+                changeAccountCModeBundle.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, accountManagementEvent.getNewUid());
+                replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), changeAccountCModeBundle, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CHANGE_ACCOUNT_CERTIFICATION_SUCCESS:
+                extras.putInt(ActGameCertification.SKIP_CODE_USER_BEHAVIOR, ActGameCertification.JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS);
+                extras.putString(ActGameCertification.EXTRAS_NEED_GET_TOKEN, accountManagementEvent.getToken());
+                skip2Activity(ActGameCertification.class, extras);
+                ActAccountManage.this.finish();
+                break;
+            case JOB_CHANGE_ACCOUNT_CERTIFICATION_CHECK:
+                Bundle checkChangeAccountCModeBundle = new Bundle(extras);
+                checkChangeAccountCModeBundle.putString(EXTRAS_NEED_GET_TOKEN, accountManagementEvent.getToken());
+                checkChangeAccountCModeBundle.putString(EXTRAS_NEED_GET_UID, accountManagementEvent.getNewUid() + "");
+                checkChangeAccountCModeBundle.putString(EXTRAS_NEED_GET_NICKNAME, accountManagementEvent.getNickName());
+                checkChangeAccountCModeBundle.putString(EXTRAS_NEED_GET_OPENID, accountManagementEvent.getOpenId());
+                checkChangeAccountCModeBundle.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REPLACE_HEAD_CERTIFICATION_CHECK);
+                int newUid = accountManagementEvent.getNewUid();
+                if (newUid == 0) {
+                    newUid = extras.getInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, 0);
+                }
+                checkChangeAccountCModeBundle.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, newUid);
+                replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), checkChangeAccountCModeBundle, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_NEW_ACCOUNT:
+                Bundle newAccount = new Bundle();
+                newAccount.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_NEW_ACCOUNT);
+                skip2Activity(ActAuth.class, newAccount);
+                //                ActAccountManage.this.finish();
+                break;
+            case JOB_NEW_ACCOUNT_CERTIFICATION:
+                Bundle newAccountCertification = new Bundle(extras);
+                newAccountCertification.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_LOGIN_CERTIFICATION);
+                skip2Activity(ActAuth.class, newAccountCertification);
+                ActAccountManage.this.finish();
+                break;
+            case JOB_NEW_ACCOUNT_SUCCESS:
+                Bundle newAccountSuccess = new Bundle();
+                newAccountSuccess.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_NEW_ACCOUNT_CHECK);
+                replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), newAccountSuccess, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_REPLACE_HEAD_ACCOUNT:
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setTitle("是否切换帐户");
+                builder.setMessage("昵称:" + accountManagementEvent.getNickName() + "\n");
+                builder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        Bundle replaceHeadAccount = new Bundle();
+                        replaceHeadAccount.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REPLACE_HEAD);
+                        replaceHeadAccount.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, accountManagementEvent.getNewUid());
+                        replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(),
+                                replaceHeadAccount, false,
+                                AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                    }
+                });
+                builder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+
+                    }
+                });
+                builder.create().show();
+                break;
+            case JOB_REMOVE_ACCOUNT:
+                AlertDialog.Builder removeBuilder = new AlertDialog.Builder(this);
+                removeBuilder.setTitle("是否移除帐户");
+                removeBuilder.setMessage("昵称:" + accountManagementEvent.getNickName() + "\n");
+                removeBuilder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        Bundle replaceHeadAccount = new Bundle();
+                        replaceHeadAccount.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REMOVE_ONE);
+                        replaceHeadAccount.putInt(ManagementAccountFragment.KEY_ACCOUNT_REMOVE_UID, accountManagementEvent.getNewUid());
+                        replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), replaceHeadAccount, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                    }
+                });
+                removeBuilder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+
+                    }
+                });
+                removeBuilder.create().show();
+                break;
+            case JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD_CHECK:
+                final int uuid = extras.getInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID);
+                String uNickName = "";
+                List<UserBean> userBeen = KFZSUserHelper.getInstance().checkOutFullUser(app);
+                for (UserBean user : userBeen) {
+                    if (uuid == user.getUid()) {
+                        uNickName = user.getNickname();
+                    }
+                }
+                AlertDialog.Builder builderChangePwd = new AlertDialog.Builder(this);
+                builderChangePwd.setTitle("是否换帐户,来修改密码");
+                builderChangePwd.setMessage("昵称:" + uNickName + "\n");
+                builderChangePwd.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        Bundle replaceHeadAccount = new Bundle(extras);
+                        replaceHeadAccount.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REPLACE_HEAD_CERTIFICATION_CHECK_CHANGE_PASSWORD_CHECK);
+                        replaceHeadAccount.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, uuid);
+                        replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), replaceHeadAccount, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                    }
+                });
+                builderChangePwd.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        extras.putInt(ActGameCertification.SKIP_CODE_USER_BEHAVIOR, ActGameCertification.JOB_CHANGE_ACCOUNT_CANCEL);
+                        skip2Activity(ActGameCertification.class, extras);
+                        ActAccountManage.this.finish();
+                    }
+                });
+                builderChangePwd.create().show();
+                break;
+            case JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD:
+                Bundle changeAccountSuccessByChangePassword = new Bundle(extras);
+                changeAccountSuccessByChangePassword.putInt(ManagementAccountFragment.KEY_ACCOUNT_TYPE, ManagementAccountFragment.TYPE_ACCOUNT_REPLACE_HEAD_CERTIFICATION_CHECK_CHANGE_PASSWORD);
+                replaceSupportFragment(R.id.fl_act_management_account_replace_fgt, new ManagementAccountFragment(), changeAccountSuccessByChangePassword, false, AccountManagementEvent.CHANGE_ACCOUNT, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD_SUCCESS:
+                Bundle changePsd = new Bundle(extras);
+                changePsd.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_SELF_CHANGE_PASSWORD_BY_CERTIFICATION);
+                skip2Activity(ActAuth.class, changePsd);
+                this.finish();
+                break;
+            default:
+                showToast("默认帐户管理行为为错误行为,关闭管理界面");
+                ActAccountManage.this.finish();
+                break;
+        }
+    }
+
+    private void initListeners() {
+        homeListenByBroadcast.setOnHomeBtnPressListener(new HomeListenByBroadcast.OnHomeBtnPressListener() {
+            @Override
+            public void onHomeBtnPress() {
+                ActAccountManage.this.finish();
+            }
+
+            @Override
+            public void onHomeBtnLongPress() {
+
+            }
+        });
+    }
+
+    @Subscribe
+    public void onEventMainThread(ReStartEvent startEvent) {
+        if (startEvent != null && startEvent.isReStart()) {
+            Intent intent = getIntent();
+            finish();
+            startActivity(intent);
+        }
+    }
+
+    @Subscribe
+    public void onEventMainThread(AccountManagementEvent accountManagementEvent) {
+        filterSkipJobByCode(accountManagementEvent);
+    }
+
+
+    protected void setActionBarTitle(@StringRes int resId) {
+        titleString = getString(resId);
+        TitleBarUtils.getInstance().setTitle(this, titleString);
+    }
+}

+ 374 - 0
app/src/main/java/com/kfzs/duanduan/ActAuth.java

@@ -0,0 +1,374 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.widget.NestedScrollView;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.volleyplus.Response;
+import com.android.volleyplus.VolleyError;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.appstore.utils.restful.KFZSRestfulError;
+import com.kfzs.appstore.utils.restful.KFZSRestfulErrorCallBack;
+import com.kfzs.appstore.utils.sys.InputMethodUtils;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.data.graph.provider.user.UserBean;
+import com.kfzs.duanduan.datashare.CertificationDog;
+import com.kfzs.duanduan.datashare.KFZSDDCertificationDog;
+import com.kfzs.duanduan.db.UserGraphUtils;
+import com.kfzs.duanduan.event.AuthEvent;
+import com.kfzs.duanduan.event.ReStartEvent;
+import com.kfzs.duanduan.fragment.AuthBindPhoneFragment;
+import com.kfzs.duanduan.fragment.ChangeSelfNickNameFragment;
+import com.kfzs.duanduan.fragment.ChangeSelfPasswordFragment;
+import com.kfzs.duanduan.fragment.ManagementAccountFragment;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.UserOuterClass;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.sheep.jiuyan.samllsheep.R;
+import com.umeng.socialize.UMShareAPI;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import mdl.sinlov.android.log.ALog;
+
+/**
+ * 这些类写得就像一索粑粑,sign.Diao
+ */
+public class ActAuth extends BaseCompatActivity {
+    public static final int JOB_CHANGE_EXTRAS = 0;
+    public static final int JOB_CODE_SELF_UPDATE_USER_INFO_HEAD = -1;
+    public static final int JOB_CODE_SELF_UPDATE_USER_INFO_HEAD_CERTIFICATION_NO_NEED_LOGIN = -2;
+    public static final int JOB_FINISH_SELF = 1;
+    public static final int JOB_CHANGE_TITLE = 1 << 1;
+    public static final int JOB_CODE_LOGIN = 2 << 1;
+    public static final int JOB_CODE_LOGIN_CERTIFICATION = 3 << 1;
+    public static final int JOB_CODE_LOGIN_CERTIFICATION_SUCCESS = 4 << 1;
+    public static final int JOB_CODE_REGISTER_PHONE = 5 << 1;
+    public static final int JOB_CODE_REGISTER_ORDINARY = 6 << 1;
+    public static final int JOB_CODE_FORGET_PASSWORD = 7 << 1;
+    public static final int JOB_CODE_NEW_ACCOUNT = 8 << 1;
+    public static final int JOB_CODE_NEW_ACCOUNT_SUCCESS = 9 << 1;
+    public static final int JOB_CODE_NEW_ACCOUNT_CERTIFICATION = 10 << 1;
+    public static final int JOB_CODE_NEW_ACCOUNT_CERTIFICATION_SUCCESS = 11 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_PASSWORD = 12 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_NICKNAME = 13 << 1;
+    public static final int JOB_CODE_SELF_BIND_PHONE = 14 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_PASSWORD_BY_CERTIFICATION = 15 << 1;
+    public static final int JOB_CODE_SELF_LOGIN_BY_CHANGE_PASSWORD_CERTIFICATION = 16 << 1;
+    public static final int JOB_CODE_SELF_BIND_PHONE_BY_CERTIFICATION = 17 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_NICK_NAME_BY_CERTIFICATION = 18 << 1;
+    public static final String KEY_SKIP_JOB_CODE = ActAuth.class.getCanonicalName() + ".job";
+
+    @BindView(R.id.fl_act_auth_replace_fgt)
+    FrameLayout flActAuthReplaceFgt;
+    @BindView(R.id.nsv_content_auth)
+    NestedScrollView nsvContentAuth;
+    private Bundle extras;
+    private String titleString;
+    private KFZSDDCertificationDog certificationDog;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        EventBus.getDefault().register(this);
+
+        setContentView(R.layout.activity_auth);
+        ButterKnife.bind(this);
+        certificationDog = KFZSDDCertificationDog.getInstance();
+        certificationDog.init(this.getApplication(), new CertificationDog() {
+            @Override
+            public void onCertificationCodeCallBack(User user, String gamePackageName, String gameCode, String extrasString) {
+                try {
+                    if (certificationDog != null) {
+                        certificationDog.doCertificationCancel();
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+            @Override
+            public void onCertificationSuccess() {
+                KFZSApp.getInstance().quit();
+
+            }
+
+            @Override
+            public void onCertificationCancel() {
+                KFZSApp.getInstance().quit();
+
+            }
+
+            @Override
+            public void onLoginJob() {
+
+            }
+
+            @Override
+            public void onError(int errorCode, String msg) {
+
+            }
+        });
+        TitleBarUtils.getInstance().setTitleListen(this, -1, new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                InputMethodUtils.closeInputPan(ActAuth.this);
+                //                ActAuth.this.finish();
+                try {
+                    if (certificationDog != null) {
+                        certificationDog.doCertificationCancel();
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                onBackPressed();
+                //finish();
+            }
+        });
+        extras = getIntent().getExtras();
+        if (extras != null) {
+            int skipCode = extras.getInt(KEY_SKIP_JOB_CODE, 0);
+            AuthEvent event = new AuthEvent();
+            event.setSkipCode(skipCode);
+            filterSkipJobByCode(event);
+        }
+        TitleBarUtils.getInstance().setRightBotton(this, "注册", -1,
+                new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        AuthEvent authEvent = new AuthEvent();
+                        authEvent.setSkipCode(ActAuth.JOB_CODE_REGISTER_PHONE);
+                        EventBus.getDefault().post(authEvent);
+                    }
+                });
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+    @Subscribe
+    public void onEventMainThread(AuthEvent authEvent) {
+        filterSkipJobByCode(authEvent);
+    }
+
+    private void filterSkipJobByCode(AuthEvent authEvent) {
+        int skipCode = authEvent.getSkipCode();
+        switch (skipCode) {
+            case JOB_CHANGE_TITLE:
+                titleString = getString(authEvent.getTitleID());
+                TitleBarUtils.getInstance().setTitle(ActAuth.this, titleString);
+                TitleBarUtils.getInstance().setRightBtnVisibility(ActAuth.this,
+                        authEvent.getTitleID() == R.string.title_user_activity_login ? View.VISIBLE : View.GONE);
+                break;
+            case JOB_FINISH_SELF:
+                removeAllFragment();
+                this.finish();
+                break;
+            case JOB_CHANGE_EXTRAS:
+                String extrasKey = authEvent.getExtrasKey();
+                String extrasValue = authEvent.getExtrasValue();
+                if (!TextUtils.isEmpty(extrasKey) && !TextUtils.isEmpty(extrasValue)) {
+                    extras.putString(extrasKey, extrasValue);
+                } else {
+                    ALog.w("empty extrasKey: " + extrasKey + " |extrasValue: " + extrasValue);
+                }
+                break;
+            case JOB_CODE_SELF_UPDATE_USER_INFO_HEAD:
+                updateHeadUserGraph(false, true);
+                break;
+            case JOB_CODE_SELF_UPDATE_USER_INFO_HEAD_CERTIFICATION_NO_NEED_LOGIN:
+                updateHeadUserGraph(true, false);
+                break;
+            case JOB_CODE_LOGIN:
+                SkipUtils.getInstance().goLogin(this);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_LOGIN_CERTIFICATION_SUCCESS:
+                extras.putInt(ActGameCertification.SKIP_CODE_USER_BEHAVIOR, ActGameCertification.JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS);
+                extras.putBoolean(getString(R.string.kfzs_duanduan_datashare_certificationed), authEvent.isAuth());
+                extras.putString(getString(R.string.kfzs_duanduan_datashare_certification_userid), String.valueOf(authEvent.getNewUid()));
+                extras.putString(getString(R.string.kfzs_duanduan_datashare_certification_token), authEvent.getToken());
+                skip2Activity(ActGameCertification.class, extras);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_LOGIN_CERTIFICATION:
+                SkipUtils.getInstance().goLogin(this, ActLogin.LOGIN_TYPE_IS_CERTIFICATION);
+                ActAuth.this.finish();
+                break;
+//            case JOB_CODE_REGISTER_PHONE:
+//                SkipUtils.getInstance().goRegist(this,ActLogin.LOGIN_TYPE_IS_CERTIFICATION);
+//                finish();
+//                break;
+//            case JOB_CODE_REGISTER_ORDINARY:
+//                SkipUtils.getInstance().goRegist(this,ActLogin.LOGIN_TYPE_IS_CERTIFICATION);
+//                finish();
+//                break;
+//          case JOB_CODE_FORGET_PASSWORD:
+//                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new AuthForgetPasswordFragment(),
+//                        true, AuthEvent.FORGET_PASSWORD_TAG, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+//                break;
+            case JOB_CODE_NEW_ACCOUNT:
+                SkipUtils.getInstance().goLogin(this, ActLogin.LOGIN_TYPE_CODE_IS_NEW_ACCOUNT);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_NEW_ACCOUNT_CERTIFICATION:
+                SkipUtils.getInstance().goLogin(this, ActLogin.LOGIN_TYPE_CODE_IS_NEW_ACCOUNT_CERTIFICATION);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_NEW_ACCOUNT_SUCCESS:
+                ReStartEvent event = new ReStartEvent();
+                event.setReStart(true);
+                EventBus.getDefault().post(event);
+                Bundle newAccountSuccess = new Bundle(extras);
+                newAccountSuccess.putInt(ActAccountManage.KEY_SKIP_JOB_CODE,
+                        ActAccountManage.JOB_NEW_ACCOUNT_SUCCESS);
+                skip2Activity(ActAccountManage.class, newAccountSuccess);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_NEW_ACCOUNT_CERTIFICATION_SUCCESS:
+                Bundle newAccountModeCSuccess = new Bundle(extras);
+                newAccountModeCSuccess.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, authEvent.getNewUid());
+                newAccountModeCSuccess.putInt(ActAccountManage.KEY_SKIP_JOB_CODE, ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION_CHECK);
+                skip2Activity(ActAccountManage.class, newAccountModeCSuccess);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_SELF_CHANGE_PASSWORD:
+                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new ChangeSelfPasswordFragment(), true, AuthEvent.CHANGE_PASSWORD, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CODE_SELF_CHANGE_NICKNAME:
+                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new ChangeSelfNickNameFragment(), true, AuthEvent.CHANGE_NICKNAME, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CODE_SELF_BIND_PHONE:
+                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new AuthBindPhoneFragment(), false, AuthEvent.CHANGE_NICKNAME, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CODE_SELF_CHANGE_PASSWORD_BY_CERTIFICATION:
+                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new ChangeSelfPasswordFragment(), extras, true, AuthEvent.CHANGE_PASSWORD, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CODE_SELF_LOGIN_BY_CHANGE_PASSWORD_CERTIFICATION:
+                SkipUtils.getInstance().goLogin(this, ActLogin.LOGIN_TYPE_IS_CERTIFICATION);
+                ActAuth.this.finish();
+                break;
+            case JOB_CODE_SELF_BIND_PHONE_BY_CERTIFICATION:
+                Bundle certificationBindPhoneBundle = new Bundle(extras);
+                certificationBindPhoneBundle.putInt(AuthBindPhoneFragment.KEY_BIND_TYPE, AuthBindPhoneFragment.BIND_TYPE_IS_CERTIFICATION);
+                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new AuthBindPhoneFragment(), certificationBindPhoneBundle, false, AuthEvent.CHANGE_NICKNAME, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CODE_SELF_CHANGE_NICK_NAME_BY_CERTIFICATION:
+                Bundle certificationChangeNickNameBundle = new Bundle(extras);
+                certificationChangeNickNameBundle.putInt(ChangeSelfNickNameFragment.KEY_CHANGE_TYPE, ChangeSelfNickNameFragment.CHANGE_TYPE_IS_CERTIFICATION);
+                replaceSupportFragment(R.id.fl_act_auth_replace_fgt, new ChangeSelfNickNameFragment(), certificationChangeNickNameBundle, true, AuthEvent.CHANGE_NICKNAME, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            default:
+                ALog.w("develop use error JOB Code: " + skipCode);
+                break;
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
+    }
+
+    private void updateHeadUserGraph(final boolean isCertification, final boolean isNeedLogin) {
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(app, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                needLogin(isCertification);
+            }
+        });
+        APIRequest userSelfRequest = APIRequestInstance.getReq(TAG, UrlBll.UserApi.SELF,
+                null, new OnHeadSessionUserGraph(isCertification, isNeedLogin), errorListener);
+        KFZSNetwork.addRequest(userSelfRequest);
+    }
+
+    private class OnHeadSessionUserGraph implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        private final boolean isCertification;
+        private final boolean isNeedLogin;
+
+        public OnHeadSessionUserGraph(boolean isCertification, boolean isNeedLogin) {
+            this.isCertification = isCertification;
+            this.isNeedLogin = isNeedLogin;
+        }
+
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    UserOuterClass.User user = apiResponse.getUser();
+                    if (user != null) {
+                        UserBean userGraph = UserGraphUtils.saveNewUserGraph(user);
+                        if (userGraph != null) {
+                            closeSelf(isNeedLogin, isCertification);
+                        } else {
+                            if (isNeedLogin) {
+                                needLogin(isCertification);
+                            }
+                        }
+                    } else {
+                        if (isNeedLogin) {
+                            needLogin(isCertification);
+                        }
+                    }
+                    break;
+                case ApiResponseOuterClass.Codes.Unauthorized_VALUE:
+                    ALog.d("popHeadToken: Unauthorized_VALUE");
+                    if (isNeedLogin) {
+                        needLogin(isCertification);
+                    }
+                    break;
+                default:
+                    if (isNeedLogin) {
+                        needLogin(isCertification);
+                    }
+                    break;
+            }
+
+        }
+    }
+
+    private void closeSelf(boolean isNeedLogin, boolean isCertification) {
+        if (isCertification && !isNeedLogin) {
+            extras.putBoolean(ActGameCertification.EXTRAS_NEED_GET_CODE, false);
+            skip2Activity(ActGameCertification.class, extras);
+            ActAuth.this.finish();
+        }
+        InputMethodUtils.closeInputPan(this);
+        this.finish();
+    }
+
+    private void needLogin(boolean isCertification) {
+        AuthEvent loginEvent = new AuthEvent();
+        if (isCertification) {
+            loginEvent.setSkipCode(JOB_CODE_LOGIN_CERTIFICATION);
+        } else {
+            loginEvent.setSkipCode(JOB_CODE_LOGIN);
+        }
+        EventBus.getDefault().post(loginEvent);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+            certificationDog.doCertificationCancel();
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+}

+ 427 - 0
app/src/main/java/com/kfzs/duanduan/ActDownloadMgr.java

@@ -0,0 +1,427 @@
+package com.kfzs.duanduan;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.kfzs.appstore.utils.adapter.OnMDLItemChildClickListener;
+import com.kfzs.duanduan.adp.DownloadMgrAdapter;
+import com.kfzs.duanduan.bean.CompareResult;
+import com.kfzs.duanduan.bean.DownloadStatus;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.datashare.provider.download.DownLoadInfo;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventDownloadHandler;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.services.DownloadTaskService;
+import com.kfzs.duanduan.utils.ApkUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.kfzs.duanduan.view.DialogStorageLow;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.wlf.filedownloader.DownloadFileInfo;
+import org.wlf.filedownloader.FileDownloader;
+import org.wlf.filedownloader.base.Log;
+import org.wlf.filedownloader.listener.OnDeleteDownloadFileListener;
+
+import java.io.File;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+/**
+ * Download manger activity
+ * Created by HooRang on 2017/4/10.
+ */
+
+public class ActDownloadMgr extends BaseCompatActivity {
+
+
+    @BindView(R.id.download_mgr_listview)
+    ListView lvDownloadMgr;
+
+    @BindView(R.id.download_mgr_empty_view)
+    View tvEmptyView;
+
+    /**
+     * Download manager list view data's adapter
+     */
+    DownloadMgrAdapter downloadMgrAdapter;
+
+    /**
+     * The service about persistence data and sqlite helper
+     */
+    DownloadTaskService downloadTaskService;
+
+    /**
+     * Data source
+     */
+    List<DownLoadInfo> downloadTasks;
+    private EventDownloadHandler.OnDownCallback mOnDownCallback;
+
+    //防止手抖,双击;
+    private boolean doubleKill = false;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_download_mgr);
+        TitleBarUtils.getInstance().setTitleFinish(this)
+                .setTitle(this, getString(R.string.label_download_mgr));
+
+        ButterKnife.bind(this);
+        EventBus.getDefault().register(this);
+
+        downloadTasks = new ArrayList<>();
+        downloadTaskService = new DownloadTaskService(this);
+
+        initControlsEvents();
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        setDownloadTaskData();
+    }
+
+    private void initControlsEvents() {
+
+        downloadMgrAdapter = new DownloadMgrAdapter(this);
+        lvDownloadMgr.setAdapter(downloadMgrAdapter);
+        downloadMgrAdapter.setOnItemChildClickListener(new OnMDLItemChildClickListener() {
+            @Override
+            public void onItemChildClick(ViewGroup parent, View childView, final int position) {
+                if (downloadTasks.size() <= position) {
+                    return;
+                }
+                final DownLoadInfo downloadTask = downloadTaskService.getDownloadTaskByUrl(downloadTasks.get(position).getMDownloadUrl());
+                if (null == downloadTask) {
+                    return;
+                }
+
+                switch (childView.getId()) {
+                    case R.id.download_mgr_ib_delete:
+                        if (!doubleKill) {
+                            doubleKill = true;
+                            downloadTaskItemEventDelete(downloadTask, position);
+                        }
+                        break;
+                    case R.id.download_mgr_btn_act:
+
+                        downloadTaskItemEventAction(downloadTask);
+                        break;
+                    case R.id.download_mgr_iv_icon:
+                        Intent intent = new Intent(ActDownloadMgr.this, ActGameDetails.class);
+                        intent.putExtra(KFIntentKeys.EXTRA_GAME_ID, String.valueOf(downloadTask.getMGameID()));
+                        startActivity(intent);
+                        break;
+                    default:
+
+                        break;
+                }
+            }
+        });
+    }
+
+    private void setDownloadTaskData() {
+        downloadTasks.clear();
+        downloadTasks.addAll(downloadTaskService.getAllDownloadTasks());
+
+        downloadMgrAdapter.clear();
+        downloadMgrAdapter.addMoreDatas(downloadTasks);
+        showDownloadTaskList(!downloadTasks.isEmpty());
+    }
+
+
+    /*@Subscribe
+    public void onEventMainThread(final DownloadStatus info) {
+        if (mOnDownCallback == null) {
+            mOnDownCallback = DownBtnUtils.installBtnStatus(downloadMgrAdapter.getmInstallButtonMgrMap());
+        }
+        EventDownloadHandler
+                .newInstance(this, mOnDownCallback)
+                .setmTag(TAG)
+                .handlDownloadResult(info);
+    }*/
+
+    @Subscribe
+    public void onEventMainThread(BigEvent bigEvent) {
+        if (bigEvent.getEventTypes() == EventTypes.STORAGE_LOW) {
+            DialogStorageLow.showDialog(this);
+        }
+    }
+
+    @Subscribe
+    public void onEventMainThread(final DownloadStatus info) {
+        EventDownloadHandler.newInstance(this, new EventDownloadHandler.OnDownCallback() {
+            @Override
+            public void downloading(String url, Integer progress) {
+                KFProgressButton targetBtn = (KFProgressButton) lvDownloadMgr.findViewWithTag(DownloadMgrAdapter.PUBLIC_TAG_PREFIX_BUTTON + url);
+                ProgressBar pbProgress = (ProgressBar) lvDownloadMgr.findViewWithTag(DownloadMgrAdapter.PUBLIC_TAG_PREFIX_PROGRESS + url);
+                TextView tvProgress = (TextView) lvDownloadMgr.findViewWithTag(DownloadMgrAdapter.PUBLIC_TAG_PREFIX_TEXTVIEW + url);
+                if (tvProgress == null) {
+                    return;
+                }
+                tvProgress.setText(strFormat(ActDownloadMgr.this, info.getFileDownloadedSize(),
+                        info.getFileTotalSize()));
+                pbProgress.setProgress(info.getDownloadPgrs());
+                targetBtn.setText(R.string.downloading);
+
+                setTaskStatusByDownloadUrl(url, DownloadTaskService.STATUS_ING, "");
+            }
+
+            @Override
+            public void downloadFinish(String downloadUrl) {
+                TextView tvProgress = (TextView) lvDownloadMgr.findViewWithTag(DownloadMgrAdapter.PUBLIC_TAG_PREFIX_TEXTVIEW + info.getDownloadUrl());
+                tvProgress.setText(R.string.download_completed);
+
+                setTaskStatusByDownloadUrl(info.getDownloadUrl(), DownloadTaskService.STATUS_FINISH, info.getApkPath());
+            }
+
+            @Override
+            public void downloadPause(String downloadUrl) {
+
+            }
+
+            @Override
+            public void downloadFail(String url) {
+                KFProgressButton targetBtn = (KFProgressButton) lvDownloadMgr.findViewWithTag(DownloadMgrAdapter.PUBLIC_TAG_PREFIX_BUTTON + url);
+                targetBtn.setText(R.string.download_fail);
+                setTaskStatusByDownloadUrl(url, DownloadTaskService.STATUS_FAIL, "");
+            }
+
+            @Override
+            public void downloadDelete(String downloadUrl) {
+
+            }
+        }).setmTag(TAG).handlDownloadResult(info);
+
+    }
+
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+    //删除任务;
+    private void downloadTaskItemEventDelete(DownLoadInfo downloadTask, int position) {
+        if (FileDownloader.getDownloadFile(downloadTask.getMDownloadUrl()) != null) {
+            FileDownloader.delete(downloadTask.getMDownloadUrl(), true, new DownloadTaskDeleteListener(position));
+        } else {
+            if (!TextUtils.isEmpty(downloadTask.getMApkPath())) {
+                new File(downloadTask.getMApkPath()).delete();
+            }
+            removeTask(position);
+        }
+        doubleKill = false;
+    }
+
+    private void downloadTaskItemEventAction(DownLoadInfo downloadTask) {
+        switch (downloadTask.getMStatus()) {
+            case DownloadTaskService.STATUS_INIT:
+                Log.d(TAG, "Still init status #" + downloadTask.getMDownloadUrl());
+                break;
+            case DownloadTaskService.STATUS_ING:
+                changeTaskPersistenceStatus(downloadTask.getMDownloadUrl(), DownloadTaskService.STATUS_PAUSE,
+                        downloadTask.getMPercent() == null ? 0 : downloadTask.getMPercent(), true);
+                break;
+            case DownloadTaskService.STATUS_PAUSE:
+                int currentDownloadTaskSize = downloadTaskService.getDownloadingTasksCount();
+                if (currentDownloadTaskSize >= KFZSApp.MAX_DOWNLOAD_TASK_SIZE) {
+                    String strPrompt = String.format(getString(R.string.toast_download_task_out_of_rang), KFZSApp.MAX_DOWNLOAD_TASK_SIZE + "");
+                    Toast.makeText(this, strPrompt, Toast.LENGTH_SHORT).show();
+                    return;
+                }
+                changeTaskPersistenceStatus(downloadTask.getMDownloadUrl(), DownloadTaskService.STATUS_ING,
+                        downloadTask.getMPercent() == null ? 0 : downloadTask.getMPercent(), false);
+                break;
+            case DownloadTaskService.STATUS_FAIL:
+                changeTaskPersistenceStatus(downloadTask.getMDownloadUrl(), DownloadTaskService.STATUS_INIT, 0, false);
+                if (null != downloadTask.getMTotalSize() && downloadTask.getMTotalSize() > HelperUtils.getFreeSpace()) {
+                    EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.STORAGE_LOW)
+                            .setData(downloadTask.getMGameName()));
+                }
+                break;
+            case DownloadTaskService.STATUS_FINISH:
+                boolean isPkgInstalled = ApkUtils.getInstance().isPkgInstalledRealTime(downloadTask.getMPackageName());
+                if (isPkgInstalled) {
+                    int apkStatus = ApkUtils.getInstance().comparePkgVersionCode(downloadTask.getMPackageName(), downloadTask.getMVersionCode());
+                    if (apkStatus == CompareResult.EQUALS || apkStatus == CompareResult.LT) {
+                        ApkUtils.openApplication(this, downloadTask.getMPackageName());
+                    } else {
+                        changeTaskPersistenceStatus(downloadTask.getMDownloadUrl(), DownloadTaskService.STATUS_ING, 1, false);
+                    }
+                } else {
+                    if (new File(downloadTask.getMApkPath()).exists()) {
+                        ApkUtils.installApk(this, downloadTask.getMApkPath());
+                    } else {
+                        restartTaskByDownloadUrl(downloadTask);
+                    }
+                }
+                break;
+            default:
+                Log.d(TAG, "Unknown task status#" + downloadTask.getMStatus());
+                break;
+        }
+    }
+
+    private class DownloadTaskDeleteListener implements OnDeleteDownloadFileListener {
+
+        private int position;
+
+        public DownloadTaskDeleteListener(int itemPosition) {
+            this.position = itemPosition;
+        }
+
+        @Override
+        public void onDeleteDownloadFilePrepared(DownloadFileInfo downloadFileInfo) {
+        }
+
+        @Override
+        public void onDeleteDownloadFileSuccess(DownloadFileInfo downloadFileInfo) {
+            removeTask(position);
+        }
+
+        @Override
+        public void onDeleteDownloadFileFailed(DownloadFileInfo downloadFileInfo, DeleteDownloadFileFailReason deleteDownloadFileFailReason) {
+
+        }
+    }
+
+
+    private void restartTaskByDownloadUrl(final DownLoadInfo task) {
+        FileDownloader.delete(task.getMDownloadUrl(), true, new OnDeleteDownloadFileListener() {
+
+            @Override
+            public void onDeleteDownloadFilePrepared(DownloadFileInfo downloadFileInfo) {
+            }
+
+            @Override
+            public void onDeleteDownloadFileSuccess(DownloadFileInfo downloadFileInfo) {
+                Log.d(TAG, "restartTaskByDownloadUrl#onDeleteDownloadFileSuccess");
+                // Clear old data
+                downloadTaskService.deleteDownloadTaskByDownloadUrl(task.getMDownloadUrl());
+                downloadTaskService.addDownloadTask(task);
+
+                setDownloadTaskData();
+                FileDownloader.start(task.getMDownloadUrl());
+            }
+
+            @Override
+            public void onDeleteDownloadFileFailed(DownloadFileInfo downloadFileInfo, DeleteDownloadFileFailReason deleteDownloadFileFailReason) {
+
+                Log.d(TAG, "restartTaskByDownloadUrl#onDeleteDownloadFileFailed");
+            }
+        });
+
+    }
+
+    private void changeTaskPersistenceStatus(String downloadUrl, int status, int percent, boolean bPauseTask) {
+        boolean isUpdate = downloadTaskService.setDownloadTaskStatus(downloadUrl, status);
+        if (isUpdate) {
+            setDownloadTaskData();
+            if (bPauseTask) {
+                FileDownloader.pause(downloadUrl);
+            } else {
+                FileDownloader.start(downloadUrl);
+
+            }
+            postDownloadTaskEvents(downloadUrl, status, percent);
+        }
+    }
+
+    private void setTaskStatusByDownloadUrl(String downloadUrl, int status, String apkPath) {
+        int iTempPosition = -1;
+        for (int position = 0; position < downloadTasks.size(); position++) {
+            DownLoadInfo task = downloadTasks.get(position);
+            if (downloadUrl.equals(task.getMDownloadUrl())) {
+                iTempPosition = position;
+                break;
+            }
+        }
+        if (iTempPosition < 0) {
+            return;
+        }
+
+        downloadTasks.get(iTempPosition).setMStatus(status);
+        downloadTasks.get(iTempPosition).setMApkPath(apkPath);
+    }
+
+    private void removeTask(int position) {
+        if (downloadTasks.size() == 0
+                || downloadTasks.size() < position - 1
+                || downloadTasks.get(position) == null) {
+            return;
+        }
+        final String targetUrl = downloadTasks.get(position).getMDownloadUrl();
+        if (TextUtils.isEmpty(targetUrl)) {
+            return;
+        }
+
+        boolean isSuccess = downloadTaskService.deleteDownloadTaskByDownloadUrl(targetUrl);
+        if (isSuccess) {
+            setDownloadTaskData();
+            //延时执行,不然删除消息可能比下载进度信息先到,导致删除后还提示安装中
+            new Handler().postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    postDownloadTaskEvents(targetUrl, DownloadTaskService.STATUS_DELETE, 0);
+                }
+            }, 500);
+        }
+    }
+
+
+    private void postDownloadTaskEvents(String targetUrl, int status, int percent) {
+        if ("".equals(targetUrl)) {
+            return;
+        }
+        DownloadStatus downloadStatusInfo = new DownloadStatus();
+        downloadStatusInfo.setStatus(status);
+        downloadStatusInfo.setDownloadUrl(targetUrl);
+        downloadStatusInfo.setDownloadPgrs(percent);
+        EventBus.getDefault().post(downloadStatusInfo);
+    }
+
+
+    public static String strFormat(Context context, Double fileDownloadSize, Double fileTotalSize) {
+        DecimalFormat df = new DecimalFormat("######0.0");
+        if (fileDownloadSize == null || fileTotalSize == null) {
+            return context.getString(R.string.calculating);
+        }
+        return df.format(fileDownloadSize) + "MB / " + fileTotalSize.intValue() + "MB";
+    }
+
+    private void showDownloadTaskList(boolean isShow) {
+        tvEmptyView.setVisibility(isShow ? View.GONE : View.VISIBLE);
+        lvDownloadMgr.setVisibility(!isShow ? View.GONE : View.VISIBLE);
+    }
+
+
+}
+
+
+
+
+
+
+

+ 240 - 0
app/src/main/java/com/kfzs/duanduan/ActDuJiaShouFa.java

@@ -0,0 +1,240 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RatingBar;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.appstore.utils.adapter.recyclerview.DividerItemDecoration;
+import com.kfzs.appstore.utils.adapter.recyclerview.OnItemClickListener;
+import com.kfzs.appstore.utils.adapter.recyclerview.RecyclerViewAdapter;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bean.DownloadStatus;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.event.EventDownloadHandler;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.NumberFormatUtils;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActDuJiaShouFa</p>
+ * @ <p>Description: 独家首发游戏页面,独家英文太复杂  exclusive</p>
+ * @ date:  2017/6/12 11:58
+ * @ QQ:    315096953
+ */
+
+public class ActDuJiaShouFa extends BaseCompatActivity {
+
+    private static final String TAG = ActDuJiaShouFa.class.getSimpleName();
+
+    public static final String INTENT_GAME = "INTENT_GAME";//传送过来的独家首发单游戏类,GameOuterClass.Game
+
+    private RecyclerViewAdapter mRecyAdpter;
+
+    private Map<String, InstallButtonUtils> mInstallButtonMgrMap = new HashMap<>();
+
+    private List<GameOuterClass.Game> mListGame = new ArrayList<>();
+
+    @BindView(R.id.list_activity_recommend_today)
+    RecyclerView mRecyView;
+
+    @BindView(R.id.toolbar_auth)
+    Toolbar mToolBar;
+
+    //独家首发游戏的View,如果没有传,就不显示。
+    @BindView(R.id.game_info_layout_content)
+    View mView;
+
+
+    private EventDownloadHandler.OnDownCallback mOnDownCallback;
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        EventBus.getDefault().register(this);
+        setContentView(R.layout.activity_recommend_today);
+        ButterKnife.bind(this);
+
+        mToolBar.setTitle(getString(R.string.sole_fist));
+        mToolBar.setNavigationIcon(R.drawable.ic_arrow_back_24dp);
+        mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                onBackPressed();
+            }
+        });
+
+        initDefaultGame();
+        DividerItemDecoration decor = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
+        decor.setSize(getResources().getDimensionPixelOffset(R.dimen.app_list_item_divider_size));
+        decor.setColor(getResources().getColor(R.color.theme_app_divider_color));
+        decor.setPaddingStart(getResources().getDimensionPixelOffset(R.dimen.app_list_item_divider_start));
+        decor.setPaddingEnd(getResources().getDimensionPixelOffset(R.dimen.app_list_item_divider_end));
+        mRecyView.setLayoutManager(new LinearLayoutManager(this));
+        mRecyView.addItemDecoration(decor);
+        doNetworkTask();
+    }
+
+
+    private void initDefaultGame() {
+        if (!getIntent().hasExtra(INTENT_GAME)) {
+            mView.setVisibility(View.GONE);
+            return;
+        }
+        final GameOuterClass.Game game = (GameOuterClass.Game) getIntent().getSerializableExtra(INTENT_GAME);
+
+        Glide.with(this).load(game.getIconImage())
+                .transform(new KFGlideRoundTransform(this, 5))
+                .into(ViewFindUtils.find(mView, R.id.img_logo, ImageView.class));
+
+        ViewFindUtils.find(mView, R.id.img_listview_item_game_info)
+                .setVisibility(game.getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        ViewFindUtils.find(mView, R.id.txt_list_item_game_info_title, TextView.class)
+                .setText(game.getGameName());
+        ViewFindUtils.find(mView, R.id.txt_list_item_game_info_type, TextView.class)
+                .setText(game.getTypeText());
+
+        String downloadCnt = String.format(getString(R.string.download_count),
+                game.getDownloadNum() + "");
+        ViewFindUtils.find(mView, R.id.txt_list_item_game_info_down_count, TextView.class)
+                .setText(downloadCnt + "");
+        ViewFindUtils.find(mView, R.id.ratbar_list_item_game_info, RatingBar.class)
+                .setRating(NumberFormatUtils.getDivideResult(game.getStar()));
+
+        ViewFindUtils.find(mView, R.id.game_info_layout_content).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                SkipUtils.getInstance().goGameDetails(ActDuJiaShouFa.this, game.getId());
+            }
+        });
+        DownBtnUtils.addDownloadBtnListener(ViewFindUtils.find(mView, R.id.btn_list_item_game_info,
+                KFProgressButton.class), this, mInstallButtonMgrMap, game, "DujiashoufaActivity_dujia");
+    }
+
+
+    /**
+     * 获取并加载游戏列表
+     */
+    private void doNetworkTask() {
+        HashMap<String, String> params = new HashMap<>();
+        params.put("page", UrlBll.AppStoreApi.PAGE_SOLE_GAME + "");
+
+        APIRequest bannerRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.AppStoreApi.GAME_LISTS, params, new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                mListGame.clear();
+                mListGame.addAll(apiResponse.getExclusiveStarting().getSpecialGameList());
+                mListGame.addAll(apiResponse.getExclusiveStarting().getGeneralGameList());
+
+                mRecyAdpter = new RecyclerViewAdapter<GameOuterClass.Game>(ActDuJiaShouFa.this
+                        , R.layout.listview_item_game_info, mListGame) {
+                    @Override
+                    public void convert(ViewHolder helper, GameOuterClass.Game model, int position) {
+
+                        helper.setText(R.id.txt_list_item_game_info_title, model.getGameName());
+                        helper.setText(R.id.txt_list_item_game_info_type, model.getTypeText());
+                        String downloadCnt = String.format(getString(R.string.download_count), String.valueOf(model.getDownloadNum()));
+                        helper.setText(R.id.txt_list_item_game_info_down_count, downloadCnt);
+
+                        RatingBar ratingBar = helper.getView(R.id.ratbar_list_item_game_info);
+                        ratingBar.setRating(NumberFormatUtils.getDivideResult(model.getStar()));
+                        Glide.with(mContext)
+                                .load(model.getIconImage())
+                                .transform(new KFGlideRoundTransform(mContext, 5))
+                                .into((ImageView) helper.getView(R.id.img_logo));
+
+                        /**
+                         * 初始化下载按钮的状态
+                         */
+                        DownBtnUtils.addDownloadBtnListener(helper.getView(R.id.btn_list_item_game_info, KFProgressButton.class)
+                                , ActDuJiaShouFa.this, mInstallButtonMgrMap, model, position + "");
+                    }
+                };
+
+                mRecyView.setAdapter(mRecyAdpter);
+                mRecyAdpter.setOnItemClickListener(new OnItemClickListener() {
+                    @Override
+                    public void onItemClick(ViewGroup parent, View view, Object o, int position) {
+                        Intent intent = new Intent(ActDuJiaShouFa.this, ActGameDetails.class);
+                        intent.putExtra(KFIntentKeys.EXTRA_GAME_ID, String.valueOf(mListGame.get(position).getId()));
+                        startActivity(intent);
+                    }
+
+                    @Override
+                    public boolean onItemLongClick(ViewGroup parent, View view, Object o, int position) {
+                        return false;
+                    }
+                });
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+            }
+
+        }, HelperUtils.makeErr(getString(R.string.toast_init_data_fail)));
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+
+    /**
+     * 更新下载列表进度等信息
+     *
+     * @param info
+     */
+    @Subscribe
+    public void onEventMainThread(final DownloadStatus info) {
+        if (mOnDownCallback == null) {
+            mOnDownCallback = DownBtnUtils.installBtnStatus(mInstallButtonMgrMap);
+        }
+        EventDownloadHandler
+                .newInstance(this, mOnDownCallback)
+                .setmTag(TAG)
+                .handlDownloadResult(info);
+    }
+
+    /**
+     * 反注册EventBus
+     */
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+}

+ 121 - 0
app/src/main/java/com/kfzs/duanduan/ActFeedback.java

@@ -0,0 +1,121 @@
+package com.kfzs.duanduan;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.proto.AdviceOuterClass;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.util.HashMap;
+
+/**
+ * zjb  2017-08-08
+ */
+public class ActFeedback extends BaseCompatActivity {
+
+    private EditText mEdtContact;
+    private EditText mEdtContent;
+    private String[] mTypes;
+    private int mIntSelectType = -1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_feedback);
+
+        TitleBarUtils.getInstance().setTitleFinish(this)
+                .setTitle(this, getString(R.string.nav_main_activity_action_feedback));
+        mEdtContact = (EditText) findViewById(R.id.btn_activity_feedback_contact);
+        mEdtContent = (EditText) findViewById(R.id.btn_activity_feedback_content);
+        mTypes = getResources().getStringArray(R.array.type_feedback);
+
+        findViewById(R.id.btn_activity_feedback).setOnClickListener(cls_Submit);
+
+        findViewById(R.id.txt_activity_feedback_type)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(final View v) {
+                        AlertDialog.Builder builder = new AlertDialog.Builder(ActFeedback.this);
+                        builder.setTitle("请选择反馈类型");
+                        builder.setSingleChoiceItems(mTypes, mIntSelectType, new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                mIntSelectType = which;
+                                ((TextView) v).setText(mTypes[which]);
+                                dialog.dismiss();
+                            }
+                        });
+                        builder.create().show();
+                    }
+                });
+    }
+
+
+    /**
+     * 提交
+     *
+     * @param view
+     */
+    private View.OnClickListener cls_Submit = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (!KFZSDDContentSession.getInstance().isHasHeadSession(ActFeedback.this)) {
+                showToast(getString(R.string.toast_user_login_pre));
+                SkipUtils.getInstance().goLogin(ActFeedback.this);
+                return;
+            }
+            if (mIntSelectType < 0) {
+                showToast("请选择反馈类型哦~");
+                return;
+            }
+            if (mEdtContent.length() < 1) {
+                showToast("请输入至少6字建议哦~");
+                return;
+            }
+            HashMap<String, String> params = new HashMap<>();
+            String token = KFZSDDContentSession.getInstance().findOutHeadSession(ActFeedback.this).getToken();
+            params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+
+            ApiRequestOuterClass.ApiRequest.Builder reqBuild = ApiRequestOuterClass.ApiRequest.newBuilder();
+            AdviceOuterClass.Advice.Builder builder
+                    = AdviceOuterClass.Advice.newBuilder();
+            builder.setAdviceContent(mEdtContent.getText().toString());
+            builder.setContactWay(mEdtContact.getText().toString());
+            builder.setType(mIntSelectType + 1);
+            reqBuild.setAdvice(builder);
+
+            APIRequest apiRequest = APIRequestInstance.postReq(TAG, UrlBll.AppStoreApi.ADVICE,
+                    params, reqBuild.build().toByteArray(), new ResponseNetworkTask() {
+                        @Override
+                        public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                            showToast("提交成功,感谢您的支持!");
+                            finish();
+                        }
+
+                        @Override
+                        public void onFail(int code, String msg) {
+                            showToast(msg);
+                        }
+                    }, HelperUtils.makeErr("网络错误,请稍后再试。"));
+            KFZSNetwork.addRequest(apiRequest);
+        }
+    };
+
+}

+ 639 - 0
app/src/main/java/com/kfzs/duanduan/ActGameCertification.java

@@ -0,0 +1,639 @@
+package com.kfzs.duanduan;
+
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.volleyplus.Response;
+import com.android.volleyplus.VolleyError;
+import com.kf.utils.ToastBuilder;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.appstore.utils.restful.KFZSRestfulError;
+import com.kfzs.appstore.utils.restful.KFZSRestfulErrorCallBack;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.data.graph.provider.current.Current;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.datashare.CertificationDog;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.KFZSDDCertificationDog;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.utils.ApkUtils;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.Sdk;
+import com.kfzs.duanduan.proto.UpdateContentOuterClass;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.dlg.UpdateUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.view.DialogUpdateFragment;
+import com.kfzs.duanduan.fragment.ManagementAccountFragment;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import mdl.sinlov.android.log.ALog;
+
+public class ActGameCertification extends BaseCompatActivity {
+
+    public static final String SKIP_CODE_USER_BEHAVIOR = "skip:code:act:game:certification:user:behavior";
+    public static final String EXTRAS_NEED_GET_CODE = "extras:act:game:certification:need:get:code:boolean";
+    public static final String EXTRAS_NEED_GET_TOKEN = "extras:act:game:certification:need:get:token:string";
+    public static final int JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS = 1 << 1;
+    public static final int JOB_CHANGE_ACCOUNT_CANCEL = 2 << 1;
+    public static final long SKIP_TIME = 3000;
+
+    @BindView(R.id.img_act_game_certification_self)
+    ImageView imgFgtGameCertificationSelf;
+    @BindView(R.id.img_act_game_certification_target)
+    ImageView imgFgtGameCertificationTarget;
+    @BindView(R.id.tv_act_game_certification_now)
+    TextView tvFgtGameCertificationNow;
+    @BindView(R.id.tv_act_game_certification_change_account)
+    TextView tvFgtGameCertificationChangeAccount;
+    @BindView(R.id.btn_act_game_certification)
+    Button btnFgtGameCertification;
+    @BindView(R.id.tv_act_game_certification_self)
+    TextView tvActGameCertificationSelf;
+    @BindView(R.id.tv_act_game_certification_target)
+    TextView tvActGameCertificationTarget;
+    @BindView(R.id.ll_act_game_certification_content)
+    LinearLayout llActGameCertificationContent;
+    private KFZSDDCertificationDog certificationDog;
+    private ProgressDialog progressDialog;
+    private boolean isAuthOutOfTime = false;
+    private boolean isLoginParamError = false;
+    private Bundle extras;
+    private String certificationKey;
+    private String extrasStr;
+    private int userBehavior;
+    private boolean isNeedGetCode = true;
+    private boolean cancelUpdateApp = false;
+
+    private UpdateContentOuterClass.UpdateContent mUpdateContent;
+    private String update_version_Name;
+    private String mStrUpdateDesc;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_game_certification);
+        //noinspection deprecation
+
+        ButterKnife.bind(this);
+        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        setSupportActionBar(toolbar);
+        ActionBar supportActionBar = getSupportActionBar();
+        if (null != supportActionBar) {
+            supportActionBar.setTitle(R.string.title_game_activity_certification);
+        }
+        extras = getIntent().getExtras();
+        if (extras != null) {
+            cancelUpdateApp = extras.getBoolean(getString(R.string.kfzs_duanduan_datashare_certificationed), false);
+            userBehavior = extras.getInt(SKIP_CODE_USER_BEHAVIOR, 0);
+            isNeedGetCode = extras.getBoolean(EXTRAS_NEED_GET_CODE, true);
+            certificationDog = KFZSDDCertificationDog.getInstance();
+            certificationDog.init(this.getApplication(), new GameDog());
+            ((KFZSApp) getApplication()).GameCode = extras.getString(getString(com.kfzs.duanduan.datashare.R.string.kfzs_duanduan_datashare_game_code), "");
+            progressDialog = new ProgressDialog(this);
+            progressDialog.setMessage(getString(R.string.dialog_progress_waiting));
+        } else {
+            showCertificationErrorAndExit("基础配置参数错误,请检查后再次请求授权!");
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        isAuthOutOfTime = false;
+        isLoginParamError = false;
+        if (isNeedGetCode && !cancelUpdateApp) {
+            popUpdateAPP();
+        } else {
+            checkCertification();
+        }
+    }
+
+    private void checkCertification() {
+        if (certificationDog != null) {
+            if (extras != null) {
+                certificationDog.doCertificationCode(extras);
+            } else {
+                showCertificationErrorAndExit("授权异常\n, 参数未传入");
+            }
+        } else {
+            showCertificationErrorAndExit("授权异常\n, 未初始化");
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        KFZSNetwork.stopByTag(TAG);
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (progressDialog != null)
+            progressDialog.dismiss();
+        super.onDestroy();
+    }
+
+    private void popUpdateAPP() {
+        Response.ErrorListener updateErrorListener = KFZSRestfulError.job(new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                showCertificationErrorAndExitApp("获取更新网络异常,取消授权 code: " + code);
+            }
+        });
+        HashMap<String, String> params = new HashMap<>();
+        String channelName = DataSave.getInstance().getChannelName();
+        params.put("cp_id", channelName);
+        ALog.d("channelName: " + channelName);
+        APIRequest updateAPP = APIRequestInstance.getReqUrl(TAG, UrlBll.VersionControlApi.APP_VERSION_INFO, params, new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                if (apiResponse.getUpdateContentsList().isEmpty()) {
+                    showCertificationErrorAndExitApp("获取更新数据异常,取消授权");
+                    return;
+                }
+                handleVersionCallBack(apiResponse.getUpdateContentsList().get(0));
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                showCertificationErrorAndExitApp("获取更新数据回调异常,取消授权\ncode" + code);
+            }
+
+        }, updateErrorListener);
+        KFZSNetwork.addRequest(updateAPP);
+    }
+
+    private void handleVersionCallBack(UpdateContentOuterClass.UpdateContent updateContent) {
+        String strUpdateDesc = updateContent.getContent();
+        if (TextUtils.isEmpty(strUpdateDesc)) {
+            showCertificationErrorAndExitApp("获取更新内容异常,取消授权");
+        } else {
+            this.mUpdateContent = updateContent;
+            mStrUpdateDesc = updateContent.getContent();
+            Boolean force = updateContent.getForce() == 1;
+            UpdateUtils.getInstance(this).setmUpdateSetting(updateSetting)
+                    .setmIsForceUpdate(force)
+                    .update(updateContent.getPackageName()
+                            , updateContent.getApkUrl(), updateContent.getVersionNum());
+        }
+    }
+
+    private UpdateUtils.UpdateSetting updateSetting = new UpdateUtils.UpdateSetting() {
+
+        @Override
+        public void updateForce() {
+            showForciblyUpdateUI(mStrUpdateDesc, true);
+        }
+
+        @Override
+        public void updateSilent() {
+
+        }
+
+        @Override
+        public void updateNormal() {
+            showForciblyUpdateUI(mStrUpdateDesc, false);
+        }
+
+        @Override
+        public void updateNo() {
+            checkCertification();
+        }
+
+        @Override
+        public void udateProcess(int process) {
+
+        }
+
+        @Override
+        public void updateComplete() {
+
+        }
+    };
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+            certificationDog.doCertificationCancel();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    private void showCertificationErrorAndExit(String errorMsg) {
+//        ToastBuilder.make(app, errorMsg, ToastBuilder.MIDDLE_TOAST_SINGLE);
+        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                ActGameCertification.this.finish();
+            }
+        }, SKIP_TIME);
+    }
+
+    private void showCertificationErrorAndExitApp(String errorMsg) {
+        ToastBuilder.make(app, errorMsg, ToastBuilder.MIDDLE_TOAST_SINGLE);
+        progressDialog.show();
+        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                ActGameCertification.this.finish();
+                KFZSApp.getInstance().quit();
+            }
+        }, SKIP_TIME);
+    }
+
+    private void initViewByBundle(String targetPackageName) {
+        llActGameCertificationContent.setVisibility(View.VISIBLE);
+        try {
+            Current lastUser = DDProviderHelper.getInstance().getLastUser(app);
+            String account = getString(R.string.str_act_certification_now_hint) + lastUser.getMNickName();
+            tvFgtGameCertificationNow.setText(account);
+            ApkUtils apkUtil = ApkUtils.getInstance();
+            Drawable selfIcon = apkUtil.getAppIconOnce(app, this.getPackageName());
+            if (selfIcon != null) {
+                imgFgtGameCertificationSelf.setImageDrawable(selfIcon);
+            }
+            String selfAPPName = apkUtil.getAppLabelOnce(app, this.getPackageName());
+            tvActGameCertificationSelf.setText(selfAPPName);
+            Drawable targetPackageNameIcon = apkUtil.getAppIconOnce(app, targetPackageName);
+            if (targetPackageNameIcon != null) {
+                imgFgtGameCertificationTarget.setImageDrawable(targetPackageNameIcon);
+            }
+            String targetAppName = apkUtil.getAppLabelOnce(app, targetPackageName);
+            tvActGameCertificationTarget.setText(targetAppName);
+        } catch (Exception e) {
+            e.printStackTrace();
+            showCertificationErrorAndExit("获取应用数据错误,取消授权!");
+        }
+    }
+
+    private void popSDKOut(User user, String gameCode) {
+        String token = user.getMToken();
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(app, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                showCertificationErrorAndExit("网络错误,检查网络后后再次请求授权");
+            }
+        });
+        if (TextUtils.isEmpty(token)) {
+            isLoginParamError = true;
+            certificationDog.doForceNeedReLogin();
+            return;
+        }
+        //如果yog端的token返回的是空,而自己端端却有token,传给PLAYER
+        if (!TextUtils.isEmpty(KFZSApp.getInstance().GameCode)) {
+            DDProviderHelper.getInstance().addOrUpdatePlayer(this, user, KFZSApp.getInstance().GameCode);
+        }
+
+        HashMap<String, String> urlParams = new HashMap<>();
+        urlParams.put(UrlBll.HeadParams.AUTHORIZATION, token);
+        String url = UrlBll.SDKApi.SDK + "/" + gameCode;
+        APIRequest apiRequest = APIRequestInstance.getReq(TAG, url, urlParams, new OnSDKOut(), errorListener);
+        KFZSNetwork.addRequest(apiRequest);
+        progressDialog.show();
+    }
+
+
+    @OnClick({R.id.tv_act_game_certification_change_account, R.id.btn_act_game_certification})
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.tv_act_game_certification_change_account:
+                Bundle bundle = new Bundle(extras);
+                bundle.putInt(ActAccountManage.KEY_SKIP_JOB_CODE, ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION);
+                skip2Activity(ActAccountManage.class, bundle);
+                this.finish();
+                break;
+            case R.id.btn_act_game_certification:
+                if (!TextUtils.isEmpty(certificationKey) && !TextUtils.isEmpty(extrasStr)) {
+                    certificationDog.doCertification(certificationKey, extrasStr);
+                } else {
+                    showCertificationErrorAndExit("授权错误!未获取到\n认证: " + certificationKey + "\n或者没获取到渠道值: " + extrasStr);
+                }
+                break;
+        }
+    }
+
+    private class OnSDKOut implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int codeValue = apiResponse.getCodeValue();
+            String msg = apiResponse.getMsg();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    Sdk.SdkOut sdkOut = apiResponse.getSdkOut();
+                    filterSDKOut(msg, sdkOut);
+                    break;
+                case ApiResponseOuterClass.Codes.Unauthorized_VALUE:
+                    isAuthOutOfTime = true;
+                    certificationDog.doForceNeedReLogin();
+                    showToast(msg);
+                    Log.w("AUTH", "get code error msg: " + msg);
+                    break;
+                case ApiResponseOuterClass.Codes.Bad_Request_VALUE:
+                    showCertificationErrorAndExit("请求授权错误 " + msg);
+                    break;
+                default:
+                    showCertificationErrorAndExit("请求授权错误 " + msg);
+                    break;
+            }
+        }
+
+        private void filterSDKOut(String msg, Sdk.SdkOut sdkOut) {
+            if (sdkOut != null) {
+                certificationKey = sdkOut.getCode();
+                /*String userID = extras.getString(getString(R.string.kfzs_duanduan_datashare_certification_userid));
+                if (userID != null) {
+                    ContentValues values = new ContentValues();
+                    values.put(YogConfig.Player.CODE, certificationKey);
+                    values.put(YogConfig.Player.DD_USERID, userID);
+                    DDProviderHelper.getInstance().insertOrUpdatePalyer(ActGameCertification.this, values);
+                }*/
+                try {
+                    JSONObject jsonObject;
+                    String extrasFromGame = DataSave.getInstance().getExtrasFromGame();
+                    ALog.d("extrasFromGame from : " + extrasFromGame);
+                    if (TextUtils.isEmpty(extrasFromGame)) {
+                        jsonObject = new JSONObject();
+                    } else {
+                        jsonObject = new JSONObject(extrasFromGame);
+                    }
+                    jsonObject.put("dd_channel", DataSave.getInstance().getChannelName());
+                    extrasStr = jsonObject.toString();
+                    progressDialog.hide();
+                    if (userBehavior == JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS) {
+                        if (!TextUtils.isEmpty(certificationKey) && !TextUtils.isEmpty(extrasStr)) {
+                            ALog.d("extrasFromGame to : " + extrasStr);
+                            certificationDog.doCertification(certificationKey, extrasStr);
+                        } else {
+                            showCertificationErrorAndExit("授权错误!未获取到\n认证: " + certificationKey + "\n或者没获取到渠道值: " + extrasStr);
+                        }
+                    }
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                    showCertificationErrorAndExit("授权错误!透传参数拼装错误\n认证: " + certificationKey + "\n或者没获取到渠道值: " + extrasStr);
+                }
+            } else {
+                showCertificationErrorAndExit("请求授权错误!未获取到输出 " + msg);
+            }
+        }
+    }
+
+
+    private class GameDog implements CertificationDog {
+
+
+        @Override
+        public void onCertificationCodeCallBack(User user, String gamePackageName, String gameCode, String ext) {
+            Log.e("gamePackageName: ", gamePackageName + " |gameCode: " + gameCode + " ext: " + ext);
+            if (isNeedGetCode) {
+                switch (userBehavior) {
+                    case JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS:
+                        doCertificationByChangeAccount(gameCode, user);
+                        break;
+                    case JOB_CHANGE_ACCOUNT_CANCEL:
+                        if (certificationDog != null) {
+                            certificationDog.doCertificationCancel();
+                        }
+                        break;
+                    default:
+                        if (TextUtils.isEmpty(ext)) {
+                            initViewByBundle(gamePackageName);
+                            popSDKOut(user, gameCode);
+                        } else {
+                            DataSave.getInstance().setExtrasFromGame(ext);
+                            filterUserBehavior(ext, user);
+                        }
+                        break;
+                }
+            } else {
+                try {
+                    JSONObject jsonObject;
+                    String extrasFromGame = DataSave.getInstance().getExtrasFromGame();
+                    if (TextUtils.isEmpty(extrasFromGame)) {
+                        jsonObject = new JSONObject();
+                    } else {
+                        jsonObject = new JSONObject(extrasFromGame);
+                    }
+                    jsonObject.put("dd_channel", DataSave.getInstance().getChannelName());
+                    String user_behavior = jsonObject.optString("user_behavior", "");
+                    jsonObject.remove("user_behavior");
+                    jsonObject.put("user_behavior", user_behavior + "_callback");
+                    extrasStr = jsonObject.toString();
+                    progressDialog.hide();
+                    ALog.d("extrasFromGame from : " + extrasStr);
+                    certificationKey = jsonObject.optString("user_behavior");
+                    certificationDog.doCertification(certificationKey, extrasStr);
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                    showCertificationErrorAndExit("授权错误!透传参数拼装错误\n认证: " + certificationKey + "\n或者没获取到渠道值: " + extrasStr);
+                }
+            }
+        }
+
+        @Override
+        public void onCertificationSuccess() {
+            showToast("授权成功", ToastBuilder.DEFAULT_TOAST_SINGLE);
+            KFZSApp.getInstance().quit();
+        }
+
+        @Override
+        public void onCertificationCancel() {
+            showToast("授权取消", ToastBuilder.DEFAULT_TOAST_SINGLE);
+            KFZSApp.getInstance().quit();
+        }
+
+        @Override
+        public void onLoginJob() {
+            needLogin();
+        }
+
+        @Override
+        public void onError(int code, String message) {
+            ALog.e("code:----------- " + code + " |message: " + message);
+            switch (code) {
+                default:
+                    showCertificationErrorAndExit("参数错误, 请检查后再次请求授权\n" + message);
+                    break;
+            }
+        }
+    }
+
+    private void doCertificationByChangeAccount(String gameCode, User user) {
+        popSDKOut(user, gameCode);
+    }
+
+    private void filterUserBehavior(String ext, User user) {
+        try {
+            JSONObject extObj = new JSONObject(ext);
+            String user_behavior = extObj.getString("user_behavior");
+            switch (user_behavior) {
+                case "change_account":
+                    Bundle bundle = new Bundle(extras);
+                    bundle.putInt(ActAccountManage.KEY_SKIP_JOB_CODE, ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION);
+                    skip2Activity(ActAccountManage.class, bundle);
+                    this.finish();
+                    break;
+                case "change_password":
+                    filterOpenIDDoJob(user_behavior, user, extObj);
+                    break;
+                case "bind_phone":
+                    filterOpenIDDoJob(user_behavior, user, extObj);
+                    break;
+                case "change_nick_name":
+                    filterOpenIDDoJob(user_behavior, user, extObj);
+                    break;
+                default:
+                    showCertificationErrorAndExit("筛选用户行为错误,错误行为: " + user_behavior);
+                    break;
+            }
+        } catch (JSONException e) {
+            e.printStackTrace();
+            showCertificationErrorAndExit("请求授权错误!透传字段设置错误: " + e.getMessage());
+        }
+    }
+
+    private void filterOpenIDDoJob(String behavior, User user, JSONObject extObj) {
+        String openId = user.getMOpenId();
+        String open_id = extObj.optString("openid", "");
+        int sameOpenIDJob = 0;
+        int oldOpenIDJob = 0;
+        switch (behavior) {
+            case "change_password":
+                sameOpenIDJob = ActAuth.JOB_CODE_SELF_CHANGE_PASSWORD_BY_CERTIFICATION;
+                oldOpenIDJob = ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION_BY_PASSWORD_CHECK;
+                break;
+            case "bind_phone":
+                sameOpenIDJob = ActAuth.JOB_CODE_SELF_BIND_PHONE_BY_CERTIFICATION;
+                // TODO bind phone by change account
+                oldOpenIDJob = ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION_CHECK;
+                break;
+            case "change_nick_name":
+                // TODO change nick name
+                sameOpenIDJob = ActAuth.JOB_CODE_SELF_CHANGE_NICK_NAME_BY_CERTIFICATION;
+                // TODO bind phone by change account
+                oldOpenIDJob = ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION_CHECK;
+                break;
+            default:
+                showCertificationErrorAndExit("筛选用户错误,错误行为: " + behavior);
+                break;
+        }
+        if (open_id.equals(openId)) {
+            Bundle changePsd = new Bundle(extras);
+            changePsd.putInt(ActAuth.KEY_SKIP_JOB_CODE, sameOpenIDJob);
+            skip2Activity(ActAuth.class, changePsd);
+            this.finish();
+        } else {
+            List<User> sessionBeen = KFZSDDContentSession.getInstance().checkOutAllUser(app);
+            User sessionOld = null;
+            for (User session : sessionBeen) {
+                if (open_id.equals(session.getMOpenId())) {
+                    sessionOld = session;
+                }
+            }
+            if (sessionOld != null) {
+                Bundle bundlePwd = new Bundle(extras);
+                Integer uid = Integer.parseInt(sessionOld.getMUserId());
+                if (uid != 0) {
+                    bundlePwd.putInt(ActAccountManage.KEY_SKIP_JOB_CODE, oldOpenIDJob);
+                    bundlePwd.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, uid);
+                    skip2Activity(ActAccountManage.class, bundlePwd);
+                    this.finish();
+                } else {
+                    needLogin();
+                }
+            } else {
+                needLogin();
+            }
+        }
+    }
+
+    private void needLogin() {
+        if (isLoginParamError) {
+            showToast(R.string.toast_user_info_you_sign_error, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            KFZSDDContentSession.getInstance().removeHeadSession(app);
+        }
+        if (isAuthOutOfTime) {
+            showToast(R.string.toast_user_info_you_sign_out_of_time, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            KFZSDDContentSession.getInstance().removeHeadSession(app);
+            EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.USER_LOGIN_FAIL));
+        }
+        if (!isLoginParamError && !isAuthOutOfTime) {
+            showToast(R.string.toast_user_info_you_ara_not_sign, ToastBuilder.MIDDLE_TOAST_SINGLE);
+        }
+        progressDialog.show();
+        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                Bundle bundle = new Bundle(extras);
+                bundle.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_LOGIN_CERTIFICATION);
+                skip2Activity(ActAuth.class, bundle);
+                ActGameCertification.this.finish();
+            }
+        }, SKIP_TIME);
+    }
+
+
+    private void showForciblyUpdateUI(String strUpdateDesc, boolean isForce) {
+        String update_time_date = DateFormatUtils.doSecondDate(mUpdateContent.getCreatedTime());
+
+        update_version_Name = mUpdateContent.getVersionName();
+        new DialogUpdateFragment().init(isForce,
+                strUpdateDesc,
+                mUpdateContent.getVersionName(),
+                update_time_date,
+                mUpdateContent.getSize(),
+                new DialogUpdateFragment.CancelCallback() {
+                    @Override
+                    public void onCancel() {
+                        checkCertification();
+                    }
+                })
+                .show(getSupportFragmentManager(), "update");
+    }
+
+    private static void canCloseDialog(DialogInterface dialogInterface, boolean close) {
+        try {
+            Field field = dialogInterface.getClass().getSuperclass().getDeclaredField("mShowing");
+            field.setAccessible(true);
+            field.set(dialogInterface, close);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 479 - 0
app/src/main/java/com/kfzs/duanduan/ActGameDetails.java

@@ -0,0 +1,479 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.design.widget.AppBarLayout;
+import android.support.design.widget.CollapsingToolbarLayout;
+import android.support.design.widget.TabLayout;
+import android.support.v4.view.ViewPager;
+import android.support.v4.widget.NestedScrollView;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RatingBar;
+import android.widget.TextView;
+
+import com.android.volleyplus.Response;
+import com.android.volleyplus.VolleyError;
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.duanduan.bean.BaseMsg;
+import com.kfzs.duanduan.bean.UserRecord;
+import com.kfzs.duanduan.fragment.FgContinuePlay;
+import com.kfzs.duanduan.utils.net.APIRequestV2;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bean.DownloadStatus;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventDownloadHandler;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.fragment.FgtGameDetail;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.NumberFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.utils.ShareUtils;
+import com.kfzs.duanduan.adp.AdpViewPagerDetail;
+import com.kfzs.duanduan.fragment.FgtGift;
+import com.kfzs.duanduan.view.DialogStorageLow;
+import com.kfzs.duanduan.view.ViewPagerAutoHeigh;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+import static com.kfzs.duanduan.bean.KFIntentKeys.EXTRA_PAGE_NUM;
+
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActGameDetails</p>
+ * @ <p>Description: 商品详情页,已经重构了</p>
+ * @ KFIntentKeys.EXTRA_GAME_ID 传商品Id
+ * @ date:  2017/6/19 13:36
+ * @ QQ:    315096953
+ */
+public class ActGameDetails extends BaseCompatActivity {
+
+    private GameOuterClass.Game respGame;
+
+    private Boolean bShowDownloadBtn = true;
+
+    private String sGameId = "";
+    private Map<String, InstallButtonUtils> mInstallButtonMgr = new HashMap<>();
+    private UserRecord userRecord;
+
+    private int selectType = 0;//选择tab项0,1,2
+
+
+    @BindView(R.id.viewpager_act_game_details)
+    ViewPagerAutoHeigh mViewPager;
+
+    @BindView(R.id.img_act_game_details_logo)
+    ImageView mGameIcon;
+
+    @BindView(R.id.img_act_game_details_bg)
+    ImageView mImgBg;
+
+    @BindView(R.id.txt_act_game_details_name)
+    TextView mGameName;
+
+    @BindView(R.id.txt_act_game_details_types)
+    TextView mGameTags;
+
+    @BindView(R.id.img_back)
+    View mBack;
+
+    @BindView(R.id.img_share)
+    View mShare;
+
+    @BindView(R.id.txt_act_game_details_downcount)
+    TextView mGameDldCnt;
+
+    @BindView(R.id.ratb_act_game_details)
+    RatingBar mGameStars;
+
+    @BindView(R.id.downbtn_frg_fgt_app_detail_install)
+    KFProgressButton mBtnDown;
+
+
+    @BindView(R.id.toolbar_layout_act_game_details)
+    CollapsingToolbarLayout collapsingToolbarLayout;
+
+    @BindView(R.id.txt_act_game_details_title)
+    TextView mTxtTitle;
+
+    @BindView(R.id.tabLayout)
+    TabLayout tabLayout;
+    @BindView(R.id.nestedScrollView)
+    NestedScrollView nestedScrollView;
+
+    private EventDownloadHandler.OnDownCallback mOnDownCallback;
+    private FgtGameDetail mFragmentGameDetail;
+    private boolean mIsExpanded = false;//是否是折叠状态
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_game_details_parent);
+        ButterKnife.bind(this);
+
+        EventBus.getDefault().register(this);
+
+        bShowDownloadBtn = !getIntent().hasExtra(KFIntentKeys.EXTRA_GAME_REQUEST_ORDER);
+        selectType = getIntent().getIntExtra(EXTRA_PAGE_NUM, 0);
+        initView();
+        initData();
+    }
+
+    private void initData() {
+        Intent intent = getIntent();
+        sGameId = intent.getStringExtra(KFIntentKeys.EXTRA_GAME_ID);
+        loadLoanUserercord(sGameId);
+
+        doNetworkTask(sGameId);
+    }
+
+    /**
+     * 初始化各组件
+     */
+    private void initView() {
+//        int height = HelperUtils.W * 310 / 720;
+//        mImgBg.setLayoutParams(new RelativeLayout.LayoutParams(HelperUtils.W, height));
+
+        setSupportActionBar((Toolbar) findViewById(R.id.toolbar_act_game_details));
+        mFragmentGameDetail = new FgtGameDetail();
+        AdpViewPagerDetail adpViewPagerDetail = new AdpViewPagerDetail(getSupportFragmentManager());
+        adpViewPagerDetail.add(mFragmentGameDetail, getString(R.string.app_details_details));
+        adpViewPagerDetail.add(new FgtGift(), getString(R.string.app_details_user_gift));
+        adpViewPagerDetail.add(new FgContinuePlay(), getString(R.string.continue_play));
+        mViewPager.setOffscreenPageLimit(2);
+        mViewPager.setAdapter(adpViewPagerDetail);
+
+        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+                mViewPager.reSetHeight();
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+
+            }
+        });
+
+        /**
+         * 标题显示和隐藏的监听
+         */
+        ((AppBarLayout) findViewById(R.id.appbar_act_game_details)).addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
+            @Override
+            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
+                if (Math.abs(verticalOffset) <
+                        appBarLayout.getTotalScrollRange() - HelperUtils.getDpiToPix(20)) {
+                    if (!mIsExpanded) {
+                        mIsExpanded = true;//修改状态标记为展开
+                        mTxtTitle.setVisibility(View.INVISIBLE);
+                    }
+                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
+                    if (mIsExpanded) {
+                        mTxtTitle.setVisibility(View.VISIBLE);
+                        mIsExpanded = false;//修改状态标记为折叠
+                    }
+                }
+            }
+        });
+
+        tabLayout.setupWithViewPager(mViewPager);
+        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
+            @Override
+            public void onTabSelected(TabLayout.Tab tab) {
+                selectType = tab.getPosition();
+//                G.showToast(tab.getPosition()+","+tab.getText());
+                Log.e("tab.getPosition()", tab.getPosition() + "");
+                setButtonStatue(tab.getPosition());
+
+            }
+
+            @Override
+            public void onTabUnselected(TabLayout.Tab tab) {
+
+            }
+
+            @Override
+            public void onTabReselected(TabLayout.Tab tab) {
+
+            }
+        });
+
+        mBack.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                onBackPressed();
+            }
+        });
+        mShare.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                popShare();
+            }
+        });
+
+
+        if (getIntent().hasExtra(EXTRA_PAGE_NUM)) {
+            mViewPager.setCurrentItem(selectType);
+        }
+    }
+
+    /**
+     * 设置button状态
+     */
+    private void setButtonStatue(int position){
+        if (position == 2) {
+//                    mBtnDown.setVisibility(View.GONE);
+            if (userRecord == null) {
+                return;
+            }
+            if (userRecord.getLoan_state() == 2 && userRecord.getHave_access_state() == 2) {//不允许借款
+//                        mBtnDown.setVisibility(View.GONE);
+            } else {
+//                        mBtnDown.setVisibility(View.VISIBLE);
+                if (userRecord.getHave_access_state() == 2) {//未借款
+                    mBtnDown.setText("去还款");
+                } else {
+                    mBtnDown.setText("去借款");
+                }
+            }
+            mBtnDown.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    G.showToast("该功能正在建设中");
+                }
+            });
+        } else {
+            if (!bShowDownloadBtn) {
+                mBtnDown.setVisibility(View.GONE);
+                return;
+            }
+            mBtnDown.setVisibility(View.VISIBLE);
+            if (respGame == null) {
+                return;
+            }
+//                    nestedScrollView.setNestedScrollingEnabled(true);
+            try {
+                DownBtnUtils.addDownloadBtnListener(mBtnDown, ActGameDetails.this,
+                        mInstallButtonMgr, respGame, "game_detail" + respGame.getId());
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 分享游戏;
+     */
+    private void popShare() {
+        String shareUrl = "";
+        if (respGame != null && !TextUtils.isEmpty(respGame.getDownloadUrl())) {
+            shareUrl = respGame.getDownloadUrl();
+        } else if (respGame != null && !TextUtils.isEmpty(respGame.getBookDownloadUrl())) {
+            shareUrl = respGame.getBookDownloadUrl();
+        } else {
+            showToast("分享地址错误!");
+            return;
+        }
+        if (!TextUtils.isEmpty(shareUrl) && shareUrl.toLowerCase().startsWith("http")) {
+            new ShareUtils().showShareView(this, shareUrl, respGame.getGameName(),
+                    respGame.getIconImage(), respGame.getIntroduce());
+        } else {
+            String msg = "分享错误,请联系客服!\n错误链接为: " + shareUrl;
+            Log.w("DD_ERROR", msg);
+            showToast(msg);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (KFZSApp.actMain == null) {
+            Intent intent = new Intent(this, ActMain.class);
+            startActivity(intent);
+        }
+        this.finish();
+    }
+
+    private void doNetworkTask(final String sGameId) {
+
+        String reqUrl = UrlBll.AppStoreApi.GAME_LISTS + "/" + sGameId;
+
+        APIRequest bannerRequest = APIRequestInstance.getReq(TAG, reqUrl, null, new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                respGame = apiResponse.getGame();
+                if (TextUtils.isEmpty(respGame.getGameName()) || isFinishing()) {
+                    return;
+                }
+
+
+                //                mImgIconGift.setVisibility(View.VISIBLE);
+                mGameName.setText(respGame.getGameName());
+                mTxtTitle.setText(respGame.getGameName());
+                mGameTags.setText(respGame.getTypeText());
+                mGameDldCnt.setText(" (" + String.format(getString(R.string.download_count), respGame.getDownloadNum() + "") + ")");
+                //                mGameSize.setText(respGame.getSize());
+                //                mGameDescription.setText(respGame.getIntroduce());
+                mGameStars.setRating(NumberFormatUtils.getDivideResult(respGame.getStar()));
+
+
+                Glide.with(ActGameDetails.this).load(respGame.getIconImage())
+                        .transform(new KFGlideRoundTransform(ActGameDetails.this, 10)).into(mGameIcon);
+
+                Glide.with(ActGameDetails.this).load(respGame.getDetailBackImage()).into(mImgBg);
+
+
+                mFragmentGameDetail.setData(respGame);
+
+
+                setButtonStatue(selectType);
+//                if (!bShowDownloadBtn) {
+//                    mBtnDown.setVisibility(View.GONE);
+//                    return;
+//                }
+//                mBtnDown.setVisibility(View.VISIBLE);
+//                DownBtnUtils.addDownloadBtnListener(mBtnDown, ActGameDetails.this,
+//                        mInstallButtonMgr, respGame, "game_detail" + respGame.getId());
+
+
+//               mInstallButtonMgr.put(respGame.getDownloadUrl(),
+//                        InstallButtonUtils.init("game_detail", respGame.getDownloadUrl(),
+//                                mBtnDown, "game_detail"));
+//
+//                DownBtnUtils.addDownloadBtnListener(mBtnDown, ActGameDetails.this, mInstallButtonMgr, respGame, "game_detail");
+//                GameStatusScanner scanner = new GameStatusScanner(ActGameDetails.this, mBtnDown, TAG) {
+//                    @Override
+//                    public void onButtonClickReturnListener(String downloadUrl, boolean bPaused, int percent) {
+//                        mBtnDown.updateButtonUI(bPaused ? KFProgressButton.STATUS.STATUS_PAUSED : KFProgressButton.STATUS.STATUS_INSTALLING);
+//                    }
+//                };
+//                scanner.compare(respGame);
+//                scanner.addListener();
+
+
+                if (TextUtils.isEmpty(respGame.getDownloadUrl())) {
+                    mBtnDown.setEnabled(false);
+                    mBtnDown.setText(getString(R.string.please_wait));
+                    mBtnDown.setVisibility(View.VISIBLE);
+                }
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+
+            }
+
+        }, HelperUtils.makeErr(getString(R.string.toast_init_data_fail)));
+
+        KFZSNetwork.addRequest(bannerRequest);
+
+    }
+
+
+    /**
+     * 安装按钮状态更新
+     *
+     * @param info
+     */
+    @Subscribe
+    public void onEventMainThread(DownloadStatus info) {
+        if (mOnDownCallback == null) {
+            mOnDownCallback = DownBtnUtils.installBtnStatus(mInstallButtonMgr);
+        }
+        EventDownloadHandler.newInstance(this, mOnDownCallback)
+                .setmTag(TAG).handlDownloadResult(info);
+    }
+
+    @Subscribe
+    public void onEventMainThread(BigEvent event) {
+        if (event.getEventTypes() == EventTypes.STORAGE_LOW) {
+            DialogStorageLow.showDialog(this);
+        }
+    }
+
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+    /**
+     * 获取借着完状态
+     * return 401:未登录 400:未绑定手机 200:成功
+     */
+    public void loadLoanUserercord(final String sGameId) {
+        String url = UrlBll.V2.BORROW_PLAY_LOAN_USERRECORD;
+        HashMap<String, String> m = new HashMap();
+        m.put("gameId", sGameId);
+        APIRequestV2 apiRequestV2 = APIRequestInstance.getReqUrlV2(url,
+                url, m, new Response.Listener<BaseMsg>() {
+                    @Override
+                    public void onResponse(BaseMsg baseMsg) {
+//                        doNetworkTask(sGameId);
+                        String s = baseMsg.getMsg();
+                        int code = baseMsg.getCode();
+                        switch (code) {
+                            case 400:
+//                                G.showToast("请绑定手机号");
+                                return;
+                            case 401:
+//                                G.showToast(baseMsg.getMsg() + "");
+                                return;
+                            case 200:
+                                UserRecord u = baseMsg.getData(UserRecord.class);
+                                if (u != null) {
+                                    userRecord = u;
+                                }
+                                break;
+                        }
+                    }
+                }, new Response.ErrorListener() {
+                    @Override
+                    public void onErrorResponse(VolleyError volleyError) {
+
+                    }
+                });
+        KFZSNetwork.addRequest(apiRequestV2);
+    }
+
+    /**
+     *
+     */
+    private boolean getFlagBorrow() {
+        if (userRecord == null) {
+            return false;
+        }
+        if (userRecord.getLoan_state() == 2 && userRecord.getHave_access_state() == 1) {
+            return true;
+        }
+        return false;
+    }
+}

+ 48 - 0
app/src/main/java/com/kfzs/duanduan/ActGategoryRank.java

@@ -0,0 +1,48 @@
+package com.kfzs.duanduan;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.BaseCompatActivity;
+import com.kfzs.duanduan.fragment.CategoryRankFragment;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+
+/**
+ * 游戏列表页面
+ * Created by Administrator on 2017/12/13.
+ */
+
+public class ActGategoryRank extends BaseCompatActivity {
+
+    public static final String INTENT_TYPE_ID="INTENT_TYPE_ID";
+
+    private int mIntGameTypeId=0;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_game_lists_common);
+        mIntGameTypeId=getIntent().getIntExtra(INTENT_TYPE_ID,0);
+        TitleBarUtils.getInstance().setTitle(this, "分类");
+        TitleBarUtils.getInstance().setTitleFinish(this);
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();;
+        Bundle bundle = new Bundle();
+        bundle.putInt(INTENT_TYPE_ID, mIntGameTypeId);
+        Fragment fragment = getSupportFragmentManager().findFragmentByTag("tag");
+        if(fragment == null){
+            fragment = new CategoryRankFragment();
+            fragment.setArguments(bundle);
+            transaction.add(R.id.fragment_container, fragment, "tag");
+            transaction.commit();
+        }else{
+            fragment.setArguments(bundle);
+            transaction.replace(R.id.fragment_container, fragment);
+            transaction.commit();
+        }
+
+
+    }
+}

+ 183 - 0
app/src/main/java/com/kfzs/duanduan/ActGift.java

@@ -0,0 +1,183 @@
+package com.kfzs.duanduan;
+
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.datashare.provider.session.SessionBean;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GiftCodeOuterClass;
+import com.kfzs.duanduan.proto.ShelvesGiftOuterClass;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.util.HashMap;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActGift</p>
+ * @ <p>Description:礼包详情页</p>
+ * @ date:  2017/8/4 11:21
+ * @ QQ:    315096953
+ */
+
+public class ActGift extends BaseCompatActivity {
+
+    private ShelvesGiftOuterClass.ShelvesGift mGift;
+    public final static String INTENT_GIFT = "INTENT_GIFT";
+    private Button mBtnSubmit;
+    private final int ALREADY_GET = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (!getIntent().hasExtra(INTENT_GIFT)) {
+            showToast("未找到该礼包");
+            finish();
+            return;
+        }
+        setContentView(R.layout.activity_gift);
+
+
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        initView();
+
+        initLisener();
+    }
+
+    private void initView() {
+        if (mGift == null) {
+            mGift = (ShelvesGiftOuterClass.ShelvesGift) getIntent().getSerializableExtra(INTENT_GIFT);
+        }
+        mBtnSubmit = (Button) findViewById(R.id.btn_activity_gift);
+        findViewById(R.id.img_activity_icon)
+                .setVisibility(mGift.getGame().getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        Glide.with(this)
+                .load(mGift.getGame().getIconImage())
+                .into((ImageView) findViewById(R.id.img_activity_gift));
+        ((TextView) findViewById(R.id.txt_activity_gift_title))
+                .setText(mGift.getGame().getGameName() + " - " + mGift.getGiftName());
+        ((TextView) findViewById(R.id.txt_activity_gift_number))
+                .setText(getString(R.string.gift_get_number) + mGift.getPlanNum());
+        ((TextView) findViewById(R.id.txt_activity_gift_descp))
+                .setText(mGift.getUseInstruction());
+        long remain = mGift.getRemainNum();
+        ((TextView) findViewById(R.id.txt_activity_gift_remain))
+                .setText(getString(R.string.gift_get_remain) + (remain < 1 ? 0 : remain));
+        ((TextView) findViewById(R.id.txt_activity_gift_content))
+                .setText(mGift.getGiftContent());
+        ((TextView) findViewById(R.id.txt_activity_gift_time))
+                .setText(DateFormatUtils.doDefaultDate(mGift.getCreatedTime())
+                        + " 至 " + DateFormatUtils.doDefaultDate(mGift.getEndTime()));
+
+
+//        final int percent = HelperUtils.getPercent(mGift.getTotalNum(), mGift.getReceiveNum());
+        final int percent = (int) Math.ceil((mGift.getPercentum() * 100));
+        ((TextView) findViewById(R.id.txt_activity_gift_progress))
+                .setText(percent + "%");
+        ((ProgressBar) findViewById(R.id.view_activity_gift_progress))
+                .setProgress(percent);
+
+
+        if (mGift.getStatus() == ALREADY_GET) {
+            //如果已经领取了 ,按钮变色等操作
+            mBtnSubmit.setBackgroundResource(ThemeUtils.getInstance()
+                    .getThemeResId(this, R.attr.button_full_normal, R.drawable.button_full_normal_main));
+            mBtnSubmit.setText("复制兑换码");
+            findViewById(R.id.txt_activity_gift_code).setVisibility(View.VISIBLE);
+            findViewById(R.id.layout_activity_gift_head).setVisibility(View.GONE);
+            ((TextView) findViewById(R.id.txt_activity_gift_code)).setText("激活码:" + mGift.getGiftCode());
+        }//实际上不用写else,因为是不可逆的
+
+    }
+
+    /**
+     * 领取码
+     */
+    private void initLisener() {
+        findViewById(R.id.ibtn_act_webview)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        finish();
+                    }
+                });
+        findViewById(R.id.layout_activity_gift_title)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameDetails(ActGift.this, mGift.getGameId());
+                    }
+                });
+        mBtnSubmit.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mGift.getStatus() == ALREADY_GET) {
+                    ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+                    cm.setText(mGift.getGiftCode());
+                    showToast("复制成功!");
+                    return;
+                }
+
+                GiftCodeOuterClass.GiftCode.Builder builder = GiftCodeOuterClass.GiftCode.newBuilder();
+                builder.setGiftId(mGift.getId());
+
+                HashMap<String, String> headParams = new HashMap<>();
+                SessionBean outHeadSession = KFZSDDContentSession.getInstance()
+                        .findOutHeadSession(ActGift.this);
+                if (outHeadSession == null) {
+                    SkipUtils.getInstance().goLogin(ActGift.this);
+                    showToast(R.string.toast_user_login_pre);
+                    return;
+                }
+                headParams.put(UrlBll.HeadParams.AUTHORIZATION, outHeadSession.getToken());
+
+                ApiRequestOuterClass.ApiRequest.Builder reqBuild = ApiRequestOuterClass.ApiRequest.newBuilder();
+                reqBuild.setGiftCode(builder);
+
+                APIRequest bannerRequest = APIRequestInstance.putReq(TAG, UrlBll.Gift.GIFT_EXCHANGE,
+                        reqBuild.build().toByteArray(), headParams, new ResponseNetworkTask() {
+                            @Override
+                            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                                showToast("领取成功!");
+                                //领取后,置1,这些暂时没有用常量。
+                                mGift = mGift.toBuilder()
+                                        .setStatus(ALREADY_GET)
+                                        .setGiftCode(apiResponse.getGiftCode().getGiftCode())
+                                        .setReceiveNum(mGift.getReceiveNum() + 1)
+                                        .build();
+                                initView();
+                            }
+
+                            @Override
+                            public void onFail(int code, String msg) {
+                                showToast(msg);
+                            }
+                        }, HelperUtils.makeErr(getString(R.string.toast_gift_get_fail)));
+                KFZSNetwork.addRequest(bannerRequest);
+            }
+        });
+    }
+
+}

+ 666 - 0
app/src/main/java/com/kfzs/duanduan/ActLogin.java

@@ -0,0 +1,666 @@
+package com.kfzs.duanduan;
+
+
+import android.content.ContentValues;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.design.widget.TextInputLayout;
+import android.support.v7.widget.AppCompatAutoCompleteTextView;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.volleyplus.Response;
+import com.android.volleyplus.VolleyError;
+import com.kf.utils.ToastBuilder;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.appstore.utils.restful.KFZSRestfulError;
+import com.kfzs.appstore.utils.restful.KFZSRestfulErrorCallBack;
+import com.kfzs.appstore.utils.sys.InputMethodUtils;
+import com.kfzs.duanduan.bll.AppBaseBll;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.provider.current.Current;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.YogConfig;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.event.AuthEvent;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.fragment.ManagementAccountFragment;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.Session;
+import com.kfzs.duanduan.proto.UserOuterClass;
+import com.kfzs.duanduan.react.ReactUtil;
+import com.kfzs.duanduan.utils.dlg.CheckUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.view.TimeButton;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import mdl.sinlov.android.log.ALog;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActLogin</p>
+ * @ <p>Description: 下面不全是我的代码,移植了很多代码过来,以前的全是eventbus恶心死了</p>
+ * @ <p>Description: 虽然代码优化了很多,但这些垃圾代码我怕背锅,备注一下。</p>
+ * @ date:  2018/1/24 11:57
+ * @ QQ:    315096953
+ */
+
+public class ActLogin extends BaseCompatActivity implements View.OnClickListener {
+
+    public static final int LOGIN_TYPE_IS_APP_LOGIN = 1;
+    public static final int LOGIN_TYPE_IS_CERTIFICATION = 2 << 1;
+    public static final int LOGIN_TYPE_CODE_IS_NEW_ACCOUNT = 3 << 1;
+    public static final int LOGIN_TYPE_CODE_IS_NEW_ACCOUNT_CERTIFICATION = 4 << 1;
+
+    public static final String KEY_LOGIN_TYPE = "fragment:auth:login:type";
+    private AppCompatAutoCompleteTextView mEdtUserName;
+    private TextInputLayout mEdtPass;
+    private TextInputLayout mEdtValicode;
+    private LinearLayout mLayoutValicode;
+    private TimeButton mBtnTime;
+    private CheckBox mChkUserList;
+    private boolean mIsLogin = false;
+    private boolean mIsLoginErr = false;
+    private TextView mTxtLoginType;
+    private int loginType = LOGIN_TYPE_IS_APP_LOGIN;//登录的方式,顶上的四个登录方式
+
+
+    private static final int LOGIN_ENTER_USERNAME_PASSWORD = 0;
+    private static final int LOGIN_ENTER_PHONE_SMS = 1;
+    /**
+     * 登录模式是密码登录还是短信登录
+     */
+    private int mIntCurrentLoginStyle = LOGIN_ENTER_USERNAME_PASSWORD;
+    private Bundle extras;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏
+        extras = getIntent().getExtras();
+        if (extras == null) {
+            extras = new Bundle();
+        }
+
+        setContentView(R.layout.act_login);
+        if (getIntent().hasExtra(KEY_LOGIN_TYPE)) {
+            loginType = getIntent().getIntExtra(KEY_LOGIN_TYPE, LOGIN_TYPE_IS_APP_LOGIN);
+        }
+        initView();
+    }
+
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (!TextUtils.isEmpty(AuthEvent.getRegisterback())) {
+            mEdtUserName.setText(AuthEvent.getUserName());
+            mEdtPass.getEditText().setText(AuthEvent.getUserPassword());
+        }
+        if (mEdtUserName != null && mEdtPass != null) {
+            mEdtUserName.setFocusable(true);
+        }
+
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mIsLogin = false;
+        mIsLoginErr = false;
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        switch (id) {
+            case R.id.btn_act_login_submit:
+                mIsLoginErr = false;
+                AuthEvent.setRegisterback("");
+                loginByStatus();
+                break;
+            case R.id.txt_act_login_forget:
+                SkipUtils.getInstance().goActSimple(this, ActSimple.ACTION.FORGET_PASS);
+                break;
+            case R.id.txt_act_login_phone:
+                if (mIntCurrentLoginStyle == LOGIN_ENTER_USERNAME_PASSWORD) {
+                    mIntCurrentLoginStyle = LOGIN_ENTER_PHONE_SMS;
+                    mTxtLoginType.setText(getString(R.string.login_type_sms));
+                    mLayoutValicode.setVisibility(View.VISIBLE);
+                    mEdtPass.setVisibility(View.GONE);
+                } else {
+                    mIntCurrentLoginStyle = LOGIN_ENTER_USERNAME_PASSWORD;
+                    mTxtLoginType.setText(getString(R.string.login_type_pass));
+                    mLayoutValicode.setVisibility(View.GONE);
+                    mEdtPass.setVisibility(View.VISIBLE);
+                }
+                break;
+            case R.id.btn_act_login_time:
+                postGetCaptchaPhone();
+                break;
+            case R.id.txt_act_login_regist:
+                SkipUtils.getInstance().goRegist(this, loginType);
+                break;
+            case R.id.img_act_login_back:
+                finish();
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * 短信登录方式
+     *
+     * @param phone
+     * @param valicode
+     */
+    private void submit_SMS(String phone, String valicode) {
+        if (!CheckUtils.getInstance().isPhoneSucc(phone)) {
+            return;
+        }
+        if (TextUtils.isEmpty(valicode)) {
+            G.showToast(R.string.tv_user_login_act_please_input_captcha_phone);
+            return;
+        }
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(KFZSApp.context, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                ALog.d("code: " + code + " | errorMsg: " + error.getMessage());
+                if (KFZSApp.DEBUG) {
+                    showToast("网络服务错误", ToastBuilder.MIDDLE_TOAST_SINGLE);
+                } else {
+                    showToast(R.string.toast_user_login_act_login_error_repeat, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                }
+                mIsLogin = false;
+            }
+        });
+        ApiRequestOuterClass.ApiRequest.Builder builder = ApiRequestOuterClass.ApiRequest.newBuilder();
+        Session.SessionIn.Builder sessionBuild = Session.SessionIn.newBuilder();
+        sessionBuild.setAccount(phone);
+        sessionBuild.setSmsSeccode(valicode);
+        Session.SessionIn session = sessionBuild.build();
+        builder.setSessionIn(session);
+        ApiRequestOuterClass.ApiRequest apiRequest1 = builder.build();
+        APIRequest loginReq = APIRequestInstance.postReq(TAG, UrlBll.AuthApi.LOGIN_SMS,
+                null, apiRequest1.toByteArray(), 20 * 1000,
+                new ResponseAuthLogin(phone), errorListener);
+        KFZSNetwork.addRequest(loginReq);
+        mIsLogin = true;
+    }
+
+    /**
+     * 密码方式登录
+     *
+     * @param account
+     * @param psd
+     */
+    private void submit_Pass(String account, String psd) {
+        if (!CheckUtils.getInstance().isLoginParamsSuccs(account, psd)) {
+            return;
+        }
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(KFZSApp.context, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                ALog.d("code: " + code + " | errorMsg: " + error.getMessage());
+                mIsLogin = false;
+            }
+        });
+        ApiRequestOuterClass.ApiRequest.Builder builder = ApiRequestOuterClass.ApiRequest.newBuilder();
+        Session.SessionIn.Builder sessionBuild = Session.SessionIn.newBuilder();
+        sessionBuild.setAccount(account);
+        sessionBuild.setPwd(psd);
+        Session.SessionIn session = sessionBuild.build();
+        builder.setSessionIn(session);
+        ApiRequestOuterClass.ApiRequest apiRequest1 = builder.build();
+        byte[] bytes = apiRequest1.toByteArray();
+        APIRequest loginReq = APIRequestInstance.postReq(TAG, UrlBll.AuthApi.LOGIN, null, bytes,
+                new ResponseAuthLogin(account), errorListener);
+        KFZSNetwork.addRequest(loginReq);
+        mIsLogin = true;
+    }
+
+    /**
+     * 验证登录返回的token是否有效
+     *
+     * @param token
+     */
+    private void popHeadSessionUserGraphInfo(String token) {
+        ALog.d("Auth popHeadToken: " + token);
+        if (TextUtils.isEmpty(token)) {
+            showToast(R.string.toast_user_info_you_sign_error);
+            return;
+        }
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(this, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                showToast(R.string.toast_user_login_act_login_error_repeat + "==错误码:" + code);
+                mIsLogin = false;
+            }
+        });
+        HashMap<String, String> params = new HashMap<>();
+        params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+        APIRequest userSelfRequest = APIRequestInstance.getReq(TAG, UrlBll.UserApi.SELF, params,
+                new OnHeadSessionUserGraph(token), errorListener);
+        KFZSNetwork.addRequest(userSelfRequest);
+        mIsLogin = true;
+    }
+
+    private void loginByStatus() {
+        if (mIsLoginErr) {
+            G.showToast(R.string.toast_user_login_act_login_error_repeat);
+            return;
+        }
+        if (!mIsLogin) {
+            if (mIntCurrentLoginStyle == LOGIN_ENTER_PHONE_SMS) {
+                submit_SMS(mEdtUserName.getText().toString().trim(),
+                        mEdtValicode.getEditText().getText().toString().trim());
+            } else {
+                submit_Pass(mEdtUserName.getText().toString().trim(),
+                        mEdtPass.getEditText().getText().toString().trim());
+            }
+        } else {
+            G.showToast(R.string.toast_user_login_act_is_login);
+        }
+    }
+
+
+    /**
+     * 密码框输入时的监听处理
+     */
+    private void setEtOnEditorAction() {
+        mEdtPass.getEditText().setOnEditorActionListener(new EditText.OnEditorActionListener() {
+            @Override
+            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+                if (null != event) {
+                    if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
+                            || EditorInfo.IME_ACTION_GO == event.getAction()) {
+                        if (KeyEvent.ACTION_UP == event.getAction()) {
+                            InputMethodUtils.closeInputPan(ActLogin.this);
+                            mIsLoginErr = false;
+                            loginByStatus();
+                        }
+                        return true;
+                    }
+                }
+                return false;
+            }
+        });
+    }
+
+
+    private void initView() {
+        this.mTxtLoginType = findViewByIdT(R.id.txt_act_login_phone);
+        this.mBtnTime = findViewByIdT(R.id.btn_act_login_time);
+        this.mEdtUserName = findViewByIdT(R.id.edt_act_login_user);
+        this.mEdtPass = findViewByIdT(R.id.edt_act_login_pass);
+        this.mEdtValicode = findViewByIdT(R.id.edt_act_login_valicode);
+        this.mLayoutValicode = findViewByIdT(R.id.layout_act_login_valicode);
+        this.mChkUserList = findViewByIdT(R.id.chk_act_login);
+
+        findViewByIdT(R.id.txt_act_login_forget).setOnClickListener(this);
+        findViewByIdT(R.id.btn_act_login_submit).setOnClickListener(this);
+        findViewByIdT(R.id.img_act_login_back).setOnClickListener(this);
+        findViewByIdT(R.id.txt_act_login_regist).setOnClickListener(this);
+
+        if (Build.VERSION.SDK_INT > 20) {
+            findViewByIdT(R.id.layout_act_login)
+                    .setPadding(0, G.getRealPix(25), 0, 0);
+        }
+
+
+        mBtnTime.setOnClickListener(this);
+        setEtOnEditorAction();
+        mTxtLoginType.setOnClickListener(this);
+        mChkUserList.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+                if (b) {
+                    mEdtUserName.showDropDown();
+                    InputMethodUtils.closeInputPan(ActLogin.this);
+                } else {
+                    mEdtUserName.dismissDropDown();
+                }
+            }
+        });
+
+        quickLogin();
+    }
+
+    /**
+     * 方便测试时快速登录账号
+     */
+    private void quickLogin() {
+        boolean isRnTest = false;//帮你到这儿了。。
+        List<String> userlist = getUserList();
+        //如果用户资料为空,才去看RN用户有没有。
+        if (userlist == null || userlist.size() < 1) {
+            userlist = ReactUtil.initArr();
+            isRnTest = true;
+        }
+
+        if (userlist != null && userlist.size() > 0) {
+            ArrayAdapter arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, userlist);
+            mEdtUserName.setAdapter(arrayAdapter);
+            mEdtUserName.setThreshold(99);
+            mEdtUserName.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                @Override
+                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                    mChkUserList.setChecked(false);
+                    if (ReactUtil.MAP_PWD == null) {
+                        return;
+                    }
+                    Object obj = parent.getItemAtPosition(position);
+                    String pwd = ReactUtil.MAP_PWD.get(obj.toString());
+                    if (TextUtils.isEmpty(pwd)) {
+                        pwd = "123456";
+                    }
+                    mEdtPass.getEditText().setText(pwd);
+                    findViewById(R.id.btn_act_login_submit).performClick();
+                }
+            });
+
+
+            if (isRnTest) {
+                mEdtUserName.setDropDownVerticalOffset(-90);
+                mEdtUserName.setThreshold(1);
+                mEdtUserName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+                    @Override
+                    public void onFocusChange(View view, boolean hasFocus) {
+                        if (hasFocus && view instanceof AppCompatAutoCompleteTextView) {
+                            ((AppCompatAutoCompleteTextView) view).showDropDown();
+                        }
+                    }
+                });
+            }
+        } else if (KFZSApp.DEBUG) {
+            mEdtUserName.setText("tianran6");
+            mEdtPass.getEditText().setText("qwer1234");
+        }
+    }
+
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (mChkUserList.isChecked()) {
+            mChkUserList.setChecked(false);
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
+    private List<String> getUserList() {
+        List<User> userList = DDProviderHelper.getInstance().getUserList(this);
+        List<String> list = new ArrayList<>();
+        if (userList != null && userList.size() > 0) {
+            for (User user : userList) {
+                if (TextUtils.isEmpty(user.getMMobile())) {
+                    if (mIntCurrentLoginStyle != LOGIN_ENTER_PHONE_SMS
+                            && !TextUtils.isEmpty(user.getMUserName())) {
+                        list.add(user.getMUserName());
+                    }
+                } else {
+                    list.add(user.getMMobile());
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * 两种登录模式的回调处理
+     */
+    private class ResponseAuthLogin implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        private final String account;
+
+        public ResponseAuthLogin(String account) {
+            this.account = account;
+        }
+
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int code = apiResponse.getCodeValue();
+            switch (code) {
+                case ApiResponseOuterClass.Codes.Capt_Err_VALUE:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+                case ApiResponseOuterClass.Codes.Bad_Request_VALUE:
+                    mIsLoginErr = true;
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    Session.SessionOut sessionOut = apiResponse.getSessionOut();
+                    popHeadSessionUserGraphInfo(sessionOut.getToken());
+                    break;
+                default:
+                    showToast(R.string.toast_user_login_act_login_error_repeat + ",错误码:" + code, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+            }
+            mIsLogin = false;
+        }
+    }
+
+    private void filterByDifferentLoginType(UserOuterClass.User user, String token) {
+        mIsLogin = true;
+        InputMethodUtils.closeInputPan(this);
+        EventBus eventBus = EventBus.getDefault();
+        ALog.e("-loginType: " + loginType);
+        switch (loginType) {
+            case LOGIN_TYPE_IS_APP_LOGIN:
+                upDateUserInfo(user, token, true);
+                showToast(R.string.toast_user_login_act_login_success, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.USER_LOGIN_SUCC));
+                new AppBaseBll().reloadVipStyle(this);
+                break;
+            case LOGIN_TYPE_IS_CERTIFICATION://游戏认证登录;
+                upDateUserInfo(user, token, false);
+                setPlayer(user, token);
+                extras.putInt(ActGameCertification.SKIP_CODE_USER_BEHAVIOR, ActGameCertification.JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS);
+                extras.putBoolean(getString(R.string.kfzs_duanduan_datashare_certificationed), true);
+                extras.putString(getString(R.string.kfzs_duanduan_datashare_certification_userid), String.valueOf(user.getId()));
+                extras.putString(getString(R.string.kfzs_duanduan_datashare_certification_token), token);
+                skip2Activity(ActGameCertification.class, extras);
+                this.finish();
+                break;
+            case LOGIN_TYPE_CODE_IS_NEW_ACCOUNT:
+                upDateUserInfo(user, token, true);
+                AuthEvent authNewAccountEvent = new AuthEvent();
+                authNewAccountEvent.setSkipCode(ActAuth.JOB_CODE_NEW_ACCOUNT_SUCCESS);
+                eventBus.post(authNewAccountEvent);
+                showToast(R.string.toast_user_login_act_login_success, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.USER_LOGIN_SUCC));
+                new AppBaseBll().reloadVipStyle(this);
+                break;
+            case LOGIN_TYPE_CODE_IS_NEW_ACCOUNT_CERTIFICATION://游戏认证登录;
+                Bundle newAccountModeCSuccess = new Bundle(extras);
+                newAccountModeCSuccess.putInt(ManagementAccountFragment.KEY_ACCOUNT_NEW_UID, user.getId());
+                newAccountModeCSuccess.putInt(ActAccountManage.KEY_SKIP_JOB_CODE, ActAccountManage.JOB_CHANGE_ACCOUNT_CERTIFICATION_CHECK);
+                skip2Activity(ActAccountManage.class, newAccountModeCSuccess);
+                this.finish();
+                break;
+            default:
+                ALog.d("filterByDifferentLoginType default develop use!");
+                break;
+        }
+    }
+
+    //游戏授权 保存数据;
+    private void setPlayer(UserOuterClass.User user, String token) {
+        ContentValues values = new ContentValues();
+        values.put(YogConfig.Player.TOKEN, token);
+        values.put(YogConfig.Player.DD_USERID, String.valueOf(user.getId()));
+        values.put(YogConfig.Player.OPENID, user.getOpenId());
+        values.put(YogConfig.Player.USERNAME, user.getName());
+        values.put(YogConfig.Player.CHANNEL, DataSave.getInstance().getChannelName());
+        String gameCode = KFZSApp.getInstance().GameCode;
+
+        try {
+            DDProviderHelper.getInstance().insertOrUpdatePalyer(this, values, gameCode);
+            DDProviderHelper.getInstance().setGameLastPalyer(this, String.valueOf(user.getOpenId()), gameCode);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * 获取手机验证码的操作
+     */
+    private void postGetCaptchaPhone() {
+        mBtnTime.reset();
+        if (CheckUtils.getInstance().isPhoneSucc(mEdtUserName.getText().toString())) {
+            Session.SessionIn.Builder sessionBuild = Session.SessionIn.newBuilder();
+            sessionBuild.setAccount(mEdtUserName.getText().toString().trim());
+
+            Session.SessionIn sessionOut = sessionBuild.build();
+            ApiRequestOuterClass.ApiRequest.Builder reqBuild = ApiRequestOuterClass.ApiRequest.newBuilder();
+            reqBuild.setSessionIn(sessionOut);
+
+            Response.ErrorListener errorListener = KFZSRestfulError.toast(KFZSApp.context, new KFZSRestfulErrorCallBack() {
+                @Override
+                public void callErrorJob(boolean flag, int code, VolleyError error) {
+                    showToast(R.string.toast_user_login_act_register_captcha_phone_error);
+                    mBtnTime.reset();
+                }
+            });
+            APIRequest postReqCaptchaPhone = APIRequestInstance.postReq(TAG, UrlBll.AuthApi.SMS_LOGIN,
+                    null, reqBuild.build().toByteArray(), 20 * 1000,
+                    new OnSmsLogin(), errorListener
+            );
+
+            KFZSNetwork.addRequest(postReqCaptchaPhone);
+            mBtnTime.star();
+        }
+    }
+
+
+    /**
+     * 获取手机验证码的回调接口
+     */
+    private class OnSmsLogin implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    showToast(R.string.toast_user_login_act_register_captcha_phone_success, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+                case ApiResponseOuterClass.Codes.Capt_Err_VALUE:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    mBtnTime.reset();
+                    break;
+                default:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    mBtnTime.reset();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * 登录得到token后,去验证这个token后的回调实现
+     */
+    private class OnHeadSessionUserGraph implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        String token;
+
+        public OnHeadSessionUserGraph(String token) {
+            this.token = token;
+        }
+
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    mIsLoginErr = false;
+                    mIsLogin = false;
+                    UserOuterClass.User user = apiResponse.getUser();
+                    if (user != null) {
+                        filterByDifferentLoginType(user, token);
+                    } else {
+                        G.showToast(R.string.toast_user_login_act_login_error_repeat);
+                    }
+                    break;
+                case ApiResponseOuterClass.Codes.Unauthorized_VALUE:
+                    mIsLoginErr = true;
+                    showToast(R.string.toast_user_login_act_login_error_repeat, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                default:
+                    showToast("出现未知错误:code:" + codeValue, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+            }
+            mIsLogin = false;
+        }
+
+    }
+
+    /**
+     * 补全用户信息到数据库
+     *
+     * @param user
+     * @param token
+     * @param isApp
+     */
+    private void upDateUserInfo(UserOuterClass.User user, String token, boolean isApp) {
+        int id = user.getId();
+        if (isApp) {
+            Current lastUser = DDProviderHelper.getInstance().getLastUser(this);
+            if (lastUser == null)
+                lastUser = new Current();
+            lastUser.setMUserId(String.valueOf(id));
+            lastUser.setMUserName(user.getName());
+            lastUser.setMVipType(user.getVipType());
+            lastUser.setMNickName(user.getNickname());
+            lastUser.setMMobile(user.getPhone());
+            lastUser.setMOpenId(user.getOpenId());
+            lastUser.setMUpdateTime(String.valueOf(user.getUpdatedTime()));
+            lastUser.setMAvatar(user.getAvatar());
+            lastUser.setMToken(token);
+            DDProviderHelper.getInstance().setLastUser(this, lastUser);
+        }
+
+        User player = DDProviderHelper.getInstance().getUser(this, String.valueOf(id));
+        if (player == null)
+            player = new User();
+        player.setMUserId(String.valueOf(id));
+        player.setMUserName(user.getName());
+        player.setMVipType(user.getVipType());
+        player.setMNickName(user.getNickname());
+        player.setMMobile(user.getPhone());
+        player.setMOpenId(user.getOpenId());
+        player.setMUpdateTime(String.valueOf(user.getUpdatedTime()));
+        player.setMAvatar(user.getAvatar());
+        player.setMToken(token);
+
+        DDProviderHelper.getInstance().addOrUpdateUser(this, player);
+        if (!TextUtils.isEmpty(KFZSApp.getInstance().GameCode)) {
+            DDProviderHelper.getInstance().addOrUpdatePlayer(this, player, KFZSApp.getInstance().GameCode);
+        }
+    }
+}

+ 543 - 0
app/src/main/java/com/kfzs/duanduan/ActMain.java

@@ -0,0 +1,543 @@
+package com.kfzs.duanduan;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.BitmapFactory;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.volleyplus.Response;
+import com.google.gson.Gson;
+import com.kf.utils.ToastBuilder;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bean.GiftItem;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.KFZSUserHelper;
+import com.kfzs.duanduan.data.graph.provider.user.UserBean;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.datashare.provider.download.DownLoadInfo;
+import com.kfzs.duanduan.datashare.provider.session.SessionBean;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.db.UserGraphUtils;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.proto.RecommendedGameOuterClass;
+import com.kfzs.duanduan.proto.ShelvesGiftOuterClass;
+import com.kfzs.duanduan.proto.UserOuterClass;
+import com.kfzs.duanduan.react.MainTab;
+import com.kfzs.duanduan.react.TabsHelper;
+import com.kfzs.duanduan.services.DownloadTaskService;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.view.AppHomepageAdvertisementDialog;
+import com.kfzs.duanduan.view.DialogStorageLow;
+import com.sheep.jiuyan.samllsheep.BuildConfig;
+import com.sheep.jiuyan.samllsheep.R;
+import com.zhy.http.okhttp.OkHttpUtils;
+import com.zhy.http.okhttp.callback.StringCallback;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.wlf.filedownloader.FileDownloader;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import mdl.sinlov.android.log.ALog;
+import okhttp3.Call;
+
+
+public class ActMain extends BaseCompatActivity{
+
+
+    @BindView(R.id.other_container)
+    LinearLayout other_container;
+    @BindView(R.id.layout_bottom)
+    RelativeLayout mLayoutBottom;
+
+    public final static String INTEN_GAME_ID = "INTEN_GAME_ID";
+
+    private boolean hasHeadSession = false;
+    private KFZSDDContentSession mKFZSDDContentSession;
+    private DownloadTaskService mDownloadTaskService;
+    private TextView mTxtToolBar;
+
+    private final static String INTENT_SKIP_MODE = "INTENT_SKIP_MODE";
+    private final static String INTENT_SKIP_DATA = "INTENT_SKIP_DATA";
+    private ImageView mImgDot;//下载按钮的小红点
+    private AppHomepageAdvertisementDialog gameDialog;//预约窗口
+
+
+    private final static int INTENT_GET_PERMISSION = 1;
+
+    public TabsHelper tabsHelper;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        KFZSApp.actMain = this;
+        setContentView(R.layout.activity_main);
+        tabsHelper = new TabsHelper();
+        getSA();//6.0以上获取必要权限
+        HelperUtils.init();//初始化屏幕的高,density等
+        ButterKnife.bind(this);
+        EventBus.getDefault().register(this);
+
+        mTxtToolBar = (TextView) findViewById(R.id.txt_main_activity_toolbar);
+        mImgDot = (ImageView) findViewById(R.id.img_download_manager_dot);
+        tabsHelper.init();
+        mKFZSDDContentSession = KFZSDDContentSession.getInstance();
+        mDownloadTaskService = new DownloadTaskService(this);
+        mDownloadTaskService.restoreDownloadTaskStatus();
+
+        initLinsener();
+        initAnimation();
+    }
+
+    private void initLinsener() {
+        findViewById(R.id.edt_main_search_enter).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startActivity(new Intent(ActMain.this, ActSearch.class));
+            }
+        });
+        findViewById(R.id.img_download_manager).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mImgDot.setVisibility(View.GONE);
+                startActivity(new Intent(ActMain.this, ActDownloadMgr.class));
+            }
+        });
+    }
+
+
+    /**
+     * 申请读写权限6.0
+     */
+    private void getSA() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            return;
+        }
+        List<String> sa = new ArrayList<>();
+        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
+                != PackageManager.PERMISSION_GRANTED) {
+            sa.add(Manifest.permission.READ_PHONE_STATE);
+        }
+        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
+                != PackageManager.PERMISSION_GRANTED) {
+            sa.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+        }
+        if (sa.size() < 1) {//如果都已经授权了,不能空列表去请求,否则报异常
+            return;
+        }
+        ActivityCompat.requestPermissions(this, sa.toArray(new String[]{}), INTENT_GET_PERMISSION);
+    }
+
+
+    /**
+     * 权限申请的回调
+     *
+     * @param requestCode
+     * @param permissions
+     * @param grantResults
+     */
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+        if (requestCode == INTENT_GET_PERMISSION) {
+            boolean isOk = true;
+            for (int result : grantResults) {
+                if (result == PackageManager.PERMISSION_DENIED) {
+                    isOk = false;
+                    break;//只要有一个拒绝,就退出并提示
+                }
+            }
+            if (!isOk) {
+                Toast.makeText(ActMain.this, "权限获取失败,部分功能可能无法正常工作。", Toast.LENGTH_SHORT).show();
+            }
+        }
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    }
+
+//
+//    /**
+//     * 传递事件
+//     */
+//    @Override
+//    protected void onResume() {
+//        super.onResume();
+//    }
+
+
+    /**
+     * 传递事件
+     */
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        KFZSNetwork.stopByTag(TAG);
+        EventBus.getDefault().unregister(this);
+    }
+
+
+    /**
+     * 主要的事件广播接收更新处理
+     *
+     * @param event
+     */
+    @Subscribe
+    public void onEventMainThread(BigEvent event) {
+        switch (event.getEventTypes()) {
+            case USER_LOGIN_SUCC:
+                checkHeadSessionUserGraph();
+                break;
+            case TIPS_DOWN_ICON:
+                mImgDot.setVisibility(View.VISIBLE);
+                break;
+            case STORAGE_LOW:
+                DialogStorageLow.showDialog(this);
+                break;
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+        if (intent.hasExtra(INTEN_GAME_ID)) {
+        } else {
+            recreate();
+            if (gameDialog != null) {
+                gameDialog.dismiss();
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    @Override
+    public void onBackPressed() {
+        tabsHelper.onBackPressed();
+    }
+
+    /**
+     * 获取首页弹窗Dialog广告
+     */
+    public void getAdvertisementDialogData() {
+        Log.d(TAG, "getAdvertisementDialogData: " + UrlBll.AdvertisementApi.RECOMMENDED_ADVERTISEMENT);
+        APIRequest bannerRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.AdvertisementApi.RECOMMENDED_ADVERTISEMENT, null, new ResponseNetworkTask() {
+
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                showAdvertisementDialog(apiResponse);
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                Log.d("FLY", "code: " + code + "\nmsg: " + msg);
+            }
+        }, null);
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+    private void showAdvertisementDialog(ApiResponseOuterClass.ApiResponse apiResponse) {
+        if (apiResponse == null || apiResponse.getRecommendedGamesList().isEmpty()) {
+            Log.d(TAG, "The showAdvertisementDialog response is null ");
+            return;
+        }
+
+        final RecommendedGameOuterClass.RecommendedGame recommendeGame = apiResponse.getRecommendedGamesList().get(0);
+        final String splashImageUrL = recommendeGame.getImageUrl();
+        Log.d(TAG, "splashImageUrL: " + splashImageUrL);
+        final String splashImageUr1 = recommendeGame.getTitle();
+        Log.d(TAG, "splashImageUrL: " + splashImageUr1);
+        final GameOuterClass.Game game = recommendeGame.getGame();
+        Log.d(TAG, "game: " + game.toString());
+        if (null != game || splashImageUrL != null || (!"".equals(splashImageUrL))) {
+            if (gameDialog != null) {
+                gameDialog.dismiss();
+            }
+            gameDialog = new AppHomepageAdvertisementDialog(ActMain.this);
+            gameDialog.setShutImg(BitmapFactory.decodeResource(getResources(), R.drawable.btn_dialog_close));
+            gameDialog.setBackground(splashImageUrL);
+            if (getBtntext(recommendeGame).equals(getString(R.string.book_now))) {
+                gameDialog.setCanceledOnTouchOutside(true);
+                gameDialog.setCanceledOnTouchOutside(true);
+                gameDialog.setCancelable(true);
+                gameDialog.setDownloadOnOnclickListener(getBtntext(recommendeGame), new AppHomepageAdvertisementDialog.onDownloadOnclickListener() {
+                    @Override
+                    public void onDownloadClick() {
+                        SkipUtils.getInstance().goGameDetails(ActMain.this,
+                                recommendeGame.getGame().getId());
+                    }
+                });
+                gameDialog.setBackgroundOnclickListener(new AppHomepageAdvertisementDialog.onBackOnclickListener() {
+                    @Override
+                    public void onClick() {
+                        SkipUtils.getInstance().goGameDetails(ActMain.this, recommendeGame.getGame().getId());
+                    }
+                });
+
+
+            } else {
+                gameDialog.setDownloadOnOnclickListener(getBtntext(recommendeGame),
+                        new AppHomepageAdvertisementDialog.onDownloadOnclickListener() {
+                            @Override
+                            public void onDownloadClick() {
+                                final String downloadUrl = game.getDownloadUrl();
+                                if (!TextUtils.isEmpty(downloadUrl) && !downloadUrl.endsWith(".apk")) {
+                                    String url = UrlBll.GameApi.DOWNLOAD_REDIRECT + "game_id=" + game.getId() + "&channel=" + DataSave.getInstance().getChannelName();
+                                    OkHttpUtils.get().url(url).build().execute(new StringCallback() {
+                                        @Override
+                                        public void onError(Call call, Exception e, int id) {
+
+                                        }
+
+                                        @Override
+                                        public void onResponse(String response, int id) {
+                                            if (!TextUtils.isEmpty(response)) {
+                                                try {
+                                                    JSONObject object = new JSONObject(response);
+                                                    String realUrl = object.optString("DownloadUrl");
+                                                    if (TextUtils.isEmpty(realUrl))
+                                                        Toast.makeText(ActMain.this, "获取" + DataSave.getInstance().getChannelName() + "渠道下载地址失败", Toast.LENGTH_SHORT).show();
+                                                    else {
+                                                        KFZSApp.getInstance().mRealDownloadUrl.put(realUrl, downloadUrl);
+                                                        FileDownloader.start(realUrl);
+                                                        addNewDownloadTask(game.getGameName(), realUrl, game.getPackageName(),
+                                                                Integer.parseInt(game.getVersionCode()), game.getIconImage(), game.getSize(), game.getId());
+                                                        EventBus.getDefault().post(BigEvent.get()
+                                                                .setEventTypes(EventTypes.TIPS_DOWN_ICON));
+                                                    }
+                                                } catch (JSONException e) {
+                                                    e.printStackTrace();
+                                                }
+                                            }
+
+                                        }
+                                    });
+                                } else {
+
+                                    FileDownloader.start(downloadUrl);
+                                    addNewDownloadTask(game.getGameName(),
+                                            downloadUrl,
+                                            game.getPackageName(),
+                                            Integer.parseInt(game.getVersionCode()),
+                                            game.getIconImage(),
+                                            game.getSize(),
+                                            game.getId());
+
+                                    EventBus.getDefault().post(BigEvent.get()
+                                            .setEventTypes(EventTypes.TIPS_DOWN_ICON));
+                                }
+                            }
+                        });
+
+                gameDialog.setBackgroundOnclickListener(new AppHomepageAdvertisementDialog.onBackOnclickListener() {
+                    @Override
+                    public void onClick() {
+                        Intent intent = new Intent(ActMain.this, ActGameDetails.class);
+                        intent.putExtra(KFIntentKeys.EXTRA_GAME_ID, recommendeGame.getGameId() + "");
+                        ActMain.this.startActivity(intent);
+                    }
+                });
+            }
+
+
+            gameDialog.show();
+        } else {
+            Log.d(TAG, "showAdvertisementDialog: game or splashImageUrL is null");
+        }
+    }
+
+    private void addNewDownloadTask(String gameName, String downloadUrl, String packageName,
+                                    int versionCode, String iconUrl, String size, Integer gameId) {
+
+        DownLoadInfo task = new DownLoadInfo();
+        task.setMIconUrl(iconUrl);
+        task.setMGameName(gameName);
+        task.setMDownloadUrl(downloadUrl);
+        task.setMPackageName(packageName);
+        task.setMVersionCode(versionCode);
+        task.setMTotalSize(Double.valueOf(size));
+        task.setMGameID(gameId);
+        mDownloadTaskService.addDownloadTask(task);
+    }
+
+
+    /**
+     * 返回首页启动广告弹窗的按钮文本
+     *
+     * @param game
+     * @return
+     */
+    private String getBtntext(RecommendedGameOuterClass.RecommendedGame game) {
+        String backStr = "立即下载";
+        if (TextUtils.isEmpty(game.getApkUrl())) {
+            backStr = getString(R.string.book_now);
+        }
+        return backStr;
+    }
+
+    //从下面开始是一堆没有注释的一堆原始代码,以后有空再分析。
+    private void checkSessionHead() {
+        hasHeadSession = mKFZSDDContentSession.isHasHeadSession(app);
+        if (hasHeadSession) {
+            popHeadSessionUserGraphInfo();
+        }
+    }
+
+    private void checkHeadSessionUserGraph() {
+        if (mKFZSDDContentSession.isHeadSessionChange(app)) {
+            popHeadSessionUserGraphInfo();
+        } else {
+            //TODO if not change what time for recheck?
+            popHeadSessionUserGraphInfo();
+        }
+    }
+
+    private void popHeadSessionUserGraphInfo() {
+        SessionBean saveHeadSessionInMem = KFZSDDContentSession.getInstance().findOutHeadSession(this);
+        if (saveHeadSessionInMem == null) {
+            return;
+        }
+        String token = saveHeadSessionInMem.getToken();
+        ALog.d("popHeadToken: " + token);
+        if (TextUtils.isEmpty(token)) {
+            showToast(R.string.toast_user_info_you_sign_error, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            KFZSDDContentSession.getInstance().removeHeadSession(app);
+            DDProviderHelper.getInstance().deleteCurrent(app);
+            return;
+        }
+        HashMap<String, String> params = new HashMap<>();
+        params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+        APIRequest userSelfRequest = APIRequestInstance.getReq(TAG, UrlBll.UserApi.SELF,
+                params, new OnHeadSessionUserGraph(), HelperUtils
+                        .makeErr(getString(R.string.toast_user_info_you_sign_error)));
+        KFZSNetwork.addRequest(userSelfRequest);
+    }
+
+    private class OnHeadSessionUserGraph implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    UserOuterClass.User user = apiResponse.getUser();
+                    if (user != null) {
+                        UserBean userGraph = UserGraphUtils.saveNewUserGraph(user);
+                        if (userGraph != null) {
+                            hasHeadSession = true;
+                            EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.WEB_TRY_LOGIN_BY_TOKEN));
+                        }
+                    }
+                    break;
+                //这一句一定要加上,不然会出现Token error
+                case ApiResponseOuterClass.Codes.Unauthorized_VALUE:
+                    showToast(R.string.toast_user_login_pre);
+                    KFZSUserHelper.getInstance().removeHeadUser(ActMain.this);
+                    DDProviderHelper.getInstance().deleteCurrent(ActMain.this);
+                    SkipUtils.getInstance().goLogin(ActMain.this);
+                    if (gameDialog != null) {
+                        gameDialog.dismiss();
+                    }
+                    break;
+            }
+        }
+    }
+
+
+    private Animation animationShow;
+    private Animation animationHide;
+
+    private void initAnimation() {
+        if(mLayoutBottom == null){
+            mLayoutBottom = findViewByIdT(R.id.layout_bottom);
+            if(BuildConfig.DEBUG)   G.showToast("怎么会是空呢?");
+        }
+        animationShow = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,
+                Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 1f,
+                Animation.RELATIVE_TO_SELF, 0f);
+        animationShow.setDuration(600);
+        animationShow.setAnimationListener(new Animation.AnimationListener() {
+            @Override
+            public void onAnimationStart(Animation animation) {
+
+            }
+
+            @Override
+            public void onAnimationEnd(Animation animation) {
+                mLayoutBottom.clearAnimation();
+                mLayoutBottom.setVisibility(View.VISIBLE);
+            }
+
+            @Override
+            public void onAnimationRepeat(Animation animation) {
+
+            }
+        });
+
+        animationHide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,
+                Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
+                Animation.RELATIVE_TO_SELF, 1f);
+        animationHide.setDuration(600);
+        animationHide.setAnimationListener(new Animation.AnimationListener() {
+            @Override
+            public void onAnimationStart(Animation animation) {
+
+            }
+
+            @Override
+            public void onAnimationEnd(Animation animation) {
+                mLayoutBottom.clearAnimation();
+                if (tabsHelper.getCurrentItem() == MainTab.FgtMainGame.getPosition()) {
+                    mLayoutBottom.setVisibility(View.GONE);
+                }
+            }
+
+            @Override
+            public void onAnimationRepeat(Animation animation) {
+
+            }
+        });
+    }
+
+    /**
+     * 显示或者隐藏底部
+     *
+     * @param isShow
+     */
+    public void showOrHideBottom(boolean isShow) {
+        if (isShow) {
+            mLayoutBottom.startAnimation(animationShow);
+            return;
+        }
+        mLayoutBottom.startAnimation(animationHide);
+    }
+}

+ 301 - 0
app/src/main/java/com/kfzs/duanduan/ActNewGameBook.java

@@ -0,0 +1,301 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.text.Html;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.duanduan.bean.VipStyle;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.fragment.KFDialogFragment;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GameBookOuterClass;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.view.ListMore;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActNewGameBook</p>
+ * @ <p>Description:新游预约页</p>
+ * @ date:  2017/12/14 16:32
+ * @ QQ:    315096953
+ */
+
+public class ActNewGameBook extends BaseCompatActivity {
+
+    private ListMore mListMore;
+    private List<GameBookOuterClass.GameBook> lGameBookCollection = new ArrayList<>();
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.act_new_game_book);
+
+        mListMore = findViewByIdT(R.id.list_act_new_game_book);
+        mListMore.getmListView().setAdapter(adapter);
+
+        doNetworkTask(100, 1);
+        mListMore.setmPullMoreEnable(false);
+        mListMore.setmOnListMoreListener(new ListMore.OnListMoreListener() {
+            @Override
+            public void onRefresh() {
+                doNetworkTask(100, 1);
+            }
+
+            @Override
+            public void onLoadMore() {
+
+            }
+        });
+        findViewById(R.id.txt_act_new_game_book)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        finish();
+                    }
+                });
+    }
+
+    /**
+     * 这里是以前的代码写得稀烂。。。
+     */
+    private BaseAdapter adapter = new BaseAdapter() {
+        @Override
+        public int getCount() {
+            return lGameBookCollection.size();
+        }
+
+        @Override
+        public GameBookOuterClass.GameBook getItem(int position) {
+            return lGameBookCollection.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return 0;
+        }
+
+        @Override
+        public View getView(final int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = View.inflate(ActNewGameBook.this, R.layout.listview_item_game_order, null);
+            }
+
+            ViewFindUtils.hold(convertView, R.id.game_order_introduces, TextView.class)
+                    .setText(getItem(position).getGame().getIntroduce());
+            ViewFindUtils.hold(convertView, R.id.game_order_tv_name, TextView.class)
+                    .setText(getItem(position).getGame().getGameName());
+            ViewFindUtils.hold(convertView, R.id.game_order_tv_date, TextView.class)
+                    .setText(DateFormatUtils.doSecond2Date(getItem(position).getGame().getStartTime()));
+            ViewFindUtils.hold(convertView, R.id.game_order_tv_count, TextView.class)
+                    .setText(Html.fromHtml(getHTMLStr(String.valueOf(getItem(position).getCount()))));
+
+            Glide.with(ActNewGameBook.this)
+                    .load(getItem(position).getGame().getIconImage())
+                    .transform(new KFGlideRoundTransform(ActNewGameBook.this, 5))
+                    .into(ViewFindUtils.find(convertView, R.id.game_order_iv_icon, ImageView.class));
+            Glide.with(ActNewGameBook.this)
+                    .load(VipStyle.getInstance().getGamebookimg())
+                    .transform(new KFGlideRoundTransform(ActNewGameBook.this, 2))
+                    .into(ViewFindUtils.find(convertView, R.id.img_listview_item_game_order_vip, ImageView.class));
+
+            ViewFindUtils.find(convertView, R.id.txt_listview_item_game_order_gift, TextView.class)
+                    .setText(getItem(position).getGiftContent());
+
+            final String[] strUrlArray = getItem(position).getGame().getDetailImage().split("&&");
+            final Map<Integer, String> mUrlsCollection = new HashMap<>();
+            for (int index = 0; index < strUrlArray.length; index++) {
+                if (index > 2) {
+                    break;
+                }
+                final int mPostion = index;
+                int resImageId = getResources().getIdentifier("game_order_iv_" + (index + 1), "id", ActNewGameBook.this.getPackageName());
+
+                ImageView vpImageChildItem = ViewFindUtils.hold(convertView, resImageId);
+                Glide.with(ActNewGameBook.this)
+                        .load(strUrlArray[index])
+                        .placeholder(R.drawable.loading)
+                        .into(vpImageChildItem);
+
+                vpImageChildItem.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        startPictureEnlarge(mPostion, mUrlsCollection);
+                    }
+                });
+                mUrlsCollection.put(index, strUrlArray[index]);
+
+            }
+            ViewFindUtils.hold(convertView, R.id.img_listview_item_game_order)
+                    .setVisibility(View.VISIBLE);
+
+            KFProgressButton btnTarget = ViewFindUtils.hold(convertView, R.id.game_order_btn_order);
+            if (KFZSDDContentSession.getInstance().isHasHeadSession(ActNewGameBook.this)
+                    && getItem(position).getBooked()) {
+                btnTarget.setText(R.string.btn_ordered);
+                btnTarget.setClickable(false);
+            } else {
+                btnTarget.setText(R.string.btn_order);
+                btnTarget.setClickable(true);
+            }
+
+            btnTarget.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (!KFZSDDContentSession.getInstance().isHasHeadSession(ActNewGameBook.this)) {
+                        Bundle bundle = new Bundle();
+                        bundle.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActUser.JOB_CODE_LOGIN);
+                        Intent intent = new Intent(ActNewGameBook.this, ActAuth.class);
+                        intent.putExtras(bundle);
+                        ActNewGameBook.this.startActivity(intent);
+                    } else {
+                        postGameBook(String.valueOf(getItem(position).getId()));
+                    }
+                }
+            });
+            ViewFindUtils.hold(convertView, R.id.rl_item_list_view_game_order_title)
+                    .setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+//                            int id = getItem(position).getId();
+//                            String url = getItem(position).getUrl();
+//                            long gameId = getItem(position).getGameId();
+//                            String name = getItem(position).getName();
+//                            String packageName = getItem(position).getGame().getPackageName();
+//                            String versionCode = getItem(position).getGame().getVersionCode();
+//                            String iconImage = getItem(position).getGame().getIconImage();
+//                            String size = getItem(position).getGame().getSize();
+//                            Bundle bundle = new Bundle();
+//                            bundle.putString(KFIntentKeys.EXTRA_BEHAIOR, ActWeb.BEHAVIOR_GAME_BOOK);
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_URL, url);
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_TITLE, name);
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_SHARE_IMGURL, iconImage);
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_GAME_BOOK_ID, String.valueOf(id));
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_GAME_ID, String.valueOf(gameId));
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_PACKAGENAME, packageName);
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_GAME_VERSION, versionCode);
+//                            bundle.putString(KFIntentKeys.EXTRA_WEBVIEW_GAME_SIZE, size);
+//                            Intent intent = new Intent(ActNewGameBook.this, ActWeb.class);
+//                            intent.putExtras(bundle);
+//                            startActivity(intent);
+                            SkipUtils.getInstance().goGameDetails(ActNewGameBook.this,getItem(position).getGame().getId());
+                        }
+                    });
+
+            return convertView;
+        }
+    };
+
+    private void doNetworkTask(int limit, int offset) {
+        mListMore.setRefreshing(true);
+        HashMap<String, String> params = new HashMap<>();
+        params.put("limit", limit + "");
+        params.put("offset", offset + "");
+        if (null != KFZSDDContentSession.getInstance().findOutHeadSession(this)) {
+            String token = KFZSDDContentSession.getInstance().findOutHeadSession(this).getToken();
+            params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+        }
+
+        APIRequest bannerRequest = APIRequestInstance.getReq(TAG, UrlBll.GameBookAllApi.GAME_ALL_BOOK, params, new ResponseNetworkTask() {
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                lGameBookCollection.clear();
+                lGameBookCollection.addAll(apiResponse.getGameBooksList());
+                adapter.notifyDataSetChanged();
+                mListMore.setRefreshing(false);
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                mListMore.setRefreshing(false);
+            }
+
+        }, HelperUtils.makeErr(getString(R.string.toast_init_data_fail)));
+
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+    private final String getHTMLStr(String strCount) {
+        return "已有 <font color='#fa6324' size='30'>" + strCount + "</font>" + " 人预约";
+    }
+
+
+    private void startPictureEnlarge(int position, Map<Integer, String> mUrlsCollection) {
+        Intent picEnlargeIntent = new Intent(ActNewGameBook.this, ActPicturesEnlarge.class);
+        picEnlargeIntent.putExtra(KFIntentKeys.EXTRA_CURRENT_PICTURE_INDEX, position);
+        picEnlargeIntent.putExtra(KFIntentKeys.EXTRA_CURRENT_PICTURE_COLLECTIONS, (Serializable) mUrlsCollection);
+        ActNewGameBook.this.startActivity(picEnlargeIntent);
+    }
+
+
+    /**
+     * 发起预约请求
+     *
+     * @param gameBookId
+     */
+    public void postGameBook(String gameBookId) {
+
+        if (KFZSDDContentSession.getInstance().findOutHeadSession(this) == null) {
+            showToast(R.string.toast_user_info_you_ara_not_sign);
+            return;
+        }
+
+        ApiRequestOuterClass.ApiRequest.Builder request = ApiRequestOuterClass.ApiRequest.newBuilder();
+        GameBookOuterClass.GameBooked.Builder gameBook = GameBookOuterClass.GameBooked.newBuilder();
+        gameBook.setGameBookId(Long.valueOf(gameBookId));
+        request.setGameBooked(gameBook);
+
+        HashMap<String, String> params = new HashMap<>();
+        String token = KFZSDDContentSession.getInstance().findOutHeadSession(this).getToken();
+        params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+
+        APIRequest bannerRequest = APIRequestInstance.postReq(TAG, UrlBll.GameBookApi.GAME_BOOK_POST, params, request.build().toByteArray(), new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.TIPS_BOOK_ICON));
+                doNetworkTask(100, 1);
+                new KFDialogFragment().show(ActNewGameBook.this.getSupportFragmentManager(), "book");
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                showToast(msg);
+            }
+
+        }, HelperUtils.makeErr(getString(R.string.toast_init_data_fail)));
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+}

+ 350 - 0
app/src/main/java/com/kfzs/duanduan/ActPersonPage.java

@@ -0,0 +1,350 @@
+package com.kfzs.duanduan;
+
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.appstore.utils.update.UriUtils;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.provider.current.Current;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.data.graph.provider.user.UserBean;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.datashare.provider.session.SessionBean;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.PictureAssetOuterClass;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.kfzs.duanduan.utils.net.ApiUploadFileCallBack;
+import com.kfzs.duanduan.utils.net.UploadHttpURLConnectionUtils;
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+
+import mdl.sinlov.android.log.ALog;
+import top.zibin.luban.Luban;
+import top.zibin.luban.OnCompressListener;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActPersonPage</p>
+ * @ <p>Description:个人信息页的页面</p>
+ * @ date:  2017/8/7 18:44
+ * @ QQ:    315096953
+ */
+
+public class ActPersonPage extends PicBottomSheetActivity implements View.OnClickListener {
+
+    public static final int WHAT_COMPRESS_IMG_START = -100;
+    public static final int WHAT_COMPRESS_IMG_SUCCESS = -101;
+    public static final int WHAT_COMPRESS_IMG_ERROR = -102;
+    public static final int WHAT_SEND_IMG_START = -103;
+    public static final int WHAT_SEND_IMG_IN_PROGRESS = -104;
+    public static final int WHAT_SEND_IMG_SUCCESS = -105;
+    public static final int WHAT_SEND_IMG_ERROR = -106;
+    public static final int JOB_CHANGE_TITLE = 1;
+    public static final int JOB_CODE_LOGIN = 2 << 1;
+    public static final int JOB_CODE_SELF_CENTER = 3 << 1;
+    public static final int JOB_CODE_SELF_INFO_SHOW = 4 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_PASSWORD = 5 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_NICKNAME = 6 << 1;
+    public static final int JOB_CODE_SELF_BIND_PHONE = 7 << 1;
+
+
+    private TextView mTxtPhone;
+    private ImageView mImgHead;
+    private final int INTENT_BACK_PIC = 2;
+    private ProgressDialog userAvatarProgressDialog;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_person_page);
+        TitleBarUtils.getInstance().setTitleFinish(this).setTitle(this, "个人信息");
+
+
+        mTxtPhone = (TextView) findViewById(R.id.txt_person_page_phone);
+        mImgHead = (ImageView) findViewById(R.id.img_activity_person_page_icon);
+
+        findViewById(R.id.btn_activity_person_page)
+                .setOnClickListener(this);
+        findViewById(R.id.layout_activity_person_page_head)
+                .setOnClickListener(this);
+        findViewById(R.id.activity_person_page_nick)
+                .setOnClickListener(this);
+        findViewById(R.id.activity_person_page_changepass)
+                .setOnClickListener(this);
+
+
+        initView();
+        initPicChoose();
+    }
+
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        initView();
+    }
+
+    /**
+     * 载入初始化数据
+     */
+    private void initView() {
+        /**
+         * 没有绑定,就要绑定
+         */
+        UserBean userBean = DDProviderHelper.getInstance().getLastUserBean(this);
+        if (userBean == null) {
+            return;
+        }
+        if (TextUtils.isEmpty(userBean.getPhone())) {
+            findViewById(R.id.activity_person_page_phone)
+                    .setOnClickListener(this);
+            mTxtPhone.setText("绑定手机");
+        } else {
+            findViewById(R.id.img__person_page_phone).setVisibility(View.INVISIBLE);
+            mTxtPhone.setText(userBean.getPhone());
+        }
+        ((TextView) findViewById(R.id.txt_activity_person_page_nick))
+                .setText(userBean.getNickname());
+        ((TextView) findViewById(R.id.txt_activity_person_page_account))
+                .setText(TextUtils.isEmpty(userBean.getUserName())
+                        ? userBean.getPhone() : userBean.getUserName());
+
+        Glide.with(this)
+                .load(userBean.getAvatar())
+                .transform(new KFGlideRoundTransform(this, 5))
+                .error(R.drawable.ic_user_head_default)
+                .into(mImgHead);
+    }
+
+    /**
+     * 更改图片相关的初始化
+     */
+    private void initPicChoose() {
+        initBottomSheetLayoutByID(R.id.bottom_sheet_layout_activity_person_page, R.string.title_bottom_select_image_view);
+        initPicBottomSheetHandler();
+        userAvatarProgressDialog = new ProgressDialog(this);
+        userAvatarProgressDialog.setCancelable(false);
+        userAvatarProgressDialog.setCanceledOnTouchOutside(false);
+    }
+
+    @Override
+    public void onClick(View v) {
+        Intent intent;
+        switch (v.getId()) {
+            //点切换帐号
+            case R.id.btn_activity_person_page:
+                Bundle bundle = new Bundle();
+                bundle.putInt(ActAccountManage.KEY_SKIP_JOB_CODE, ActAccountManage.JOB_CHANGE_ACCOUNT_SHOW_LIST);
+                skip2Activity(ActAccountManage.class, bundle);
+                break;
+            //点击头像换头像
+            case R.id.activity_person_page_nick:
+                intent = new Intent(ActPersonPage.this, ActSimple.class);
+                intent.putExtra(ActSimple.INTENT_ACTION, ActSimple.ACTION.CHANGE_NICK_NAME);
+                startActivity(intent);
+                break;
+            //修改密码
+            case R.id.activity_person_page_changepass:
+                intent = new Intent(ActPersonPage.this, ActSimple.class);
+                intent.putExtra(ActSimple.INTENT_ACTION, ActSimple.ACTION.CHANGE_PASS);
+                startActivity(intent);
+                break;
+            //绑定手机号
+            case R.id.activity_person_page_phone:
+                intent = new Intent(ActPersonPage.this, ActSimple.class);
+                intent.putExtra(ActSimple.INTENT_ACTION, ActSimple.ACTION.BIND_PHONE);
+                startActivity(intent);
+                break;
+            //修改用户头像
+            case R.id.layout_activity_person_page_head:
+                System.gc();
+                callSheetImageViewPop();
+                break;
+        }
+    }
+
+    @Override
+    protected boolean showSheetImageView(ImageView imageView, Uri imageUri, int size) {
+        Glide.with(ActPersonPage.this)
+                .load(imageUri)
+                .centerCrop()
+                .crossFade()
+                .into(imageView);
+        return true;
+    }
+
+    @Override
+    protected void callBackSelectedImageUriByBottomSheet(Uri selectedImageUri) {
+        ALog.d("callBackSelectedImageUriByBottomSheet: " + selectedImageUri);
+        sendSafeHandle(WHAT_COMPRESS_IMG_START, selectedImageUri);
+        userAvatarProgressDialog.setMessage("上传中");
+        userAvatarProgressDialog.show();
+    }
+
+    @Override
+    public void safeHandleCallBack(WeakReference<PicBottomSheetActivity> wrAct, int what, Object obj) {
+        switch (what) {
+            case WHAT_COMPRESS_IMG_START:
+                final Uri selectedImageUri = (Uri) obj;
+                final File file = UriUtils.absoluteImageFile(wrAct.get(), selectedImageUri);
+                if (file != null) {
+                    compressImageByLuBan(selectedImageUri, file);
+                } else {
+                    //TODO 压缩图片错误 关闭 loading UI
+                    hideAvatarProgressDialogByMessage("图片选择错误,取消上传");
+                }
+                break;
+            case WHAT_COMPRESS_IMG_ERROR:
+                //TODO 压缩图片错误 关闭 loading UI
+                hideAvatarProgressDialogByMessage("压缩图片错误 取消上传");
+                break;
+            case WHAT_COMPRESS_IMG_SUCCESS:
+                File compressImageFile = (File) obj;
+                if (compressImageFile != null) {
+                    sendSafeHandle(WHAT_SEND_IMG_START, compressImageFile);
+                } else {
+                    sendSafeHandle(WHAT_COMPRESS_IMG_ERROR, "压缩图片输出错误,取消上传");
+                }
+                break;
+            case WHAT_SEND_IMG_START:
+                File compressImageSuccess = (File) obj;
+                UploadHttpURLConnectionUtils uploadHttpURLConnectionUtils = new UploadHttpURLConnectionUtils();
+                String token = findOutNewUserToken(uploadHttpURLConnectionUtils);
+                uploadHttpURLConnectionUtils.setSecurityValue(token);
+                uploadHttpURLConnectionUtils.setErrorMsgOutOfTime(getString(R.string.network_conf_timeout));
+                uploadHttpURLConnectionUtils.setUploadFileCallBack(new ApiUploadFileCallBack() {
+                    @Override
+                    public void uploadProgress(int progress) {
+                        sendSafeHandle(WHAT_SEND_IMG_IN_PROGRESS, progress);
+                    }
+
+                    @Override
+                    public void onApiSuccess(ApiResponseOuterClass.ApiResponse response) {
+                        ALog.d(response.toString());
+                        PictureAssetOuterClass.PictureAsset pictureAsset = response.getAsset();
+                        if (pictureAsset != null) {
+                            String pictureAssetUrl = pictureAsset.getUrl();
+                            if (TextUtils.isEmpty(pictureAssetUrl)) {
+                                sendSafeHandle(WHAT_SEND_IMG_ERROR, "上传图片显示URL失败");
+                            } else {
+                                sendSafeHandle(WHAT_SEND_IMG_SUCCESS, pictureAssetUrl);
+                            }
+                        } else {
+                            sendSafeHandle(WHAT_SEND_IMG_ERROR, "上传图片显示失败");
+                        }
+                    }
+
+                    @Override
+                    public void onApiUnauthorized(ApiResponseOuterClass.ApiResponse response) {
+                        sendSafeHandle(WHAT_SEND_IMG_ERROR, response.getMsg());
+                    }
+
+                    @Override
+                    public void onApiError(int errorCode, ApiResponseOuterClass.ApiResponse response) {
+                        sendSafeHandle(WHAT_SEND_IMG_ERROR, response.getMsg());
+                    }
+
+                    @Override
+                    public void onParseError(int errorCode, Exception e) {
+                        sendSafeHandle(WHAT_SEND_IMG_ERROR, e.getMessage());
+                    }
+                });
+                uploadHttpURLConnectionUtils.uploadFileByThread(compressImageSuccess, UrlBll.UploadPic.AVATAR);
+                break;
+            case WHAT_SEND_IMG_ERROR:
+                //TODO send Error 上传错误 关闭 loading UI
+                String imageError = (String) obj;
+                String imageErrorMsg = "上传失败: " + imageError;
+                ALog.d(imageErrorMsg);
+                hideAvatarProgressDialogByMessage(imageErrorMsg);
+                break;
+            case WHAT_SEND_IMG_IN_PROGRESS:
+                int progress = (int) obj;
+                String imageProgressMsg = "上传中: " + progress + "%";
+                ALog.d(imageProgressMsg);
+                userAvatarProgressDialog.setMessage(imageProgressMsg);
+                break;
+            case WHAT_SEND_IMG_SUCCESS:
+                String pictureAssetUrl = String.valueOf(obj);
+                showUserAvatar(pictureAssetUrl);
+                String imgSuccessMsg = "上传成功!";
+                hideAvatarProgressDialogByMessage(imgSuccessMsg);
+                break;
+        }
+    }
+
+    private void compressImageByLuBan(final Uri selectedImageUri, File file) {
+        Luban.get(this)
+                .load(file)                     //传人要压缩的图片
+                .putGear(Luban.THIRD_GEAR)      //设定压缩档次,默认三挡
+                .setCompressListener(new OnCompressListener() {
+                    @Override
+                    public void onStart() {
+                        // TODO 压缩开始前调用,可以在方法内启动 loading UI
+                    }
+
+                    @Override
+                    public void onSuccess(File file) {
+                        sendSafeHandle(WHAT_COMPRESS_IMG_SUCCESS, file);
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+                        sendSafeHandle(WHAT_COMPRESS_IMG_ERROR, selectedImageUri);
+                    }
+                }).launch();
+    }
+
+    protected String findOutNewUserToken(UploadHttpURLConnectionUtils uploadHttpURLConnectionUtils) {
+        SessionBean outHeadSession = KFZSDDContentSession.getInstance().findOutHeadSession(app);
+        if (outHeadSession != null) {
+            String token = outHeadSession.getToken();
+            if (!TextUtils.isEmpty(token)) {
+                return token;
+            } else {
+                return "";
+            }
+        } else {
+            return "";
+        }
+    }
+
+
+    protected void hideAvatarProgressDialogByMessage(String msg) {
+        showToast(msg);
+        userAvatarProgressDialog.hide();
+    }
+
+    private void showUserAvatar(String avatar) {
+        if (!TextUtils.isEmpty(avatar)) {
+            ALog.d(avatar);
+            Glide.with(this)
+                    .load(avatar)
+                    .error(R.drawable.ic_user_head_default)
+                    .into(mImgHead);
+
+            User user = DDProviderHelper.getInstance().getLastUser(this);
+            user.setMAvatar(avatar);
+            DDProviderHelper.getInstance().addOrUpdateUser(this, user);
+
+            Current current = DDProviderHelper.getInstance().getLastUser(this);
+            current.setMAvatar(avatar);
+            DDProviderHelper.getInstance().setLastUser(this, current);
+        }
+    }
+}

+ 84 - 0
app/src/main/java/com/kfzs/duanduan/ActPicturesEnlarge.java

@@ -0,0 +1,84 @@
+package com.kfzs.duanduan;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.view.ViewPager;
+import android.widget.TextView;
+
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.fragment.PictureViewPagerAdapter;
+import com.kfzs.duanduan.view.DepthPageTransformer;
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.util.Map;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+/**
+ * Created by HooRang on 2017/3/22.
+ */
+public class ActPicturesEnlarge extends BaseCompatActivity {
+
+    private Bundle extras;
+
+    @BindView(R.id.picture_enlarge_viewpager)
+    ViewPager vpPictureEnlarge;
+
+    @BindView(R.id.picture_enlarge_label)
+    TextView tvLabel;
+
+    Map<Integer, String> mUrlCollections;
+    int iCurrentItem = 1;
+
+    PictureViewPagerAdapter picViewPagerAdapter;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_picture_enlarge);
+        ButterKnife.bind(this);
+
+        extras = getIntent().getExtras();
+        mUrlCollections = (Map<Integer, String>) extras.getSerializable(KFIntentKeys.EXTRA_CURRENT_PICTURE_COLLECTIONS);
+        iCurrentItem = extras.getInt(KFIntentKeys.EXTRA_CURRENT_PICTURE_INDEX);
+
+        initActivityUI();
+
+    }
+
+
+    private void initActivityUI() {
+        tvLabel.setText(formatLabel(iCurrentItem + 1));
+
+        picViewPagerAdapter = new PictureViewPagerAdapter(this, mUrlCollections, PictureViewPagerAdapter.ViewPagerOpenModel.PICTURE_ENLARGE);
+        vpPictureEnlarge.setOffscreenPageLimit(mUrlCollections.size());
+        vpPictureEnlarge.setPageMargin(15);
+        vpPictureEnlarge.setAdapter(picViewPagerAdapter);
+        picViewPagerAdapter.setmIntFirstShowPos(iCurrentItem);
+        vpPictureEnlarge.setPageTransformer(true, new DepthPageTransformer());
+
+
+        vpPictureEnlarge.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+                tvLabel.setText(formatLabel(position + 1));
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+            }
+        });
+
+    }
+
+    private String formatLabel(int iCurrentIndex) {
+        return iCurrentIndex + "/" + (mUrlCollections == null ? 0 : mUrlCollections.size());
+    }
+
+}

+ 671 - 0
app/src/main/java/com/kfzs/duanduan/ActRegist.java

@@ -0,0 +1,671 @@
+package com.kfzs.duanduan;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.design.widget.TextInputEditText;
+import android.support.design.widget.TextInputLayout;
+import android.text.InputFilter;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.text.method.DigitsKeyListener;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.volleyplus.Response;
+import com.android.volleyplus.VolleyError;
+import com.kf.utils.ToastBuilder;
+import com.kfzs.android.view.widget.MDLCheckBox;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.appstore.utils.restful.KFZSRestfulError;
+import com.kfzs.appstore.utils.restful.KFZSRestfulErrorCallBack;
+import com.kfzs.appstore.utils.sys.InputMethodUtils;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.provider.current.Current;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.datashare.YogConfig;
+import com.kfzs.duanduan.datashare.provider.session.SessionBean;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.event.AuthEvent;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.event.ReStartEvent;
+import com.kfzs.duanduan.fragment.AuthLoginFragment;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.Session;
+import com.kfzs.duanduan.proto.UserOuterClass;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.utils.net.AuthRequestBytes;
+import com.kfzs.duanduan.utils.net.UITextUtils;
+import com.kfzs.duanduan.view.OneMinuteCountDownTimer;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.HashMap;
+
+import mdl.sinlov.android.log.ALog;
+
+import static com.kfzs.duanduan.ActLogin.KEY_LOGIN_TYPE;
+import static com.kfzs.duanduan.ActLogin.LOGIN_TYPE_IS_APP_LOGIN;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActRegist</p>
+ * @ <p>Description:移植过来的,代码恶心不背锅</p>
+ * @ date:  2018/1/24 17:33
+ * @ QQ:    315096953
+ */
+
+public class ActRegist extends BaseCompatActivity implements View.OnClickListener {
+
+    private TextInputLayout etUserName;
+    private TextInputEditText etCaptchaPhone;
+    private TextInputEditText etPassword;
+    private TextInputEditText etPasswordOnceMore;
+    private TextInputEditText etInviteCode;
+    private TextView btnCaptchaPhone;
+    private Button btnRegister;
+    private MDLCheckBox ckClause;
+    private TextView tvShowClause;
+    private TextView tvSkip2RegisterByUserName;
+    private LinearLayout mLayoutValicode;
+
+    private boolean isRegistering = false;
+    private boolean canGetCaptchaPhone = true;
+    private OneMinuteCountDownTimer countDownGetCaptchaPhone;
+    private String agreementKuaifaAssentClause;
+    private String Token;
+    private int loginFrom = ActLogin.LOGIN_TYPE_IS_APP_LOGIN;
+    private boolean mIsRegistNick = false;//是否为用户名注册
+    private LinearLayout mLayoutFirstStep;
+    private LinearLayout mLayoutSecondStep;
+    private Bundle extras;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏
+        extras = getIntent().getExtras();
+        if (extras == null) {
+            extras = new Bundle();
+        }
+
+
+        setContentView(R.layout.act_regist);
+        if (getIntent().hasExtra(KEY_LOGIN_TYPE)) {
+            loginFrom = getIntent().getIntExtra(KEY_LOGIN_TYPE, LOGIN_TYPE_IS_APP_LOGIN);
+        }
+
+
+        agreementKuaifaAssentClause = getString(R.string.toast_user_login_act_please_agreement_kuaifa_assent_clause) + getString(R.string.str_public_html_clause) + "!";
+        initViewByID();
+        setListeners();
+        if (Build.VERSION.SDK_INT > 20) {
+            findViewByIdT(R.id.img_act_regist_back)
+                    .setPadding(0, G.getRealPix(25), 0, 0);
+        }
+    }
+
+    private void initViewByID() {
+        this.mLayoutFirstStep = findViewById(R.id.layout_act_regist_first);
+        this.mLayoutSecondStep = findViewById(R.id.layout_act_regist_second);
+        this.mLayoutValicode = findViewById(R.id.layout_act_regist_valicode);
+        this.etUserName = findViewById(R.id.et_fgt_register_phone_username);
+        this.etCaptchaPhone = findViewById(R.id.et_fgt_register_phone_captcha_phone);
+        this.etPassword = findViewById(R.id.et_fgt_register_phone_password);
+        this.etPasswordOnceMore = findViewById(R.id.et_fgt_register_phone_password_once_more);
+        this.btnCaptchaPhone = findViewById(R.id.btn_fgt_register_phone_get_captcha_phone);
+        this.btnRegister = findViewById(R.id.btn_fgt_register_phone_action);
+        this.ckClause = findViewById(R.id.ck_fgt_register_phone_clause);
+        this.tvShowClause = findViewById(R.id.tv_fgt_register_phone_clause);
+        this.tvSkip2RegisterByUserName = findViewById(R.id.tv_fgt_register_phone_skip_register_fgt_ordinary);
+        this.etInviteCode = findViewById(R.id.et_flage_invite_code);
+    }
+
+    private void setListeners() {
+        findViewByIdT(R.id.img_act_regist_back).setOnClickListener(this);
+        btnCaptchaPhone.setOnClickListener(this);
+        btnRegister.setOnClickListener(this);
+        tvSkip2RegisterByUserName.setOnClickListener(this);
+        tvShowClause.setOnClickListener(this);
+        setEtOnEditorAction();
+        countDownGetCaptchaPhone = new OneMinuteCountDownTimer() {
+            @Override
+            public void onTimerRest() {
+                canGetCaptchaPhone = true;
+                btnCaptchaPhone.setText(getString(R.string.getvalicode));
+            }
+
+            @Override
+            public void onTimerTick(long millisUntilFinished, int countTime) {
+                String text = countTime + " s";
+                btnCaptchaPhone.setText(text);
+            }
+
+            @Override
+            public void onTimerFinish() {
+                canGetCaptchaPhone = true;
+                btnCaptchaPhone.setText(getString(R.string.getvalicode));
+            }
+        };
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        switch (id) {
+            case R.id.btn_fgt_register_phone_get_captcha_phone:
+                postGetCaptchaPhone();
+                break;
+            case R.id.btn_fgt_register_phone_action:
+                registerByStatus();
+                break;
+            case R.id.tv_fgt_register_phone_skip_register_fgt_ordinary:
+                mIsRegistNick = !mIsRegistNick;
+                this.etUserName.getEditText().setText("");
+                if (mIsRegistNick) {
+                    tvSkip2RegisterByUserName.setText(R.string.tv_user_login_act_user_register_phone);
+                    mLayoutValicode.setVisibility(View.INVISIBLE);
+                    this.etUserName.setHint(getString(R.string.hint_user_et_login_act_username));
+                    this.etUserName.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_FILTER);
+                    this.etUserName.getEditText().setKeyListener(DigitsKeyListener
+                            .getInstance(getString(R.string.digits_username)));
+
+                    InputFilter[] filters = {new InputFilter
+                            .LengthFilter(getResources().getInteger(R.integer.size_max_user_name))};
+                    this.etUserName.getEditText().setFilters(filters);
+                } else {
+                    tvSkip2RegisterByUserName.setText(R.string.tv_user_login_act_user_register_ordinary);
+                    mLayoutValicode.setVisibility(View.VISIBLE);
+                    this.etUserName.setHint(getString(R.string.hint_user_et_login_act_phone_hint));
+                    this.etUserName.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
+
+                    InputFilter[] filters = {new InputFilter
+                            .LengthFilter(getResources().getInteger(R.integer.size_phone_number))};
+                    this.etUserName.getEditText().setFilters(filters);
+                }
+                break;
+            case R.id.tv_fgt_register_phone_clause:
+                Uri uri = Uri.parse(getString(R.string.str_public_html_clause_url));
+                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                startActivity(intent);
+                break;
+            case R.id.img_act_regist_back:
+                if (mLayoutSecondStep.getVisibility() == View.VISIBLE) {
+                    mLayoutSecondStep.setVisibility(View.GONE);
+                    mLayoutFirstStep.setVisibility(View.VISIBLE);
+                    btnRegister.setText("下一步");
+                } else {
+                    finish();
+                }
+                break;
+            default:
+                break;
+
+        }
+    }
+
+    private void setEtOnEditorAction() {
+        TextView.OnEditorActionListener onRegisterEditorActionListener = new EditText.OnEditorActionListener() {
+            @Override
+            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+                if (null != event) {
+                    if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER || EditorInfo.IME_ACTION_GO == event.getAction()) {
+                        if (KeyEvent.ACTION_UP == event.getAction()) {
+                            InputMethodUtils.closeInputPan(ActRegist.this);
+                            registerByStatus();
+                        }
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };
+        etPasswordOnceMore.setOnEditorActionListener(onRegisterEditorActionListener);
+    }
+
+    private void postGetCaptchaPhone() {
+        if (!canGetCaptchaPhone) {
+            return;
+        }
+        countDownGetCaptchaPhone.reset();
+        if (checkUserWithPhone()) {
+            byte[] captchaPhoneBytes;
+            String phoneNum = etUserName.getEditText().getText().toString().trim();
+            String inviationCode = etInviteCode.getText().toString().trim();
+
+            captchaPhoneBytes = AuthRequestBytes.getInstance()
+                    .buildRegisterBytes(null, phoneNum, inviationCode, "",
+                            null, Session.RegisterStepCodes.CaptchaPhone_VALUE, null);
+            Response.ErrorListener errorListener = KFZSRestfulError.toast(KFZSApp.context, new KFZSRestfulErrorCallBack() {
+                @Override
+                public void callErrorJob(boolean flag, int code, VolleyError error) {
+                    canGetCaptchaPhone = true;
+                    countDownGetCaptchaPhone.reset();
+                }
+            });
+            APIRequest postReqCaptchaPhone = APIRequestInstance.postReq(TAG, UrlBll.AuthApi.REGISTER, null, captchaPhoneBytes,
+                    new OnCaptchaPhone(), errorListener);
+            KFZSNetwork.addRequest(postReqCaptchaPhone);
+            canGetCaptchaPhone = false;
+            countDownGetCaptchaPhone.start();
+        }
+    }
+
+    private boolean checkUserWithPhone() {
+        if (UITextUtils.isEditTextEmpty(etUserName.getEditText())) {
+            showToast(R.string.tv_user_login_act_please_input_phone_error, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            return false;
+        }
+        String phoneNumber = etUserName.getEditText().getText().toString().trim();
+        if (phoneNumber.length() != getResources().getInteger(R.integer.size_phone_number)) {
+            showToast(R.string.toast_warning_phone_number_size, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            return false;
+        }
+        if (!phoneNumber.matches("^\\d{11}$")) {
+            showToast(R.string.toast_warning_phone_number_error, ToastBuilder.MIDDLE_TOAST_SINGLE);
+        }
+        return true;
+    }
+
+    private void registerByStatus() {
+        if (mLayoutFirstStep.getVisibility() == View.VISIBLE) {
+            if (mIsRegistNick && etUserName.getEditText().length() < 4) {
+                showToast("用户名至少输入4位哦");
+                return;
+            }
+            if (!mIsRegistNick && etUserName.getEditText().length() < 11) {
+                showToast("请输入11位手机号");
+                return;
+            }
+            if (!mIsRegistNick && etCaptchaPhone.length()
+                    != getResources().getInteger(R.integer.size_phone_captcha_image_code)) {
+                showToast("请先正确输入验证码哦");
+                return;
+            }
+            mLayoutFirstStep.setVisibility(View.GONE);
+            mLayoutSecondStep.setVisibility(View.VISIBLE);
+            btnRegister.setText(R.string.btn_user_register_action);
+            return;
+        }
+        if (!isRegistering) {
+            postRegister();
+        } else {
+            showToast(R.string.toast_user_login_act_is_register, ToastBuilder.MIDDLE_TOAST_SINGLE);
+        }
+    }
+
+    private void postRegister() {
+        if (checkRegisterParams()) {
+            String pwd = etPassword.getText().toString().trim();
+            String pwdOnceMore = etPasswordOnceMore.getText().toString().trim();
+            if (pwd.equals(pwdOnceMore)) {
+                Response.ErrorListener errorListener = KFZSRestfulError.toast(KFZSApp.context,
+                        new KFZSRestfulErrorCallBack() {
+                            @Override
+                            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                                isRegistering = false;
+                            }
+                        });
+                byte[] registerBytes;
+                String userName = etUserName.getEditText().getText().toString().trim();
+                String captchaPhone = null;
+                if (!mIsRegistNick) {
+                    captchaPhone = etCaptchaPhone.getText().toString().trim();
+                }
+                String inviationCode = etInviteCode.getText().toString().trim();
+
+                registerBytes = AuthRequestBytes.getInstance().buildRegisterBytes(pwdOnceMore,
+                        userName, inviationCode, "", null,
+                        Session.RegisterStepCodes.RegisterByCaptchaPhone_VALUE, captchaPhone);
+
+                APIRequest apiRequest = APIRequestInstance.postReq(TAG, UrlBll.AuthApi.REGISTER,
+                        null, registerBytes,
+                        new OnRegisterByPhone(), errorListener);
+                KFZSNetwork.addRequest(apiRequest);
+                isRegistering = true;
+            } else {
+                showToast(R.string.toast_user_login_act_multi_password_difference, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            }
+        }
+    }
+
+
+    private boolean checkRegisterParams() {
+        if (!ckClause.isChecked()) {
+            showToast(agreementKuaifaAssentClause, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            return false;
+        }
+        if (UITextUtils.isEditTextEmpty(etUserName.getEditText())) {
+            showToast(R.string.tv_user_login_act_please_input_username, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            return false;
+        }
+        if (mIsRegistNick) {
+            String phoneNumber = etUserName.getEditText().getText().toString().trim();
+            if (phoneNumber.length() < getResources().getInteger(R.integer.size_less_user_name)) {
+                showToast(R.string.toast_warning_user_name_less);
+                return false;
+            }
+            if (!phoneNumber.matches("^[a-zA-Z].*")) {
+                showToast(R.string.toast_warning_user_name_start, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                return false;
+            }
+        } else {
+            String phoneNumber = etUserName.getEditText().getText().toString().trim();
+            if (phoneNumber.length() != getResources().getInteger(R.integer.size_phone_number)) {
+                showToast(R.string.toast_warning_phone_number_size, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                return false;
+            }
+            if (!phoneNumber.matches("^\\d{11}$")) {
+                showToast(R.string.toast_warning_phone_number_error, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            }
+            if (UITextUtils.isEditTextEmpty(etCaptchaPhone)) {
+                showToast(R.string.tv_user_login_act_please_input_captcha_phone, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                return false;
+            } else {
+                if (etCaptchaPhone.getText().toString().trim().length()
+                        != getResources().getInteger(R.integer.size_phone_captcha_image_code)) {
+                    showToast(R.string.toast_warning_captcha_image_code_size);
+                    return false;
+                }
+            }
+        }
+
+        if (UITextUtils.isEditTextEmpty(etPassword)) {
+            showToast(R.string.tv_user_login_act_please_input_password, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            return false;
+        } else {
+            String pwd = etPassword.getText().toString().trim();
+            if (pwd.length() < getResources().getInteger(R.integer.size_less_password)) {
+                showToast(R.string.toast_warning_password_less);
+                return false;
+            }
+        }
+        if (UITextUtils.isEditTextEmpty(etPasswordOnceMore)) {
+            showToast(R.string.tv_user_login_act_please_input_password_once_more, ToastBuilder.MIDDLE_TOAST_SINGLE);
+            return false;
+        } else {
+            if (etPassword.getText().toString().trim().length()
+                    < getResources().getInteger(R.integer.size_less_password)) {
+                showToast(R.string.toast_warning_password_less);
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    private class OnRegisterByPhone implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            isRegistering = false;
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    showToast(R.string.toast_user_login_act_register_success, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    //                    skip2JobFgt(ActAuth.JOB_CODE_LOGIN);
+//                    setLoginCannel();
+                    autoLogin();
+                    break;
+                case ApiResponseOuterClass.Codes.Capt_Err_VALUE:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+                default:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+            }
+        }
+    }
+
+    //注册成功,自动登录;
+    private void autoLogin() {
+        AuthEvent.setRegisterback("");
+        postLoginByNetwork(etUserName.getEditText().getText().toString().trim(),
+                etPasswordOnceMore.getText().toString().trim(), "");
+    }
+
+
+    private void postLoginByNetwork(String account, String psd, String captcha) {
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(KFZSApp.context, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                ALog.d("code: " + code + " | errorMsg: " + error.getMessage());
+            }
+        });
+        ApiRequestOuterClass.ApiRequest.Builder builder = ApiRequestOuterClass.ApiRequest.newBuilder();
+        Session.SessionIn.Builder sessionBuild = Session.SessionIn.newBuilder();
+        sessionBuild.setAccount(account);
+        sessionBuild.setCaptcha(captcha);
+        sessionBuild.setCaptchaKey("");
+        sessionBuild.setPwd(psd);
+        Session.SessionIn session = sessionBuild.build();
+        builder.setSessionIn(session);
+        ApiRequestOuterClass.ApiRequest apiRequest1 = builder.build();
+        APIRequest loginReq = APIRequestInstance.postReq(TAG, UrlBll.AuthApi.LOGIN,
+                null, apiRequest1.toByteArray(), new ResponseAuthLogin(account), errorListener);
+        KFZSNetwork.addRequest(loginReq);
+    }
+
+    private class ResponseAuthLogin implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+
+        private final String account;
+
+        public ResponseAuthLogin(String account) {
+            this.account = account;
+        }
+
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int code = apiResponse.getCodeValue();
+            switch (code) {
+
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    Session.SessionOut sessionOut = apiResponse.getSessionOut();
+                    String openId = sessionOut.getOpenId();
+                    KFZSDDContentSession.getInstance().insertOrUpdateSession(ActRegist.this, account,
+                            openId, sessionOut.getUid(), sessionOut.getToken());
+                    Token = sessionOut.getToken();
+                    popHeadSessionUserGraphInfo(sessionOut.getToken());
+                    break;
+                default:
+                    showToast(R.string.toast_user_login_act_login_error_repeat, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+            }
+        }
+    }
+
+
+    private void popHeadSessionUserGraphInfo(String uid) {
+        SessionBean saveHeadSessionInMem = KFZSDDContentSession.getInstance().getSaveHeadSessionInMem();
+        String token = saveHeadSessionInMem.getToken();
+        ALog.d("Auth popHeadToken: " + token);
+        if (TextUtils.isEmpty(token)) {
+            showToast(R.string.toast_user_info_you_sign_error);
+            KFZSDDContentSession.getInstance().removeHeadSession(this);
+            return;
+        }
+        Response.ErrorListener errorListener = KFZSRestfulError.toast(this, new KFZSRestfulErrorCallBack() {
+            @Override
+            public void callErrorJob(boolean flag, int code, VolleyError error) {
+                showToast(R.string.toast_user_login_act_login_error_repeat);
+            }
+        });
+        HashMap<String, String> params = new HashMap<>();
+        params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+        APIRequest userSelfRequest = APIRequestInstance.getReq(TAG, UrlBll.UserApi.SELF, params,
+                new OnHeadSessionUserGraph(uid), errorListener);
+        KFZSNetwork.addRequest(userSelfRequest);
+    }
+
+
+    private class OnCaptchaPhone implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    showToast(R.string.toast_user_login_act_register_captcha_phone_success, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+                case ApiResponseOuterClass.Codes.Capt_Err_VALUE:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    countDownGetCaptchaPhone.reset();
+                    break;
+                default:
+                    showToast(apiResponse.getMsg(), ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    countDownGetCaptchaPhone.reset();
+                    break;
+            }
+        }
+    }
+
+
+    private class OnHeadSessionUserGraph implements Response.Listener<ApiResponseOuterClass.ApiResponse> {
+        String token;
+
+        public OnHeadSessionUserGraph(String uid) {
+            this.token = uid;
+        }
+
+        @Override
+        public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+            ALog.d(apiResponse.toString());
+            int codeValue = apiResponse.getCodeValue();
+            switch (codeValue) {
+                case ApiResponseOuterClass.Codes.Success_VALUE:
+                    UserOuterClass.User user = apiResponse.getUser();
+                    if (user != null) {
+                        filterByDifferentLoginType(user, token);
+                    } else {
+                        showToast(R.string.toast_user_login_act_login_error_repeat, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    }
+                    break;
+                case ApiResponseOuterClass.Codes.Unauthorized_VALUE:
+                    ALog.d("Auth popHeadToken: Unauthorized_VALUE");
+                    showToast(R.string.toast_user_login_act_login_error_repeat, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+                default:
+                    showToast(R.string.toast_user_login_act_login_error_repeat, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                    break;
+            }
+        }
+    }
+
+    private void filterByDifferentLoginType(UserOuterClass.User user, String token) {
+        InputMethodUtils.closeInputPan(ActRegist.this);
+        EventBus eventBus = EventBus.getDefault();
+
+        loginFrom = 1;
+        switch (loginFrom) {
+            case AuthLoginFragment.LOGIN_TYPE_IS_CERTIFICATION://游戏认证登录;
+                upDateUserInfo(user, token, false);
+                setPlayer(user, token);
+                extras.putInt(ActGameCertification.SKIP_CODE_USER_BEHAVIOR, ActGameCertification.JOB_CHANGE_ACCOUNT_TOKEN_SUCCESS);
+                extras.putBoolean(getString(R.string.kfzs_duanduan_datashare_certificationed), true);
+                extras.putString(getString(R.string.kfzs_duanduan_datashare_certification_userid), String.valueOf(user.getId()));
+                extras.putString(getString(R.string.kfzs_duanduan_datashare_certification_token), token);
+                skip2Activity(ActGameCertification.class, extras);
+                this.finish();
+                break;
+            default:
+                eventBus.post(BigEvent.get().setEventTypes(EventTypes.USER_LOGIN_SUCC));
+                ReStartEvent event = new ReStartEvent();
+                event.setReStart(true);
+                EventBus.getDefault().post(event);
+                showToast(R.string.toast_user_login_act_login_success, ToastBuilder.MIDDLE_TOAST_SINGLE);
+                if (null != countDownGetCaptchaPhone) {
+                    countDownGetCaptchaPhone.reset();
+                }
+                ActRegist.this.finish();
+
+                break;
+        }
+    }
+
+    //游戏授权 保存数据;
+    public void setPlayer(UserOuterClass.User user, String token) {
+        ContentValues values = new ContentValues();
+        values.put(YogConfig.Player.TOKEN, token);
+        values.put(YogConfig.Player.DD_USERID, String.valueOf(user.getId()));
+        values.put(YogConfig.Player.OPENID, user.getOpenId());
+        values.put(YogConfig.Player.USERNAME, user.getName());
+        values.put(YogConfig.Player.CHANNEL, DataSave.getInstance().getChannelName());
+        String gameCode = KFZSApp.getInstance().GameCode;
+
+        try {
+            DDProviderHelper.getInstance().insertOrUpdatePalyer(this, values, gameCode);
+            DDProviderHelper.getInstance().setGameLastPalyer(this, String.valueOf(user.getOpenId()), gameCode);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    //补全用户信息到数据库;
+    public void upDateUserInfo(UserOuterClass.User user, String token, boolean isApp) {
+        int id = user.getId();
+        if (isApp) {
+            Current lastUser = DDProviderHelper.getInstance().getLastUser(this);
+            if (lastUser == null)
+                lastUser = new Current();
+            lastUser.setMUserId(String.valueOf(id));
+            lastUser.setMUserName(user.getName());
+            lastUser.setMVipType(user.getVipType());
+            lastUser.setMNickName(user.getNickname());
+            lastUser.setMMobile(user.getPhone());
+            lastUser.setMOpenId(user.getOpenId());
+            lastUser.setMUpdateTime(String.valueOf(user.getUpdatedTime()));
+            lastUser.setMAvatar(user.getAvatar());
+            lastUser.setMToken(token);
+
+            DDProviderHelper.getInstance().setLastUser(this, lastUser);
+        }
+
+
+        User player = DDProviderHelper.getInstance().getUser(this, String.valueOf(id));
+        if (player == null)
+            player = new User();
+        player.setMUserId(String.valueOf(id));
+        player.setMUserName(user.getName());
+        player.setMVipType(user.getVipType());
+        player.setMNickName(user.getNickname());
+        player.setMMobile(user.getPhone());
+        player.setMOpenId(user.getOpenId());
+        player.setMUpdateTime(String.valueOf(user.getUpdatedTime()));
+        player.setMAvatar(user.getAvatar());
+        player.setMToken(token);
+
+        DDProviderHelper.getInstance().addOrUpdateUser(this, player);
+        if (!TextUtils.isEmpty(KFZSApp.getInstance().GameCode)) {
+            DDProviderHelper.getInstance().addOrUpdatePlayer(this, player, KFZSApp.getInstance().GameCode);
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK
+                && event.getAction() == KeyEvent.ACTION_DOWN
+                && mIsRegistNick) {
+            findViewById(R.id.img_act_regist_back).performClick();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+}

+ 601 - 0
app/src/main/java/com/kfzs/duanduan/ActSearch.java

@@ -0,0 +1,601 @@
+package com.kfzs.duanduan;
+
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.design.widget.TabLayout;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.AlertDialog;
+import android.text.Editable;
+import android.text.Html;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.kf.utils.ToastBuilder;
+import com.kfzs.android.view.tag.FlowLayout;
+import com.kfzs.android.view.tag.TagAdapter;
+import com.kfzs.android.view.tag.TagFlowLayout;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bean.DownloadStatus;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.KFZSUserHelper;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventDownloadHandler;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GameBookOuterClass;
+import com.kfzs.duanduan.proto.HotWordsOuterClass;
+import com.kfzs.duanduan.proto.MistinessNamesOuterClass;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.adp.AdpSearchGame;
+import com.kfzs.duanduan.adp.AdpSearchGift;
+import com.kfzs.duanduan.adp.AdpSearchNewGame;
+import com.kfzs.duanduan.adp.AdpSearchRecord;
+import com.kfzs.duanduan.adp.AdpSearchTest;
+import com.kfzs.duanduan.adp.AdpSearchViewPager;
+import com.kfzs.duanduan.fragment.KFDialogFragment;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import cn.jpush.android.api.JPushInterface;
+import mdl.sinlov.android.log.ALog;
+
+
+public class ActSearch extends BaseCompatActivity {
+
+    private static final String TAG = ActSearch.class.getSimpleName();
+    private final String TAG_REQUEST_URL = "ActSearch:TAG_REQUEST_URL";
+    private Map<String, InstallButtonUtils> mInstallButtonMgrMap = new HashMap<>();
+
+    @BindView(R.id.edt_act_search_keyword)
+    AutoCompleteTextView mEdtKeyWord;
+    @BindView(R.id.img_act_search_clear)
+    ImageView mImgClear;
+
+    @BindView(R.id.tabs_act_search)
+    TabLayout mTabLayout;
+    @BindView(R.id.viewpager_act_search)
+    ViewPager mViewPager;
+    @BindView(R.id.search_history_listview)
+    ListView mListRecord;
+
+    @BindView(R.id.layout_activity_search_record)
+    View mViewRecord;
+    @BindView(R.id.layout_activity_search_content)
+    View mViewContent;
+
+
+    private AdpSearchRecord mAdpSearchRecord;
+    private TagAdapter<HotWordsOuterClass.HotWords> hotWordAdapter;
+    ;
+    private List<HotWordsOuterClass.HotWords> lHotWords = new ArrayList<>();
+
+    private String mStrSearchKey;
+
+    private EventDownloadHandler.OnDownCallback mOnDownCallback;
+    private AdpSearchViewPager mAdpSearchViewPager;
+
+    private AdpSearchGame mAdpSearchGame;
+    private AdpSearchGift mAdpSearchGift;
+    //private AdpSearchNewGame mAdpSearchNewGame;
+    //private AdpSearchTest mAdpSearchTest;
+    private ArrayAdapter<String> mAdpKeyWords;
+
+    private boolean mIsAutoShowTxt = true;//是否自动提示输入,不然在点搜索历史的时候,也会自动提示
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_search);
+
+        ButterKnife.bind(this);
+        EventBus.getDefault().register(this);
+
+        mAdpSearchViewPager = new AdpSearchViewPager(this);
+        mAdpSearchRecord = new AdpSearchRecord(this, new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                setShowKeyTips(false);
+                showRecord(false);
+                mEdtKeyWord.setText(mAdpSearchRecord.getItem(position).getKey());
+                doQueryTask(mAdpSearchRecord.getItem(position).getKey());
+            }
+        });
+        //设置返回主页的按钮
+        mTabLayout.setupWithViewPager(mViewPager);
+
+
+        setSearchInputStatus();
+        setInputEvents();
+        initTabGame();
+        initTabGift();
+        //initTabNewGame();
+        //initTabTest();
+
+
+        loadSearchHistory();
+        loadHotTagView();
+        mViewPager.setAdapter(mAdpSearchViewPager);
+    }
+
+    private void setShowKeyTips(boolean isAutoShowTxt) {
+        mIsAutoShowTxt = isAutoShowTxt;
+        if (!mIsAutoShowTxt) {
+            mAdpKeyWords.clear();
+            mAdpKeyWords.notifyDataSetChanged();
+        }
+    }
+
+
+    /**
+     * 载入搜索历史列表
+     */
+    private void loadSearchHistory() {
+        View tvFooter = LayoutInflater.from(this).inflate(R.layout.listview_item_search_histroy_footer, null);
+        mListRecord.addFooterView(tvFooter);
+        mListRecord.setAdapter(mAdpSearchRecord);
+
+        tvFooter.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mAdpSearchRecord.getCount() < 1) {
+                    return;
+                }
+                mAdpSearchRecord.clear();
+                mAdpSearchRecord.notifyDataSetChanged();
+            }
+        });
+    }
+
+
+    /**
+     * 载入热门标签,用得以前别人的,没去具体了解了
+     */
+    private void loadHotTagView() {
+
+        TagFlowLayout tagList = (TagFlowLayout) findViewById(R.id.search_tagflow_layout);
+        tagList.setMaxSelectCount(1);
+        hotWordAdapter = new TagAdapter<HotWordsOuterClass.HotWords>(lHotWords) {
+            @Override
+            public View getView(FlowLayout parent, int position, HotWordsOuterClass.HotWords o) {
+
+                TextView tv = (TextView) LayoutInflater.from(ActSearch.this).inflate(R.layout.hot_tag_item, parent, false);
+                tv.setText(o.getHotWord());
+                return tv;
+            }
+        };
+
+        tagList.setAdapter(hotWordAdapter);
+        tagList.setOnTagClickListener(new TagFlowLayout.OnTagClickListener() {
+            @Override
+            public boolean onTagClick(View view, int position, FlowLayout parent) {
+                setShowKeyTips(false);
+                showRecord(true);
+                mEdtKeyWord.setText(lHotWords.get(position).getHotWord());
+                doQueryTask(lHotWords.get(position).getHotWord());
+                return false;
+            }
+        });
+
+        APIRequest hotWordsRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.AppStoreApi.HOTWORDS, null, new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                lHotWords.clear();
+                lHotWords.addAll(apiResponse.getHotWordsList());
+                hotWordAdapter.notifyDataChanged();
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                ALog.d("onFail", msg);
+            }
+
+        }, HelperUtils.makeErr(getString(R.string.toast_init_tag_fail)));
+        KFZSNetwork.addRequest(hotWordsRequest);
+    }
+
+
+    /**
+     * 是否显示搜索历史
+     *
+     * @param isShowRecord
+     */
+    private void showRecord(boolean isShowRecord) {
+        mViewRecord.setVisibility(isShowRecord ? View.VISIBLE : View.GONE);
+        mViewContent.setVisibility(isShowRecord ? View.GONE : View.VISIBLE);
+    }
+
+    /**
+     * 调试专用的一些数据信息展示
+     */
+    private void testShowTips() {
+        final StringBuilder tips = new StringBuilder();
+        tips.append("极光ID:")
+                .append(JPushInterface.getRegistrationID(this))
+                .append("\n");
+        String token = DDProviderHelper.getInstance().getLastUserToken(this);
+        if (!TextUtils.isEmpty(token)) {
+            tips.append("Token:")
+                    .append(token)
+                    .append("\n");
+        } else {
+            tips.append("Token:未登录\n");
+        }
+
+        AlertDialog alertDialog = new AlertDialog.Builder(this)
+                .setTitle("信息")
+                .setMessage(tips.toString())
+                .setPositiveButton("复制", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+                        cm.setText(tips.toString());
+                        showToast("复制成功!");
+                    }
+                })
+                .setCancelable(true)
+                .create();
+        alertDialog.show();
+    }
+
+
+    /**
+     * 初始化游戏Tab
+     */
+    private void initTabGame() {
+        View view = View.inflate(this, R.layout.list_search, null);
+        ListView listView = (ListView) view.findViewById(R.id.list_list_search);
+        listView.setEmptyView(view.findViewById(R.id.download_mgr_empty_view));
+        mAdpSearchGame = new AdpSearchGame(this);
+        mAdpSearchGame.setmInstallButtonMgrMap(mInstallButtonMgrMap);
+        listView.setAdapter(mAdpSearchGame);
+
+        mAdpSearchViewPager.addView(view, R.string.tab_search_game);
+    }
+
+    /**
+     * 初始化游戏Gift
+     */
+    private void initTabGift() {
+        View view = View.inflate(this, R.layout.list_search, null);
+        ListView listView = (ListView) view.findViewById(R.id.list_list_search);
+        listView.setEmptyView(view.findViewById(R.id.download_mgr_empty_view));
+        mAdpSearchGift = new AdpSearchGift(this);
+        listView.setAdapter(mAdpSearchGift);
+
+        mAdpSearchViewPager.addView(view, R.string.tab_search_gift);
+    }
+
+    /**
+     * 初始化游戏NewGame
+     */
+    private void initTabNewGame() {
+        View view = View.inflate(this, R.layout.list_search, null);
+        ListView listView = (ListView) view.findViewById(R.id.list_list_search);
+        listView.setEmptyView(view.findViewById(R.id.download_mgr_empty_view));
+
+        //mAdpSearchNewGame = new AdpSearchNewGame(this);
+        //mAdpSearchNewGame.setmInstallButtonMgrMap(mInstallButtonMgrMap);
+        //listView.setAdapter(mAdpSearchNewGame);
+
+        mAdpSearchViewPager.addView(view, R.string.tab_search_newgame);
+    }
+
+    /**
+     * 初始化游戏Test
+     */
+    private void initTabTest() {
+        View view = View.inflate(this, R.layout.list_search, null);
+        ListView listView = (ListView) view.findViewById(R.id.list_list_search);
+        listView.setEmptyView(view.findViewById(R.id.download_mgr_empty_view));
+
+        //mAdpSearchTest = new AdpSearchTest(this);
+        //mAdpSearchTest.setmInstallButtonMgrMap(mInstallButtonMgrMap);
+        //listView.setAdapter(mAdpSearchTest);
+
+        mAdpSearchViewPager.addView(view, R.string.tab_search_test);
+    }
+
+
+    /**
+     * 自动转到输入模式
+     */
+    private void setSearchInputStatus() {
+        mEdtKeyWord.setFocusable(true);
+        mEdtKeyWord.setFocusableInTouchMode(true);
+        mEdtKeyWord.requestFocus();
+        InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
+        imm.showSoftInput(mEdtKeyWord, 0);
+    }
+
+
+    /**
+     * 监听输入框,如果是按回车就搜索,有内容时显示清除按钮等。
+     */
+    private void setInputEvents() {
+        mAdpKeyWords = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
+        mEdtKeyWord.setAdapter(mAdpKeyWords);
+        //以逗号为分隔符
+//        mEdtKeyWord.setTokenizer(new AutoCompleteTextView.CommaTokenizer());
+        mEdtKeyWord.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+            }
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                mImgClear.setVisibility(TextUtils.isEmpty(s) ? View.GONE : View.VISIBLE);
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                if (mIsAutoShowTxt) {
+                    loadKeyWords();
+                } else {
+                    mEdtKeyWord.setSelection(mEdtKeyWord.length());
+                }
+                setShowKeyTips(true);
+                if (s.length() < 1) {
+                    showRecord(true);
+                    return;
+                }
+
+                if (mEdtKeyWord.getText().toString().equals("9527")) {
+                    testShowTips();
+                } else if (mEdtKeyWord.getText().toString().equals("9528")) {
+                    DDProviderHelper.getInstance().deleteAllUser(ActSearch.this);
+                    DDProviderHelper.getInstance().deleteCurrent(ActSearch.this);
+                    KFZSUserHelper.getInstance().removeHeadUser(ActSearch.this);
+                    KFZSUserHelper.getInstance().clearAllUser(ActSearch.this);
+                    showToast("所有用户数据清除成功!");
+                }
+            }
+        });
+
+        mEdtKeyWord.setOnKeyListener(new View.OnKeyListener() {
+            @Override
+            public boolean onKey(View v, int keyCode, KeyEvent event) {
+                if (keyCode == KeyEvent.KEYCODE_ENTER) {
+                    ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
+                            .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+                    doQueryTask(mEdtKeyWord.getText().toString());
+                }
+                return false;
+            }
+        });
+    }
+
+    private void loadKeyWords() {
+        if (mEdtKeyWord.length() < 1) {
+            return;
+        }
+        KFZSNetwork.stopByTag(TAG_REQUEST_URL);
+        HashMap<String, String> paramsurl = new HashMap<>();
+        paramsurl.put("q", mEdtKeyWord.getText().toString().trim());
+        APIRequest bannerRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.AppStoreApi.SEARCH_KEYWORDS,
+                paramsurl, new ResponseNetworkTask() {
+                    @Override
+                    public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                        List<MistinessNamesOuterClass.MistinessNames> list = apiResponse.getMistinessNamesList();
+                        mAdpKeyWords.clear();
+                        for (MistinessNamesOuterClass.MistinessNames min : list) {
+                            mAdpKeyWords.add(min.getGameNames());
+                        }
+                        mAdpKeyWords.notifyDataSetChanged();
+                        //强制匹配
+                        mAdpKeyWords.getFilter().filter(mEdtKeyWord.getText().toString());
+                    }
+
+                    @Override
+                    public void onFail(int code, String msg) {
+
+                    }
+                }, null);
+        bannerRequest.setTag(TAG_REQUEST_URL);
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+
+    /**
+     * 主要的点击事件监听
+     *
+     * @param v
+     */
+    @OnClick({R.id.ibtn_act_serach, R.id.btn_act_search_search, R.id.img_act_search_clear})
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.ibtn_act_serach:
+
+                try {
+                    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
+                            .hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                this.finish();
+                break;
+            case R.id.btn_act_search_search:
+                doQueryTask(mEdtKeyWord.getText().toString());
+                break;
+            case R.id.img_act_search_clear:
+                mEdtKeyWord.setText("");
+                mImgClear.setVisibility(View.GONE);
+                break;
+        }
+    }
+
+
+    /**
+     * 提交搜索请求
+     *
+     * @param keyword
+     */
+    private void doQueryTask(String keyword) {
+        if (keyword == null || keyword.trim().length() < 1) {
+            return;
+        }
+        mStrSearchKey = keyword.trim();
+        mAdpSearchRecord.add(mStrSearchKey);
+
+        HashMap<String, String> params = new HashMap<>();
+        if (null != KFZSDDContentSession.getInstance().findOutHeadSession(app)) {
+            params.put(UrlBll.HeadParams.AUTHORIZATION,
+                    KFZSDDContentSession.getInstance().findOutHeadSession(app).getToken());
+        }
+        HashMap<String, String> paramsurl = new HashMap<>();
+        paramsurl.put("q", mStrSearchKey);
+        APIRequest bannerRequest = APIRequestInstance.getReqUrlWithHead(TAG, UrlBll.AppStoreApi.SEARCH,
+                params, paramsurl, new ResponseNetworkTask() {
+                    @Override
+                    public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                        mAdpSearchGame.clear();
+                        mAdpSearchGift.clear();
+                        //mAdpSearchNewGame.clear();
+                        //mAdpSearchTest.clear();
+                        mAdpSearchGame.addAll(apiResponse.getGamesList());
+                        mAdpSearchGift.addAll(apiResponse.getShelvesGiftsList());
+                        //mAdpSearchNewGame.addAll(apiResponse.getOpenServersList());
+                        //mAdpSearchTest.addAll(apiResponse.getOpenTestsList());
+
+                        mAdpSearchGame.notifyDataSetChanged();
+                        mAdpSearchGift.notifyDataSetChanged();
+                        //mAdpSearchNewGame.notifyDataSetChanged();
+                        //mAdpSearchTest.notifyDataSetChanged();
+                        showRecord(false);
+                    }
+
+                    @Override
+                    public void onFail(int code, String msg) {
+                        ALog.d(TAG, "搜索结果获取失败" + msg);
+                    }
+                }, HelperUtils.makeErr(getString(R.string.toast_init_data_fail)));
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+
+    /**
+     * 载入游戏弹窗页面
+     *
+     * @param gameBookId
+     */
+    private void loadGameBook(String gameBookId) {
+        if (KFZSDDContentSession.getInstance().findOutHeadSession(app) == null) {
+            ToastBuilder.make(app, R.string.toast_user_info_you_ara_not_sign
+                    , ToastBuilder.DEFAULT_TOAST_SINGLE);
+            return;
+        }
+
+        ApiRequestOuterClass.ApiRequest.Builder request = ApiRequestOuterClass.ApiRequest.newBuilder();
+        GameBookOuterClass.GameBooked.Builder gameBook = GameBookOuterClass.GameBooked.newBuilder();
+        gameBook.setGameBookId(Long.valueOf(gameBookId));
+        request.setGameBooked(gameBook);
+
+        HashMap<String, String> params = new HashMap<>();
+        String token = KFZSDDContentSession.getInstance().findOutHeadSession(app).getToken();
+        params.put(UrlBll.HeadParams.AUTHORIZATION, token);
+
+        APIRequest bannerRequest = APIRequestInstance.postReq(TAG, UrlBll.GameBookApi.GAME_BOOK_POST, params, request.build().toByteArray(), new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.TIPS_BOOK_ICON));
+                doQueryTask(mEdtKeyWord.getText().toString());
+                new KFDialogFragment().show(getSupportFragmentManager(), "book");
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                ToastBuilder.make(app, msg, ToastBuilder.DEFAULT_TOAST_SINGLE);
+            }
+
+        }, HelperUtils.makeErr(getString(R.string.toast_init_data_fail)));
+
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+
+    /**
+     * 格式化搜索结果显示
+     *
+     * @param strKey
+     * @param strCount
+     * @return
+     */
+    private Spanned getHTMLStr(String strKey, String strCount) {
+        return Html.fromHtml("与<font color='#fa6324' size='20'>“" + strKey + "”</font>" + "结果相关" +
+                "共 <font color='#fa6324' size='25'>" + strCount + "</font>" + " 条");
+    }
+
+
+    /**
+     * 下载任务状态的事件
+     *
+     * @param info
+     */
+    @Subscribe
+    public void onEventMainThread(DownloadStatus info) {
+        if (mOnDownCallback == null) {
+            mOnDownCallback = DownBtnUtils.installBtnStatus(mInstallButtonMgrMap);
+        }
+
+        EventDownloadHandler
+                .newInstance(this, mOnDownCallback)
+                .setmTag(TAG)
+                .handlDownloadResult(info);
+    }
+
+    /**
+     * ????这里没分析意义
+     *
+     * @param event
+     */
+    @Subscribe
+    public void onEventMainThread(BigEvent event) {
+        switch (event.getEventTypes()) {
+            case USER_LOGIN_SUCC:
+                doQueryTask(mEdtKeyWord.getText().toString());
+                break;
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+}

+ 218 - 0
app/src/main/java/com/kfzs/duanduan/ActSetting.java

@@ -0,0 +1,218 @@
+package com.kfzs.duanduan;
+
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.Window;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.appstore.utils.string.HexUtils;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.utils.ApkUtils;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.UpdateContentOuterClass;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.UpdateUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.view.DialogUpdateFragment;
+import com.sheep.jiuyan.samllsheep.R;
+import com.zhy.http.okhttp.OkHttpUtils;
+import com.zhy.http.okhttp.callback.StringCallback;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.util.HashMap;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import go.kfzssafe.Kfzssafe;
+import okhttp3.Call;
+
+public class ActSetting extends BaseCompatActivity {
+
+    @BindView(R.id.tv_act_setting_version_info)
+    TextView tvActSettingVersionInfo;
+    @BindView(R.id.txt_content_setting_tips)
+    TextView mTxtTips;
+
+    @BindView(R.id.ll_contant)
+    LinearLayout llContact;
+    private String strUpdateDesc;
+    private UpdateContentOuterClass.UpdateContent mUpdateContent;
+    private Boolean mIsNeedUpdate = null;//null是未检测,其实是是否需要更新
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_setting);
+        TitleBarUtils.getInstance().setTitleFinish(this)
+                .setTitle(this,
+                        getString(R.string.title_activity_setting));
+        ButterKnife.bind(this);
+        String currentPkgVersionName = ApkUtils.getCurrentPkgVersionName(app);
+
+        String strVersion = "V".concat(currentPkgVersionName) + "(" + DataSave.getInstance().getChannelName() + ")";
+        tvActSettingVersionInfo.setText(strVersion);
+        checkUpdate();
+        initData();
+    }
+
+    private void checkUpdate() {
+        HashMap<String, String> params = new HashMap<>();
+        params.put("cp_id", DataSave.getInstance().getChannelName());
+        APIRequest bannerRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.VersionControlApi.APP_VERSION_INFO, params, new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                if (apiResponse.getUpdateContentsList().isEmpty()) {
+                    mTxtTips.setText(R.string.already_lastest_version);
+                    return;
+                }
+                handleVersionCallBack(apiResponse.getUpdateContentsList().get(0));
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                mTxtTips.setText(R.string.already_lastest_version);
+            }
+        }, null);
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+    /**
+     * 检测到有版本列表后的回调
+     *
+     * @param updateContent
+     */
+    private void handleVersionCallBack(UpdateContentOuterClass.UpdateContent updateContent) {
+
+        strUpdateDesc = updateContent.getContent();
+        mUpdateContent = updateContent;
+        Boolean force = updateContent.getForce() == 1;
+        UpdateUtils.getInstance(this).setmUpdateSetting(updateSetting)
+                .setmIsForceUpdate(force)
+                .update(updateContent.getPackageName()
+                        , updateContent.getApkUrl(), updateContent.getVersionNum());
+    }
+
+    private void showForciblyUpdateUI(String strUpdateDesc, boolean isForceUpdate) {
+        String update_time_date = DateFormatUtils.doSecondDate(mUpdateContent.getCreatedTime());
+        new DialogUpdateFragment().init(isForceUpdate,
+                strUpdateDesc,
+                mUpdateContent.getVersionName(),
+                update_time_date,
+                mUpdateContent.getSize(),
+                new DialogUpdateFragment.CancelCallback() {
+                    @Override
+                    public void onCancel() {
+                    }
+                })
+                .show(getSupportFragmentManager(), "update");
+    }
+
+
+    private UpdateUtils.UpdateSetting updateSetting = new UpdateUtils.UpdateSetting() {
+
+        @Override
+        public void updateForce() {
+            mIsNeedUpdate = true;
+            mTxtTips.setText(R.string.found_new_version);
+            showForciblyUpdateUI(strUpdateDesc, true);
+        }
+
+        @Override
+        public void updateSilent() {
+            mIsNeedUpdate = true;
+            mTxtTips.setText(R.string.found_new_version);
+            showForciblyUpdateUI(strUpdateDesc, false);
+        }
+
+        @Override
+        public void updateNormal() {
+            mIsNeedUpdate = true;
+            mTxtTips.setText(R.string.found_new_version);
+            showForciblyUpdateUI(strUpdateDesc, false);
+        }
+
+        @Override
+        public void updateNo() {
+            mIsNeedUpdate = false;
+            mTxtTips.setText(R.string.already_lastest_version);
+        }
+
+        @Override
+        public void udateProcess(int process) {
+
+        }
+
+        @Override
+        public void updateComplete() {
+
+        }
+    };
+
+    private void initData() {
+        OkHttpUtils
+                .get()
+                .url(UrlBll.ReactNtiveApi.RN_SYS_CONF)
+                .build()
+                .execute(new StringCallback() {
+                    @Override
+                    public void onError(Call call, Exception e, int id) {
+                        //                        L.e("onError");
+                    }
+
+                    @Override
+                    public void onResponse(String response, int respenseId) {
+                        if (!response.startsWith("{")) {
+                            byte[] bytes = HexUtils.hexStr2Bytes(response);
+                            byte[] byteDecode = Kfzssafe.XByteDecode(bytes);
+                            response = new String(byteDecode);
+                        }
+                        Log.e("version_update", "response = " + response);
+                        try {
+                            JSONObject jsonObject = new JSONObject(response);
+                            int code = jsonObject.optInt("code");
+                            if (code == 200) {
+                                JSONArray dataObject = jsonObject.optJSONArray("data");
+                                if (dataObject != null && dataObject.length() > 0) {
+                                    for (int i = 0; i < dataObject.length(); i++) {
+                                        JSONObject obj = dataObject.getJSONObject(i);
+                                        TextView textView = new TextView(ActSetting.this);
+                                        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
+                                        textView.setGravity(Gravity.CENTER);
+                                        textView.setTextColor(getResources().getColor(R.color.tv_about_text));
+                                        textView.setText(obj.optString("contact_type") + ":" + obj.optString("description"));
+                                        llContact.addView(textView);
+                                    }
+
+                                }
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                });
+
+    }
+
+
+    @OnClick(R.id.layout_content_setting_update)
+    public void onClick() {
+        checkUpdate();
+    }
+}

+ 112 - 0
app/src/main/java/com/kfzs/duanduan/ActSimple.java

@@ -0,0 +1,112 @@
+package com.kfzs.duanduan;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+import android.widget.FrameLayout;
+
+import com.kfzs.duanduan.bean.VipStyle;
+import com.kfzs.duanduan.fragment.FgtBindPhone;
+import com.kfzs.duanduan.fragment.FgtBookedGame;
+import com.kfzs.duanduan.fragment.FgtChangeNick;
+import com.kfzs.duanduan.fragment.FgtChangePass;
+import com.kfzs.duanduan.fragment.FgtCouponHistory;
+import com.kfzs.duanduan.fragment.FgtForgetPass;
+import com.kfzs.duanduan.fragment.FgtVipCoupon;
+import com.kfzs.duanduan.utils.dlg.TitleBarUtils;
+import com.sheep.jiuyan.samllsheep.R;
+
+import static com.kfzs.duanduan.ActSimple.ACTION.BIND_PHONE;
+import static com.kfzs.duanduan.ActSimple.ACTION.BOOKED_GAME;
+import static com.kfzs.duanduan.ActSimple.ACTION.CHANGE_NICK_NAME;
+import static com.kfzs.duanduan.ActSimple.ACTION.CHANGE_PASS;
+import static com.kfzs.duanduan.ActSimple.ACTION.COUPON_HISTORY;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActSimple</p>
+ * @ <p>Description:一些常用功能的页面,放此页面用Fragment实现</p>
+ * @ date:  2017/8/8 10:03
+ * @ QQ:    315096953
+ */
+
+public class ActSimple extends BaseCompatActivity {
+
+    public final static String INTENT_ACTION = "INTENT_ACTION";
+    private FrameLayout mFrameLayout;
+    private FragmentManager mFragmentManager;
+
+    public enum ACTION {
+        CHANGE_NICK_NAME,//修改昵称页面
+        CHANGE_PASS,//修改密码页面
+        BIND_PHONE,//绑定手机页面
+        COUPON_HISTORY,//优惠券历史列表
+        COUPON_VIP,//已领取优惠券列表
+        BOOKED_GAME,//已经预约的游戏界面
+        FORGET_PASS//忘记密码
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.simple_activity);
+
+        TitleBarUtils.getInstance().setTitleFinish(this);
+
+        mFrameLayout = (FrameLayout) findViewById(R.id.fragment_simple_activity);
+
+        mFragmentManager = getSupportFragmentManager();
+        if (!getIntent().hasExtra(INTENT_ACTION)) {
+            G.showToast("操作请求失败!");
+            finish();
+            return;
+        }
+        doAction((ACTION) getIntent().getSerializableExtra(INTENT_ACTION));
+    }
+
+
+    /**
+     * 主要执行方法
+     */
+    private void doAction(ACTION action) {
+        switch (action) {
+            case CHANGE_NICK_NAME:
+                TitleBarUtils.getInstance().setTitle(this, "修改昵称");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtChangeNick(),
+                        true, CHANGE_NICK_NAME.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case CHANGE_PASS:
+                TitleBarUtils.getInstance().setTitle(this, "修改密码");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtChangePass(),
+                        true, CHANGE_PASS.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case BIND_PHONE:
+                TitleBarUtils.getInstance().setTitle(this, "绑定手机");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtBindPhone(),
+                        false, BIND_PHONE.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case COUPON_HISTORY:
+                TitleBarUtils.getInstance().setTitle(this, "xxxxx");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtCouponHistory(),
+                        false, COUPON_HISTORY.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case COUPON_VIP:
+                TitleBarUtils.getInstance().setTitle(this,
+                        VipStyle.getInstance().getViptypename() + "用户福利-兑换记录");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtVipCoupon(),
+                        false, COUPON_HISTORY.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case BOOKED_GAME:
+                TitleBarUtils.getInstance().setTitle(this, "已经预约");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtBookedGame(),
+                        false, BOOKED_GAME.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case FORGET_PASS:
+                TitleBarUtils.getInstance().setTitle(this, "忘记密码");
+                replaceSupportFragment(R.id.fragment_simple_activity, new FgtForgetPass(),
+                        false, BOOKED_GAME.toString(), R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+
+        }
+    }
+
+}

+ 331 - 0
app/src/main/java/com/kfzs/duanduan/ActSplash.java

@@ -0,0 +1,331 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import com.android.volleyplus.Response;
+import com.android.volleyplus.VolleyError;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.request.target.Target;
+import com.kf.utils.KFLog;
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.bll.AppBaseBll;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.SplashOuterClass;
+import com.kfzs.duanduan.proto.UpdateContentOuterClass;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.dlg.UpdateUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.view.DialogUpdateFragment;
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.concurrent.ExecutionException;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+/**
+ * Created by HooRang on 2017/3/3.
+ */
+public class ActSplash extends BaseCompatActivity {
+
+    private final static int SECOND_DURATION = 3000;//首页闪屏延时毫秒。
+    private long mLngLaunchTime = 0L;
+
+    private String strUpdateDesc;
+
+    @BindView(R.id.activity_splash_image)
+    ImageView mImageView;
+
+    private String mStrSplashImgUrl;
+    private UpdateContentOuterClass.UpdateContent mUpdateContent;
+    private boolean mIsClickSplashImg = false;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题栏
+        new AppBaseBll().loadVipStyleAll(this);
+        StatusBarUtils.setTransparent(this);
+        super.onCreate(savedInstanceState);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏状态栏
+        setContentView(R.layout.activity_splash);
+
+        ButterKnife.bind(this);
+        setSplashImage();
+        mLngLaunchTime = System.currentTimeMillis();
+        checkUpdate();
+    }
+
+
+    /**
+     * 检查更新
+     */
+    private void checkUpdate() {
+        HashMap<String, String> params = new HashMap<>();
+        params.put("cp_id", DataSave.getInstance().getChannelName());
+        APIRequest bannerRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.VersionControlApi.APP_VERSION_INFO, params, new ResponseNetworkTask() {
+
+            @Override
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                if (apiResponse.getUpdateContentsList().isEmpty()) {
+                    delayStartActivity();//如果更新版本列表为空,直接延时启动主页
+                    return;
+                }
+                handleVersionCallBack(apiResponse.getUpdateContentsList().get(0));
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                startMainActivity();
+            }
+        }, null);
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+
+    /**
+     * 检测到有版本列表后的回调
+     *
+     * @param updateContent
+     */
+    private void handleVersionCallBack(UpdateContentOuterClass.UpdateContent updateContent) {
+        strUpdateDesc = updateContent.getContent();
+        this.mUpdateContent = updateContent;
+        Boolean force = updateContent.getForce() == 1;
+
+        UpdateUtils.getInstance(this).setmUpdateSetting(updateSetting)
+                .setmIsForceUpdate(force)
+//                .setmIntFileLength(Integer.valueOf(updateContent.getSize()))
+                .update(updateContent.getPackageName()
+                        , updateContent.getApkUrl(), updateContent.getVersionNum());
+
+//        CheckUpdate checkUpdate = new CheckUpdate(force, updateContent.getVersionNum(),
+//                updateContent.getPackageName(), updateContent.getApkUrl());
+//        Updater.getInstance().init(this.getApplication(), new UpdateCheckSetting(checkUpdate));
+//        Updater.getInstance().update(false);
+    }
+
+    private UpdateUtils.UpdateSetting updateSetting = new UpdateUtils.UpdateSetting() {
+
+        @Override
+        public void updateForce() {
+            showForciblyUpdateUI(strUpdateDesc, true);
+        }
+
+        @Override
+        public void updateSilent() {
+
+        }
+
+        @Override
+        public void updateNormal() {
+            showForciblyUpdateUI(strUpdateDesc, false);
+        }
+
+        @Override
+        public void updateNo() {
+            delayStartActivity();
+        }
+
+        @Override
+        public void udateProcess(int process) {
+
+        }
+
+        @Override
+        public void updateComplete() {
+
+        }
+    };
+
+
+    /**
+     * 延时启动主页
+     */
+    private void delayStartActivity() {
+        final long duration = (System.currentTimeMillis() - mLngLaunchTime);
+        if (duration >= SECOND_DURATION) {
+            startMainActivity();
+            return;
+        }
+
+        Handler handler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                super.handleMessage(msg);
+                if (!isFinishing()) {
+                    startMainActivity();
+                }
+            }
+        };
+        handler.sendEmptyMessageDelayed(0, SECOND_DURATION - duration);
+    }
+
+    private void showForciblyUpdateUI(String strUpdateDesc, boolean isForceUpdate) {
+        String update_time_date = DateFormatUtils.doSecondDate(mUpdateContent.getCreatedTime());
+        new DialogUpdateFragment().init(isForceUpdate,
+                strUpdateDesc,
+                mUpdateContent.getVersionName(),
+                update_time_date,
+                mUpdateContent.getSize(),
+                new DialogUpdateFragment.CancelCallback() {
+                    @Override
+                    public void onCancel() {
+                        startMainActivity();
+                    }
+                })
+                .show(getSupportFragmentManager(), "update");
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        KFZSNetwork.stopByTag(TAG);
+    }
+
+
+    /**
+     * 直接跳主页
+     */
+    private void startMainActivity() {
+        this.finish();
+        if (!mIsClickSplashImg) {
+            startActivity(new Intent(this, ActMain.class));
+        }
+    }
+
+
+    /**
+     * 加载闪屏图片,网络端或者本地端
+     */
+    private void setSplashImage() {
+        final String imagePath = Environment.getExternalStorageDirectory().getAbsolutePath()
+                + UrlBll.AdvertisementApi.SPLASH_ADVERTISEMENT_FILE_NAME
+                + UrlBll.AdvertisementApi.SPLASH_ADVERTISEMENT_IMAGE_NAME;
+        KFLog.d(TAG, "setSplashImage: " + imagePath);
+
+        APIRequest bannerRequest = APIRequestInstance.getReqUrl(TAG, UrlBll.AdvertisementApi.SPLASH_ADVERTISEMENT, null, new ResponseNetworkTask() {
+            public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                mStrSplashImgUrl = apiResponse.getSplash().getImageUrl();
+                KFLog.d(TAG, "onSuccess: " + mStrSplashImgUrl);
+                if (TextUtils.isEmpty(mStrSplashImgUrl)) {
+                    Glide.with(ActSplash.this).load(imagePath).diskCacheStrategy(DiskCacheStrategy.RESULT).skipMemoryCache(true).error(R.drawable.app_splash).into(mImageView);
+                } else {
+                    Glide.with(ActSplash.this).load(mStrSplashImgUrl).diskCacheStrategy(DiskCacheStrategy.RESULT).skipMemoryCache(true).error(R.drawable.app_splash).into(mImageView);
+                    initSplashImgListener(apiResponse.getSplash());
+                    new Thread(new Runnable() {
+                        @Override
+                        public void run() {
+                            downloadSplashImage(mStrSplashImgUrl);
+                        }
+                    }).start();
+                }
+            }
+
+            @Override
+            public void onFail(int code, String msg) {
+                KFLog.d(TAG, "闪屏图片加载失败:code: " + code + "\nmsg: " + msg);
+                Glide.with(ActSplash.this).load(imagePath).diskCacheStrategy(DiskCacheStrategy.NONE)
+                        .skipMemoryCache(true).error(R.drawable.app_splash).into(mImageView);
+                delayStartActivity();
+            }
+        }, new Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError volleyError) {
+                startMainActivity();
+            }
+        });
+        KFZSNetwork.addRequest(bannerRequest);
+    }
+
+
+    /**
+     * 加载闪屏图片点击的监听
+     *
+     * @param splash
+     */
+    private void initSplashImgListener(final SplashOuterClass.Splash splash) {
+        mImageView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent;
+                switch (splash.getType()) {//游戏详情
+                    case 1:
+                        intent = new Intent(ActSplash.this, ActGameDetails.class);
+                        intent.putExtra(KFIntentKeys.EXTRA_GAME_ID, splash.getParam() + "");
+                        break;
+                    case 2://H5页面
+                        intent = new Intent(ActSplash.this, ActWeb.class);
+                        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_URL, splash.getHtmlUrl());
+                        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_TITLE, "闪屏推荐");
+                        break;
+                    default:
+                        return;
+                }
+                mIsClickSplashImg = true;
+                startActivity(intent);
+            }
+        });
+    }
+
+
+    /**
+     * 下载闪屏图片并保存
+     *
+     * @param splashImageUri 图片网址
+     */
+    private void downloadSplashImage(String splashImageUri) {
+        if (null != splashImageUri) {
+            try {
+                Bitmap bitmap = Glide.with(this).load(splashImageUri).asBitmap().
+                        into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get();
+                if (null != bitmap) {
+                    File appDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), UrlBll.AdvertisementApi.SPLASH_ADVERTISEMENT_FILE_NAME);
+                    if (!appDir.exists()) {
+                        appDir.mkdir();
+                    }
+                    File file = new File(appDir, UrlBll.AdvertisementApi.SPLASH_ADVERTISEMENT_IMAGE_NAME);
+                    file.delete();//直接删除,没必要判断是否存在等。
+                    FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
+                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
+                    fos.flush();
+                    fos.close();
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            KFLog.d(TAG, "闪屏图片为空:SplashImageURI is null");
+        }
+    }
+}

+ 67 - 0
app/src/main/java/com/kfzs/duanduan/ActTest.java

@@ -0,0 +1,67 @@
+package com.kfzs.duanduan;
+
+import android.os.Bundle;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.view.ArrowDownloadButton;
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ActTest</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/15 17:28
+ * @ QQ:    315096953
+ */
+public class ActTest extends BaseCompatActivity {
+
+
+    private int count;
+    private ArrowDownloadButton mBtnDown;
+    private float progress;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.act_test);
+        mBtnDown = findViewById(R.id.btn_act_test);
+        mBtnDown.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                progress = 0;
+                mBtnDown.reset();
+                if ((count % 2) == 0) {
+                    mBtnDown.startAnimating();
+                    final Timer timer = new Timer();
+                    timer.schedule(new TimerTask() {
+                        @Override
+                        public void run() {
+                            mBtnDown.post(new Runnable() {
+
+                                @Override
+                                public void run() {
+                                    progress = progress + 1;
+                                    mBtnDown.setProgress(progress);
+                                    if (progress == 100)
+                                        timer.cancel();
+                                }
+                            });
+                        }
+                    }, 800, 20);
+                } else {
+                    progress = 0;
+                    mBtnDown.reset();
+                }
+                count++;
+            }
+        });
+    }
+
+}

+ 428 - 0
app/src/main/java/com/kfzs/duanduan/ActUser.java

@@ -0,0 +1,428 @@
+package com.kfzs.duanduan;
+
+import android.app.ProgressDialog;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.StringRes;
+import android.support.design.widget.AppBarLayout;
+import android.support.design.widget.CollapsingToolbarLayout;
+import android.support.v4.widget.NestedScrollView;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.appstore.utils.update.UriUtils;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.data.graph.provider.user.UserBean;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.datashare.provider.session.SessionBean;
+import com.kfzs.duanduan.event.UserEvent;
+import com.kfzs.duanduan.fragment.UserSelfInfoShowFragment;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.PictureAssetOuterClass;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.net.ApiUploadFileCallBack;
+import com.kfzs.duanduan.utils.net.UploadHttpURLConnectionUtils;
+import com.sheep.jiuyan.samllsheep.R;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import mdl.sinlov.android.log.ALog;
+import top.zibin.luban.Luban;
+import top.zibin.luban.OnCompressListener;
+
+public class ActUser extends PicBottomSheetActivity {
+
+    public static final int WHAT_COMPRESS_IMG_START = -100;
+    public static final int WHAT_COMPRESS_IMG_SUCCESS = -101;
+    public static final int WHAT_COMPRESS_IMG_ERROR = -102;
+    public static final int WHAT_SEND_IMG_START = -103;
+    public static final int WHAT_SEND_IMG_IN_PROGRESS = -104;
+    public static final int WHAT_SEND_IMG_SUCCESS = -105;
+    public static final int WHAT_SEND_IMG_ERROR = -106;
+    public static final int JOB_CHANGE_TITLE = 1;
+    public static final int JOB_CODE_LOGIN = 2 << 1;
+    //    public static final int JOB_CODE_SELF_CENTER = 3 << 1;
+    public static final int JOB_CODE_SELF_INFO_SHOW = 4 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_PASSWORD = 5 << 1;
+    public static final int JOB_CODE_SELF_CHANGE_NICKNAME = 6 << 1;
+    public static final int JOB_CODE_SELF_BIND_PHONE = 7 << 1;
+    public static final String KEY_SKIP_JOB_CODE = ActUser.class.getCanonicalName() + ".job";
+
+    @BindView(R.id.fl_act_user_replace_fgt)
+    FrameLayout flActLoginReplaceFgt;
+    private AppBarLayout appBarLayout;
+    private ActionBar supportActionBar;
+    private CollapsingToolbarLayout collapsingToolbarLayout;
+    private Toolbar toolbar;
+    private NestedScrollView nestedScrollView;
+    private ImageView imgUserIcon;
+    private TextView tvButtonUserAvatarEdit;
+    private String titleString = "";
+    private Bundle extras;
+
+    private ProgressDialog userAvatarProgressDialog;
+    private CollapsingToolbarLayoutState collapsingToolbarLayoutState;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        EventBus.getDefault().register(this);
+        setContentView(R.layout.activity_user);
+
+        ButterKnife.bind(this);
+        toolbar = (Toolbar) findViewById(R.id.toolbar_user);
+        setSupportActionBar(toolbar);
+        supportActionBar = getSupportActionBar();
+        if (null != supportActionBar) {
+            supportActionBar.setDisplayHomeAsUpEnabled(true);
+        }
+        initViewByID();
+        initUploadImg();
+        initListeners();
+        extras = getIntent().getExtras();
+        if (extras != null) {
+            int skipCode = extras.getInt(KEY_SKIP_JOB_CODE, 0);
+            UserEvent event = new UserEvent();
+            event.setSkipCode(skipCode);
+            filterUIByJobCode(event);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+    }
+
+    private void initUploadImg() {
+        initPicBottomSheetHandler();
+    }
+
+    private void filterUIByJobCode(UserEvent userEvent) {
+        int skipCode = userEvent.getSkipCode();
+        filterAppBarByJobChangeTitle(userEvent, skipCode);
+        switch (skipCode) {
+            case JOB_CHANGE_TITLE:
+                setActionBarTitle(userEvent.getTitleID());
+                letAppBarExpandedAndNested(userEvent);
+                break;
+            case JOB_CODE_LOGIN:
+                Bundle bundle = new Bundle();
+                bundle.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_LOGIN);
+                skip2Activity(ActAuth.class, bundle);
+                break;
+//            case JOB_CODE_SELF_CENTER:    这个垃圾类为什么这么大?这就是原因,全是Goto无注释的写法,艹。Sign.Diao
+//                setActionBarTitle(R.string.title_user_activity_self_center);
+//                replaceSupportFragment(R.id.fl_act_user_replace_fgt, new UserSelfCenterFragment(), true,
+//                        UserEvent.SELF_CENTER, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+//                break;
+            case JOB_CODE_SELF_INFO_SHOW:
+                replaceSupportFragment(R.id.fl_act_user_replace_fgt, new UserSelfInfoShowFragment(), true,
+                        UserEvent.SELF_INFO_SHOW, R.anim.fgt_fade_in, R.anim.fgt_fade_out);
+                break;
+            case JOB_CODE_SELF_CHANGE_PASSWORD:
+                Bundle changePsd = new Bundle();
+                changePsd.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_SELF_CHANGE_PASSWORD);
+                skip2Activity(ActAuth.class, changePsd);
+                break;
+            case JOB_CODE_SELF_CHANGE_NICKNAME:
+                Bundle changeNickName = new Bundle();
+                changeNickName.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_SELF_CHANGE_NICKNAME);
+                skip2Activity(ActAuth.class, changeNickName);
+                break;
+            case JOB_CODE_SELF_BIND_PHONE:
+                Bundle bindPhone = new Bundle();
+                bindPhone.putInt(ActAuth.KEY_SKIP_JOB_CODE, ActAuth.JOB_CODE_SELF_BIND_PHONE);
+                skip2Activity(ActAuth.class, bindPhone);
+                break;
+            default:
+                ALog.w("develop use error JOB skipCode: " + skipCode);
+                break;
+        }
+    }
+
+    private void filterAppBarByJobChangeTitle(UserEvent event, int userEvent) {
+        Integer titleID = event.getTitleID();
+        if (userEvent == JOB_CHANGE_TITLE) {
+            switch (titleID) {
+                case R.string.title_user_activity_self_info:
+                    tvButtonUserAvatarEdit.setVisibility(View.VISIBLE);
+                    break;
+                default:
+                    tvButtonUserAvatarEdit.setVisibility(View.GONE);
+                    break;
+            }
+        }
+        // other JOB not filter show tvButtonUserAvatarEdit
+    }
+
+    private void initViewByID() {
+        appBarLayout = (AppBarLayout) findViewById(R.id.appbar_user);
+        collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_user);
+        nestedScrollView = (NestedScrollView) findViewById(R.id.nsv_content_user);
+        this.imgUserIcon = (ImageView) findViewById(R.id.img_act_user_icon_large);
+        this.tvButtonUserAvatarEdit = (TextView) findViewById(R.id.tv_act_user_avatar_edit);
+        initBottomSheetLayoutByID(R.id.bottom_sheet_layout_act_user, R.string.title_bottom_select_image_view);
+        userAvatarProgressDialog = new ProgressDialog(this);
+        userAvatarProgressDialog.setCancelable(false);
+        userAvatarProgressDialog.setCanceledOnTouchOutside(false);
+    }
+
+    private void initListeners() {
+        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
+            @Override
+            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
+                if (verticalOffset == 0) {
+                    if (collapsingToolbarLayoutState != CollapsingToolbarLayoutState.EXPANDED) {
+                        collapsingToolbarLayout.setTitle("");
+                        collapsingToolbarLayoutState = CollapsingToolbarLayoutState.EXPANDED;
+                    } else {
+                        collapsingToolbarLayout.setTitle("");
+                    }
+                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
+                    if (collapsingToolbarLayoutState != CollapsingToolbarLayoutState.COLLAPSED) {
+                        collapsingToolbarLayout.setTitle(titleString);
+                        collapsingToolbarLayoutState = CollapsingToolbarLayoutState.COLLAPSED;
+                    }
+                } else {
+                    if (collapsingToolbarLayoutState != CollapsingToolbarLayoutState.INTERMEDIATE) {
+                        if (collapsingToolbarLayoutState == CollapsingToolbarLayoutState.COLLAPSED) {
+                            // do mid
+                            collapsingToolbarLayout.setTitle("");
+                        }
+                        collapsingToolbarLayout.setTitle("");
+                        collapsingToolbarLayoutState = CollapsingToolbarLayoutState.INTERMEDIATE;
+                    }
+                }
+            }
+        });
+        imgUserIcon.setOnClickListener(new OnUserIconClick());
+        tvButtonUserAvatarEdit.setOnClickListener(new OnChangeUserAvatarClick());
+        UserBean headUser = DDProviderHelper.getInstance().getLastUserBean(app);
+        if (headUser != null) {
+            String avatar = headUser.getAvatar();
+            showUserAvatar(avatar);
+        }
+    }
+
+    private enum CollapsingToolbarLayoutState {
+        EXPANDED,
+        COLLAPSED,
+        INTERMEDIATE
+    }
+
+    private void showUserAvatar(String avatar) {
+        if (!TextUtils.isEmpty(avatar)) {
+            ALog.d(avatar);
+            Glide.with(this)
+                    .load(avatar)
+                    .error(R.drawable.ic_user_head_default)
+                    .into(imgUserIcon);
+        }
+    }
+
+    @Subscribe
+    public void onEventMainThread(UserEvent userEvent) {
+        filterUIByJobCode(userEvent);
+    }
+
+    @Override
+    protected void callBackSelectedImageUriByBottomSheet(Uri selectedImageUri) {
+        ALog.d("callBackSelectedImageUriByBottomSheet: " + selectedImageUri);
+        sendSafeHandle(WHAT_COMPRESS_IMG_START, selectedImageUri);
+        userAvatarProgressDialog.setMessage("上传中");
+        userAvatarProgressDialog.show();
+    }
+
+    @Override
+    public void safeHandleCallBack(WeakReference<PicBottomSheetActivity> wrAct, int what, Object obj) {
+        switch (what) {
+            case WHAT_COMPRESS_IMG_START:
+                final Uri selectedImageUri = (Uri) obj;
+                final File file = UriUtils.absoluteImageFile(wrAct.get(), selectedImageUri);
+                if (file != null) {
+                    compressImageByLuBan(selectedImageUri, file);
+                } else {
+                    //TODO 压缩图片错误 关闭 loading UI
+                    hideAvatarProgressDialogByMessage("图片选择错误,取消上传");
+                }
+                break;
+            case WHAT_COMPRESS_IMG_ERROR:
+                //TODO 压缩图片错误 关闭 loading UI
+                hideAvatarProgressDialogByMessage("压缩图片错误 取消上传");
+                break;
+            case WHAT_COMPRESS_IMG_SUCCESS:
+                File compressImageFile = (File) obj;
+                if (compressImageFile != null) {
+                    sendSafeHandle(WHAT_SEND_IMG_START, compressImageFile);
+                } else {
+                    sendSafeHandle(WHAT_COMPRESS_IMG_ERROR, "压缩图片输出错误,取消上传");
+                }
+                break;
+            case WHAT_SEND_IMG_START:
+                File compressImageSuccess = (File) obj;
+                UploadHttpURLConnectionUtils uploadHttpURLConnectionUtils = new UploadHttpURLConnectionUtils();
+                String token = findOutNewUserToken(uploadHttpURLConnectionUtils);
+                uploadHttpURLConnectionUtils.setSecurityValue(token);
+                uploadHttpURLConnectionUtils.setErrorMsgOutOfTime(getString(R.string.network_conf_timeout));
+                uploadHttpURLConnectionUtils.setUploadFileCallBack(new ApiUploadFileCallBack() {
+                    @Override
+                    public void uploadProgress(int progress) {
+                        sendSafeHandle(WHAT_SEND_IMG_IN_PROGRESS, progress);
+                    }
+
+                    @Override
+                    public void onApiSuccess(ApiResponseOuterClass.ApiResponse response) {
+                        ALog.d(response.toString());
+                        PictureAssetOuterClass.PictureAsset pictureAsset = response.getAsset();
+                        if (pictureAsset != null) {
+                            String pictureAssetUrl = pictureAsset.getUrl();
+                            if (TextUtils.isEmpty(pictureAssetUrl)) {
+                                sendSafeHandle(WHAT_SEND_IMG_ERROR, "上传图片显示URL失败");
+                            } else {
+                                sendSafeHandle(WHAT_SEND_IMG_SUCCESS, pictureAssetUrl);
+                            }
+                        } else {
+                            sendSafeHandle(WHAT_SEND_IMG_ERROR, "上传图片显示失败");
+                        }
+                    }
+
+                    @Override
+                    public void onApiUnauthorized(ApiResponseOuterClass.ApiResponse response) {
+                        sendSafeHandle(WHAT_SEND_IMG_ERROR, response.getMsg());
+                    }
+
+                    @Override
+                    public void onApiError(int errorCode, ApiResponseOuterClass.ApiResponse response) {
+                        sendSafeHandle(WHAT_SEND_IMG_ERROR, response.getMsg());
+                    }
+
+                    @Override
+                    public void onParseError(int errorCode, Exception e) {
+                        sendSafeHandle(WHAT_SEND_IMG_ERROR, e.getMessage());
+                    }
+                });
+                uploadHttpURLConnectionUtils.uploadFileByThread(compressImageSuccess, UrlBll.UploadPic.AVATAR);
+                break;
+            case WHAT_SEND_IMG_ERROR:
+                //TODO send Error 上传错误 关闭 loading UI
+                String imageError = (String) obj;
+                String imageErrorMsg = "上传失败: " + imageError;
+                ALog.d(imageErrorMsg);
+                hideAvatarProgressDialogByMessage(imageErrorMsg);
+                break;
+            case WHAT_SEND_IMG_IN_PROGRESS:
+                int progress = (int) obj;
+                String imageProgressMsg = "上传中: " + progress + "%";
+                ALog.d(imageProgressMsg);
+                userAvatarProgressDialog.setMessage(imageProgressMsg);
+                break;
+            case WHAT_SEND_IMG_SUCCESS:
+                String pictureAssetUrl = String.valueOf(obj);
+                showUserAvatar(pictureAssetUrl);
+                String imgSuccessMsg = "上传成功!";
+                hideAvatarProgressDialogByMessage(imgSuccessMsg);
+                break;
+        }
+    }
+
+    protected String findOutNewUserToken(UploadHttpURLConnectionUtils uploadHttpURLConnectionUtils) {
+        SessionBean outHeadSession = KFZSDDContentSession.getInstance().findOutHeadSession(app);
+        if (outHeadSession != null) {
+            String token = outHeadSession.getToken();
+            if (!TextUtils.isEmpty(token)) {
+                return token;
+            } else {
+                return "";
+            }
+        } else {
+            return "";
+        }
+    }
+
+    protected void hideAvatarProgressDialogByMessage(String msg) {
+        showToast(msg);
+        userAvatarProgressDialog.hide();
+    }
+
+
+    private void compressImageByLuBan(final Uri selectedImageUri, File file) {
+        Luban.get(this)
+                .load(file)                     //传人要压缩的图片
+                .putGear(Luban.THIRD_GEAR)      //设定压缩档次,默认三挡
+                .setCompressListener(new OnCompressListener() {
+
+                    @Override
+                    public void onStart() {
+                        // TODO 压缩开始前调用,可以在方法内启动 loading UI
+                    }
+
+                    @Override
+                    public void onSuccess(File file) {
+                        sendSafeHandle(WHAT_COMPRESS_IMG_SUCCESS, file);
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+                        sendSafeHandle(WHAT_COMPRESS_IMG_ERROR, selectedImageUri);
+                    }
+                }).launch();
+    }
+
+    @Override
+    protected boolean showSheetImageView(ImageView imageView, Uri imageUri, int size) {
+        Glide.with(ActUser.this)
+                .load(imageUri)
+                .centerCrop()
+                .crossFade()
+                .into(imageView);
+        return true;
+    }
+
+    protected void letAppBarExpandedAndNested(UserEvent userEvent) {
+        appBarLayout.setExpanded(userEvent.getIsExpandedAppBar(), userEvent.getIsExpandedAnimAppBar());
+        nestedScrollView.setNestedScrollingEnabled(userEvent.getIsNestedScrollingAppBar());
+    }
+
+    protected void setActionBarTitle(@StringRes int resId) {
+        if (null != collapsingToolbarLayout) {
+            titleString = getString(resId);
+            collapsingToolbarLayout.setTitle(titleString);
+        }
+    }
+
+    private class OnUserIconClick implements View.OnClickListener {
+        @Override
+        public void onClick(View v) {
+            if (KFZSDDContentSession.getInstance().isHasHeadSession(app)) {
+                if (!titleString.equals(getString(R.string.title_user_activity_self_info))) {
+//                    UserEvent userEvent = new UserEvent();
+//                    userEvent.setSkipCode(JOB_CODE_SELF_INFO_SHOW);
+//                    EventBus.getDefault().post(userEvent);
+                    SkipUtils.getInstance().goUserCenter(ActUser.this);
+
+                }
+            }
+        }
+    }
+
+    private class OnChangeUserAvatarClick implements View.OnClickListener {
+        @Override
+        public void onClick(View v) {
+            callSheetImageViewPop();
+        }
+    }
+}

+ 367 - 0
app/src/main/java/com/kfzs/duanduan/ActWeb.java

@@ -0,0 +1,367 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.webkit.JavascriptInterface;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import com.kfzs.android.view.RunThreadUtils;
+import com.kfzs.android.view.widget.SafeWebView;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.data.graph.provider.current.Current;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.net.OnURLParseByJS;
+import com.kfzs.duanduan.utils.ShareUtils;
+import com.sheep.jiuyan.samllsheep.R;
+import com.umeng.analytics.MobclickAgent;
+import com.umeng.socialize.UMShareAPI;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import mdl.sinlov.android.log.ALog;
+
+import static com.kfzs.duanduan.bean.KFIntentKeys.EXTRA_WEBVIEW_NO_TITLE;
+
+/**
+ * all web view
+ * Created by HooRang on 2017/2/17.
+ */
+public class ActWeb extends BaseCompatActivity {
+
+    public static final String BEHAVIOR_GAME_BOOK = "behavior:act:webView:game_book";
+
+    public
+    @BindView(R.id.tv_nav_label)
+    TextView tvLabel;
+
+    @BindView(R.id.activity_webview)
+    SafeWebView mWebView;
+
+    @BindView(R.id.ibtn_act_webview)
+    ImageButton btnBack;
+
+    @BindView(R.id.btn_share)
+    ImageButton btnShare;
+
+    private String extraUrl;
+    private String shareUrl;
+    private String extraTitle;
+    private String extraGameBookID;
+    private String extraGameID;
+    private String behavior;
+    private String extraShareImgUrl;
+    private WebSettings webViewSettings;
+    private OnURLParseByJS urlParseByJS;
+    private String packageName;
+    private String gameVer;
+    private String gameSize;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_webview);
+
+        ButterKnife.bind(this);
+        webViewSettings = mWebView.getSettings();
+        webViewSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+        mWebView.autoSettingWebViewDefaultByWideViewPort(this, false);
+        behavior = getIntent().getStringExtra(KFIntentKeys.EXTRA_BEHAIOR);
+        extraUrl = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_URL);
+        extraTitle = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_TITLE);
+        extraShareImgUrl = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_SHARE_IMGURL);
+        extraGameID = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_ID);
+        extraGameBookID = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_BOOK_ID);
+        packageName = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_PACKAGENAME);
+        gameVer = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_VERSION);
+        gameSize = getIntent().getStringExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_SIZE);
+        if (getIntent().hasExtra(EXTRA_WEBVIEW_NO_TITLE)) {//不显示标题
+            findViewById(R.id.appbar_act_webview).setVisibility(View.GONE);
+        }
+
+
+        mWebView.addJavascriptInterface(new PublicJavaScript(), "PublicJavaScript");
+        urlParseByJS = new JSCallFilter();
+        filterURLByBehavior();
+        loadUrl();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        webViewSettings.setJavaScriptEnabled(true);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        webViewSettings.setJavaScriptEnabled(false);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mWebView.setVisibility(View.GONE);
+        mWebView.removeAllViews();
+        mWebView.destroy();
+    }
+
+    private void loadUrl() {
+        tvLabel.setText(extraTitle);
+        ALog.d("loadUrl: " + extraUrl);
+        //        extraUrl = "http://app.haowan.yunduanzs.cn/static/index.html?type=android&dd_channel=family&gamebookid=21&gameid=132#/";
+        mWebView.setWebChromeClient(new WebChromeClient());
+        mWebView.setWebViewClient(new WebViewClient() {
+            boolean once = true;
+
+            @Override
+            public boolean shouldOverrideUrlLoading(WebView view, String url) {
+                try {
+                    if (filterURLByJS(url, "openActivity"))
+                        return true;
+
+                    if (url.contains(".apk") && !url.contains("channel") && once) {
+                        // 创建下载请求
+                        once = false;
+                        setUmengOnEvent(extraTitle);
+                        Intent intent = new Intent();
+                        intent.setAction(Intent.ACTION_VIEW);
+                        intent.addCategory(Intent.CATEGORY_BROWSABLE);
+                        intent.setData(Uri.parse(url));
+                        startActivity(intent);
+
+
+//                        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
+//                        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+//                        request.setTitle(extraTitle);
+//                        request.setDescription("文件下载中...");
+//                        File saveFile = new File(Environment.getExternalStorageDirectory(), extraTitle + ".apk");
+//                        request.setDestinationUri(Uri.fromFile(saveFile));
+//                        DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
+//                        long downloadId = manager.enqueue(request);
+//
+//                        FileDownloader.start(url);
+//
+//                        DownLoadInfo task = new DownLoadInfo();
+//                        task.setMIconUrl(extraShareImgUrl);
+//                        task.setMGameName(extraTitle);
+//                        task.setMGameID(Integer.valueOf(extraGameID));
+//                        task.setMDownloadUrl(url);
+//                        task.setMPackageName(packageName);
+//                        task.setMVersionCode(Integer.parseInt(TextUtils.isEmpty(gameVer) ? "1.0" : gameVer));
+//                        task.setMTotalSize(Double.valueOf(gameSize));
+//                        downloadTaskService.addDownloadTask(task);
+//
+//                        EventBus.getDefault().post(BigEvent.get()
+//                                .setEventTypes(EventTypes.TIPS_DOWN_ICON));
+//
+//                        startActivity(new Intent(ActWeb.this, ActDownloadMgr.class));
+//                        ActWeb.this.finish();
+                        return true;
+                    }
+                    view.loadUrl(url);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return true;
+            }
+        });
+        mWebView.loadUrl(extraUrl);
+    }
+
+
+    private void setUmengOnEvent(String extInfo) {
+        Map<String, String> map = new HashMap<>();
+        map.put("gameUnique", extInfo);
+        MobclickAgent.onEvent(ActWeb.this, "GameDownload", map);
+    }
+
+
+    private void filterURLByBehavior() {
+        ALog.d("extraGameID: " + extraGameID + " |extraGameBookID: " + extraGameBookID);
+        String channelName = DataSave.getInstance().getChannelName();
+        if (TextUtils.equals(behavior, BEHAVIOR_GAME_BOOK)) {
+            shareUrl = extraUrl + "?type=share&dd_channel=" + channelName;
+            extraUrl = extraUrl + "?type=android&dd_channel=" + channelName;
+            if (!TextUtils.isEmpty(extraGameID) && !TextUtils.isEmpty(extraGameBookID)) {
+                extraUrl = extraUrl + "&gamebookid=" + extraGameBookID + "&gameid=" + extraGameID;
+                shareUrl = shareUrl + "&gamebookid=" + extraGameBookID + "&gameid=" + extraGameID;
+            } else {
+                showToast("订阅游戏参数错误\nbehavior: " + behavior + "\nGameID: " + extraGameID + "\nGameBookID: " + extraGameBookID);
+                ActWeb.this.finish();
+            }
+        }
+        filterShareBtn();
+    }
+
+    private void filterShareBtn() {
+        if (TextUtils.equals(behavior, BEHAVIOR_GAME_BOOK)) {
+            btnShare.setVisibility(View.VISIBLE);
+        } else {
+            btnShare.setVisibility(View.GONE);
+        }
+    }
+
+    private boolean filterURLByJS(String url, String router) {
+        Uri uri = Uri.parse(url);
+        String scheme = uri.getScheme();
+        if (scheme.equals("js")) {
+            if (uri.getAuthority().equals(router)) {
+                Set<String> collection = uri.getQueryParameterNames();
+                if (urlParseByJS != null) {
+                    String who = "";
+                    String where = "";
+                    String doJob = "";
+                    for (String name : collection) {
+                        if (name.equals("who")) {
+                            who = uri.getQueryParameter(name);
+                        }
+                        if (name.equals("where")) {
+                            where = uri.getQueryParameter(name);
+                        }
+                        if (name.equals("do")) {
+                            doJob = uri.getQueryParameter(name);
+                        }
+                    }
+                    urlParseByJS.whoWhereDo(who, where, doJob);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @OnClick({R.id.ibtn_act_webview, R.id.btn_share})
+    public void onClick(View v) {
+        int resId = v.getId();
+        switch (resId) {
+            case R.id.ibtn_act_webview:
+                onBackPressed();
+                //                this.finish();
+                break;
+            case R.id.btn_share:
+                popShare();
+                break;
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (KFZSApp.actMain == null) {
+            Intent intent = new Intent(this, ActMain.class);
+            startActivity(intent);
+        }
+        this.finish();
+    }
+
+    private void popShare() {
+        ALog.d("now share url: " + shareUrl);
+        if (!TextUtils.isEmpty(shareUrl) && shareUrl.toLowerCase().startsWith("http")) {
+            new ShareUtils().showShareView(this, shareUrl, extraTitle, extraShareImgUrl, extraTitle);
+        } else {
+            String msg = "分享错误,请联系客服!\n错误链接为: " + shareUrl;
+            Log.w("DD_ERROR", msg);
+            showToast(msg);
+        }
+    }
+
+    private class JSCallFilter implements OnURLParseByJS {
+
+        private static final String WHO_WEB = "1";
+        private static final String WHERE_CLOSE_SELF = "11";
+        private static final String WHERE_BOOK_GAME = "22";
+
+        @Override
+        public void whoWhereDo(String who, String where, String doJob) {
+            ALog.d("who:" + who + " |where:" + where + " |doJob:" + doJob);
+            switch (who) {
+                case WHO_WEB:
+                    switch (where) {
+                        case WHERE_BOOK_GAME:
+                            skip2GameDetails(doJob, true);
+                            break;
+                        case WHERE_CLOSE_SELF:
+                            showInfoAndCloseSelf("");
+                            break;
+                        default:
+                            showInfoAndCloseSelf("异常Web行为,关闭Web");
+                            break;
+                    }
+                    break;
+                default:
+                    showInfoAndCloseSelf("异常Web对象,关闭Web");
+                    break;
+            }
+        }
+    }
+
+
+    public class PublicJavaScript {
+        @JavascriptInterface
+        public String getHeader() {
+            return DDProviderHelper.getInstance().getLastUserToken(KFZSApp.context);
+        }
+        @JavascriptInterface
+        public String getNick() {
+            Current current= DDProviderHelper.getInstance().getLastUser(ActWeb.this);
+            if(current==null || TextUtils.isEmpty(current.getMNickName())){
+                return "";
+            }
+
+            return current.getMNickName();
+        }
+
+        @JavascriptInterface
+        public void finish() {
+            ActWeb.this.finish();
+        }
+    }
+
+    private void showInfoAndCloseSelf(String msg) {
+        ALog.d(msg);
+        if (!TextUtils.isEmpty(msg)) {
+            showToast(msg);
+        }
+        RunThreadUtils.delay(new Runnable() {
+            @Override
+            public void run() {
+                ActWeb.this.finish();
+            }
+        }, 100, true);
+    }
+
+    private void skip2GameDetails(String doJob, boolean bRequestOrder) {
+        Bundle bundle = new Bundle();
+        bundle.putString(KFIntentKeys.EXTRA_GAME_ID, doJob);
+        if (bRequestOrder) {
+            bundle.putString(KFIntentKeys.EXTRA_GAME_REQUEST_ORDER, doJob);
+        }
+        skip2Activity(ActGameDetails.class, bundle);
+        this.finish();
+    }
+
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
+    }
+
+
+}

+ 331 - 0
app/src/main/java/com/kfzs/duanduan/BaseCompatActivity.java

@@ -0,0 +1,331 @@
+package com.kfzs.duanduan;
+
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.View;
+
+import com.kf.utils.ToastBuilder;
+import com.kfzs.android.view.CompatActivity;
+import com.kfzs.duanduan.bean.VipStyle;
+import com.kfzs.duanduan.utils.StatusBarUtils;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.umeng.analytics.MobclickAgent;
+
+import java.util.List;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by sinlov on 17/2/10.
+ */
+public abstract class BaseCompatActivity extends CompatActivity {
+
+    /**
+     * auto TAG for mark subclass
+     */
+    protected String TAG;
+
+    public static boolean isDebugMode = false;
+    private static final int FINISH_BACK_STACK_THRESHOLD = 0;
+
+    private FragmentManager fragmentManager = getSupportFragmentManager();
+    private FragmentTransaction fragmentTransaction;
+    private boolean isAddStack = false;
+    /**
+     * supper application see {@link KFZSApp}
+     */
+    protected KFZSApp app;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        setTheme(ThemeUtils.getInstance().getThemeId(VipStyle.getInstance().getViptypeid()));
+//        StatusBarUtils.setColor(this, ThemeUtils.getInstance().getColorDark(), 0);
+        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        super.onCreate(savedInstanceState);
+
+        TAG = this.getClass().getCanonicalName();
+        app = KFZSApp.getInstance();
+        app.appCompatActivityList.add(this);
+    }
+
+    /**
+     * 不如注入方便,暂时这样用吧。。。
+     *
+     * @param id
+     * @param <T>
+     * @return
+     */
+    protected <T extends View> T findViewByIdT(int id) {
+        return (T) super.findViewById(id);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        MobclickAgent.onResume(this);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        MobclickAgent.onPause(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        app.appCompatActivityList.remove(this);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton) {
+        addSupportFragment(containerViewId, fragment, null, isSupportBackButton);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, Integer animIn, Integer animOut) {
+        addSupportFragment(containerViewId, fragment, null, isSupportBackButton, animIn, animOut);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag) {
+        addSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, null, null);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag) {
+        addSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, null, null);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton) {
+        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, Integer animIn, Integer animOut) {
+        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, animIn, animOut);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton) {
+        addSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag) {
+        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        addSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, animIn, animOut);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        addSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, animIn, animOut);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag) {
+        addSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, stackTag, null, null);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag, animIn, animOut);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, Integer animIn, Integer animOut) {
+        addSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null, animIn, animOut);
+    }
+
+    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        if (null == fragment) {
+            new Throwable("your fragment is null").printStackTrace();
+            return;
+        }
+        fragmentTransaction = fragmentManager.beginTransaction();
+        if (null != bundle) {
+            fragment.setArguments(bundle);
+        }
+        fragmentTransaction.add(containerViewId, fragment, tag);
+        if (null != animIn && null != animOut) {
+            fragmentTransaction.setCustomAnimations(animIn, animOut);
+        }
+        if (isSupportBackButton) {
+            fragmentTransaction.addToBackStack(stackTag);
+            fragmentTransaction.commit();
+            isAddStack = true;
+        } else {
+            removeChildFragment();
+            isAddStack = false;
+        }
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton) {
+        replaceSupportFragment(containerViewId, fragment, null, isSupportBackButton);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, Integer animIn, Integer animOut) {
+        replaceSupportFragment(containerViewId, fragment, null, isSupportBackButton, animIn, animOut);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag) {
+        replaceSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, null, null);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag) {
+        replaceSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, null, null);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton) {
+        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, Integer animIn, Integer animOut) {
+        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, animIn, animOut);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton) {
+        replaceSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag) {
+        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        replaceSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, animIn, animOut);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        replaceSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, animIn, animOut);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag) {
+        replaceSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, stackTag, null, null);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag, animIn, animOut);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, Integer animIn, Integer animOut) {
+        replaceSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null, animIn, animOut);
+    }
+
+    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
+        if (null == fragment) {
+            new Throwable("your fragment is null").printStackTrace();
+        }
+        fragmentTransaction = fragmentManager.beginTransaction();
+        if (null != bundle) {
+            assert fragment != null;
+            fragment.setArguments(bundle);
+        }
+        if (null != animIn && null != animOut) {
+            fragmentTransaction.setCustomAnimations(animIn, animOut);
+        }
+        fragmentTransaction.replace(containerViewId, fragment, tag);
+        if (isSupportBackButton) {
+            fragmentTransaction.addToBackStack(stackTag);
+            fragmentTransaction.commit();
+            isAddStack = true;
+        } else {
+            removeChildFragment();
+            isAddStack = false;
+        }
+    }
+
+    private void removeChildFragment() {
+        fragmentManager.popBackStackImmediate();
+        List<Fragment> childFragments = fragmentManager.getFragments();
+        if (null != childFragments) {
+            for (Fragment stackFragment : fragmentManager.getFragments()) {
+                if (null != stackFragment) {
+                    fragmentTransaction.remove(stackFragment);
+                }
+            }
+        }
+        fragmentTransaction.commit();
+    }
+
+    public void removeSupportFragment(BaseCompatFragment fragment) {
+        fragmentTransaction = fragmentManager.beginTransaction();
+        fragmentTransaction.remove(fragment);
+        fragmentTransaction.commit();
+    }
+
+    public void removeAllFragment() {
+        int backStackEntryCount = fragmentManager.getBackStackEntryCount();
+        if (backStackEntryCount > 0) {
+            fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
+        }
+    }
+
+    public void hideSupportFragment(BaseCompatFragment fragment) {
+        fragmentTransaction = fragmentManager.beginTransaction();
+        fragmentTransaction.hide(fragment);
+        fragmentTransaction.commit();
+    }
+
+    @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+        if (isDebugMode) {
+            Log.d(TAG, "isAddStack: " + isAddStack + " |BackStackEntryCount: " + fragmentManager.getBackStackEntryCount());
+        }
+        if (!isAddStack || FINISH_BACK_STACK_THRESHOLD == fragmentManager.getBackStackEntryCount()) {
+            finish();
+        }
+        //TODO of synchronized way
+        synchronized (this) {
+        }
+    }
+
+    /**
+     * show toast by string
+     *
+     * @param string toast string
+     */
+    protected void showToast(String string) {
+        showToast(string, ToastBuilder.DEFAULT_TOAST_SINGLE);
+    }
+
+
+    /**
+     * show toast by res
+     *
+     * @param string string resource id
+     * @param tag    {@link ToastBuilder#DEFAULT_TOAST} or other
+     */
+    protected void showToast(String string, int tag) {
+        ToastBuilder.make(app, string, tag);
+    }
+
+    /**
+     * show toast by res
+     *
+     * @param strID string resource id
+     */
+    protected void showToast(int strID) {
+        showToast(strID, ToastBuilder.DEFAULT_TOAST_SINGLE);
+    }
+
+    /**
+     * show toast by res
+     *
+     * @param strID string resource id
+     * @param tag   {@link ToastBuilder#DEFAULT_TOAST} or other
+     */
+    protected void showToast(int strID, int tag) {
+        ToastBuilder.make(app, strID, tag);
+    }
+}

+ 236 - 0
app/src/main/java/com/kfzs/duanduan/BaseCompatFragment.java

@@ -0,0 +1,236 @@
+package com.kfzs.duanduan;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.IdRes;
+import android.support.annotation.LayoutRes;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.kf.utils.ToastBuilder;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+
+import java.lang.reflect.Field;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by sinlov on 17/2/13.
+ */
+public abstract class BaseCompatFragment extends Fragment {
+
+    private static final String STATE_SAVE_IS_HIDDEN = "Fragment:STATE:SAVE_IS_HIDDEN";
+
+    protected final String TAG = this.getClass().getCanonicalName();
+
+    //Fragment主要管理
+    protected FragmentManager mFragmentManager;
+    //Fragment的主View
+    protected View mContentView;
+
+    protected Context mContext;
+
+    //刷新组件,直接static
+    private static SwipeRefreshLayout mSwipeRefreshLayout;
+
+
+    /**
+     * attach fragment and init base member
+     *
+     * @param context context
+     */
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        this.mContext = context;
+        mFragmentManager = getFragmentManager();
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (savedInstanceState != null) {
+            boolean isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN);
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            if (isSupportHidden) {
+                ft.hide(this);
+            } else {
+                ft.show(this);
+            }
+            ft.commit();
+        }
+    }
+
+    /**
+     * @param inflater
+     * @param container
+     * @param savedInstanceState
+     * @return
+     */
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        if (mContentView == null) {
+            initView(savedInstanceState);
+        } else {
+            ViewGroup parent = (ViewGroup) mContentView.getParent();
+            if (null != parent) {
+                parent.removeView(mContentView);
+            }
+        }
+        return mContentView;
+    }
+
+    protected abstract void initView(Bundle savedInstanceState);
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
+    }
+
+    protected void setContentView(@LayoutRes int layoutResID) {
+//        mContentView = LayoutInflater.from(KFZSApp.getInstance()).inflate(layoutResID, null);
+        //上面句大坑,在做主题的时候搞了很久,我去!
+        mContentView = LayoutInflater.from(getActivity()).inflate(layoutResID, null);
+    }
+
+    protected void setContentViewChildMode(@LayoutRes int layoutResID) {
+        mContentView = LayoutInflater.from(getActivity()).inflate(layoutResID, null);
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        try {
+            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
+            childFragmentManager.setAccessible(true);
+            childFragmentManager.set(this, null);
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * find view by id which in content view
+     *
+     * @param id   view id
+     * @param <CV> extends {@link View}
+     * @return extends view
+     */
+    @SuppressWarnings("unchecked")
+    protected <CV extends View> CV getViewById(@IdRes int id) {
+        return (CV) mContentView.findViewById(id);
+    }
+
+    /**
+     * show toast by string
+     *
+     * @param string toast string
+     */
+    protected void showToast(String string) {
+        G.showToast(string);
+    }
+
+
+    /**
+     * show toast by res
+     *
+     * @param string string resource id
+     * @param tag    {@link ToastBuilder#DEFAULT_TOAST} or other
+     */
+    protected void showToast(String string, int tag) {
+        ToastBuilder.make(mContext, string, tag);
+    }
+
+    /**
+     * show toast by res
+     *
+     * @param strID string resource id
+     */
+    protected void showToast(int strID) {
+        showToast(strID, ToastBuilder.DEFAULT_TOAST_SINGLE);
+    }
+
+    /**
+     * show toast by res
+     *
+     * @param strID string resource id
+     * @param tag   {@link ToastBuilder#DEFAULT_TOAST} or other
+     */
+    protected void showToast(int strID, int tag) {
+        ToastBuilder.make(mContext, strID, tag);
+    }
+
+
+    protected void skip2GameDetails(int sGameId) {
+        Intent intent = new Intent(mContext, ActGameDetails.class);
+        intent.putExtra(KFIntentKeys.EXTRA_GAME_ID, String.valueOf(sGameId));
+        startActivity(intent);
+    }
+
+    protected void skip2Activity(Class<?> cls) {
+        skip2Activity(cls, null);
+    }
+
+    protected void skip2Activity(Class<?> cls, Bundle bundle) {
+        Intent intent = new Intent(getActivity(), cls);
+        if (null != bundle) {
+            intent.putExtras(bundle);
+        }
+        startActivity(intent);
+    }
+
+
+    /**
+     * 刷新数据
+     */
+    public void refreshData() {
+
+    }
+
+    /**
+     * 刷新结束
+     */
+    public void refreshOver() {
+        if (mSwipeRefreshLayout != null
+                && mSwipeRefreshLayout.isRefreshing()) {
+            mSwipeRefreshLayout.setRefreshing(false);
+        }
+    }
+
+
+    /**
+     * 设置刷新组件
+     *
+     * @param swipeRefreshLayout
+     */
+    public void setmSwipeRefreshLayout(SwipeRefreshLayout swipeRefreshLayout) {
+        this.mSwipeRefreshLayout = swipeRefreshLayout;
+    }
+
+    public static SwipeRefreshLayout getmSwipeRefreshLayout() {
+        return mSwipeRefreshLayout;
+    }
+}

+ 79 - 0
app/src/main/java/com/kfzs/duanduan/CompatActivity.java

@@ -0,0 +1,79 @@
+package com.kfzs.duanduan;
+
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import android.support.annotation.IdRes;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by "sinlov" on 16/6/30.
+ */
+public abstract class CompatActivity extends AppCompatActivity {
+
+    private long testTimeUse;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+    }
+
+    /**
+     * @param id   widget id
+     * @param <VT> View
+     * @return extends {@link View}
+     */
+    @SuppressWarnings("unchecked")
+    protected <VT extends View> VT getViewById(@IdRes int id) {
+        return (VT) findViewById(id);
+    }
+
+    protected void showToast(String text) {
+        Toast.makeText(this.getApplicationContext(), text, Toast.LENGTH_SHORT).show();
+    }
+
+    protected void showToast(int id) {
+        Toast.makeText(this.getApplicationContext(), id, Toast.LENGTH_SHORT).show();
+    }
+
+    protected void skip2Activity(Class<?> cls) {
+        skip2Activity(cls, null);
+    }
+
+    protected void skip2Activity(Class<?> cls, Bundle bundle) {
+        Intent intent = new Intent(CompatActivity.this, cls);
+        if (null != bundle) {
+            intent.putExtras(bundle);
+        }
+        startActivity(intent);
+    }
+
+    protected void testTimeUseStart() {
+        testTimeUse = System.currentTimeMillis();
+    }
+
+    protected long testTimeUseEnd() {
+        long useTime = System.currentTimeMillis() - testTimeUse;
+        Log.d("CompatActivity", "testTimeUse: " + useTime);
+        return useTime;
+    }
+}

+ 79 - 0
app/src/main/java/com/kfzs/duanduan/G.java

@@ -0,0 +1,79 @@
+package com.kfzs.duanduan;
+
+import android.content.Context;
+import android.support.annotation.StringRes;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  G</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/7 10:46
+ * @ QQ:    315096953
+ */
+
+public class G {
+
+    public static int WIDTH = 0;
+    public static int HEIGHT = 0;
+    public static float DENSITY = 2;//屏幕的Density
+    private static Toast mToast;//全局的Toast
+
+
+    /**
+     * 全局的Toast
+     *
+     * @param context
+     * @param msg      显示的msg,如果为null或者空表示取消显示
+     * @param duration 显示的时长
+     */
+    public static void showToast(Context context, String msg, int duration) {
+        if (mToast == null) {
+            mToast = Toast.makeText(context, msg, duration);
+            mToast.setGravity(Gravity.CENTER, 0, getRealPix(200));//居中靠下
+            if (mToast.getView() instanceof ViewGroup
+                    && ((ViewGroup) mToast.getView()).getChildAt(0) instanceof TextView) {
+                ((TextView) ((ViewGroup) mToast.getView()).getChildAt(0)).setSingleLine(false);
+            }
+        } else if (msg == null || msg.equals(""))
+            mToast.cancel();
+        else {
+            mToast.setText(msg);
+        }
+        mToast.show();
+    }
+
+    /**
+     * 显示短暂消息
+     *
+     * @param msg
+     */
+    public static void showToast(String msg) {
+        showToast(KFZSApp.getInstance().getApplicationContext(), msg, Toast.LENGTH_SHORT);
+    }
+
+    /**
+     * 显示短暂消息
+     * @param resId
+     */
+    public static void showToast(@StringRes int resId) {
+        showToast(KFZSApp.getInstance().getApplicationContext(),
+                KFZSApp.getInstance().getApplicationContext().getString(resId),
+                Toast.LENGTH_SHORT);
+    }
+
+    /**
+     * 返回像素值
+     *
+     * @param dp 将转换的dp值
+     * @return 返回像素植
+     */
+    public static int getRealPix(int dp) {
+        return (int) (dp * G.DENSITY);
+    }
+
+
+}

+ 303 - 0
app/src/main/java/com/kfzs/duanduan/KFZSApp.java

@@ -0,0 +1,303 @@
+package com.kfzs.duanduan;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.os.Build;
+import android.os.Environment;
+import android.support.multidex.MultiDex;
+import android.support.multidex.MultiDexApplication;
+import android.util.DisplayMetrics;
+import android.util.Log;
+
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.db.DataSave;
+import com.kfzs.duanduan.services.KFDownloadServices;
+import com.kfzs.duanduan.utils.ApkUtils;
+import com.sheep.jiuyan.samllsheep.BuildConfig;
+import com.umeng.analytics.MobclickAgent;
+import com.umeng.socialize.Config;
+import com.umeng.socialize.PlatformConfig;
+import com.umeng.socialize.UMShareAPI;
+import com.umeng.socialize.common.QueuedWork;
+
+import org.wlf.filedownloader.FileDownloadConfiguration;
+import org.wlf.filedownloader.FileDownloader;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import cn.jpush.android.api.JPushInterface;
+import mdl.sinlov.android.log.ALog;
+import mdl.sinlov.android.log.ALogLevel;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by sinlov on 17/2/10.
+ */
+public class KFZSApp extends MultiDexApplication{
+
+    public static final boolean DEBUG = BuildConfig.KF_DEBUG;
+
+    public static final String SD_PATH_EXTERNAL = Environment.getExternalStorageDirectory()
+            .getAbsolutePath();
+    private static KFZSApp application;
+    public static Context context;
+    public static String TAG;
+    public static String ownPath;
+    public static String path_catch;
+    public static String path_img;
+    public static String path_img_catch;
+    public static String path_download;
+    public static String path_Log;
+    public static ActMain actMain;
+    public String GameCode = null;
+
+    public List<BaseCompatActivity> appCompatActivityList = new ArrayList<BaseCompatActivity>();
+
+    private Map<String, PackageInfo> installedApkContainer;
+    public static final int MAX_DOWNLOAD_TASK_SIZE = 5;
+    public HashMap<String, String> mRealDownloadUrl;
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        TAG = this.getPackageName();
+        mRealDownloadUrl = new HashMap<>();
+        setOnlyContext(this);
+        initUtils(DEBUG);
+        initOwnCatchPath();
+        initFileDownloader();
+    }
+
+    private void initUtils(boolean debug) {
+        if (debug) {
+            ALog.initTag();
+        } else {
+            ALog.initTag().logLevel(ALogLevel.NONE);
+        }
+        DisplayMetrics metric = getResources().getDisplayMetrics();
+        G.DENSITY = metric.density;
+        G.HEIGHT=metric.heightPixels;
+        G.WIDTH=metric.widthPixels;
+
+        DataSave dataSave = DataSave.getInstance();
+        String umengKey = dataSave.getUmengKey();
+        String channelName = dataSave.getChannelName();
+        Log.w("DDINIT", "API_VERSION: " + UrlBll.API_VERSION + " |CAPTCHA: " + UrlBll.CAPTCHA_DOMAIN);
+        Log.w("DDINIT", "GRAPH" + BuildConfig.DUANDUAN_GRAPH + " |GRAPH" + BuildConfig.DUANDUAN_GRAPH);
+        Log.w("DDINIT", "umengKey: " + umengKey + " |channelName: " + channelName + " |debug: " + debug);
+        Log.w("DDINIT", "wxAppId: " + BuildConfig.WX_APPID + " |wxAppSecret: " + BuildConfig.WX_APPSECRET + " |debug: " + debug);
+        Log.w("DDINIT", "wbAppId: " + BuildConfig.WB_APPID + " |wbAppSecret: " + BuildConfig.WB_APPSECRET + " |debug: " + debug);
+        MobclickAgent.UMAnalyticsConfig umAnalyticsConfig = new MobclickAgent.UMAnalyticsConfig(application, umengKey, channelName);
+        MobclickAgent.startWithConfigure(umAnalyticsConfig);
+        MobclickAgent.setDebugMode(debug);
+        JPushInterface.setDebugMode(debug);
+        JPushInterface.init(this);
+        //Log.e("JPushRegzid", JPushInterface.getRegistrationID(this));
+        MobclickAgent.setCatchUncaughtExceptions(!debug);
+        MobclickAgent.enableEncrypt(true);
+        //um Share
+        Config.DEBUG = true;
+        QueuedWork.isUseThreadPool = false;
+        UMShareAPI.get(this);
+        //end
+        KFZSNetwork.init(application);
+        initShareSDK();
+    }
+
+    //各个平台的配置,建议放在全局Application或者程序入口
+    private void initShareSDK() {
+        PlatformConfig.setWeixin(BuildConfig.WX_APPID, BuildConfig.WX_APPSECRET);
+        PlatformConfig.setSinaWeibo(BuildConfig.WB_APPID, BuildConfig.WB_APPSECRET, "http://sns.whalecloud.com");
+        PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba");
+    }
+
+    /**
+     * get MDLApplication instance
+     *
+     * @return {@link KFZSApp}
+     */
+    public static KFZSApp getInstance() {
+        return application;
+    }
+
+    public void clearUI() {
+        try {
+            for (BaseCompatActivity appCompatActivity : appCompatActivityList) {
+                appCompatActivity.finish();
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "app clearUI error" + e.getMessage() + "\n" + e.getCause());
+        } finally {
+            Log.v(TAG, "App clearUI");
+        }
+    }
+
+    /**
+     * quit app safe
+     */
+    public void quit() {
+        try {
+            for (BaseCompatActivity appCompatActivity : appCompatActivityList) {
+                appCompatActivity.finish();
+            }
+
+            stopDownloadService();
+            killAppProcess();
+        } catch (Exception e) {
+            Log.e(TAG, "quit error" + e.getMessage() + "\n" + e.getCause());
+        } finally {
+            Log.v(TAG, "App quite");
+        }
+
+    }
+
+    /**
+     * kill App by os Process
+     */
+    public void killAppProcess() {
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            android.os.Process.killProcess(android.os.Process.myPid());
+        } else {
+            System.exit(0);
+        }
+    }
+
+    private static void setContext(Context context) {
+        KFZSApp.context = context;
+    }
+
+    private void setOnlyContext(Context context) {
+        setContext(context);
+    }
+
+    private void initOwnCatchPath() {
+        initOwnPath();
+        File appPath = new File(path_catch);
+        if (!appPath.exists()) {
+            appPath.mkdirs();
+        }
+    }
+
+    private void initOwnPath() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(SD_PATH_EXTERNAL);
+        sb.append("/Android/data/");
+        sb.append(TAG);
+        ownPath = sb.toString();
+        sb.append("/catch");
+        path_catch = sb.toString();
+        sb.setLength(0);
+        sb.append(ownPath);
+        sb.append("/img");
+        path_img = sb.toString();
+        sb.setLength(0);
+        sb.append(ownPath);
+        sb.append("/img/catch");
+        path_img_catch = sb.toString();
+        sb.setLength(0);
+        sb.append(ownPath);
+        sb.append("/download");
+        path_download = sb.toString();
+        sb.setLength(0);
+        sb.append(ownPath);
+        sb.append("/log");
+        path_Log = sb.toString();
+    }
+
+    public KFZSApp() {
+        super();
+        application = this;
+    }
+
+    // init FileDownloader
+    private void initFileDownloader() {
+
+        // 1.create FileDownloadConfiguration.Builder
+        FileDownloadConfiguration.Builder builder = new FileDownloadConfiguration.Builder(this);
+
+        // 2.config FileDownloadConfiguration.Builder
+        builder.configFileDownloadDir(path_download);
+
+        // allow 3 download tasks at the same time
+        builder.configDownloadTaskSize(MAX_DOWNLOAD_TASK_SIZE);
+
+
+        // config retry download times when failed
+        builder.configRetryDownloadTimes(5);
+
+        // enable debug mode
+        //builder.configDebugMode(true);
+
+        // config connect timeout
+        builder.configConnectTimeout(25000); // 25s
+
+        // 3.init FileDownloader with the configuration
+        FileDownloadConfiguration configuration = builder.build(); // build FileDownloadConfiguration with the builder
+        FileDownloader.init(configuration);
+
+        startDownloadService();
+    }
+
+
+    /**
+     * Preload all installed packages to memory
+     */
+    public Map<String, PackageInfo> preloadPackagesInfo() {
+        if (null == installedApkContainer) {
+            installedApkContainer = ApkUtils.getInstalledApks(this);
+        }
+        return installedApkContainer;
+    }
+
+    public Map<String, PackageInfo> loadPackagesInfoRealTime() {
+        return ApkUtils.getInstalledApks(this);
+    }
+
+
+    private void startDownloadService() {
+        Intent downloadService = new Intent(this, KFDownloadServices.class);
+        startService(downloadService);
+    }
+
+    private void stopDownloadService() {
+
+        Log.d(TAG, "stopDownloadService");
+        Intent downloadService = new Intent(this, KFDownloadServices.class);
+        stopService(downloadService);
+    }
+
+
+    @Override
+    public void onTerminate() {
+        super.onTerminate();
+        Log.d(TAG, "onTerminate");
+        FileDownloader.release();
+        stopDownloadService();
+    }
+
+
+    @Override
+    protected void attachBaseContext(Context base) {
+        super.attachBaseContext(base);
+        MultiDex.install(this);
+    }
+}

+ 334 - 0
app/src/main/java/com/kfzs/duanduan/PicBottomSheetActivity.java

@@ -0,0 +1,334 @@
+package com.kfzs.duanduan;
+
+import android.Manifest;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.MediaStore;
+import android.support.annotation.IdRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.v4.app.ActivityCompat;
+import android.text.TextUtils;
+import android.widget.ImageView;
+
+import com.flipboard.bottomsheet.BottomSheetLayout;
+import com.flipboard.bottomsheet.commons.ImagePickerSheetView;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by sinlov on 17/3/30.
+ */
+public abstract class PicBottomSheetActivity extends BaseCompatActivity {
+
+    private static final int REQUEST_STORAGE = 9525;
+    private static final int REQUEST_IMAGE_CAPTURE = REQUEST_STORAGE + 1;
+    private static final int REQUEST_LOAD_IMAGE = REQUEST_IMAGE_CAPTURE + 1;
+
+    private static int what;
+    protected static PicBottomSheetHandler picBottomSheetHandler;
+
+    protected BottomSheetLayout bottomSheetLayout;
+    private Uri callBackImageUri = null;
+    private String chooseTitleString;
+
+//    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+//    @Override
+//    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
+//        super.onCreate(savedInstanceState, persistentState);
+//    }
+
+    protected void initPicBottomSheetHandler() {
+        picBottomSheetHandler = new PicBottomSheetHandler(this);
+    }
+
+    protected void initBottomSheetLayoutByID(@IdRes int bottomSheetID, @StringRes int titleStringID) {
+        bottomSheetLayout = (BottomSheetLayout) findViewById(bottomSheetID);
+        chooseTitleString = getString(titleStringID);
+        if (bottomSheetLayout != null || !TextUtils.isEmpty(chooseTitleString)) {
+            bottomSheetLayout.setPeekOnDismiss(true);
+        } else {
+            throw new IllegalArgumentException("in this activity you are not use right ID" +
+                    " at setting initBottomSheetLayoutByID(id)!");
+        }
+    }
+
+    protected abstract boolean showSheetImageView(ImageView imageView, Uri imageUri, int size);
+
+    protected abstract void callBackSelectedImageUriByBottomSheet(Uri selectedImageUri);
+
+
+    /**
+     * You can send message for {@link #safeHandleCallBack(WeakReference, int, Object)}
+     *
+     * @param what int
+     * @param obj  object
+     */
+    protected void sendSafeHandle(int what, Object obj) {
+        setInstanceWhat(what);
+        picBottomSheetHandler.obtainMessage(what, obj).sendToTarget();
+    }
+
+    /**
+     * you can use this tCallBack to do safe handler things by method {@link #sendSafeHandle(int, Object)}
+     *
+     * @param wrAct WeakReference
+     * @param what  int
+     * @param obj   object
+     */
+    public abstract void safeHandleCallBack(WeakReference<PicBottomSheetActivity> wrAct, int what, Object obj);
+
+    protected boolean callSheetImageViewPop() {
+        boolean needsPermission = checkNeedsPermission();
+        if (needsPermission) {
+            requestStoragePermission();
+        } else {
+            showSheetView();
+        }
+        return needsPermission;
+    }
+
+    protected static void setWhat(int what) {
+        PicBottomSheetActivity.what = what;
+    }
+
+
+    public static class PicBottomSheetHandler extends Handler {
+
+        private static WeakReference<PicBottomSheetActivity> wrActivity;
+
+        /**
+         * set target Activity to Weak reference and the customize handler be recycle timely.
+         *
+         * @param wrActivity WeakActivity
+         */
+        public PicBottomSheetHandler(PicBottomSheetActivity wrActivity) {
+            PicBottomSheetHandler.wrActivity = new WeakReference<PicBottomSheetActivity>(wrActivity);
+        }
+
+        public WeakReference<PicBottomSheetActivity> get() {
+            return wrActivity;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            PicBottomSheetActivity ba = wrActivity.get();
+            Object obj = msg.obj;
+            if (null != ba && null != obj) {
+                ba.safeHandleCallBack(wrActivity, what, obj);
+            }
+        }
+    }
+
+    private void setInstanceWhat(int what) {
+        setWhat(what);
+    }
+
+
+    private boolean checkNeedsPermission() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && ActivityCompat.checkSelfPermission(PicBottomSheetActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
+    }
+
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+    private void requestStoragePermission() {
+        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
+        } else {
+            // Eh, prompt anyway
+            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.M)
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        if (requestCode == REQUEST_STORAGE) {
+            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                showSheetView();
+            } else {
+                // Permission denied
+                showToast("Sheet is useless without access to external storage : ");
+            }
+        } else {
+            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        }
+    }
+
+    /**
+     * Show an {@link ImagePickerSheetView}
+     */
+    private void showSheetView() {
+        ImagePickerSheetView sheetView = new ImagePickerSheetView.Builder(this)
+                .setMaxItems(30)
+                .setShowCameraOption(createCameraIntent() != null)
+                .setShowPickerOption(createPickIntent() != null)
+                .setImageProvider(new ImagePickerSheetView.ImageProvider() {
+                    @Override
+                    public void onProvideImage(ImageView imageView, Uri imageUri, int size) {
+                        boolean isSetting = showSheetImageView(imageView, imageUri, size);
+                        if (!isSetting) {
+                            throw new IllegalArgumentException("you are not use showSheetImageView() and return true!");
+                        }
+                    }
+                })
+                .setOnTileSelectedListener(new ImagePickerSheetView.OnTileSelectedListener() {
+                    @Override
+                    public void onTileSelected(ImagePickerSheetView.ImagePickerTile selectedTile) {
+                        bottomSheetLayout.dismissSheet();
+                        if (selectedTile.isCameraTile()) {
+                            dispatchTakePictureIntent();
+                        } else if (selectedTile.isPickerTile()) {
+                            startActivityForResult(createPickIntent(), REQUEST_LOAD_IMAGE);
+                        } else if (selectedTile.isImageTile()) {
+                            callBackSelectedImageUriByBottomSheet(selectedTile.getImageUri());
+                        } else {
+                            genericError();
+                        }
+                    }
+                })
+                .setTitle(chooseTitleString)
+                .create();
+        if (bottomSheetLayout != null) {
+            bottomSheetLayout.showWithSheetView(sheetView);
+        } else {
+            throw new IllegalArgumentException("in this activity you are not setting initBottomSheetLayoutByID(id) at Layout!");
+        }
+    }
+
+    /**
+     * For images captured from the camera, we need to create a File first to tell the camera
+     * where to store the image.
+     *
+     * @return the File created for the image to be store under.
+     */
+    private File createImageFile() throws IOException {
+        // Create an image file name
+        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
+        String imageFileName = "JPEG_" + timeStamp + "_";
+        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        File imageFile = File.createTempFile(
+                imageFileName,  /* prefix */
+                ".jpg",         /* suffix */
+                storageDir      /* directory */
+        );
+
+        // Save a file: path for use with ACTION_VIEW intents
+        callBackImageUri = Uri.fromFile(imageFile);
+        return imageFile;
+    }
+
+    /**
+     * This checks to see if there is a suitable activity to handle the `ACTION_PICK` intent
+     * and returns it if found. {@link Intent#ACTION_PICK} is for picking an image from an external app.
+     *
+     * @return A prepared intent if found.
+     */
+    @Nullable
+    private Intent createPickIntent() {
+        Intent picImageIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+        if (picImageIntent.resolveActivity(getPackageManager()) != null) {
+            return picImageIntent;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * This checks to see if there is a suitable activity to handle the {@link MediaStore#ACTION_IMAGE_CAPTURE}
+     * intent and returns it if found. {@link MediaStore#ACTION_IMAGE_CAPTURE} is for letting another app take
+     * a picture from the camera and store it in a file that we specify.
+     *
+     * @return A prepared intent if found.
+     */
+    @Nullable
+    private Intent createCameraIntent() {
+        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
+            return takePictureIntent;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * This utility function combines the camera intent creation and image file creation, and
+     * ultimately fires the intent.
+     *
+     * @see {@link #createCameraIntent()}
+     * @see {@link #createImageFile()}
+     */
+    private void dispatchTakePictureIntent() {
+        Intent takePictureIntent = createCameraIntent();
+        // Ensure that there's a camera activity to handle the intent
+        if (takePictureIntent != null) {
+            // Create the File where the photo should go
+            try {
+                File imageFile = createImageFile();
+                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
+                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
+            } catch (IOException e) {
+                // Error occurred while creating the File
+                genericError("Could not create imageFile for camera");
+            }
+        }
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode == Activity.RESULT_OK) {
+            Uri selectedImage = null;
+            if (requestCode == REQUEST_LOAD_IMAGE && data != null) {
+                selectedImage = data.getData();
+                if (selectedImage == null) {
+                    genericError();
+                }
+            } else if (requestCode == REQUEST_IMAGE_CAPTURE) {
+                // Do something with imagePath
+                selectedImage = callBackImageUri;
+            }
+
+            if (selectedImage != null) {
+                callBackSelectedImageUriByBottomSheet(selectedImage);
+            } else {
+                genericError();
+            }
+        }
+    }
+
+    private void genericError() {
+        genericError(null);
+    }
+
+    private void genericError(String message) {
+        showToast(message == null ? "Something went wrong." : message);
+    }
+}

+ 88 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpCommonRecy.java

@@ -0,0 +1,88 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.kfzs.duanduan.bean.RecyleType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpCommonRecy</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/15 11:36
+ * @ QQ:    315096953
+ */
+
+public abstract class AdpCommonRecy<T> extends RecyclerView.Adapter<ViewHolder> {
+    protected Context mContext;
+    protected List<T> mListDatas = new ArrayList<>();
+
+    public AdpCommonRecy(Context context) {
+        mContext = context;
+    }
+
+    public Context getmContext() {
+        return mContext;
+    }
+
+    public List<T> getmListDatas() {
+        return mListDatas;
+    }
+
+    public void addAll(List<T> mListDatas) {
+        this.mListDatas.addAll(mListDatas);
+    }
+
+    public void add(T t) {
+        this.mListDatas.add(t);
+    }
+
+    public void add(T t, int position) {
+        this.mListDatas.set(position, t);
+    }
+
+    public void clear() {
+        this.mListDatas.clear();
+    }
+
+    public abstract int getViewIdByType(int viewType);
+
+    @Override
+    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
+        ViewHolder viewHolder = ViewHolder.get(mContext, null, parent,
+                getViewIdByType(viewType), -1);
+        return viewHolder;
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        holder.updatePosition(position);
+        convert(holder, mListDatas.get(position));
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
+        if (payloads.isEmpty()) {
+            onBindViewHolder(holder, position);
+        } else {
+            holder.updatePosition(position);
+            convert(holder, mListDatas.get(position));
+        }
+    }
+
+
+
+    public abstract void convert(ViewHolder holder, T t);
+
+    @Override
+    public int getItemCount() {
+        return mListDatas.size();
+    }
+
+}

+ 96 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpCoupon.java

@@ -0,0 +1,96 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.android.volleyplus.Response;
+import com.kfzs.duanduan.G;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bll.CouponBll;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.VoucherOuterClass;
+import com.kfzs.duanduan.utils.CouponUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpCoupon</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/18 20:04
+ * @ QQ:    315096953
+ */
+
+public class AdpCoupon extends RecyclerView.Adapter {
+
+    private Context mContext;
+    private final static int TAG_ID_COUPON_ID = R.id.view_tag_1;
+    private final static int TAG_ID_POSITION = R.id.view_tag_2;
+    private List<VoucherOuterClass.Voucher> mVoucherList;
+
+
+    public AdpCoupon(Context context, List<VoucherOuterClass.Voucher> vouchers) {
+        mContext = context;
+        mVoucherList = new ArrayList<>(vouchers);
+    }
+
+
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        View itemView = LayoutInflater.from(mContext)
+                .inflate(R.layout.item_fgt_main_coupon, parent, false);
+        itemView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(final View v) {
+                new CouponBll().postCoupon(mContext, new Response.Listener<ApiResponseOuterClass.ApiResponse>() {
+                    @Override
+                    public void onResponse(ApiResponseOuterClass.ApiResponse apiResponse) {
+                        if (apiResponse.getCodeValue() == ApiResponseOuterClass.Codes.Success_VALUE) {
+                            G.showToast("领取成功!");
+                            VoucherOuterClass.Voucher voucher = mVoucherList.get((int) v.getTag(TAG_ID_POSITION))
+                                    .toBuilder().setReceiveStatus(true).build();
+                            mVoucherList.set((int) v.getTag(TAG_ID_POSITION), voucher);
+                            AdpCoupon.this.notifyDataSetChanged();
+                            return;
+                        } else {
+                            G.showToast(apiResponse.getMsg());
+                        }
+                    }
+                }, (int) v.getTag(TAG_ID_COUPON_ID));
+            }
+        });
+
+        RecyclerView.ViewHolder viewHolder = new RecyclerView.ViewHolder(itemView) {
+        };
+        return viewHolder;
+    }
+
+    @Override
+    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+        holder.itemView.setTag(TAG_ID_COUPON_ID, mVoucherList.get(position).getId());
+        holder.itemView.setTag(TAG_ID_POSITION, position);
+
+        holder.itemView.findViewById(R.id.img_item_fgt_main_coupon)
+                .setSelected(mVoucherList.get(position).getReceiveStatus());
+
+        ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_price))
+                .setText("¥ " + mVoucherList.get(position).getAmount());
+        ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_desc))
+                .setText(new CouponUtils().getVoucherContent(mVoucherList.get(position)));
+        ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_name))
+                .setText(new CouponUtils().getVoucherName(mVoucherList.get(position)));
+    }
+
+    @Override
+    public int getItemCount() {
+        return mVoucherList.size();
+    }
+
+
+
+}

+ 63 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpFgtAppDetailBbs.java

@@ -0,0 +1,63 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpFgtAppDetailBbs</p>
+ * @ <p>Description: 商品详情页中论坛列表的适配器</p>
+ * @ date:  2017/6/20 11:32
+ * @ QQ:    315096953
+ */
+
+public class AdpFgtAppDetailBbs extends BaseAdapter {
+
+    private Context mContext;
+
+    public AdpFgtAppDetailBbs(Context context) {
+        this.mContext = context;
+    }
+
+    @Override
+    public int getCount() {
+        return 12;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return null;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.item_app_detail_bbs, null);
+        }
+
+
+//        ViewFindUtils.hold(convertView,R.id.txt_item_app_detail_bbs_count, TextView.class)
+//                .setText("");
+//        ViewFindUtils.hold(convertView,R.id.txt_item_app_detail_bbs_nick, TextView.class)
+//                .setText("");
+//        ViewFindUtils.hold(convertView,R.id.txt_item_app_detail_bbs_time, TextView.class)
+//                .setText("");
+//        ViewFindUtils.hold(convertView,R.id.txt_item_app_detail_bbs_title, TextView.class)
+//                .setText("");
+//        ViewFindUtils.hold(convertView,R.id.img_item_app_detail_bbs, ImageView.class);
+
+        return convertView;
+    }
+}

+ 70 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpFgtAppDetailNewGame.java

@@ -0,0 +1,70 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.OpenTestOpenServerList;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpFgtAppDetailNewGame</p>
+ * @ <p>Description: 商品详情页中开服列表的适配器</p>
+ * @ date:  2017/6/20 11:18
+ * @ QQ:    315096953
+ */
+
+public class AdpFgtAppDetailNewGame extends BaseAdapter {
+
+    private Context mContext;
+    private List<OpenTestOpenServerList.OpenServer> mData = new ArrayList<>();
+
+    public AdpFgtAppDetailNewGame(Context context) {
+        this.mContext = context;
+    }
+
+    @Override
+    public int getCount() {
+        return mData.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return position;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.item_app_detail_new_game, null);
+        }
+        OpenTestOpenServerList.OpenServer openServer = mData.get(position);
+        String date = DateFormatUtils.doOpenserveDate(openServer.getOpenServerTime());
+        //暂时不需要这个了
+//        ViewFindUtils.hold(convertView, R.id.txt_item_app_detail_new_game_title, TextView.class)
+//                        .setText(openServer.getRemark());
+        ViewFindUtils.hold(convertView, R.id.txt_item_app_detail_new_game_zone, TextView.class)
+                .setText(openServer.getRemark());
+        ViewFindUtils.hold(convertView, R.id.txt_item_app_detail_new_game_time, TextView.class)
+                .setText(date);
+        return convertView;
+    }
+
+    public void setData(List<OpenTestOpenServerList.OpenServer> list) {
+        this.mData = list;
+
+    }
+}

+ 221 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpFragmentRank.java

@@ -0,0 +1,221 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.RatingBar;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.duanduan.utils.DiscountUtils;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.bean.RecyleObj;
+import com.kfzs.duanduan.bean.RecyleType;
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.utils.NumberFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.view.FilterWindow;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jp.wasabeef.glide.transformations.BlurTransformation;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpFragmentRank</p>
+ * @ <p>Description: 首页排行页面的Recycle适配器</p>
+ * @ date:  2017/7/12 14:30
+ * @ QQ:    315096953
+ */
+
+public class AdpFragmentRank extends AdpCommonRecy<RecyleObj> {
+
+
+    private final String TAG = this.getClass().getName();
+    private final int TAG_ID = R.id.btn_list_item_game_info;
+    private Map<String, InstallButtonUtils> mDownLoadItemLogicMgrMap = new HashMap<>();
+    private Context mContext;
+    private RecyclerView mRecyView;
+    private FilterWindow filterWindow;
+    private Button btnPanel;
+    private View.OnClickListener mTypeClickListener;
+
+    private int[] mIconId = {R.id.game_rank_top3_icon1, R.id.game_rank_top3_icon2, R.id.game_rank_top3_icon3};
+    private int[] mNameId = {R.id.game_rank_top3_name1, R.id.game_rank_top3_name2, R.id.game_rank_top3_name3};
+    private int[] mBtnId = {R.id.game_rank_top3_install1, R.id.game_rank_top3_install2, R.id.game_rank_top3_install3};
+    private int[] mLayoutId = {R.id.game_rank_top3_content1, R.id.game_rank_top3_content2, R.id.game_rank_top3_content3};
+    private int[] mGiftId = {R.id.img_listview_item_game_rank_top1, R.id.img_listview_item_game_rank_top2, R.id.img_listview_item_game_rank_top3};
+
+    public AdpFragmentRank(Context context, RecyclerView recyclerView, View.OnClickListener clickListener) {
+        super(context);
+        mContext = context;
+        mRecyView = recyclerView;
+        mTypeClickListener = clickListener;
+    }
+
+    @Override
+    public int getViewIdByType(int viewType) {
+        int resId = 0;
+        RecyleType recyleType = RecyleType.values()[viewType];
+        switch (recyleType) {
+            case RANK_TYPE:
+                resId = R.layout.listview_item_filter_panel;
+                break;
+            case RANK_TOP3:
+                resId = R.layout.listview_item_game_rank_top3;
+                break;
+            case RANK_LIST:
+                resId = R.layout.listview_item_game_info;
+        }
+        return resId;
+    }
+
+    /**
+     * 返回下载管理年HashMap
+     *
+     * @return
+     */
+    public Map<String, InstallButtonUtils> getmDownLoadItemLogicMgrMap() {
+        return mDownLoadItemLogicMgrMap;
+    }
+
+    /**
+     * 这一步不能少,不然会类型不匹配
+     *
+     * @param position
+     * @return
+     */
+    @Override
+    public int getItemViewType(int position) {
+        return getmListDatas().get(position).getRecyleType().ordinal();
+    }
+
+    @Override
+    public void convert(ViewHolder holder, RecyleObj recyleObj) {
+        switch (recyleObj.getRecyleType()) {
+            case RANK_TYPE:
+                bindFilterPanel(holder);
+                break;
+            case RANK_TOP3:
+                bindTop3(holder, (List<GameOuterClass.Game>) recyleObj.getDataObj());
+                break;
+            case RANK_LIST:
+                bindList(holder, (GameOuterClass.Game) recyleObj.getDataObj(), holder.getAdapterPosition());
+                break;
+        }
+    }
+
+
+    /**
+     * 绑定排行页的分类选择View
+     *
+     * @param helper
+     */
+    private void bindFilterPanel(final ViewHolder helper) {
+        btnPanel = helper.getView(R.id.btn_query_condition);
+        btnPanel.setOnClickListener(mTypeClickListener);
+    }
+
+
+    /**
+     * 绑定排行页的列表View
+     *
+     * @param helper
+     * @param model
+     */
+    private void bindList(final ViewHolder helper, GameOuterClass.Game model, int position) {
+        helper.setText(R.id.txt_list_item_game_info_title, model.getGameName());
+        helper.setText(R.id.txt_list_item_game_info_type, model.getTypeText());
+
+        helper.setText(R.id.txt_list_item_game_info_down_count,
+                String.format(mContext.getString(R.string.download_count), model.getDownloadNum() + ""));
+
+        helper.getView(R.id.ratbar_list_item_game_info, RatingBar.class)
+                .setRating(NumberFormatUtils.getDivideResult(model.getStar()));
+        DiscountUtils.getInstance().showDiscount(helper.itemView,
+                model.getIconImage(),
+                model.getDiscount());
+
+//        Glide.with(mContext)
+//                .load(model.getIconImage())
+//                .transform(new KFGlideRoundTransform(mContext, 5))
+//                .into((ImageView) helper.getView(R.id.img_list_item_game_info_logo));
+
+        if (!helper.getConvertView().hasOnClickListeners()) {
+            helper.getConvertView().setOnClickListener(clsListGoDetail);
+        }
+        helper.getConvertView().setTag(TAG_ID, model.getId());
+        DownBtnUtils.addDownloadBtnListener(helper.getView(R.id.btn_list_item_game_info, KFProgressButton.class),
+                mContext, mDownLoadItemLogicMgrMap, model, "rank_list" + position);
+    }
+
+
+    /**
+     * 点击排行 ,跳游戏详情
+     */
+    private View.OnClickListener clsListGoDetail = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID));
+        }
+    };
+
+    /**
+     * 绑定Top3的View
+     *
+     * @param helper
+     * @param lResponseTopThreeList
+     */
+    private void bindTop3(final ViewHolder helper, final List<GameOuterClass.Game> lResponseTopThreeList) {
+        for (int i = 0; i < lResponseTopThreeList.size(); i++) {
+            final GameOuterClass.Game oTempGame = lResponseTopThreeList.get(i);
+            if (i == 0) {
+                ImageView ivChampion = helper.getView(R.id.game_rank_top3_1_bg);
+                Glide.with(mContext)
+                        .load(oTempGame.getDetailBackImage())
+                        .bitmapTransform(new BlurTransformation(mContext, 15))//radius的取值范围是1-25,radius越大,模糊度越高
+                        .into(ivChampion);
+            }
+
+            helper.setText(mNameId[i], oTempGame.getGameName());
+            helper.setVisible(mGiftId[i], oTempGame.getExistGift() == 1);
+            ImageView ivGameIcon = helper.getView(mIconId[i]);
+            Glide.with(mContext)
+                    .load(oTempGame.getIconImage())
+                    .transform(new KFGlideRoundTransform(mContext, 5))
+                    .into(ivGameIcon);
+
+            String position = String.valueOf((i + 1) * 12345);
+            mDownLoadItemLogicMgrMap.put(oTempGame.getDownloadUrl(), InstallButtonUtils
+                    .init(position, oTempGame.getDownloadUrl(), helper.getView(mBtnId[i], KFProgressButton.class),
+                            "bindTopThreePanel" + i));
+            DownBtnUtils.addDownloadBtnListener(helper.getView(mBtnId[i], KFProgressButton.class),
+                    mContext,mDownLoadItemLogicMgrMap,lResponseTopThreeList.get(i),TAG);
+            helper.getView(mLayoutId[i]).setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    SkipUtils.getInstance().goGameDetails(mContext, oTempGame.getId());
+                }
+            });
+        }
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        return super.onCreateViewHolder(parent, viewType);
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        super.onBindViewHolder(holder, position);
+    }
+}

+ 97 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpGameBook.java

@@ -0,0 +1,97 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.kfzs.appstore.utils.sys.ClipboardUtils;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.GameBookOuterClass;
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.proto.GiftOuterClass;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpGameBook</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/11/24 13:39
+ * @ QQ:    315096953
+ */
+
+public class AdpGameBook extends AdpCommonRecy<GameBookOuterClass.GameBooked> {
+    private final String giftEndTimeHint;
+    private final String itemHintMsgFirstPlayTime;
+    private Context mContext;
+    private AdapterView.OnItemClickListener mOnItemClickListener;
+
+
+    public AdpGameBook(Context context) {
+        super(context);
+        mContext = context;
+        giftEndTimeHint = context.getResources().getString(R.string.item_hint_msg_gift_end_time);
+        itemHintMsgFirstPlayTime = context.getResources().getString(R.string.item_hint_msg_first_play_time);
+    }
+
+    public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
+        this.mOnItemClickListener = onItemClickListener;
+    }
+
+    @Override
+    public int getViewIdByType(int viewType) {
+        return R.layout.listview_item_game_book_self;
+    }
+
+    @Override
+    public void convert(final ViewHolder holder, GameBookOuterClass.GameBooked gameBooked) {
+        GameOuterClass.Game game = gameBooked.getGame();
+        holder.setText(R.id.tv_item_game_book_self_name, game.getGameName());
+        String giftEndTime = DateFormatUtils.doSecond2Date(gameBooked.getGift().getEndTime());
+        giftEndTime = giftEndTimeHint + giftEndTime;
+        holder.setText(R.id.tv_item_game_book_self_gift_end_time, giftEndTime);
+
+        String playTime = DateFormatUtils.doSecond2Date(gameBooked.getGame().getStartTime());
+        playTime = itemHintMsgFirstPlayTime + playTime;
+        holder.setText(R.id.tv_item_game_book_self_date_play, playTime);
+
+        GiftOuterClass.Gift gift = gameBooked.getGift();
+        if (gift != null) {
+            final String code = gift.getCode();
+            if (!TextUtils.isEmpty(code)) {
+                holder.setVisible(R.id.ll_item_game_book_self_gift, true);
+                holder.setText(R.id.tv_item_game_book_self_gift_code, code);
+
+                holder.getView(R.id.btn_item_game_book_self_gift_copy).setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        if (!TextUtils.isEmpty(code)) {
+                            ClipboardUtils.copy2Clipboard(mContext, code);
+                            Toast.makeText(mContext, "礼包码: " + code + "\n已经复制,请粘贴使用", Toast.LENGTH_SHORT).show();
+                        }
+                    }
+                });
+            }
+        }
+        ImageView icon = holder.getView(R.id.img_item_game_book_self_icon);
+        Glide.with(mContext).load(game.getIconImage())
+                .error(android.R.drawable.stat_notify_error)
+                .into(icon);
+
+        holder.getConvertView().setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                if (AdpGameBook.this.mOnItemClickListener != null) {
+                    AdpGameBook.this.mOnItemClickListener
+                            .onItemClick(null,
+                                    v, holder.getLayoutPosition(), 0);
+                }
+
+            }
+        });
+    }
+
+}

+ 212 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpMainPageGift.java

@@ -0,0 +1,212 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.RecyleObj;
+import com.kfzs.duanduan.bean.RecyleType;
+import com.kfzs.duanduan.proto.GiftCenterOuterClass;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpMainPageGift</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/23 14:00
+ * @ QQ:    315096953
+ */
+
+public class AdpMainPageGift extends AdpCommonRecy<RecyleObj> {
+
+    private final String TAG = this.getClass().getName();
+    //设置Tag,因为默认Tag用于HoldView了 ,所以加个TagKey,ID必须为任意ResId
+    private final static int TAG_ID_TEMP = R.id.view_common_adpter;
+
+    public AdpMainPageGift(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+
+
+    /**
+     * @param viewType
+     * @return 失败返回0
+     */
+    @Override
+    public int getViewIdByType(int viewType) {
+        int resId = 0;
+        RecyleType recyleType = RecyleType.values()[viewType];
+        switch (recyleType) {
+            case GIFT_BANNER:
+                resId = R.layout.fgt_main_banner;
+                break;
+            case ALREADY_INSTALL:
+                resId = R.layout.fgt_main_gift_install;
+                break;
+            case OWN_GIFT:
+                resId = R.layout.fgt_main_gift_dujia;
+                break;
+        }
+        return resId;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return getmListDatas().get(position).getRecyleType().ordinal();
+    }
+
+
+    /**
+     * @param holder
+     * @param recyleObj
+     */
+    @Override
+    public void convert(ViewHolder holder, RecyleObj recyleObj) {
+        switch (recyleObj.getRecyleType()) {
+            case GIFT_BANNER:
+                //bindGiftBanner(holder, (List<IndexBannerGiftCenterOuterClass.IndexBannerGiftCenter>) recyleObj.getDataObj());
+                break;
+            case ALREADY_INSTALL:
+                bindAlreadyPlayed(holder, (List<GiftCenterOuterClass.GiftCenter>) recyleObj.getDataObj());
+                break;
+            case OWN_GIFT:
+                bindDuJiaGift(holder, (List<GiftCenterOuterClass.GiftCenter>) recyleObj.getDataObj());
+                break;
+        }
+    }
+
+
+    /**
+     * 绑定独家礼包
+     *
+     * @param holder
+     * @param models
+     */
+    private void bindDuJiaGift(ViewHolder holder, final List<GiftCenterOuterClass.GiftCenter> models) {
+        RecyclerView recyclerView = holder.getView(R.id.recy_fgt_main_gift_dujia);
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new GridLayoutManager(mContext, 2));
+        recyclerView.setAdapter(new RecyclerView.Adapter() {
+            @Override
+            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                View view = View.inflate(mContext, R.layout.list_item_main_page_gift_dujia, null);
+                view.setOnClickListener(cls_GoGameDetail);
+                return new ViewHolder(mContext, view, parent, -1);
+            }
+
+            @Override
+            public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
+                ViewFindUtils.find(holder.itemView, R.id.txt_list_item_main_page_gift_dujia_title,
+                        TextView.class).setText(models.get(position).getTitle());
+                ViewFindUtils.find(holder.itemView, R.id.txt_list_item_main_page_gift_dujia_getnum,
+                        TextView.class).setText(String.format("已有 %d 人领取", models.get(position).getReceiveUserNum()));
+                ViewFindUtils.find(holder.itemView, R.id.txt_list_item_main_page_gift_dujia_gift,
+                        TextView.class).setText(String.format("礼包总数:%d", models.get(position).getGiftNum()));
+                Glide.with(mContext)
+                        .load(models.get(position).getIconImage())
+                        .into(ViewFindUtils.find(holder.itemView, R.id.img_list_item_main_page_gift_dujia_logo,
+                                ImageView.class));
+
+//                ViewFindUtils.find(holder.itemView, R.id.img_list_item_main_page_gift_dujia_icon)
+//                        .setVisibility(models.get(position).getGiftNum() - models.get(position).getReceiveUserNum() > 0 ?
+//                                View.VISIBLE : View.GONE);
+                ViewFindUtils.find(holder.itemView, R.id.img_list_item_main_page_gift_dujia_icon)
+                        .setVisibility(models.get(position).getGiftNum() > 0 ?
+                                View.VISIBLE : View.GONE);
+                holder.itemView.setTag(TAG_ID_TEMP, models.get(position).getGameId());
+            }
+
+            @Override
+            public int getItemCount() {
+                return models.size();
+            }
+        });
+
+    }
+
+
+    /**
+     * TAG_ID_TEMP为GameId
+     */
+    private View.OnClickListener cls_GoGameDetail = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID_TEMP), 1);
+        }
+    };
+
+
+    /**
+     * 绑定已经玩过游戏的礼包
+     *
+     * @param holder
+     * @param models
+     */
+    private void bindAlreadyPlayed(final ViewHolder holder,
+                                   final List<GiftCenterOuterClass.GiftCenter> models) {
+        //不能用GONE的方式,这样会有空白
+        RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) holder.getConvertView().getLayoutParams();
+        if (models == null || models.size() < 1) {
+            holder.getConvertView().setVisibility(View.GONE);
+            param.height = 0;
+            param.width = 0;
+        } else {
+            param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
+            param.width = LinearLayout.LayoutParams.MATCH_PARENT;
+            holder.getConvertView().setVisibility(View.VISIBLE);
+        }
+        holder.getConvertView().setLayoutParams(param);
+
+
+        RecyclerView recyclerView = holder.getView(R.id.recy_fgt_main_gift_played);
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.HORIZONTAL));
+        recyclerView.setAdapter(new RecyclerView.Adapter() {
+            @Override
+            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                View view = View.inflate(mContext, R.layout.list_item_main_page_gift_played, null);
+                view.setLayoutParams(new RelativeLayout
+                        .LayoutParams((HelperUtils.W - HelperUtils.getDpiToPix(10)) / 2,
+                        HelperUtils.getDpiToPix(100)));
+                view.setOnClickListener(cls_GoGameDetail);
+                ViewHolder viewHolder = new ViewHolder(mContext, view, parent, -1);
+                return viewHolder;
+            }
+
+            @Override
+            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+                ViewFindUtils.find(holder.itemView, R.id.txt_list_item_main_page_gift_played_title,
+                        TextView.class).setText(models.get(position).getTitle());
+                ViewFindUtils.find(holder.itemView, R.id.txt_list_item_main_page_gift_played_gift,
+                        TextView.class).setText("礼包总数:" + models.get(position).getGiftNum());
+                Glide.with(mContext)
+                        .load(models.get(position).getIconImage())
+                        .into(ViewFindUtils.find(holder.itemView, R.id.img_list_item_main_page_gift_played_logo,
+                                ImageView.class));
+                holder.itemView.setTag(TAG_ID_TEMP, models.get(position).getGameId());
+            }
+
+            @Override
+            public int getItemCount() {
+                return models.size();
+            }
+        });
+    }
+
+}

+ 681 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpMainPageRecy.java

@@ -0,0 +1,681 @@
+package com.kfzs.duanduan.adp;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v4.view.ViewPager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.text.Html;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.RadioGroup;
+import android.widget.RatingBar;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.resource.drawable.GlideDrawable;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.kfzs.duanduan.ActMain;
+import com.kfzs.duanduan.ActNewGameBook;
+import com.kfzs.duanduan.G;
+import com.kfzs.duanduan.KFZSApp;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.CateGameBean;
+import com.kfzs.duanduan.bean.Game;
+import com.kfzs.duanduan.bean.GuessYouLike;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.bean.NewGameRecommend;
+import com.kfzs.duanduan.bean.RecyleObj;
+import com.kfzs.duanduan.bean.RecyleType;
+import com.kfzs.duanduan.bean.SpecialRecommend;
+import com.kfzs.duanduan.bean.VipStyle;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.datashare.DDProviderHelper;
+import com.kfzs.duanduan.event.BigEvent;
+import com.kfzs.duanduan.event.EventTypes;
+import com.kfzs.duanduan.proto.IndexBannerOuterClass;
+import com.kfzs.duanduan.proto.VoucherOuterClass;
+import com.kfzs.duanduan.utils.DiscountUtils;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.utils.NumberFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.view.ImageGlarry;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.duanduan.view.TextViewList;
+import com.umeng.analytics.MobclickAgent;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpMainPageRecy</p>
+ * @ <p>Description: 这是首页推荐栏的RecyleView适配器</p>
+ * @ date:  2017/6/15 13:03
+ * @ QQ:    315096953
+ */
+
+public class AdpMainPageRecy extends AdpCommonRecy<RecyleObj> {
+
+    private final String TAG = this.getClass().getName();
+    private Map<String, InstallButtonUtils> mDownLoadItemLogicMgrMap = new HashMap<>();
+    //设置Tag,因为默认Tag用于HoldView了 ,所以加个TagKey,ID必须为任意ResId
+    private final static int TAG_ID_TEMP = R.id.view_tag_1;
+    private final static int TAG_ID_TEMP2 = R.id.view_tag_2;
+    private RecyclerView mRecyView;//返回顶层的监听
+    private final static String HTML_FORMAT = "<b><font color='#E4B441'>限时福利 </font>%s会员专享</b>";
+    private ImageGlarry mImageGlarry;
+
+    public AdpMainPageRecy(Context context, RecyclerView recyclerView) {
+        super(context);
+        mContext = context;
+        mRecyView = recyclerView;
+    }
+
+
+    /**
+     * @param viewType
+     * @return 失败返回0
+     */
+    @Override
+    public int getViewIdByType(int viewType) {
+        int resId = R.layout.empty;
+        RecyleType recyleType = RecyleType.values()[viewType];
+        switch (recyleType) {
+            case BANNER:
+                resId = R.layout.fgt_main_banner;
+                break;
+            case THREE_PLAY:
+                resId = R.layout.fgt_main_three_play;
+                break;
+            case OWN_ZONE:
+                resId = R.layout.fgt_main_own_zone;
+                break;
+            case COUPON:
+                resId = R.layout.fgt_main_coupon;
+                break;
+            case NEW_GAME_BOOK:
+                resId = R.layout.fgt_main_new_game_book;
+                break;
+            case GUESS_YOU_LIKE:
+                resId = R.layout.fgt_main_guess_you_like;
+                break;
+            case NEW_FIRST:
+                resId = R.layout.fgt_main_newrealse;
+                break;
+            case NEW_GAME_RECOMMEND:
+                resId = R.layout.fgt_main_new_game_invite;
+                break;
+            case SPECIAL_GAME_RECOMMEND:
+                resId = R.layout.fgt_main_special_game_invite;
+                break;
+            case RPG:
+            case CARTON:
+                resId = R.layout.mainpage_game_list;
+                break;
+            case SUBJECT:
+                resId = R.layout.subject_list;
+                break;
+            case PALY_WITH_YOU:
+                resId = R.layout.fgt_main_playwithyou;
+                break;
+            case NEW_GAME:
+                resId = R.layout.fgt_main_newgame;
+                break;
+            case CHOICES_GAME:
+                resId = R.layout.fgt_main_choosegames;
+                break;
+            case DEFINE_GAME:
+                resId = R.layout.fgt_main_define;
+                break;
+            case BACK_TOP:
+                resId = R.layout.listview_item_load_over;
+                break;
+        }
+        return resId;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return getmListDatas().get(position).getRecyleType().ordinal();
+    }
+
+    public Map<String, InstallButtonUtils> getmDownLoadItemLogicMgrMap() {
+        return mDownLoadItemLogicMgrMap;
+    }
+
+    @Override
+    public void convert(ViewHolder holder, RecyleObj recyleObj) {
+        if (recyleObj.getLoaded()) {//性能优化处理
+            return;
+        }
+        switch (recyleObj.getRecyleType()) {
+            case BANNER:
+                bindBanner(holder, (List<IndexBannerOuterClass.IndexBanner>) recyleObj.getDataObj());
+                break;
+            case THREE_PLAY:
+                bindThreePlay(holder);
+                break;
+            case OWN_ZONE:
+                bindOwnZone(holder);
+                break;
+            case COUPON:
+                bindCoupon(holder, recyleObj);
+                break;
+            case NEW_GAME_BOOK:
+                bindNewGameBook(holder, (List<Game>) recyleObj.getDataObj());
+                break;
+            case NEW_GAME_RECOMMEND:
+                bindNewGameRecommend(holder, (List<NewGameRecommend>) recyleObj.getDataObj());
+                break;
+            case SPECIAL_GAME_RECOMMEND:
+                bindSpecialGameRecommend(holder, (SpecialRecommend) recyleObj.getDataObj());
+                break;
+            case RPG:
+            case CARTON:
+                CateGameBean cateGameBean = (CateGameBean) recyleObj.getDataObj();
+                bindCarTonAndRPG(holder, cateGameBean, cateGameBean.getType_name());
+                break;
+            case SUBJECT:
+                bindSubject(holder, (CateGameBean) recyleObj.getDataObj());
+                break;
+            case GUESS_YOU_LIKE:
+                bindGuessYouLike(holder, (GuessYouLike) recyleObj.getDataObj());
+                break;
+            case BACK_TOP:
+                TextView textView = holder.getView(R.id.txt_back_top);
+                if (!textView.hasOnClickListeners()) {//性能优化
+                    textView.setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            mRecyView.scrollToPosition(0);
+                        }
+                    });
+                    if (mContext instanceof ActMain) {
+                        ((ActMain) mContext).showOrHideBottom(true);
+                    }
+                }
+                break;
+        }
+        recyleObj.setLoaded(true);
+    }
+
+    /**
+     * 绑定猜你喜欢
+     *
+     * @param holder
+     */
+    private void bindGuessYouLike(ViewHolder holder, final GuessYouLike guessYouLike) {
+        if (guessYouLike == null) {
+            return;
+        }
+        RecyclerView recyclerView = holder.getView(R.id.recy_fgt_main_guess_you_like);
+        Glide.with(mContext).load(guessYouLike.getImg())
+                .into(holder.getView(R.id.img_fgt_main_guess_you_like, ImageView.class));
+        holder.getView(R.id.img_fgt_main_guess_you_like)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameType(mContext, guessYouLike.getGametypeid());
+                    }
+                });
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,
+                StaggeredGridLayoutManager.HORIZONTAL));
+        recyclerView.setAdapter(new RecyclerView.Adapter() {
+            @Override
+            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                RelativeLayout itemView = (RelativeLayout) LayoutInflater.from(mContext)
+                        .inflate(R.layout.item_fgt_main_game_list, parent, false);
+                itemView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID_TEMP));
+                    }
+                });
+                ViewGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams((int) (G.WIDTH * 0.92),
+                        ViewGroup.LayoutParams.WRAP_CONTENT);
+                itemView.setLayoutParams(layoutParams);
+
+                RecyclerView.ViewHolder viewHolder = new RecyclerView.ViewHolder(itemView) {
+                };
+                return viewHolder;
+            }
+
+            @Override
+            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+                holder.itemView.setTag(TAG_ID_TEMP, guessYouLike.getGames().get(position).getId());
+
+                DiscountUtils.getInstance().showDiscount(holder.itemView,
+                        guessYouLike.getGames().get(position).getIconImage(),
+                        guessYouLike.getGames().get(position).getDiscount());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_main_game_list_title)
+                ).setText(guessYouLike.getGames().get(position).getGameName());
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_main_game_list_type)
+                ).setText(guessYouLike.getGames().get(position).getTypeText());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_game_list_down)
+                ).setText("(" + guessYouLike.getGames().get(position).getDownloadNum() + ")");
+
+                ((RatingBar) holder.itemView.findViewById(R.id.ratb_item_fgt_main_game_list)
+                ).setRating(NumberFormatUtils.getDivideResult(guessYouLike.getGames().get(position).getStar()));
+                holder.itemView.findViewById(R.id.line_item_fgt_main_game_list)
+                        .setVisibility(position % 3 == 2 ? View.GONE : View.VISIBLE);
+                DownBtnUtils.addDownloadBtnListener((KFProgressButton) holder.itemView.findViewById(R.id.btn_item_fgt_main_game_list),
+                        mContext, mDownLoadItemLogicMgrMap, guessYouLike.getGames().get(position).getGameV1(),
+                        "guess_you_like" + position);
+            }
+
+            @Override
+            public int getItemCount() {
+                return guessYouLike.getGames().size();
+            }
+
+
+        });
+    }
+
+
+    /**
+     * 绑定专题
+     *
+     * @param holder
+     * @param gameBean
+     */
+    private void bindSubject(ViewHolder holder, final CateGameBean gameBean) {
+        if (gameBean == null) {
+            return;
+        }
+        RecyclerView recyclerView = holder.getView(R.id.recy_subject_list);
+        Glide.with(mContext).load(gameBean.getImg())
+                .into(holder.getView(R.id.img_subject_list, ImageView.class));
+        holder.getView(R.id.img_subject_list)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameType(mContext, gameBean.getGametypeid());
+                    }
+                });
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,
+                StaggeredGridLayoutManager.HORIZONTAL));
+        recyclerView.setAdapter(new RecyclerView.Adapter() {
+            @Override
+            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                View itemView = LayoutInflater.from(mContext)
+                        .inflate(R.layout.item_fgt_main_game_list, parent, false);
+                itemView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID_TEMP));
+                    }
+                });
+                ViewGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams((int) (G.WIDTH * 0.92),
+                        ViewGroup.LayoutParams.WRAP_CONTENT);
+                itemView.setLayoutParams(layoutParams);
+                RecyclerView.ViewHolder viewHolder = new RecyclerView.ViewHolder(itemView) {
+                };
+                return viewHolder;
+            }
+
+            @Override
+            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+                holder.itemView.setTag(TAG_ID_TEMP, gameBean.getGames().get(position).getId());
+
+                DiscountUtils.getInstance().showDiscount(holder.itemView,
+                        gameBean.getGames().get(position).getIconImage(),
+                        gameBean.getGames().get(position).getDiscount());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_main_game_list_title)
+                ).setText(gameBean.getGames().get(position).getGameName());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_main_game_list_type)
+                ).setText(gameBean.getGames().get(position).getTypeText());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_game_list_down)
+                ).setText("(" + gameBean.getGames().get(position).getDownloadNum() + ")");
+
+                holder.itemView.findViewById(R.id.line_item_fgt_main_game_list)
+                        .setVisibility(position % 3 == 2 ? View.GONE : View.VISIBLE);
+
+                ((RatingBar) holder.itemView.findViewById(R.id.ratb_item_fgt_main_game_list)
+                ).setRating(NumberFormatUtils.getDivideResult(gameBean.getGames().get(position).getStar()));
+                DownBtnUtils.addDownloadBtnListener((KFProgressButton) holder.itemView.findViewById(R.id.btn_item_fgt_main_game_list),
+                        mContext, mDownLoadItemLogicMgrMap, gameBean.getGames().get(position).getGameV1(), "subject_" + position);
+            }
+
+            @Override
+            public int getItemCount() {
+                return gameBean.getGames().size();
+            }
+
+        });
+    }
+
+    /**
+     * 绑定卡通一栏
+     *
+     * @param holder
+     * @param gameBean
+     * @param typename 这里以后改为int或枚举吧,很可能会动增的
+     */
+    private void bindCarTonAndRPG(ViewHolder holder, final CateGameBean gameBean, String typename) {
+        if (gameBean == null) {
+            return;
+        }
+        RecyclerView recyclerView = holder.getView(R.id.recy_mainpage_game_list, RecyclerView.class);
+        holder.getView(R.id.txt_mainpage_game_list, TextView.class)
+                .setText(typename);
+        holder.getView(R.id.txt_mainpage_game_list_more)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameType(mContext, gameBean.getGametypeid());
+                    }
+                });
+//        Glide.with(mContext).load(VipStyle.getInstance().getMore())
+//                .into(holder.getView(R.id.txt_mainpage_game_list_more, ImageView.class));
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
+        recyclerView.setAdapter(new RecyclerView.Adapter() {
+            @Override
+            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                View itemView = LayoutInflater.from(mContext)
+                        .inflate(R.layout.item_fgt_main_game_list, parent, false);
+                itemView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID_TEMP));
+                    }
+                });
+                RecyclerView.ViewHolder viewHolder = new RecyclerView.ViewHolder(itemView) {
+                };
+                return viewHolder;
+            }
+
+            @Override
+            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+                holder.itemView.setTag(TAG_ID_TEMP, gameBean.getGames().get(position).getId());
+
+                DiscountUtils.getInstance().showDiscount(holder.itemView,
+                        gameBean.getGames().get(position).getIconImage(),
+                        gameBean.getGames().get(position).getDiscount());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_main_game_list_title)
+                ).setText(gameBean.getGames().get(position).getGameName());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_main_game_list_type)
+                ).setText(gameBean.getGames().get(position).getTypeText());
+
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_game_list_down)
+                ).setText("(" + gameBean.getGames().get(position).getDownloadNum() + ")");
+
+                holder.itemView.findViewById(R.id.line_item_fgt_main_game_list)
+                        .setVisibility(position == getItemCount() - 1 ? View.GONE : View.VISIBLE);
+                ((RatingBar) holder.itemView.findViewById(R.id.ratb_item_fgt_main_game_list)
+                ).setRating(NumberFormatUtils.getDivideResult(gameBean.getGames().get(position).getStar()));
+                DownBtnUtils.addDownloadBtnListener((KFProgressButton) holder.itemView.findViewById(R.id.btn_item_fgt_main_game_list),
+                        mContext, mDownLoadItemLogicMgrMap, gameBean.getGames().get(position).getGameV1(), "carton_" + position);
+            }
+
+            @Override
+            public int getItemCount() {
+                return gameBean.getGames().size();
+            }
+        });
+    }
+
+
+    /**
+     * 绑定特别推荐栏
+     *
+     * @param holder
+     */
+    private void bindSpecialGameRecommend(ViewHolder holder, final SpecialRecommend specialRecommend) {
+        if (specialRecommend == null) {
+            return;
+        }
+        Glide.with(mContext).load(specialRecommend.getImg())
+                .into(holder.getView(R.id.img_main_special_recommend_banner, ImageView.class));
+        DiscountUtils.getInstance().showDiscount(holder.itemView,
+                specialRecommend.getGame().getIconImage(),
+                specialRecommend.getGame().getDiscount());
+
+        holder.getView(R.id.txt_main_special_recommend_main_title, TextView.class)
+                .setText(specialRecommend.getName());
+        holder.getView(R.id.txt_main_special_recommend_title, TextView.class)
+                .setText(specialRecommend.getGame().getGameName());
+        holder.getView(R.id.txt_main_special_recommend_type, TextView.class)
+                .setText(specialRecommend.getGame().getSize());
+        holder.getView(R.id.lay_fgt_main_special_recommend)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        SkipUtils.getInstance().goGameDetails(mContext, specialRecommend.getGame().getId());
+                    }
+                });
+        holder.getView(R.id.img_main_special_recommend_banner)
+                .setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        SkipUtils.getInstance().goGameDetails(mContext, specialRecommend.getGame().getId());
+                    }
+                });
+        DownBtnUtils.addDownloadBtnListener(holder.getView(R.id.btn_fgt_main_special_recommend, KFProgressButton.class),
+                mContext, mDownLoadItemLogicMgrMap, specialRecommend.getGame().getGameV1(), "specail_recommend");
+    }
+
+    /**
+     * 新游推荐
+     *
+     * @param holder
+     */
+    private void bindNewGameRecommend(ViewHolder holder, final List<NewGameRecommend> recommendList) {
+        if (recommendList == null || recommendList.size() < 1) {
+            return;
+        }
+        RecyclerView recyclerView = holder.getView(R.id.recy_fgt_main_new_game_invite);
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(1,
+                StaggeredGridLayoutManager.HORIZONTAL));
+        recyclerView.setAdapter(new RecyclerView.Adapter() {
+            @Override
+            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                View itemView = LayoutInflater.from(mContext)
+                        .inflate(R.layout.item_fgt_main_new_game_invite, parent, false);
+                itemView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID_TEMP));
+                    }
+                });
+                RecyclerView.ViewHolder viewHolder = new RecyclerView.ViewHolder(itemView) {
+                };
+                return viewHolder;
+            }
+
+            @Override
+            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+                holder.itemView.setTag(TAG_ID_TEMP, recommendList.get(position).getGameid());
+                ((TextView) holder.itemView.findViewById(R.id.txt_item_fgt_main_new_game_invite)
+                ).setText(recommendList.get(position).getGamename());
+
+                DiscountUtils.getInstance().showDiscount(holder.itemView,
+                        recommendList.get(position).getIcon(), recommendList.get(position).getDiscount());
+            }
+
+            @Override
+            public int getItemCount() {
+                return recommendList.size();
+            }
+        });
+    }
+
+    /**
+     * 新游预约
+     *
+     * @param holder
+     */
+    private void bindNewGameBook(ViewHolder holder, List<Game> gameList) {
+        if (gameList == null || gameList.size() < 1) {
+            return;
+        }
+        TextViewList textViewList = holder.getView(R.id.txt_fgt_main_new_game_book);
+
+        if (!holder.itemView.hasOnClickListeners()) {
+            holder.itemView.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    Intent intent = new Intent(mContext, ActNewGameBook.class);
+                    mContext.startActivity(intent);
+                }
+            });
+            textViewList.setSingleLine();
+        }
+
+        textViewList.clearTextList();
+        for (Game game : gameList) {
+            textViewList.addTextList(game.getGameName() + " , " + game.getIntroduce());
+        }
+        textViewList.setAuto(true);
+        textViewList.startAutoScroll();
+    }
+
+
+    /**
+     * 绑定福利优惠券
+     *
+     * @param holder
+     */
+    private void bindCoupon(ViewHolder holder, RecyleObj recyleObj) {
+        RecyclerView recyclerView = holder.getView(R.id.recy_fgt_main_coupon);
+        final List<VoucherOuterClass.Voucher> vouchers = (List<VoucherOuterClass.Voucher>) recyleObj.getDataObj();
+        recyclerView.setHasFixedSize(true);
+        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(1,
+                StaggeredGridLayoutManager.HORIZONTAL));
+        final TextView textView = holder.getView(R.id.txt_fgt_main_coupon, TextView.class);
+        textView.setText(Html.fromHtml(String.format(HTML_FORMAT, VipStyle.getInstance().getViptypename())));
+
+        Glide.with(mContext).load(VipStyle.getInstance().getRhombus())
+                .into(new SimpleTarget<GlideDrawable>() {
+                    @Override
+                    public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
+                        resource.setBounds(0, 0, resource.getMinimumWidth(), resource.getMinimumHeight());
+                        textView.setCompoundDrawables(resource, null, resource, null);
+                    }
+                });
+        recyclerView.setAdapter(new AdpCoupon(mContext, vouchers));
+    }
+
+
+    /**
+     * 绑定专区
+     *
+     * @param holder
+     */
+    private void bindOwnZone(ViewHolder holder) {
+        Glide.with(mContext).load(VipStyle.getInstance().getIndexbanner())
+                .into(holder.getView(R.id.img_fgt_main_own_zone, ImageView.class));
+        holder.itemView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                G.showToast("该功能正在建设中");
+            }
+        });
+    }
+
+    /**
+     * 绑定三个玩的功能
+     *
+     * @param holder
+     */
+    private void bindThreePlay(ViewHolder holder) {
+        holder.getView(R.id.img_fgt_main_three_play_left).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                G.showToast("该功能正在建设中");
+            }
+        });
+        holder.getView(R.id.img_fgt_main_three_play_mid).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                EventBus.getDefault().post(BigEvent.get().setEventTypes(EventTypes.WEB_GO_BBS));
+            }
+        });
+        holder.getView(R.id.img_fgt_main_three_play_right).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                G.showToast("该功能正在建设中");
+            }
+        });
+
+        Glide.with(mContext)
+                .load(VipStyle.getInstance().getKaixinwan())
+                .into(holder.getView(R.id.img_fgt_main_three_play_left, ImageView.class));
+        Glide.with(mContext)
+                .load(VipStyle.getInstance().getYiqiwan())
+                .into(holder.getView(R.id.img_fgt_main_three_play_mid, ImageView.class));
+        Glide.with(mContext)
+                .load(VipStyle.getInstance().getTaozhewan())
+                .into(holder.getView(R.id.img_fgt_main_three_play_right, ImageView.class));
+
+
+    }
+
+    /**
+     * 绑定Banner的操作过程
+     *
+     * @param holder
+     * @param topBannerList
+     */
+    private void bindBanner(ViewHolder holder, final List<IndexBannerOuterClass.IndexBanner> topBannerList) {
+        ViewPager viewPager = holder.getView(R.id.viewpager_fgt_main_banner);
+        RadioGroup radioGroup = holder.getView(R.id.group_fgt_main_banner);
+        ArrayList<String> imgURL = new ArrayList<>();
+        for (IndexBannerOuterClass.IndexBanner indexBanner : topBannerList) {
+            imgURL.add(indexBanner.getImageUrl());
+        }
+        if (mImageGlarry != null) {
+            mImageGlarry.init(imgURL.toArray(new String[]{}), ImageView.ScaleType.CENTER_CROP);
+            return;
+        }
+        mImageGlarry = new ImageGlarry((Activity) mContext, viewPager, radioGroup);
+        mImageGlarry.init(imgURL.toArray(new String[]{}), ImageView.ScaleType.CENTER_CROP);
+        mImageGlarry.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                IndexBannerOuterClass.IndexBanner clickedGameObj = topBannerList.get(position);
+                Map<String, String> map = new HashMap<>();
+                map.put("BANNER_TYPE", clickedGameObj.getType() == KFIntentKeys.BANNER_TYPE_GAME ? "游戏Banner" : "广告Banner");
+                //TODO 小刁,这些事件分析以后要专门弄个静态类来统一管理
+                MobclickAgent.onEvent(mContext, "BannerClickHorizontal", map);
+                switch (clickedGameObj.getType()) {
+                    case KFIntentKeys.BANNER_TYPE_GAME:
+                        SkipUtils.getInstance().goGameDetails(mContext, clickedGameObj.getGameId());
+                        break;
+                    case KFIntentKeys.BANNER_TYPE_AD:
+                        SkipUtils.getInstance().goWebView(mContext, clickedGameObj.getHtmlUrl(),
+                                clickedGameObj.getTitle(), mContext.getPackageName(), clickedGameObj.getGameId());
+                        break;
+                }
+            }
+        });
+    }
+
+
+}

+ 169 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpMainStartService.java

@@ -0,0 +1,169 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.bean.RecyleObj;
+import com.kfzs.duanduan.bean.RecyleType;
+import com.kfzs.duanduan.proto.OpenTestOpenServerList;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpMainStartService</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/26 10:53
+ * @ QQ:    315096953
+ */
+
+public class AdpMainStartService extends AdpCommonRecy<RecyleObj> {
+
+    private final String TAG = this.getClass().getName();
+    private Map<String, InstallButtonUtils> mDownLoadItemLogicMgrMap = new HashMap<>();
+
+    public AdpMainStartService(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+
+    /**
+     * @param viewType
+     * @return 失败返回0
+     */
+    @Override
+    public int getViewIdByType(int viewType) {
+        int resId = 0;
+        RecyleType recyleType = RecyleType.values()[viewType];
+        switch (recyleType) {
+            case START_TAB_NAME:
+                resId = R.layout.item_main_page_start_service_tab;
+                break;
+            case START_SERVICE_TODAY:
+            case START_SERVICE_TOMORROW:
+            case START_TEST_TODAY:
+            case START_TEST_TOMORROW:
+                resId = R.layout.list_item_search_test;
+                break;
+        }
+        return resId;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return getmListDatas().get(position).getRecyleType().ordinal();
+    }
+
+    public Map<String, InstallButtonUtils> getmDownLoadItemLogicMgrMap() {
+        return mDownLoadItemLogicMgrMap;
+    }
+
+    @Override
+    public void convert(ViewHolder holder, RecyleObj recyleObj) {
+        switch (recyleObj.getRecyleType()) {
+            case START_TAB_NAME:
+                bindTab(holder, recyleObj);
+                break;
+            case START_SERVICE_TODAY:
+            case START_SERVICE_TOMORROW:
+                bindOpenService(holder, (OpenTestOpenServerList.OpenServer) recyleObj.getDataObj());
+                break;
+            case START_TEST_TODAY:
+            case START_TEST_TOMORROW:
+                bindOpenTest(holder, (OpenTestOpenServerList.OpenTest) recyleObj.getDataObj());
+                break;
+        }
+    }
+
+
+    /**
+     * 绑定自定义列表
+     *
+     * @param holder
+     * @param recyleObj Tab的分类名
+     */
+    private void bindTab(ViewHolder holder, RecyleObj recyleObj) {
+        holder.getView(R.id.txt_item_main_page_start_service_tab, TextView.class)
+                .setText(recyleObj.getDataObj() + "");
+    }
+
+
+    /**
+     * 加载开服信息
+     *
+     * @param holder
+     * @param openServer
+     */
+    private void bindOpenService(ViewHolder holder, OpenTestOpenServerList.OpenServer openServer) {
+        Glide.with(mContext)
+                .load(openServer.getGame().getIconImage())
+                .into(holder.getView(R.id.img_list_item_search_test_logo, ImageView.class));
+        holder.getView(R.id.txt_list_item_search_test_title, TextView.class)
+                .setText(openServer.getGame().getGameName());
+
+        holder.getView(R.id.txt_list_item_search_test_time, TextView.class)
+                .setText(DateFormatUtils.doOpenserveDate(openServer.getOpenServerTime()));
+        holder.getView(R.id.img_list_item_search_test_icon)
+                .setVisibility(openServer.getGame().getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        holder.getView(R.id.txt_list_item_search_test_type, TextView.class)
+                .setText(openServer.getRemark());
+        DownBtnUtils.addDownloadBtnListener(holder.getView(R.id.btn_list_item_search_test,
+                KFProgressButton.class), mContext, mDownLoadItemLogicMgrMap, openServer.getGame(),
+                "mainpape_open_service" + openServer.getCreatedTime() + openServer.getGameId());
+
+        final int gameid = openServer.getGameId();
+        holder.getConvertView().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                SkipUtils.getInstance().goGameDetails(mContext, gameid);
+            }
+        });
+    }
+
+
+    /**
+     * 加载开测信息
+     *
+     * @param holder
+     * @param openTest
+     */
+    private void bindOpenTest(ViewHolder holder, final OpenTestOpenServerList.OpenTest openTest) {
+        Glide.with(mContext)
+                .load(openTest.getGame().getIconImage())
+                .into(holder.getView(R.id.img_list_item_search_test_logo, ImageView.class));
+        holder.getView(R.id.txt_list_item_search_test_title, TextView.class)
+                .setText(openTest.getGame().getGameName());
+        holder.getView(R.id.txt_list_item_search_test_time, TextView.class)
+                .setText(DateFormatUtils.doOpenTestDate(openTest.getOpenTestTime()));
+        holder.getView(R.id.img_list_item_search_test_icon)
+                .setVisibility(openTest.getGame().getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        holder.getView(R.id.txt_list_item_search_test_type, TextView.class)
+                .setText(openTest.getRemark());
+        DownBtnUtils.addDownloadBtnListener(holder.getView(R.id.btn_list_item_search_test,
+                KFProgressButton.class), mContext, mDownLoadItemLogicMgrMap, openTest.getGame(),
+                "mainpape_open_test" + openTest.getCreatedTime() + openTest.getGameId());
+
+
+        final int gameid = openTest.getGameId();
+        holder.getConvertView().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                SkipUtils.getInstance().goGameDetails(mContext, gameid);
+            }
+        });
+    }
+
+
+}

+ 144 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpSearchGame.java

@@ -0,0 +1,144 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RatingBar;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.duanduan.utils.ThemeUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.duanduan.ActWeb;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.KFIntentKeys;
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.utils.NumberFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpSearchGame</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/22 16:14
+ * @ QQ:    315096953
+ */
+
+public class AdpSearchGame extends BaseAdpterWithDownBtn {
+
+    private List<GameOuterClass.Game> mList = new ArrayList<>();
+
+    public AdpSearchGame(Context context) {
+        this.mContext = context;
+    }
+
+    public void addAll(List<GameOuterClass.Game> list) {
+        mList.addAll(list);
+    }
+
+    public void clear() {
+        mList.clear();
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public GameOuterClass.Game getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(final int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.listview_item_game_info, null);
+            convertView.setOnClickListener(cls_GoDetail);
+        }
+
+        Glide.with(mContext).load(getItem(position).getIconImage())
+                .transform(new KFGlideRoundTransform(mContext, 5))
+                .into(ViewFindUtils.find(convertView, R.id.img_logo, ImageView.class));
+
+        ViewFindUtils.find(convertView, R.id.img_listview_item_game_info)
+                .setVisibility(getItem(position).getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        ViewFindUtils.find(convertView, R.id.txt_list_item_game_info_title, TextView.class)
+                .setText(getItem(position).getGameName());
+        ViewFindUtils.find(convertView, R.id.txt_list_item_game_info_type, TextView.class)
+                .setText(getItem(position).getTypeText());
+
+        String downloadCnt = String.format(mContext.getString(R.string.download_count),
+                getItem(position).getDownloadNum() + "");
+        ViewFindUtils.find(convertView, R.id.txt_list_item_game_info_down_count, TextView.class)
+                .setText(downloadCnt + "");
+        ViewFindUtils.find(convertView, R.id.ratbar_list_item_game_info, RatingBar.class)
+                .setRating(NumberFormatUtils.getDivideResult(getItem(position).getStar()));
+
+        //更新跳转位置
+        convertView.setTag(TAG_ID, getItem(position).getId());
+
+        //下载按钮的功能处理
+        KFProgressButton btn = ViewFindUtils.hold(convertView, R.id.btn_list_item_game_info);
+        if (getItem(position).getIsInBook() == 1) {
+            if (getItem(position).getIsCanPreDown()) {
+                btn.setText(mContext.getString(R.string.predown));
+                btn.setOnClickListener(null);
+                DownBtnUtils.addDownloadBtnListener(btn, mContext,
+                        getmInstallButtonMgrMap(), getItem(position),
+                        "search_game" + position);
+            } else {
+                btn.setText(mContext.getString(R.string.tab_game_order));
+                btn.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        goBookedGame(getItem(position));
+                    }
+                });
+            }
+        } else {
+            btn.setText(mContext.getString(R.string.install));
+            btn.setOnClickListener(null);
+            DownBtnUtils.addDownloadBtnListener(btn, mContext,
+                    getmInstallButtonMgrMap(), getItem(position),
+                    "search_game" + position);
+        }
+        return convertView;
+    }
+
+
+    /**
+     * 跳到预约游戏
+     *
+     * @param game
+     */
+    private void goBookedGame(GameOuterClass.Game game) {
+        SkipUtils.getInstance().goGameDetails(mContext, game.getId());
+//        Intent intent = new Intent(mContext, ActWeb.class);
+//
+//        intent.putExtra(KFIntentKeys.EXTRA_BEHAIOR, ActWeb.BEHAVIOR_GAME_BOOK);
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_SHARE_IMGURL, game.getIconImage());
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_BOOK_ID, String.valueOf(game.getBookId()));
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_ID, String.valueOf(game.getId()));
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_PACKAGENAME, game.getPackageName());
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_VERSION, game.getVersion());
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_GAME_SIZE, game.getSize());
+//
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_URL, game.getUrl());
+//        intent.putExtra(KFIntentKeys.EXTRA_WEBVIEW_TITLE, game.getGameName());
+//        mContext.startActivity(intent);
+    }
+}

+ 169 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpSearchGift.java

@@ -0,0 +1,169 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.text.Html;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.kfzs.appstore.utils.restful.KFZSNetwork;
+import com.kfzs.duanduan.ActGift;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bll.UrlBll;
+import com.kfzs.duanduan.datashare.KFZSDDContentSession;
+import com.kfzs.duanduan.datashare.provider.session.SessionBean;
+import com.kfzs.duanduan.proto.ApiRequestOuterClass;
+import com.kfzs.duanduan.proto.ApiResponseOuterClass;
+import com.kfzs.duanduan.proto.GiftCodeOuterClass;
+import com.kfzs.duanduan.proto.ShelvesGiftOuterClass;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.HelperUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+import com.kfzs.duanduan.utils.net.APIRequest;
+import com.kfzs.duanduan.utils.net.APIRequestInstance;
+import com.kfzs.duanduan.utils.net.ResponseNetworkTask;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static com.kfzs.duanduan.G.showToast;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpSearchGift</p>
+ * @ <p>Description: 商品详情页中礼包列表的适配器</p>
+ * @ date:  2017/6/22 16:15
+ * @ QQ:    315096953
+ */
+
+public class AdpSearchGift extends BaseAdapter {
+
+    private List<ShelvesGiftOuterClass.ShelvesGift> mList = new ArrayList<>();
+    private Context mContext;
+    private final String HTML_TXT = "<font color='#F66600'>%s</font><font color='black'>-%s</font>";
+    private final String TAG = "AdpSearchGift";
+    private final int TAG_GIFT_POS = R.id.view_tag_gift_btn;
+
+    public AdpSearchGift(Context context) {
+        this.mContext = context;
+    }
+
+    public void addAll(List<ShelvesGiftOuterClass.ShelvesGift> list) {
+        mList.addAll(list);
+    }
+
+    public void clear() {
+        mList.clear();
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public ShelvesGiftOuterClass.ShelvesGift getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.item_app_detail_gift, null);
+//            convertView.setOnClickListener(cls_GoGiftDetail);
+            ViewFindUtils.hold(convertView, R.id.btn_item_app_detail_get)
+                    .setOnClickListener(cls_GetCode);
+        }
+
+        ViewFindUtils.hold(convertView, R.id.txt_item_app_detail_gift_game_name, TextView.class)
+                .setText(Html.fromHtml(String.format(HTML_TXT, getItem(position).getGame().getGameName(),
+                        getItem(position).getGiftName())));
+
+        ViewFindUtils.hold(convertView, R.id.txt_act_game_gift_content, TextView.class)
+                .setText("礼包内容:\n" + getItem(position).getGiftContent());
+
+        //int percent = HelperUtils.getPercent(getItem(position).getTotalNum(), getItem(position).getReceiveNum());
+        int percent = (int) Math.ceil(getItem(position).getPercentum() * 100);
+        ViewFindUtils.hold(convertView, R.id.txt_act_game_gift_progress, TextView.class)
+                .setText(percent + "%");
+        ViewFindUtils.hold(convertView, R.id.pro_act_game_gift, ProgressBar.class)
+                .setProgress(percent);
+        ViewFindUtils.hold(convertView, R.id.txt_act_game_gift_time, TextView.class)
+                .setText("剩余礼包(有效日期:" + DateFormatUtils
+                        .doSecondDate(getItem(position).getEndTime()) + "):");
+
+        ViewFindUtils.hold(convertView, R.id.btn_item_app_detail_get)
+                .setVisibility(getItem(position).getStatus() == 1 ? View.GONE : View.VISIBLE);
+        ViewFindUtils.hold(convertView, R.id.btn_item_app_detail_get)
+                .setTag(TAG_GIFT_POS, position);
+        return convertView;
+    }
+
+
+    /**
+     * 跳转到礼包详情页
+     */
+    private View.OnClickListener cls_GoGiftDetail = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            SkipUtils.getInstance().goGiftDetails(mContext, getItem((int) v.getTag(TAG_GIFT_POS)));
+        }
+    };
+
+    /**
+     * 领取礼包码
+     */
+    private View.OnClickListener cls_GetCode = new View.OnClickListener() {
+        @Override
+        public void onClick(final View v) {
+            final int position = (int) v.getTag(TAG_GIFT_POS);
+            GiftCodeOuterClass.GiftCode.Builder builder = GiftCodeOuterClass.GiftCode.newBuilder();
+            builder.setGiftId(getItem(position).getId());
+
+            HashMap<String, String> headParams = new HashMap<>();
+            SessionBean outHeadSession = KFZSDDContentSession.getInstance()
+                    .findOutHeadSession(mContext);
+            if (outHeadSession == null) {
+                SkipUtils.getInstance().goLogin(mContext);
+                showToast(R.string.toast_user_login_pre);
+                return;
+            }
+            headParams.put(UrlBll.HeadParams.AUTHORIZATION, outHeadSession.getToken());
+
+            ApiRequestOuterClass.ApiRequest.Builder reqBuild = ApiRequestOuterClass.ApiRequest.newBuilder();
+            reqBuild.setGiftCode(builder);
+
+            APIRequest bannerRequest = APIRequestInstance.putReq(TAG, UrlBll.Gift.GIFT_EXCHANGE,
+                    reqBuild.build().toByteArray(), headParams, new ResponseNetworkTask() {
+                        @Override
+                        public void onSuccess(ApiResponseOuterClass.ApiResponse apiResponse) {
+                            showToast("领取成功!");
+//                            if (v instanceof Button) {
+//                                v.setEnabled(false);
+//                                ((Button) v).setText("已领取");
+//                            }
+                            v.setVisibility(View.GONE);
+                        }
+
+                        @Override
+                        public void onFail(int code, String msg) {
+                            showToast(msg);
+                        }
+                    }, HelperUtils.makeErr(mContext.getString(R.string.toast_gift_get_fail)));
+            KFZSNetwork.addRequest(bannerRequest);
+        }
+    };
+
+
+}

+ 84 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpSearchNewGame.java

@@ -0,0 +1,84 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.OpenTestOpenServerList;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpSearchNewGame</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/22 16:16
+ * @ QQ:    315096953
+ */
+
+public class AdpSearchNewGame extends BaseAdpterWithDownBtn {
+    private List<OpenTestOpenServerList.OpenServer> mList = new ArrayList<>();
+
+    public AdpSearchNewGame(Context context) {
+        this.mContext = context;
+    }
+
+    public void addAll(List<OpenTestOpenServerList.OpenServer> list) {
+        mList.addAll(list);
+    }
+
+    public void clear() {
+        mList.clear();
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public OpenTestOpenServerList.OpenServer getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.list_item_search_newgame, null);
+            convertView.setOnClickListener(cls_GoDetail);
+        }
+        ViewFindUtils.hold(convertView, R.id.txt_listview_item_newgame_title, TextView.class)
+                .setText(getItem(position).getGame().getGameName());
+        ViewFindUtils.hold(convertView, R.id.txt_listview_item_newgame_zone, TextView.class)
+                .setText(getItem(position).getRemark());
+        ViewFindUtils.hold(convertView, R.id.txt_listview_item_newgame_time, TextView.class)
+                .setText(DateFormatUtils.doOpenserveDate(getItem(position).getOpenServerTime()));
+
+        ViewFindUtils.hold(convertView, R.id.img_listview_item_newgame_icon)
+                .setVisibility(getItem(position).getGame().getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        Glide.with(mContext)
+                .load(getItem(position).getGame().getIconImage())
+                .into(ViewFindUtils.hold(convertView, R.id.img_list_item_search_newgame_logo, ImageView.class));
+
+        convertView.setTag(TAG_ID,getItem(position).getGameId());
+        DownBtnUtils.addDownloadBtnListener(ViewFindUtils.hold(convertView, R.id.btn_list_item_game_info,
+                KFProgressButton.class), mContext,
+                getmInstallButtonMgrMap(), getItem(position).getGame(),
+                "search_open_service" + position);
+        return convertView;
+    }
+}

+ 119 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpSearchRecord.java

@@ -0,0 +1,119 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.SearchRecordBean;
+import com.kfzs.duanduan.db.SearchRecordHelper;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpSearchRecord</p>
+ * @ <p>Description:搜索页的搜索历史列表Adp</p>
+ * @ date:  2017/8/19 10:14
+ * @ QQ:    315096953
+ */
+
+public class AdpSearchRecord extends BaseAdapter {
+
+    private Context mContext;
+    private List<SearchRecordBean> mList;
+    /**
+     * 这里是点击list列表后的监听
+     */
+    private AdapterView.OnItemClickListener mOnItemClickListener;
+    private final int TAG_ID = R.id.search_tagflow_layout;
+
+    /**
+     * @param context
+     * @param onItemClickListener 其中只有position有效,是点击时间的反馈
+     */
+    public AdpSearchRecord(Context context, AdapterView.OnItemClickListener onItemClickListener) {
+        mContext = context;
+        mList = new ArrayList<>();
+        mList = SearchRecordHelper.getInstance().getRecordList();
+        mOnItemClickListener = onItemClickListener;
+    }
+
+    public void clear() {
+        mList.clear();
+        SearchRecordHelper.getInstance().clearList();
+    }
+
+    public void add(String key) {
+        if (TextUtils.isEmpty(key)) {
+            return;
+        }
+        SearchRecordBean searchRecordBean = new SearchRecordBean();
+        searchRecordBean.setKey(key.trim());
+        searchRecordBean.setDate(new Date());
+        mList = SearchRecordHelper.getInstance().addRecordList(searchRecordBean);
+        notifyDataSetInvalidated();
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public SearchRecordBean getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.listview_item_search_history, null);
+            ViewFindUtils.hold(convertView, R.id.ibtn_listview_item_search_history_delete)
+                    .setOnClickListener(clsDelete);
+            convertView.setOnClickListener(clsSelect);
+        }
+        ViewFindUtils.hold(convertView, R.id.txt_listview_item_search_history_name, TextView.class)
+                .setText(getItem(position).getKey());
+        ViewFindUtils.hold(convertView, R.id.ibtn_listview_item_search_history_delete)
+                .setTag(TAG_ID, position);
+        convertView.setTag(TAG_ID, position);
+        return convertView;
+    }
+
+
+    /**
+     * 删除历史记录
+     */
+    private View.OnClickListener clsDelete = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            SearchRecordHelper.getInstance().deleteSameRecord(mList.get((int) v.getTag(TAG_ID)), mList);
+            notifyDataSetChanged();
+        }
+    };
+
+    /**
+     * 删除信息的回调
+     */
+    private View.OnClickListener clsSelect = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            mOnItemClickListener.onItemClick(null, v, (int) v.getTag(TAG_ID), 0);
+        }
+    };
+
+
+}

+ 86 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpSearchTest.java

@@ -0,0 +1,86 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.OpenTestOpenServerList;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.DownBtnUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpSearchTest</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/22 16:16
+ * @ QQ:    315096953
+ */
+
+public class AdpSearchTest extends BaseAdpterWithDownBtn {
+    private List<OpenTestOpenServerList.OpenTest> mList = new ArrayList<>();
+
+    public AdpSearchTest(Context context) {
+        this.mContext = context;
+    }
+
+    public void addAll(List<OpenTestOpenServerList.OpenTest> list) {
+        mList.addAll(list);
+    }
+
+    public void clear() {
+        mList.clear();
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public OpenTestOpenServerList.OpenTest getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = View.inflate(mContext, R.layout.list_item_search_test, null);
+            convertView.setOnClickListener(cls_GoDetail);
+        }
+
+        ViewFindUtils.hold(convertView, R.id.txt_list_item_search_test_title, TextView.class)
+                .setText(getItem(position).getGame().getGameName());
+        ViewFindUtils.hold(convertView, R.id.txt_list_item_search_test_time, TextView.class)
+                .setText(DateFormatUtils.doOpenTestDate(getItem(position).getOpenTestTime()));
+        ViewFindUtils.hold(convertView, R.id.txt_list_item_search_test_type, TextView.class)
+                .setText(getItem(position).getRemark());
+
+        //显示礼包图标
+        ViewFindUtils.hold(convertView, R.id.img_list_item_search_test_icon)
+                .setVisibility(getItem(position).getGame().getExistGift() == 1 ? View.VISIBLE : View.GONE);
+        Glide.with(mContext)
+                .load(getItem(position).getGame().getIconImage())
+                .into(ViewFindUtils.hold(convertView, R.id.img_list_item_search_test_logo, ImageView.class));
+
+        convertView.setTag(TAG_ID,getItem(position).getGameId());
+        DownBtnUtils.addDownloadBtnListener(ViewFindUtils.hold(convertView, R.id.btn_list_item_search_test,
+                KFProgressButton.class), mContext,
+                getmInstallButtonMgrMap(), getItem(position).getGame(),
+                "search_test" + position);
+        return convertView;
+    }
+}

+ 69 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpSearchViewPager.java

@@ -0,0 +1,69 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.support.annotation.StringRes;
+import android.support.v4.view.PagerAdapter;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.sheep.jiuyan.samllsheep.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpSearchViewPager</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/6/22 16:17
+ * @ QQ:    315096953
+ */
+
+public class AdpSearchViewPager extends PagerAdapter {
+
+    private Context mContext;
+
+    private List<Integer> mListTitles = new ArrayList<>();
+    private List<View> mListItem = new ArrayList<>();
+
+    public AdpSearchViewPager(Context context) {
+        this.mContext = context;
+    }
+
+    public void addView(View view, @StringRes int resId) {
+        mListItem.add(view);
+        mListTitles.add(resId);
+    }
+
+
+    @Override
+    public Object instantiateItem(ViewGroup container, int position) {
+        container.addView(mListItem.get(position));
+        return mListItem.get(position);
+    }
+
+    @Override
+    public void destroyItem(ViewGroup container, int position, Object object) {
+        container.removeView(mListItem.get(position));
+    }
+
+    @Override
+    public int getItemPosition(Object object) {
+        return super.getItemPosition(object);
+    }
+
+    @Override
+    public CharSequence getPageTitle(int position) {
+        return mContext.getString(mListTitles.get(position));
+    }
+
+    @Override
+    public int getCount() {
+        return mListTitles.size();
+    }
+
+    @Override
+    public boolean isViewFromObject(View view, Object object) {
+        return view.equals(object);
+    }
+}

+ 50 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpViewPagerDetail.java

@@ -0,0 +1,50 @@
+package com.kfzs.duanduan.adp;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+
+import com.kfzs.duanduan.bean.VipStyle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpViewPagerMainPage</p>
+ * @ <p>Description: 首页的ViewPager监听</p>
+ * @ date:  2017/6/14 13:21
+ * @ QQ:    315096953
+ */
+
+public class AdpViewPagerDetail extends FragmentPagerAdapter {
+
+    private List<String> mTitles = new ArrayList<>();
+    private List<Fragment> mListFragment = new ArrayList<>();
+
+    public AdpViewPagerDetail(FragmentManager fm) {
+        super(fm);
+    }
+
+    public void add(Fragment fragment, String title) {
+        mListFragment.add(fragment);
+        mTitles.add(title);
+    }
+
+    @Override
+    public CharSequence getPageTitle(int position) {
+        return position == 1 ? VipStyle.getInstance().getViptypename() + mTitles.get(position) : mTitles.get(position);
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        return mListFragment.get(position);
+    }
+
+    @Override
+    public int getCount() {
+        return mListFragment.size();
+    }
+
+
+}

+ 46 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpViewPagerMainPage.java

@@ -0,0 +1,46 @@
+package com.kfzs.duanduan.adp;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpViewPagerMainPage</p>
+ * @ <p>Description: 首页的ViewPager监听</p>
+ * @ date:  2017/6/14 13:21
+ * @ QQ:    315096953
+ */
+
+public class AdpViewPagerMainPage extends FragmentPagerAdapter {
+
+    private List<String> mTitles = new ArrayList<>();
+    private List<Fragment> mListFragment = new ArrayList<>();
+
+    public AdpViewPagerMainPage(FragmentManager fm) {
+        super(fm);
+    }
+
+    public void add(Fragment fragment, String title) {
+        mListFragment.add(fragment);
+        mTitles.add(title);
+    }
+
+    @Override
+    public CharSequence getPageTitle(int position) {
+        return mTitles.get(position);
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        return mListFragment.get(position);
+    }
+
+    @Override
+    public int getCount() {
+        return mTitles.size();
+    }
+}

+ 91 - 0
app/src/main/java/com/kfzs/duanduan/adp/AdpVipCoupon.java

@@ -0,0 +1,91 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.kfzs.duanduan.G;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.CouponCodeOuterClass;
+import com.kfzs.duanduan.utils.DateFormatUtils;
+import com.kfzs.duanduan.utils.dlg.ViewFindUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  AdpVipCoupon</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/18 22:52
+ * @ QQ:    315096953
+ */
+
+public class AdpVipCoupon extends BaseAdapter {
+
+    private Context mContext;
+    private List<CouponCodeOuterClass.CouponCode> mList = new ArrayList<>();
+    private final static int TAG_CODE = R.id.view_tag_1;
+
+    public AdpVipCoupon(Context context) {
+        mContext = context;
+    }
+
+    public void add(CouponCodeOuterClass.CouponCode couponCode) {
+        mList.add(couponCode);
+    }
+
+    public void addALL(List<CouponCodeOuterClass.CouponCode> list) {
+        mList.addAll(list);
+    }
+
+    public void clear() {
+        mList.clear();
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public CouponCodeOuterClass.CouponCode getItem(int i) {
+        return mList.get(i);
+    }
+
+    @Override
+    public long getItemId(int i) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int i, View view, ViewGroup viewGroup) {
+        if (view == null) {
+            view = View.inflate(mContext, R.layout.item_fgt_vip_coupon, null);
+            ViewFindUtils.find(view, R.id.txt_item_fgt_vip_coupon_copy)
+                    .setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View view) {
+                            ClipboardManager cm = (ClipboardManager) mContext
+                                    .getSystemService(Context.CLIPBOARD_SERVICE);
+                            cm.setText(view.getTag(TAG_CODE) + "");
+                            G.showToast("复制成功!");
+                        }
+                    });
+        }
+
+        ViewFindUtils.hold(view, R.id.txt_item_fgt_vip_coupon_title, TextView.class)
+                .setText(getItem(i).getName());
+        ViewFindUtils.hold(view, R.id.txt_item_fgt_vip_coupon_time, TextView.class)
+                .setText("兑换时间:" + DateFormatUtils.doSecond2Date(getItem(i).getReceiveTime()));
+        ViewFindUtils.hold(view, R.id.txt_item_fgt_vip_coupon_code, TextView.class)
+                .setText(getItem(i).getCode());
+        ViewFindUtils.hold(view, R.id.txt_item_fgt_vip_coupon_copy)
+                .setTag(TAG_CODE, getItem(i).getCode());
+        return view;
+    }
+}

+ 69 - 0
app/src/main/java/com/kfzs/duanduan/adp/BaseAdpterWithDownBtn.java

@@ -0,0 +1,69 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  BaseAdpterWithDownBtn</p>
+ * @ <p>Description:搜索页有下载按钮的BaseAdapter统一处理</p>
+ * @ date:  2017/8/3 18:19
+ * @ QQ:    315096953
+ */
+
+public class BaseAdpterWithDownBtn extends BaseAdapter {
+
+    private Map<String, InstallButtonUtils> mInstallButtonMgrMap = new HashMap<>();
+    protected Context mContext;
+
+    //养成习惯最好不要暂用默认TAG
+    protected final static int TAG_ID = R.id.view_tag_down_btn;
+
+
+    @Override
+    public int getCount() {
+        return 0;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return null;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        return null;
+    }
+
+    public Map<String, InstallButtonUtils> getmInstallButtonMgrMap() {
+        return mInstallButtonMgrMap;
+    }
+
+    public void setmInstallButtonMgrMap(Map<String, InstallButtonUtils> mInstallButtonMgrMap) {
+        this.mInstallButtonMgrMap = mInstallButtonMgrMap;
+    }
+
+    /**
+     * 跳详情页的统一监听
+     */
+    protected View.OnClickListener cls_GoDetail = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            SkipUtils.getInstance().goGameDetails(mContext, (int) v.getTag(TAG_ID));
+        }
+    };
+}

+ 451 - 0
app/src/main/java/com/kfzs/duanduan/adp/ClassificationAdapter.java

@@ -0,0 +1,451 @@
+package com.kfzs.duanduan.adp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+
+import com.bumptech.glide.Glide;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.GameTypeOuterClass;
+import com.kfzs.duanduan.proto.GameTypeSpecialOuterClass;
+import com.kfzs.duanduan.G;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+import com.kfzs.duanduan.view.diag.MyGridview;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * 分类adapter
+ * Created by Administrator on 2017/12/11.
+ */
+
+public class ClassificationAdapter extends BaseAdapter {  private ArrayList<String> mList;
+    private LayoutInflater mInflater;
+    private Context mContext;
+    List<GameTypeSpecialOuterClass.GameTypeSpecial> listGameTS;
+
+    public ClassificationAdapter(ArrayList list, Context context) {
+        this.mList = list;
+        this.mInflater = LayoutInflater.from(context);
+        this.mContext = context;
+    }
+
+    @Override
+    public int getCount() {
+        return mList.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        Object o = getItem(position);
+        if(position == 0 ){
+            return createTopGridView();
+        }else {
+            GameTypeOuterClass.GameType gameType = ((GameTypeOuterClass.GameType) o);
+            convertView = mInflater.inflate(R.layout.classification_item, null);
+            ImageView iconIv = (ImageView) convertView.findViewById(R.id.icon_iv);
+            TextView one_tv = (TextView) convertView.findViewById(R.id.one_tv);
+            TextView two_tv = (TextView) convertView.findViewById(R.id.two_tv);
+            TextView three_tv = (TextView) convertView.findViewById(R.id.three_tv);
+            TextView four_tv = (TextView) convertView.findViewById(R.id.four_tv);
+            TextView five_tv = (TextView) convertView.findViewById(R.id.five_tv);
+            TextView six_tv = (TextView) convertView.findViewById(R.id.six_tv);
+            LinearLayout game_classified_layout = convertView.findViewById(R.id.game_classified_layout);
+            if(position == 1){
+                game_classified_layout.setVisibility(View.VISIBLE);
+            }else {
+                game_classified_layout.setVisibility(View.GONE);
+            }
+            if(gameType.getSecondTypesList() != null && gameType.getSecondTypesList().size() > 0){
+                for(int i=0;i<gameType.getSecondTypesList().size();i++){
+                    GameTypeOuterClass.GameType gameTypeSecond = gameType.getSecondTypesList().get(i);
+                    switch (i){
+                        case 0:
+                            setTextView(mContext,gameType,one_tv, i);
+                            one_tv.setOnClickListener(new Onclick(gameTypeSecond));
+                            break;
+                        case 1:
+                            setTextView(mContext,gameType,two_tv, i);
+                            two_tv.setOnClickListener(new Onclick(gameTypeSecond));
+                            break;
+                        case 2:
+                            setTextView(mContext,gameType,three_tv, i);
+                            three_tv.setOnClickListener(new Onclick(gameTypeSecond));
+                            break;
+                        case 3:
+                            setTextView(mContext,gameType,four_tv, i);
+                            four_tv.setOnClickListener(new Onclick(gameTypeSecond));
+                            break;
+                        case 4:
+                            setTextView(mContext,gameType,five_tv, i);
+                            five_tv.setOnClickListener(new Onclick(gameTypeSecond));
+                            break;
+                        case 5:
+                            setTextView(mContext,gameType,six_tv, i);
+                            six_tv.setOnClickListener(new Onclick(gameTypeSecond));
+                            break;
+                    }
+                }
+            }
+            iconIv.setOnClickListener(new Onclick(gameType));
+            Glide.with(mContext)
+                    .load(gameType.getIcon()+"")
+                    .error(android.R.drawable.stat_notify_error)
+                    .into(iconIv);
+            return convertView;
+        }
+    }
+
+    private void setTextView(Context context, GameTypeOuterClass.GameType o, TextView v, int i){
+        if(!TextUtils.isEmpty(o.getSecondTypesList().get(i).getTypeName())){
+//            v.setTextColor(android.R.color.black);
+            v.setText(o.getSecondTypesList().get(i).getTypeName()+"");
+        }
+
+    }
+
+    class Onclick implements View.OnClickListener{
+        GameTypeOuterClass.GameType gameTypes;
+        public Onclick(GameTypeOuterClass.GameType gameType) {
+            this.gameTypes = gameType;
+        }
+
+        @Override
+        public void onClick(View v) {
+            if(!TextUtils.isEmpty(gameTypes.getTypeName()))
+                startToActivity(gameTypes, mContext);
+        }
+    }
+
+
+    public void toBindTopviewData(List<GameTypeSpecialOuterClass.GameTypeSpecial> listGameTS){
+        this.listGameTS = listGameTS;
+    }
+
+    /**
+     * 顶部 gridview
+     * @return
+     */
+    private View createTopGridView(){
+
+        View view = null;
+        GridviewHolder holder = null;
+        if( holder == null){
+            view = mInflater.inflate(R.layout.classification_gridview_item, null);
+            holder = new GridviewHolder(view);
+        }else{
+            holder = (GridviewHolder) view.getTag();
+        }
+
+        holder.adapter.toBindTopviewData(listGameTS);
+        holder.adapter.notifyDataSetChanged();
+        return view;
+    }
+
+    /**
+     * 创建图片容器
+     * @return
+     */
+    @SuppressLint("ResourceType")
+    public View createTopView() {
+        LinearLayout linearLayout = new LinearLayout(mContext);
+        if(listGameTS == null || listGameTS.size()<8){
+            return linearLayout;
+        }
+        linearLayout.setOrientation(LinearLayout.VERTICAL);
+        // 获取屏幕宽度
+        int W = G.WIDTH <G.HEIGHT ? G.WIDTH : G.HEIGHT;
+        int cricleRadius = W / 2 ;
+        Log.e("-------------", cricleRadius+"");
+        // 根据每行个数设置布局大小
+        linearLayout.setPadding(5, 5, 5, 5);
+        linearLayout.setGravity(Gravity.CENTER);
+        // 设置图片大小
+        linearLayout.setLayoutParams(new AbsListView.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT , LinearLayout.LayoutParams.WRAP_CONTENT));
+        /*--------------------------big img----------------------------------*/
+        LinearLayout bigLinearLayout = new LinearLayout(mContext);
+        bigLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
+        bigLinearLayout.setGravity(Gravity.CENTER);
+        // 设置图片大小
+        bigLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT , LinearLayout.LayoutParams.WRAP_CONTENT));
+        bigLinearLayout.setId(0);
+
+        ImageView bigCircleImageView = new ImageView(mContext);
+        bigCircleImageView.setLayoutParams(new LinearLayout.LayoutParams(cricleRadius, cricleRadius));
+//        Bitmap map = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.classification_tengxun);
+//        bigCircleImageView.setImageBitmap(map);
+        Glide.with(mContext)
+                .load(listGameTS.get(0).getIcon())
+                .error(android.R.drawable.stat_notify_error)
+                .into(bigCircleImageView);
+        bigCircleImageView.setId(1);
+        bigCircleImageView.setPadding(0,3,0,3);
+
+        bigCircleImageView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startToActivity(listGameTS.get(0), mContext);
+            }
+        });
+        bigLinearLayout.addView(bigCircleImageView);
+
+        RelativeLayout bigLinearLayout2 = new RelativeLayout(mContext);
+        bigLinearLayout2.setPadding(5, 5, 5, 5);
+        bigLinearLayout2.setLayoutParams(new LinearLayout.LayoutParams(cricleRadius , cricleRadius));
+        bigLinearLayout2.setId(2);
+
+        ImageView ircleImageView1 = new ImageView(mContext);
+        RelativeLayout.LayoutParams imageView1Params = new RelativeLayout.LayoutParams(cricleRadius/2-5,cricleRadius/2-5);
+        ircleImageView1.setLayoutParams(imageView1Params);
+        Glide.with(mContext)
+                .load(listGameTS.get(1).getIcon())
+                .error(android.R.drawable.stat_notify_error)
+                .into(ircleImageView1);
+        ircleImageView1.setId(21);
+        ircleImageView1.setPadding(0,0,2,0);
+        ircleImageView1.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startToActivity(listGameTS.get(1), mContext);
+            }
+        });
+
+        ImageView ircleImageView2 = new ImageView(mContext);
+        RelativeLayout.LayoutParams imageView1Params2 = new RelativeLayout.LayoutParams(cricleRadius/2-5,cricleRadius/2-5);
+        imageView1Params2.addRule(RelativeLayout.RIGHT_OF, ircleImageView1.getId());
+        ircleImageView2.setLayoutParams(imageView1Params2);
+        Glide.with(mContext)
+                .load(listGameTS.get(2).getIcon())
+                .error(android.R.drawable.stat_notify_error)
+                .into(ircleImageView2);
+        ircleImageView2.setId(22);
+        ircleImageView2.setPadding(3,0,0,0);
+        ircleImageView2.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startToActivity(listGameTS.get(2), mContext);
+            }
+        });
+
+        ImageView ircleImageView3 = new ImageView(mContext);
+        RelativeLayout.LayoutParams imageView1Params3 = new RelativeLayout.LayoutParams(cricleRadius/2-5,cricleRadius/2-5);
+        imageView1Params3.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+        ircleImageView3.setLayoutParams(imageView1Params3);
+
+        Glide.with(mContext)
+                .load(listGameTS.get(3).getIcon())
+                .error(android.R.drawable.stat_notify_error)
+                .into(ircleImageView3);
+        ircleImageView3.setId(23);
+        ircleImageView3.setPadding(0,5,0,0);
+        ircleImageView3.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startToActivity(listGameTS.get(3), mContext);
+            }
+        });
+
+        ImageView ircleImageView4 = new ImageView(mContext);
+        RelativeLayout.LayoutParams imageView1Params4 = new RelativeLayout.LayoutParams(cricleRadius/2-5,cricleRadius/2-5);
+        imageView1Params4.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+        imageView1Params4.addRule(RelativeLayout.RIGHT_OF, ircleImageView3.getId());
+        ircleImageView4.setLayoutParams(imageView1Params4);
+//        Bitmap map4 = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.classification_erciyuan);
+//        ircleImageView4.setImageBitmap(map4);
+        Glide.with(mContext)
+                .load(listGameTS.get(4).getIcon())
+                .error(android.R.drawable.stat_notify_error)
+                .into(ircleImageView4);
+        ircleImageView4.setId(24);
+        ircleImageView4.setPadding(5, 5, 0, 0);
+        ircleImageView4.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startToActivity(listGameTS.get(4), mContext);
+            }
+        });
+
+        bigLinearLayout2.addView(ircleImageView1);
+        bigLinearLayout2.addView(ircleImageView2);
+        bigLinearLayout2.addView(ircleImageView3);
+        bigLinearLayout2.addView(ircleImageView4);
+
+        bigLinearLayout.addView(bigLinearLayout2);
+
+        linearLayout.addView(bigLinearLayout);
+        /*------------------------------------------------------------*/
+
+        /*--------------------------bottom img----------------------------------*/
+
+        LinearLayout bottomLinearLayout = new LinearLayout(mContext);
+        bottomLinearLayout.setPadding(5, 5, 5, 5);
+        bottomLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
+        bottomLinearLayout.setGravity(Gravity.CENTER);
+        // 设置图片大小
+        bottomLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT , LinearLayout.LayoutParams.WRAP_CONTENT));
+        bottomLinearLayout.setId(3);
+
+        bottomLinearLayout.addView(createImageView(R.drawable.classification_chijizhuanq, cricleRadius/2-5, listGameTS.get(5)));
+        bottomLinearLayout.addView(createImageView(R.drawable.classification_wangyizhuanqu, cricleRadius/2-5, listGameTS.get(6)));
+        bottomLinearLayout.addView(createImageView(R.drawable.classification_xianxia, cricleRadius/2-5, listGameTS.get(7)));
+        bottomLinearLayout.addView(createImageView(R.drawable.classification_gengduoyouxo, cricleRadius/2-5, null));
+
+        linearLayout.addView(bottomLinearLayout);
+        /*--------------------------bottom img----------------------------------*/
+
+        return linearLayout;
+    }
+
+    /**
+     * 创建imageView
+     * @return
+     */
+    private View createImageView(int mipmap, final int cricleRadius, final Object o){
+        ImageView bottomImageView1 = new ImageView(mContext);
+        LinearLayout.LayoutParams bottomImgParams1 = new LinearLayout.LayoutParams(cricleRadius,cricleRadius);
+        bottomImageView1.setLayoutParams(bottomImgParams1);
+        if(o == null){
+            Bitmap  bottomMap1 = BitmapFactory.decodeResource(mContext.getResources(), mipmap);
+            bottomImageView1.setImageBitmap(bottomMap1);
+        }else {
+            Glide.with(mContext)
+                    .load(((GameTypeSpecialOuterClass.GameTypeSpecial) o).getIcon()+"")
+                    .error(android.R.drawable.stat_notify_error)
+                    .into(bottomImageView1);
+        }
+
+        bottomImageView1.setPadding(2,2,2,2);
+        bottomImageView1.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if(o == null){
+                    SkipUtils.getInstance().goGameType(mContext,0);
+                }else{
+                    startToActivity(o, mContext);
+                }
+
+
+            }
+        });
+//        bottomImageView1.setId(31);
+        return bottomImageView1;
+    }
+    /**
+     * t跳转到游戏列表页面
+     * @param o
+     * @param context
+     */
+    private void startToActivity(Object o, Context context){
+        if(o == null){
+            return;
+        }
+        int type = 0;
+        if(o instanceof GameTypeSpecialOuterClass.GameTypeSpecial){//top
+            type = ((GameTypeSpecialOuterClass.GameTypeSpecial) o).getGameTypeId();
+        }else if(o instanceof GameTypeOuterClass.GameType){
+            type = ((GameTypeOuterClass.GameType) o).getId();
+        }
+        SkipUtils.getInstance().goGameType(context,type);
+    }
+
+    /**
+     *
+     */
+    private AbsListView.LayoutParams returnLayoutparas(int w, int h){
+        return new AbsListView.LayoutParams(w, h);
+    }
+
+    /**
+     * gridview holder
+     */
+    class GridviewHolder{
+        MyGridview gridview;
+        ClassificationGridviewAdapter adapter;
+
+        public GridviewHolder(View view) {
+            this.gridview = view.findViewById(R.id.classification_gridview);
+            this.adapter = new ClassificationGridviewAdapter( listGameTS, mContext);
+            gridview.setAdapter(adapter);
+//            gridview.setSelector(new ColorDrawable(Color.TRANSPARENT));
+            view.setTag(this);
+        }
+    }
+
+    /**
+     * 获取图片的颜色
+     */
+   /* private void getImgColor(Bitmap bitmap , final View view){
+        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
+            @Override
+            public void onGenerated(Palette palette) {
+                Palette.Swatch s1, s2, s3 ,s4, s5, s6 ,s7 ;
+                s1 = palette.getVibrantSwatch();
+                s2 = palette.getDarkVibrantSwatch();
+                s3 = palette.getLightVibrantSwatch();
+                s4 = palette.getMutedSwatch();
+                s5 = palette.getDarkMutedSwatch();
+                s6 = palette.getLightMutedSwatch();
+                s7 = palette.getDominantSwatch();
+                if(s1 != null){
+                    ((TextView)view).setTextColor(s1.getRgb());
+                    Log.e("--color",s1.getRgb()+","+s1.getBodyTextColor()+","+s1.getTitleTextColor());
+                }else if(s2 != null){
+                    ((TextView)view).setTextColor(s2.getRgb());
+                    Log.e("--color",s2.getRgb()+","+s2.getBodyTextColor()+","+s2.getTitleTextColor());
+                }else if(s3 != null){
+                    ((TextView)view).setTextColor(s3.getRgb());
+                    Log.e("--color",s3.getRgb()+","+s3.getBodyTextColor()+","+s3.getTitleTextColor());
+                }else if(s4 != null){
+                    ((TextView)view).setTextColor(s4.getRgb());
+                    Log.e("--color",s4.getRgb()+","+s4.getBodyTextColor()+","+s4.getTitleTextColor());
+                }else if(s5 != null){
+                    ((TextView)view).setTextColor(s5.getRgb());
+                    Log.e("--color",s5.getRgb()+","+s5.getBodyTextColor()+","+s5.getTitleTextColor());
+                }else if(s6 != null){
+                    ((TextView)view).setTextColor(s6.getRgb());
+                    Log.e("--color",s6.getRgb()+","+s6.getBodyTextColor()+","+s6.getTitleTextColor());
+                }else if(s7 != null){
+                    ((TextView)view).setTextColor(s1.getRgb());
+                    Log.e("--color",s7.getRgb()+","+s7.getBodyTextColor()+","+s7.getTitleTextColor());
+                }
+
+//                if(palette.getSwatches() != null){
+//                    for(Palette.Swatch s : palette.getSwatches()){
+//                        if(s != null){
+//                            Log.e("s--color",s.getRgb()+","+s.getBodyTextColor()+","+s.getTitleTextColor());
+//                        }
+//                    }
+//                }
+            }
+        });
+    }*/
+}

+ 128 - 0
app/src/main/java/com/kfzs/duanduan/adp/ClassificationGridviewAdapter.java

@@ -0,0 +1,128 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.duanduan.G;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.proto.GameTypeSpecialOuterClass;
+import com.kfzs.duanduan.utils.dlg.SkipUtils;
+
+import java.util.List;
+
+/**
+ * 分类、top中gridview的adapter
+ * Created by ljy on 2018/1/22.
+ */
+
+public class ClassificationGridviewAdapter extends BaseAdapter {
+    private Context mContext;
+    private List<GameTypeSpecialOuterClass.GameTypeSpecial> listGameTS;
+
+    public ClassificationGridviewAdapter(List<GameTypeSpecialOuterClass.GameTypeSpecial> listGameTS,Context mContext) {
+        this.mContext = mContext;
+        this.listGameTS = listGameTS;
+    }
+    public void toBindTopviewData(List<GameTypeSpecialOuterClass.GameTypeSpecial> listGameTS){
+        this.listGameTS = listGameTS;
+    }
+
+    @Override
+    public int getCount() {
+        return listGameTS.size();
+    }
+
+    @Override
+    public Object getItem(int i) {
+        return listGameTS.get(i);
+    }
+
+    @Override
+    public long getItemId(int i) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int i, View view, ViewGroup viewGroup) {
+        ViewHolder holder = null;
+        if(holder == null){
+            holder = new ViewHolder();
+            view = LayoutInflater.from(mContext).inflate(R.layout.classification_gv_item_item, null);
+
+            holder.imageView = view.findViewById(R.id.classification_gv_item_iv);
+            // 获取屏幕宽度
+            int W = G.WIDTH <G.HEIGHT ? G.WIDTH : G.HEIGHT;
+            int cricleRadius = W / 3 ;
+            int h = cricleRadius * 83 / 100;
+            view.setLayoutParams(new AbsListView.LayoutParams(cricleRadius, h));
+            view.setPadding(0,15,0,20);
+            view.setTag(holder);
+        }else{
+            holder = (ViewHolder) view.getTag();
+        }
+
+        final GameTypeSpecialOuterClass.GameTypeSpecial gameTypeSpecial = (GameTypeSpecialOuterClass.GameTypeSpecial) getItem(i);
+        Log.e("gridveiw--",listGameTS.size() +","+(gameTypeSpecial == null));
+        int type = 0;
+        if(gameTypeSpecial == null){
+            type = 0;
+//            Bitmap bottomMap1 = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.classification_gengduoyouxo);
+//            holder.imageView.setImageBitmap(bottomMap1);
+            Glide.with(mContext)
+                    .load(R.drawable.classification_gengduoyouxo)
+                    .into(holder.imageView);
+        }else{
+            Log.e("gamepecial.getIcon()",listGameTS.size() +","+(gameTypeSpecial.getIcon()));
+            type = gameTypeSpecial.getGameTypeId();
+            Glide.with(mContext)
+                    .load(gameTypeSpecial.getIcon())
+                    .error(android.R.drawable.stat_notify_error)
+                    .into( holder.imageView);
+        }
+
+        final int finalType = type;
+        holder.imageView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                SkipUtils.getInstance().goGameType(mContext, finalType);
+            }
+        });
+        final ViewHolder finalHolder = holder;
+        holder.imageView.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                switch (event.getAction()){
+                    case MotionEvent.ACTION_DOWN:
+                        Glide.with(mContext)
+                                .load(gameTypeSpecial == null ?R.drawable.classification_gengduoyouxo_click :gameTypeSpecial.getHighlightIcon())
+                                .error(android.R.drawable.stat_notify_error)
+                                .into( finalHolder.imageView);
+                        break;
+                    case MotionEvent.ACTION_UP:
+                        Glide.with(mContext)
+                                .load(gameTypeSpecial == null ?R.drawable.classification_gengduoyouxo :gameTypeSpecial.getIcon())
+                                .error(android.R.drawable.stat_notify_error)
+                                .into( finalHolder.imageView);
+                        break;
+                }
+                return false;
+            }
+        });
+
+        return view;
+    }
+
+    private class ViewHolder{
+        ImageView imageView;
+    }
+}

+ 141 - 0
app/src/main/java/com/kfzs/duanduan/adp/DownloadMgrAdapter.java

@@ -0,0 +1,141 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.android.view.KFGlideRoundTransform;
+import com.kfzs.duanduan.view.KFProgressButton;
+import com.kfzs.appstore.utils.adapter.MDLAdpater;
+import com.kfzs.appstore.utils.adapter.MDLViewHolderHelper;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.CompareResult;
+import com.kfzs.duanduan.utils.InstallButtonUtils;
+import com.kfzs.duanduan.services.DownloadTaskService;
+import com.kfzs.duanduan.datashare.provider.download.DownLoadInfo;
+import com.kfzs.duanduan.utils.ApkUtils;
+import com.kfzs.duanduan.ActDownloadMgr;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Download task Listview 's data adapter
+ * Created by HooRang on 2017/4/10.
+ */
+public class DownloadMgrAdapter extends MDLAdpater<DownLoadInfo> {
+
+
+    /**
+     * List view item button tag
+     */
+    public static final String PUBLIC_TAG_PREFIX_BUTTON     = "PUBLIC_TAG_PREFIX_BUTTON";
+
+    /**
+     * List view item text view tag
+     */
+    public static final String PUBLIC_TAG_PREFIX_TEXTVIEW   = "PUBLIC_TAG_PREFIX_TEXTVIEW";
+
+    /**
+     * List view item progressbar tag
+     */
+    public static final String PUBLIC_TAG_PREFIX_PROGRESS   = "PUBLIC_TAG_PREFIX_PROGRESS";
+
+
+    private Map<String, InstallButtonUtils> mInstallButtonMgrMap = new HashMap<>();
+
+
+    public DownloadMgrAdapter(Context ctx){
+        super(ctx, R.layout.listview_item_download_mgr);
+    }
+
+
+    @Override
+    protected void fillData(MDLViewHolderHelper helper, int position, DownLoadInfo model) {
+
+        String suffix = model.getMDownloadUrl();
+        helper.getView(R.id.download_mgr_btn_act).setTag(PUBLIC_TAG_PREFIX_BUTTON       + suffix);
+        helper.getView(R.id.download_mgr_pb_progress).setTag(PUBLIC_TAG_PREFIX_PROGRESS + suffix);
+        helper.getView(R.id.download_mgr_tv_progress).setTag(PUBLIC_TAG_PREFIX_TEXTVIEW + suffix);
+
+        helper.setText(R.id.download_mgr_tv_name,model.getMGameName());
+        ProgressBar pb = helper.getView(R.id.download_mgr_pb_progress);
+
+        pb.setProgress(model.getMPercent() == null ? 0  : model.getMPercent());
+        helper.setText(R.id.download_mgr_tv_progress ,
+                ActDownloadMgr.strFormat(mContext , model.getMDownloadedSize() , model.getMTotalSize()));
+
+        helper.setItemChildClickListener(R.id.download_mgr_ib_delete);
+        helper.setItemChildClickListener(R.id.download_mgr_btn_act);
+        helper.setItemChildClickListener(R.id.download_mgr_iv_icon);
+
+        Glide.with(mContext)
+                .load(model.getMIconUrl())
+                .transform(new KFGlideRoundTransform(mContext, 5))
+                .into((ImageView) helper.getView(R.id.download_mgr_iv_icon));
+
+
+        KFProgressButton targetBtn = helper.getView(R.id.download_mgr_btn_act);
+
+
+        InstallButtonUtils installButtonUtils;
+        if (mInstallButtonMgrMap.containsKey(model.getMDownloadUrl())) {
+            installButtonUtils = mInstallButtonMgrMap.get(model.getMDownloadUrl());
+            mInstallButtonMgrMap.remove(installButtonUtils);
+        } else {
+            installButtonUtils = new InstallButtonUtils();
+            installButtonUtils.setDownloadUrl(model.getMDownloadUrl());
+        }
+        installButtonUtils.addBtnInt(targetBtn,position);
+        mInstallButtonMgrMap.put(model.getMDownloadUrl(), installButtonUtils);
+
+        switch (model.getMStatus()) {
+            case DownloadTaskService.STATUS_INIT:
+            case DownloadTaskService.STATUS_DELETE:
+                targetBtn.updateButtonUI(KFProgressButton.STATUS.STATUS_INIT);
+                break;
+            case DownloadTaskService.STATUS_ING:
+                targetBtn.updateButtonUI(KFProgressButton.STATUS.STATUS_INSTALLING);
+                break;
+            case DownloadTaskService.STATUS_PAUSE:
+                targetBtn.updateButtonUI(KFProgressButton.STATUS.STATUS_PAUSED);
+                break;
+            case DownloadTaskService.STATUS_FAIL:
+                targetBtn.updateButtonUI(KFProgressButton.STATUS.STATUS_FAIL);
+                helper.setText(R.id.download_mgr_tv_progress, R.string.download_fail_please_retry);
+                break;
+            case DownloadTaskService.STATUS_FINISH:
+                pb.setProgress(100);
+                boolean isPkgInstalled = ApkUtils.getInstance().isPkgInstalled(model.getMPackageName());
+                if (isPkgInstalled) {
+                    int apkStatus = ApkUtils.getInstance().comparePkgVersionCode(model.getMPackageName(), model.getMVersionCode());
+                    if (apkStatus == CompareResult.EQUALS || apkStatus == CompareResult.LT) {
+                        targetBtn.setText(R.string.open);
+                        helper.setText(R.id.download_mgr_tv_progress, R.string.download_completed);
+                    } else {
+                        targetBtn.setText(R.string.update);
+                        helper.setText(R.id.download_mgr_tv_progress, "");
+                    }
+                } else {
+
+                    if (new File(model.getMApkPath()).exists()) {
+                        targetBtn.setText(R.string.install);
+                        helper.setText(R.id.download_mgr_tv_progress, R.string.download_completed);
+
+                    } else {
+                        targetBtn.setText(R.string.install);
+                        helper.setText(R.id.download_mgr_tv_progress, "");
+                    }
+
+                }
+                break;
+        }
+    }
+
+    public Map<String, InstallButtonUtils> getmInstallButtonMgrMap() {
+        return mInstallButtonMgrMap;
+    }
+}

+ 67 - 0
app/src/main/java/com/kfzs/duanduan/adp/FilterWindowAdapter.java

@@ -0,0 +1,67 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import com.kfzs.android.view.tag.FlowLayout;
+import com.kfzs.android.view.tag.TagAdapter;
+import com.kfzs.android.view.tag.TagFlowLayout;
+import com.kfzs.appstore.utils.adapter.MDLAdpater;
+import com.kfzs.appstore.utils.adapter.MDLViewHolderHelper;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.QueryCondition;
+import com.kfzs.duanduan.proto.GameTypeOuterClass;
+import com.kfzs.duanduan.view.FilterWindow;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * Created by HooRang on 2017/2/15.
+ */
+public class FilterWindowAdapter extends MDLAdpater<QueryCondition> {
+
+    public static final String FLOW_LAYOUT_TAG = "FLOW_LAYOUT_TAG_";
+    private Context mContext ;
+
+    private Map<String,TagAdapter<GameTypeOuterClass.GameType>> qcItemsAdapterContainer = new HashMap<>();
+
+
+    public FilterWindowAdapter(Context context) {
+        super(context, R.layout.listview_item_query_condition);
+        this.mContext = context;
+    }
+
+
+
+    @Override
+    protected void fillData(MDLViewHolderHelper helper, int position, QueryCondition model) {
+        helper.setImageResource(R.id.query_condition_category_icon, model.getCategoryIcon());
+        String iTag = FLOW_LAYOUT_TAG  + position;
+        TagFlowLayout tagList = helper.getView(R.id.query_condition_tags);
+        tagList.setTag(iTag);
+        TagAdapter<GameTypeOuterClass.GameType> tagAdapter = new TagAdapter<GameTypeOuterClass.GameType>(model.getTags()) {
+            @Override
+            public View getView(FlowLayout parent, int position, GameTypeOuterClass.GameType o) {
+
+                TextView tv = (TextView)LayoutInflater.from(mContext).inflate(R.layout.hot_tag_item,parent,false);
+                tv.setText(o.getTypeName());
+                tv.setTag(o.getId());
+                return tv;
+            }
+        };
+
+        if (!qcItemsAdapterContainer.containsKey(iTag)){
+            qcItemsAdapterContainer.put(iTag , tagAdapter);
+        }
+
+
+        tagList.setAdapter(tagAdapter);
+        tagAdapter.setSelectedList(FilterWindow.getCheckedTagsContainer().get(position));
+    }
+
+
+}

+ 77 - 0
app/src/main/java/com/kfzs/duanduan/adp/ManagementAccountAdapter.java

@@ -0,0 +1,77 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.bumptech.glide.Glide;
+import com.kfzs.appstore.utils.adapter.recyclerview.RecyclerViewAdapter;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.kfzs.duanduan.ActAccountManage;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.data.graph.provider.player.User;
+import com.kfzs.duanduan.event.AccountManagementEventUtils;
+
+import java.util.List;
+
+import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by sinlov on 17/3/2.
+ */
+public class ManagementAccountAdapter extends RecyclerViewAdapter<User> {
+
+    public ManagementAccountAdapter(Context context, List<User> data) {
+        super(context, R.layout.listview_item_change_account, data);
+    }
+
+    public void clear(){
+        mDatas.clear();
+    }
+
+    public void addAllUser(List<User> users){
+        mDatas.addAll(users);
+    }
+
+    @Override
+    public void convert(ViewHolder holder, final User data, int position) {
+        if (data != null) {
+//            String userName = data.getUserName();
+//            ALog.d("show user name: " + userName);
+            String nickname = data.getMNickName();
+            String avatar = data.getMAvatar();
+            holder.setText(R.id.tv_item_change_account_nike_name, nickname);
+            View view = holder.getView(R.id.img_item_change_account_icon);
+            if (view instanceof ImageView) {
+                Glide.with(mContext)
+                        .load(avatar)
+                        .bitmapTransform(new RoundedCornersTransformation(mContext, 30, 0, RoundedCornersTransformation.CornerType.ALL))
+                        .crossFade(1000)
+                        .error(R.drawable.ic_user_head_default)
+                        .into((ImageView) view);
+            }
+            holder.setOnClickListener(R.id.img_item_change_account_remove, new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    AccountManagementEventUtils.getInstance().newAccountByEvent(Integer.parseInt(data.getMUserId()), data.getMNickName(), ActAccountManage.JOB_REMOVE_ACCOUNT);
+                }
+            });
+        }
+    }
+
+
+}

+ 53 - 0
app/src/main/java/com/kfzs/duanduan/adp/UserSelfInfoShowAdapter.java

@@ -0,0 +1,53 @@
+package com.kfzs.duanduan.adp;
+
+import android.content.Context;
+import android.view.View;
+
+import com.kfzs.appstore.utils.adapter.recyclerview.RecyclerViewAdapter;
+import com.kfzs.appstore.utils.adapter.recyclerview.ViewHolder;
+import com.sheep.jiuyan.samllsheep.R;
+import com.kfzs.duanduan.bean.SelfInfoPojo;
+
+import java.util.List;
+
+/**
+ * <pre>
+ *     sinlov
+ *
+ *     /\__/\
+ *    /`    '\
+ *  ≈≈≈ 0  0 ≈≈≈ Hello world!
+ *    \  --  /
+ *   /        \
+ *  /          \
+ * |            |
+ *  \  ||  ||  /
+ *   \_oo__oo_/≡≡≡≡≡≡≡≡o
+ *
+ * </pre>
+ * Created by sinlov on 17/3/2.
+ */
+public class UserSelfInfoShowAdapter extends RecyclerViewAdapter<SelfInfoPojo> {
+
+    public UserSelfInfoShowAdapter(Context context, List<SelfInfoPojo> data) {
+        super(context, R.layout.listview_item_self_info, data);
+    }
+
+    @Override
+    public void convert(ViewHolder holder, SelfInfoPojo data , int position) {
+        if (data != null) {
+            Integer iconID = data.getIconID();
+            if (iconID != null) {
+                holder.setImageResource(R.id.item_self_info_iv_icon, iconID);
+            }
+            holder.setText(R.id.item_self_info_tv_title, data.getHint());
+            holder.setText(R.id.item_self_info_tv_info, data.getInfo());
+            View canEdit = holder.getView(R.id.item_self_info_iv_can_edit);
+            if (data.isCanEdit()) {
+                canEdit.setVisibility(View.VISIBLE);
+            } else {
+                canEdit.setVisibility(View.GONE);
+            }
+        }
+    }
+}

+ 31 - 0
app/src/main/java/com/kfzs/duanduan/adp/ViewPagerFragmentAdapter.java

@@ -0,0 +1,31 @@
+package com.kfzs.duanduan.adp;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Administrator on 2017/12/25.
+ */
+
+public class ViewPagerFragmentAdapter extends FragmentPagerAdapter {
+
+    private List<Fragment> mList = new ArrayList<>();
+    public ViewPagerFragmentAdapter(FragmentManager fm , List<Fragment> list) {
+        super(fm);
+        this.mList = list;
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        return mList.get(position);
+    }
+
+    @Override
+    public int getCount() {
+        return mList != null ? mList.size() : 0;
+    }
+}

+ 110 - 0
app/src/main/java/com/kfzs/duanduan/bean/BaseMsg.java

@@ -0,0 +1,110 @@
+package com.kfzs.duanduan.bean;
+
+import android.content.Intent;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  BaseMsg</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/13 10:23
+ * @ QQ:    315096953
+ */
+
+public class BaseMsg {
+
+    private String msg;
+
+    private Integer code = 0;
+
+    private Integer total = 0;
+
+    private Object data;
+
+    public String getMsg() {
+        return msg == null ? "" : msg;
+    }
+
+    public String getMessage(String defaultmsg) {
+        return msg == null ? defaultmsg : msg;
+    }
+
+    @Override
+    public String toString() {
+        return JSONObject.toJSONString(this);
+    }
+
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    /**
+     * 默认为0表示有错误
+     *
+     * @return @NotNull
+     */
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public Integer getTotal() {
+        return total;
+    }
+
+    public void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    /**
+     * @return @NotNull
+     */
+    public Object getData() {
+        if (data == null) {
+            data = new Object();
+        }
+        return data;
+    }
+
+    /**
+     * 失败返回null
+     *
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public <T> T getData(Class<T> clazz) {
+        if (data == null) {
+            return null;
+        }
+        return JSONObject.parseObject(JSONObject.toJSONString(data), clazz);
+    }
+
+    /**
+     * 如果data里是数组,直接这样获取
+     *
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public <T> List<T> getDatas(Class<T> clazz) {
+        if (data == null) {
+            return null;
+        }
+        return JSONArray.parseArray(JSONObject.toJSONString(data), clazz);
+    }
+
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+}

+ 72 - 0
app/src/main/java/com/kfzs/duanduan/bean/BorrowPlayIntegral.java

@@ -0,0 +1,72 @@
+package com.kfzs.duanduan.bean;
+
+/**
+ * 借着玩 积分展示
+ * Created by ljy on 2018/1/16.
+ */
+
+public class BorrowPlayIntegral {
+    private String GameId ;//24;
+    private String FirstGearPay ;//3445;一档充值金额
+    private String SecondGearPay ;//423;
+    private String ThirdGearPay ;//778;
+    private String FirstGearReturn ;//2345;一档返回积分
+    private String SecondGearReturn ;//565;
+    private String ThirdGearTeturn ;//898;State //1
+
+    public String getGameId() {
+        return GameId;
+    }
+
+    public void setGameId(String gameId) {
+        GameId = gameId;
+    }
+
+    public String getFirstGearPay() {
+        return FirstGearPay;
+    }
+
+    public void setFirstGearPay(String firstGearPay) {
+        FirstGearPay = firstGearPay;
+    }
+
+    public String getSecondGearPay() {
+        return SecondGearPay;
+    }
+
+    public void setSecondGearPay(String secondGearPay) {
+        SecondGearPay = secondGearPay;
+    }
+
+    public String getThirdGearPay() {
+        return ThirdGearPay;
+    }
+
+    public void setThirdGearPay(String thirdGearPay) {
+        ThirdGearPay = thirdGearPay;
+    }
+
+    public String getFirstGearReturn() {
+        return FirstGearReturn;
+    }
+
+    public void setFirstGearReturn(String firstGearReturn) {
+        FirstGearReturn = firstGearReturn;
+    }
+
+    public String getSecondGearReturn() {
+        return SecondGearReturn;
+    }
+
+    public void setSecondGearReturn(String secondGearReturn) {
+        SecondGearReturn = secondGearReturn;
+    }
+
+    public String getThirdGearTeturn() {
+        return ThirdGearTeturn;
+    }
+
+    public void setThirdGearTeturn(String thirdGearTeturn) {
+        ThirdGearTeturn = thirdGearTeturn;
+    }
+}

+ 61 - 0
app/src/main/java/com/kfzs/duanduan/bean/CateGameBean.java

@@ -0,0 +1,61 @@
+package com.kfzs.duanduan.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  CateGameBean</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/13 16:37
+ * @ QQ:    315096953
+ */
+
+public class CateGameBean {
+    private int gametypeid = 0;
+    private String type_name = "";
+    private String img = "";
+    private int type = 0;
+    private List<Game> games = new ArrayList<>();
+
+
+    public int getGametypeid() {
+        return gametypeid;
+    }
+
+    public void setGametypeid(int gametypeid) {
+        this.gametypeid = gametypeid;
+    }
+
+    public String getType_name() {
+        return type_name;
+    }
+
+    public void setType_name(String type_name) {
+        this.type_name = type_name;
+    }
+
+    public String getImg() {
+        return img;
+    }
+
+    public void setImg(String img) {
+        this.img = img;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
+    public List<Game> getGames() {
+        return games;
+    }
+
+    public void setGames(List<Game> games) {
+        this.games = games;
+    }
+}

+ 34 - 0
app/src/main/java/com/kfzs/duanduan/bean/CateGameList.java

@@ -0,0 +1,34 @@
+package com.kfzs.duanduan.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  CateGameList</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/13 16:25
+ * @ QQ:    315096953
+ */
+
+public class CateGameList {
+
+    private CateGameBean subject = new CateGameBean();
+    private List<CateGameBean> common = new ArrayList<>();
+
+    public CateGameBean getSubject() {
+        return subject;
+    }
+
+    public void setSubject(CateGameBean subject) {
+        this.subject = subject;
+    }
+
+    public List<CateGameBean> getCommon() {
+        return common;
+    }
+
+    public void setCommon(List<CateGameBean> common) {
+        this.common = common;
+    }
+}

+ 23 - 0
app/src/main/java/com/kfzs/duanduan/bean/CompareResult.java

@@ -0,0 +1,23 @@
+package com.kfzs.duanduan.bean;
+
+/**
+ * Created by HooRang on 2017/2/23.
+ */
+public class CompareResult {
+
+
+    /**
+     * equals
+     */
+    public static final int EQUALS = 0;
+
+    /**
+     * great that
+     */
+    public static final int GT = 1;
+
+    /**
+     * less that
+     */
+    public static final int LT = -1;
+}

+ 87 - 0
app/src/main/java/com/kfzs/duanduan/bean/ContactBean.java

@@ -0,0 +1,87 @@
+package com.kfzs.duanduan.bean;
+
+import java.util.Date;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  ContactBean</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/11/14 10:10
+ * @ QQ:    315096953
+ */
+
+public class ContactBean {
+
+    private String bookCreatteTime;
+    private String contactsName;
+    private String contactsPhone1;
+    private String contactsPhone2;
+    private String contactsPhone3;
+    private String contactsPhone4;
+    private String contactsPhone5;
+    private String contactsContent;
+
+    public String getBookCreatteTime() {
+        return bookCreatteTime;
+    }
+
+    public void setBookCreatteTime(String bookCreatteTime) {
+        this.bookCreatteTime = bookCreatteTime;
+    }
+
+    public String getContactsName() {
+        return contactsName;
+    }
+
+    public void setContactsName(String contactsName) {
+        this.contactsName = contactsName;
+    }
+
+    public String getContactsPhone1() {
+        return contactsPhone1;
+    }
+
+    public void setContactsPhone1(String contactsPhone1) {
+        this.contactsPhone1 = contactsPhone1;
+    }
+
+    public String getContactsPhone2() {
+        return contactsPhone2;
+    }
+
+    public void setContactsPhone2(String contactsPhone2) {
+        this.contactsPhone2 = contactsPhone2;
+    }
+
+    public String getContactsPhone3() {
+        return contactsPhone3;
+    }
+
+    public void setContactsPhone3(String contactsPhone3) {
+        this.contactsPhone3 = contactsPhone3;
+    }
+
+    public String getContactsPhone4() {
+        return contactsPhone4;
+    }
+
+    public void setContactsPhone4(String contactsPhone4) {
+        this.contactsPhone4 = contactsPhone4;
+    }
+
+    public String getContactsPhone5() {
+        return contactsPhone5;
+    }
+
+    public void setContactsPhone5(String contactsPhone5) {
+        this.contactsPhone5 = contactsPhone5;
+    }
+
+    public String getContactsContent() {
+        return contactsContent;
+    }
+
+    public void setContactsContent(String contactsContent) {
+        this.contactsContent = contactsContent;
+    }
+}

+ 130 - 0
app/src/main/java/com/kfzs/duanduan/bean/DownloadStatus.java

@@ -0,0 +1,130 @@
+package com.kfzs.duanduan.bean;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  DownloadStatus</p>
+ * @ <p>Description: 下载状态统一Event,以前是TaskEvent分离的</p>
+ * @ date:  2017/6/12 11:58
+ * @ QQ:    315096953
+ */
+
+public class DownloadStatus {
+
+    //DownloadTaskService 和这里的STATUS_同步
+    private int status;
+
+    private int downloadPgrs;
+
+    private int gameId;
+
+    private String apkPath;
+
+    private String message;
+
+    private String downloadUrl;
+
+    private int downloadId;
+
+    private double fileTotalSize;
+    private double fileDownloadedSize;
+
+    private float downloadSpeed;
+
+
+    public int getGameId() {
+        return gameId;
+    }
+
+    public void setGameId(int gameId) {
+        this.gameId = gameId;
+    }
+
+    public String getDownloadUrl() {
+        return downloadUrl;
+    }
+
+    public void setDownloadUrl(String downloadUrl) {
+        this.downloadUrl = downloadUrl;
+    }
+
+    public int getDownloadId() {
+        return downloadId;
+    }
+
+    public void setDownloadId(int downloadId) {
+        this.downloadId = downloadId;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    /**
+     * DownloadTaskService.STATUS_ 下面的状态
+     *
+     * @param status
+     */
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public int getDownloadPgrs() {
+        return downloadPgrs;
+    }
+
+    public void setDownloadPgrs(int downloadPgrs) {
+        this.downloadPgrs = downloadPgrs;
+    }
+
+
+    public String getApkPath() {
+        return apkPath;
+    }
+
+    public void setApkPath(String apkPath) {
+        this.apkPath = apkPath;
+    }
+
+
+    public double getFileTotalSize() {
+        return fileTotalSize;
+    }
+
+    public void setFileTotalSize(double fileTotalSize) {
+        this.fileTotalSize = fileTotalSize;
+    }
+
+    public double getFileDownloadedSize() {
+        return fileDownloadedSize;
+    }
+
+    public void setFileDownloadedSize(double fileDownloadedSize) {
+        this.fileDownloadedSize = fileDownloadedSize;
+    }
+
+    public float getDownloadSpeed() {
+        return downloadSpeed;
+    }
+
+    public void setDownloadSpeed(float downloadSpeed) {
+        this.downloadSpeed = downloadSpeed;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder strBuilder = new StringBuilder();
+        strBuilder.append("status#" + status);
+        strBuilder.append(",downloadPgrs#" + this.downloadPgrs);
+        strBuilder.append(",apkPath#" + apkPath);
+        strBuilder.append(",message#" + message);
+        return strBuilder.toString();
+    }
+}

+ 313 - 0
app/src/main/java/com/kfzs/duanduan/bean/Game.java

@@ -0,0 +1,313 @@
+package com.kfzs.duanduan.bean;
+
+import com.kfzs.duanduan.proto.GameOuterClass;
+import com.kfzs.duanduan.utils.dlg.FormatAny;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  Game</p>
+ * @ <p>Description:游戏基类</p>
+ * @ date:  2017/12/13 13:39
+ * @ QQ:    315096953
+ */
+
+public class Game {
+
+    private int id = 0;
+    private String gameName = "";
+    private String iconImage = "";
+    private long startTime = 0L;
+    private String version = "";
+    private String size = "";
+    private String detailBackImage = "";
+    private String detailImage = "";
+    private String introduce = "";
+    private int isShelves = 0;
+    private int downloadNumTrue = 0;
+    private int downloadNum = 0;
+    private String downloadUrl = "";
+    private int searchNumTrue = 0;
+    private int searchNum = 0;
+    private int star = 0;
+    private String typeText = "";
+    private String packageName = "";
+    private String versionCode = "";
+    private long shelvesTime = 0L;
+    private int isInBook = 0;
+    private String onlyTag = "";
+    private int bookId = 0;
+    private String bookName = "";
+    private String url = "";
+    private boolean booked = false;
+    private boolean isCanPreDown = false;
+    private int existGift = 0;
+    private String discount;
+
+    public String getDiscount() {
+        return discount == null ? "" : discount;
+    }
+
+    public void setDiscount(String discount) {
+        this.discount = discount;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getGameName() {
+        return gameName;
+    }
+
+    public void setGameName(String gameName) {
+        this.gameName = gameName;
+    }
+
+    public String getIconImage() {
+        return iconImage;
+    }
+
+    public void setIconImage(String iconImage) {
+        this.iconImage = iconImage;
+    }
+
+    public long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(long startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getSize() {
+        return size;
+    }
+
+    public void setSize(String size) {
+        this.size = size;
+    }
+
+    public String getDetailBackImage() {
+        return detailBackImage;
+    }
+
+    public void setDetailBackImage(String detailBackImage) {
+        this.detailBackImage = detailBackImage;
+    }
+
+    public String getDetailImage() {
+        return detailImage;
+    }
+
+    public void setDetailImage(String detailImage) {
+        this.detailImage = detailImage;
+    }
+
+    public String getIntroduce() {
+        return introduce;
+    }
+
+    public void setIntroduce(String introduce) {
+        this.introduce = introduce;
+    }
+
+    public int getIsShelves() {
+        return isShelves;
+    }
+
+    public void setIsShelves(int isShelves) {
+        this.isShelves = isShelves;
+    }
+
+    public int getDownloadNumTrue() {
+        return downloadNumTrue;
+    }
+
+    public void setDownloadNumTrue(int downloadNumTrue) {
+        this.downloadNumTrue = downloadNumTrue;
+    }
+
+    public int getDownloadNum() {
+        return downloadNum;
+    }
+
+    public void setDownloadNum(int downloadNum) {
+        this.downloadNum = downloadNum;
+    }
+
+    public String getDownloadUrl() {
+        return downloadUrl;
+    }
+
+    public void setDownloadUrl(String downloadUrl) {
+        this.downloadUrl = downloadUrl;
+    }
+
+    public int getSearchNumTrue() {
+        return searchNumTrue;
+    }
+
+    public void setSearchNumTrue(int searchNumTrue) {
+        this.searchNumTrue = searchNumTrue;
+    }
+
+    public int getSearchNum() {
+        return searchNum;
+    }
+
+    public void setSearchNum(int searchNum) {
+        this.searchNum = searchNum;
+    }
+
+    public int getStar() {
+        return star;
+    }
+
+    public void setStar(int star) {
+        this.star = star;
+    }
+
+    public String getTypeText() {
+        return typeText;
+    }
+
+    public void setTypeText(String typeText) {
+        this.typeText = typeText;
+    }
+
+    public String getPackageName() {
+        return packageName;
+    }
+
+    public void setPackageName(String packageName) {
+        this.packageName = packageName;
+    }
+
+    public String getVersionCode() {
+        return versionCode;
+    }
+
+    public void setVersionCode(String versionCode) {
+        this.versionCode = versionCode;
+    }
+
+    public long getShelvesTime() {
+        return shelvesTime;
+    }
+
+    public void setShelvesTime(long shelvesTime) {
+        this.shelvesTime = shelvesTime;
+    }
+
+    public int getIsInBook() {
+        return isInBook;
+    }
+
+    public void setIsInBook(int isInBook) {
+        this.isInBook = isInBook;
+    }
+
+    public String getOnlyTag() {
+        return onlyTag;
+    }
+
+    public void setOnlyTag(String onlyTag) {
+        this.onlyTag = onlyTag;
+    }
+
+    public int getBookId() {
+        return bookId;
+    }
+
+    public void setBookId(int bookId) {
+        this.bookId = bookId;
+    }
+
+    public String getBookName() {
+        return bookName;
+    }
+
+    public void setBookName(String bookName) {
+        this.bookName = bookName;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public boolean isBooked() {
+        return booked;
+    }
+
+    public void setBooked(boolean booked) {
+        this.booked = booked;
+    }
+
+    public boolean isCanPreDown() {
+        return isCanPreDown;
+    }
+
+    public void setCanPreDown(boolean canPreDown) {
+        isCanPreDown = canPreDown;
+    }
+
+    public int getExistGift() {
+        return existGift;
+    }
+
+    public void setExistGift(int existGift) {
+        this.existGift = existGift;
+    }
+
+
+    public GameOuterClass.Game getGameV1() {
+        return GameOuterClass.Game.newBuilder()
+                .setBooked(booked)
+                .setBookId(bookId)
+                .setBookName(bookName)
+                .setDetailBackImage(detailBackImage)
+                .setDetailImage(detailImage)
+                .setDownloadNum(downloadNum)
+                .setDownloadNumTrue(downloadNumTrue)
+                .setDownloadUrl(downloadUrl)
+                .setExistGift(existGift)
+                .setGameName(gameName)
+                .setIconImage(iconImage)
+                .setId(id)
+                .setIntroduce(introduce)
+                .setIsCanPreDown(isCanPreDown)
+                .setIsInBook(isInBook)
+                .setPackageName(packageName)
+                .setIsShelves(isShelves)
+                .setOnlyTag(onlyTag)
+                .setSearchNum(searchNum)
+                .setSize(size)
+                .setStar(star)
+                .setStartTime(startTime)
+                .setSearchNum(searchNum)
+                .setShelvesTime(shelvesTime)
+                .setTypeText(typeText)
+                .setUrl(url)
+                .setVersion(version)
+                .setVersionCode(versionCode)
+                .setSearchNumTrue(searchNumTrue)
+                .build();
+    }
+
+}

+ 184 - 0
app/src/main/java/com/kfzs/duanduan/bean/GiftItem.java

@@ -0,0 +1,184 @@
+package com.kfzs.duanduan.bean;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  GiftItem</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/8/11 15:26
+ * @ QQ:    315096953
+ */
+
+public class GiftItem {
+
+    private int id_ = 0;
+    private int gameId_ = 0;
+    private String giftName_ = "";
+    private int typeId_ = 0;
+    private String giftContent_ = "";
+    private long startTime_ = 0L;
+    private long endTime_ = 0L;
+    private long createdTime_ = 0L;
+    private String useInstruction_ = "";
+    private long receiveNum_ = 0L;
+    private long remain_num = 0L;
+    private int status_ = 0;
+    private long totalNum_ = 0L;
+    private String giftCodes_ = "";
+    private int existGift = 0;
+    private String iconImage = "";
+    private String gameName = "";
+    private int plan_num=0;
+    private float percentum=0;
+
+    public int getPlan_num() {
+        return plan_num;
+    }
+
+    public void setPlan_num(int plan_num) {
+        this.plan_num = plan_num;
+    }
+
+    public float getPercentum() {
+        return percentum;
+    }
+
+    public void setPercentum(float percentum) {
+        this.percentum = percentum;
+    }
+
+    public int getId_() {
+        return id_;
+    }
+
+    public void setId_(int id_) {
+        this.id_ = id_;
+    }
+
+    public int getGameId_() {
+        return gameId_;
+    }
+
+    public void setGameId_(int gameId_) {
+        this.gameId_ = gameId_;
+    }
+
+    public String getGiftName_() {
+        return giftName_;
+    }
+
+    public void setGiftName_(String giftName_) {
+        this.giftName_ = giftName_;
+    }
+
+    public int getTypeId_() {
+        return typeId_;
+    }
+
+    public void setTypeId_(int typeId_) {
+        this.typeId_ = typeId_;
+    }
+
+    public String getGiftContent_() {
+        return giftContent_;
+    }
+
+    public void setGiftContent_(String giftContent_) {
+        this.giftContent_ = giftContent_;
+    }
+
+    public long getStartTime_() {
+        return startTime_;
+    }
+
+    public void setStartTime_(long startTime_) {
+        this.startTime_ = startTime_;
+    }
+
+    public long getEndTime_() {
+        return endTime_;
+    }
+
+    public void setEndTime_(long endTime_) {
+        this.endTime_ = endTime_;
+    }
+
+    public long getCreatedTime_() {
+        return createdTime_;
+    }
+
+    public void setCreatedTime_(long createdTime_) {
+        this.createdTime_ = createdTime_;
+    }
+
+    public String getUseInstruction_() {
+        return useInstruction_;
+    }
+
+    public void setUseInstruction_(String useInstruction_) {
+        this.useInstruction_ = useInstruction_;
+    }
+
+    public long getReceiveNum_() {
+        return receiveNum_;
+    }
+
+    public void setReceiveNum_(long receiveNum_) {
+        this.receiveNum_ = receiveNum_;
+    }
+
+    public long getRemain_num() {
+        return remain_num;
+    }
+
+    public void setRemain_num(long remain_num) {
+        this.remain_num = remain_num;
+    }
+
+    public int getStatus_() {
+        return status_;
+    }
+
+    public void setStatus_(int status_) {
+        this.status_ = status_;
+    }
+
+    public long getTotalNum_() {
+        return totalNum_;
+    }
+
+    public void setTotalNum_(long totalNum_) {
+        this.totalNum_ = totalNum_;
+    }
+
+    public String getGiftCodes_() {
+        return giftCodes_;
+    }
+
+    public void setGiftCodes_(String giftCodes_) {
+        this.giftCodes_ = giftCodes_;
+    }
+
+    public int getExistGift() {
+        return existGift;
+    }
+
+    public void setExistGift(int existGift) {
+        this.existGift = existGift;
+    }
+
+    public String getIconImage() {
+        return iconImage;
+    }
+
+    public void setIconImage(String iconImage) {
+        this.iconImage = iconImage;
+    }
+
+    public String getGameName() {
+        return gameName;
+    }
+
+    public void setGameName(String gameName) {
+        this.gameName = gameName;
+    }
+}

+ 89 - 0
app/src/main/java/com/kfzs/duanduan/bean/GiftList.java

@@ -0,0 +1,89 @@
+package com.kfzs.duanduan.bean;
+
+/**
+ * Created by Administrator on 2017/12/18.
+ */
+
+public class GiftList {
+    private String GiftName;// 我让他问题,
+    private String GameName;// 阴阳师,
+    private String UseTime;// 0,
+    private String GameId;// 1,
+    private long EndTime;// 1518672986,
+    private String GiftCode;// ih398351gu,
+    private String Icon;// http;////staticcdn.kuaifazs.com/upload/game/201609/01/ce/09/ibPuD4_100x100.png,
+    private boolean UsedStatus;// false,
+    private String GiftId;// 1
+
+    public String getGiftName() {
+        return GiftName;
+    }
+
+    public void setGiftName(String giftName) {
+        GiftName = giftName;
+    }
+
+    public String getGameName() {
+        return GameName;
+    }
+
+    public void setGameName(String gameName) {
+        GameName = gameName;
+    }
+
+    public String getUseTime() {
+        return UseTime;
+    }
+
+    public void setUseTime(String useTime) {
+        UseTime = useTime;
+    }
+
+    public String getGameId() {
+        return GameId;
+    }
+
+    public void setGameId(String gameId) {
+        GameId = gameId;
+    }
+
+    public long getEndTime() {
+        return EndTime;
+    }
+
+    public void setEndTime(long endTime) {
+        EndTime = endTime;
+    }
+
+    public String getGiftCode() {
+        return GiftCode;
+    }
+
+    public void setGiftCode(String giftCode) {
+        GiftCode = giftCode;
+    }
+
+    public String getIcon() {
+        return Icon;
+    }
+
+    public void setIcon(String icon) {
+        Icon = icon;
+    }
+
+    public boolean isUsedStatus() {
+        return UsedStatus;
+    }
+
+    public void setUsedStatus(boolean usedStatus) {
+        UsedStatus = usedStatus;
+    }
+
+    public String getGiftId() {
+        return GiftId;
+    }
+
+    public void setGiftId(String giftId) {
+        GiftId = giftId;
+    }
+}

+ 45 - 0
app/src/main/java/com/kfzs/duanduan/bean/GuessYouLike.java

@@ -0,0 +1,45 @@
+package com.kfzs.duanduan.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  GuessYouLike</p>
+ * @ <p>Description:猜你喜欢的返回类</p>
+ * @ date:  2017/12/13 13:42
+ * @ QQ:    315096953
+ */
+
+public class GuessYouLike {
+
+    private int gametypeid = 0;
+
+    private String img = "";
+
+    private List<Game> games = new ArrayList<>();
+
+    public int getGametypeid() {
+        return gametypeid;
+    }
+
+    public void setGametypeid(int gametypeid) {
+        this.gametypeid = gametypeid;
+    }
+
+    public String getImg() {
+        return img;
+    }
+
+    public void setImg(String img) {
+        this.img = img;
+    }
+
+    public List<Game> getGames() {
+        return games;
+    }
+
+    public void setGames(List<Game> games) {
+        this.games = games;
+    }
+}

+ 40 - 0
app/src/main/java/com/kfzs/duanduan/bean/KFIntentKeys.java

@@ -0,0 +1,40 @@
+package com.kfzs.duanduan.bean;
+
+/**
+ * Created by HooRang on 2017/3/3.
+ */
+public class KFIntentKeys {
+
+
+    /**
+     * Game's banner
+     */
+    public static final int BANNER_TYPE_GAME = 0x1;
+
+    /**
+     * AD's banner
+     */
+    public static final int BANNER_TYPE_AD = 0x2;
+
+
+    public static final String EXTRA_BEHAIOR = "EXTRA_BEHAIOR";
+    public static final String EXTRA_GAME_ID = "EXTRA_GAME_ID";
+    public static final String EXTRA_PAGE_NUM = "EXTRA_PAGE_NUM";
+    public static final String EXTRA_WEBVIEW_URL = "EXTRA_WEBVIEW_URL";
+    public static final String EXTRA_WEBVIEW_TITLE = "EXTRA_WEBVIEW_TITLE";
+    public static final String EXTRA_WEBVIEW_NO_TITLE = "EXTRA_WEBVIEW_NO_TITLE";
+    public static final String EXTRA_WEBVIEW_GAME_BOOK_ID = "EXTRA_WEBVIEW_GAME_BOOK_ID";
+    public static final String EXTRA_WEBVIEW_GAME_ID = "EXTRA_WEBVIEW_GAME_ID";
+    public static final String EXTRA_WEBVIEW_SHARE_IMGURL = "EXTRA_WEBVIEW_SHARE_IMGURL";
+    public static final String EXTRA_WEBVIEW_GAME_VERSION = "EXTRA_WEBVIEW_GAME_VERSION";
+    public static final String EXTRA_WEBVIEW_PACKAGENAME = "EXTRA_WEBVIEW_PACKAGENAME";
+    public static final String EXTRA_WEBVIEW_GAME_SIZE = "EXTRA_WEBVIEW_GAME_SIZE";
+
+    public static final String EXTRA_GAME_REQUEST_ORDER = "EXTRA_GAME_REQUEST_ORDER";
+
+
+    public static final String EXTRA_CURRENT_PICTURE_INDEX = "EXTRA_CURRENT_PICTURE_INDEX";
+    public static final String EXTRA_CURRENT_PICTURE_COLLECTIONS = "EXTRA_CURRENT_PICTURE_COLLECTIONS";
+
+
+}

+ 57 - 0
app/src/main/java/com/kfzs/duanduan/bean/NewGameRecommend.java

@@ -0,0 +1,57 @@
+package com.kfzs.duanduan.bean;
+
+import com.kfzs.duanduan.utils.dlg.FormatAny;
+
+import java.text.DecimalFormat;
+
+/**
+ * @ Created by Dlg
+ * @ <p>TiTle:  NewGameRecommend</p>
+ * @ <p>Description:</p>
+ * @ date:  2017/12/13 11:24
+ * @ QQ:    315096953
+ */
+
+public class NewGameRecommend {
+
+    private int gameid = 0;
+
+    private String icon = "";
+
+    private String gamename = "";
+
+    private String discount;
+
+    public String getDiscount() {
+        return discount == null ? "" : discount;
+    }
+
+    public void setDiscount(String discount) {
+        this.discount = discount;
+    }
+
+
+    public int getGameid() {
+        return gameid;
+    }
+
+    public void setGameid(int gameid) {
+        this.gameid = gameid;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public String getGamename() {
+        return gamename;
+    }
+
+    public void setGamename(String gamename) {
+        this.gamename = gamename;
+    }
+}

+ 48 - 0
app/src/main/java/com/kfzs/duanduan/bean/QueryCondition.java

@@ -0,0 +1,48 @@
+package com.kfzs.duanduan.bean;
+
+import com.kfzs.duanduan.proto.GameTypeOuterClass;
+
+import java.util.List;
+
+/**
+ * Created by HooRang on 2017/2/16.
+ */
+public class QueryCondition {
+    int id ;
+    int categoryIcon ;
+    String categoryName ;
+
+    List<GameTypeOuterClass.GameType> tags ;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getCategoryName() {
+        return categoryName;
+    }
+
+    public void setCategoryName(String categoryName) {
+        this.categoryName = categoryName;
+    }
+
+    public int getCategoryIcon() {
+        return categoryIcon;
+    }
+
+    public void setCategoryIcon(int categoryIcon) {
+        this.categoryIcon = categoryIcon;
+    }
+
+    public List<GameTypeOuterClass.GameType> getTags() {
+        return tags;
+    }
+
+    public void setTags(List<GameTypeOuterClass.GameType> tags) {
+        this.tags = tags;
+    }
+}

+ 0 - 0
app/src/main/java/com/kfzs/duanduan/bean/RecyleObj.java


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