Compare commits
468 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ba45deac9 | |||
| 0c9f741847 | |||
| 696f862633 | |||
| f85e3c2602 | |||
| d2e3635034 | |||
| 72aa1474d3 | |||
| 6d134edb0a | |||
| 7834e9d55a | |||
| 36ba95e2fd | |||
| 00deba962e | |||
| 4713594c7e | |||
| 688a169e4e | |||
| 3ace50b526 | |||
| a9dbb4850f | |||
| 910cda8dbc | |||
| 7d29c0d883 | |||
| 3f274cb4ea | |||
| 56d378b6dc | |||
| 03eebf2c07 | |||
| cf41572db7 | |||
| a2361254da | |||
| 233f786ee0 | |||
| 8590614272 | |||
| e179de3d0d | |||
| defe3bb3ff | |||
| 24ad3e0265 | |||
| e54646afcc | |||
| 4c62032c66 | |||
| 627affe0f7 | |||
| b5e21bef1e | |||
| 95999791bd | |||
| 07cba611cf | |||
| 29c2dfc1e5 | |||
| 6b904b9213 | |||
| 7e15307b46 | |||
| 626913c6ff | |||
| 00b98e4da9 | |||
| 67f565bee0 | |||
| 9eedf46294 | |||
| 810783da9c | |||
| 39dfe334ed | |||
| 1a985f2a7e | |||
| 35af46e3eb | |||
| 3eefadd83b | |||
| 0fbbd79bbd | |||
| 84eee14363 | |||
| 8f7ce5d148 | |||
| 5ed2fa4a0c | |||
| e5a06f7a3f | |||
| f0ef1c7a76 | |||
| 76ea9a4ba4 | |||
| 33454005c3 | |||
| 37b6e6bce0 | |||
| aaa9aab066 | |||
| e8669cc0cf | |||
| ddb226823f | |||
| 76eca47979 | |||
| bcac6944a0 | |||
| d9aa1c428d | |||
| 85c779ecd2 | |||
| 87a67470fd | |||
| be4142ad96 | |||
| 5a26f7735d | |||
| 11ec77ad99 | |||
| 2da4182ee1 | |||
| d17ad6a497 | |||
| 1abc0ecc79 | |||
| 51ee8c841b | |||
| 0636d2276b | |||
| bffee14882 | |||
| 93f2ed3a09 | |||
| c7b0ed26ae | |||
| e75ade83cb | |||
| 3e4f5d6361 | |||
| 999bc9f720 | |||
| cca068821b | |||
| 6d05a00488 | |||
| ba3450f2b3 | |||
| 57c084d512 | |||
| c956f35e07 | |||
| c44353fa13 | |||
| 8ebdc924f3 | |||
| 3923dd377d | |||
| 82eea64035 | |||
| 10229e59f6 | |||
| 8c2583eab3 | |||
| f9ef4851fb | |||
| d07b99fd98 | |||
| b23ce2adc3 | |||
| c4f2899e07 | |||
| ebb20f5c38 | |||
| 08aaae1b02 | |||
| 4aaef11f9c | |||
| 2d0d253149 | |||
| 875c0b8c16 | |||
| 3e285a4466 | |||
| 76e91265d5 | |||
| 47482ba793 | |||
| 685c38dcf7 | |||
| 240d97cdd5 | |||
| cd891d4378 | |||
| b9c05483d0 | |||
| 190c534dba | |||
| 5cc13d8161 | |||
| 81ac870c62 | |||
| 9eab5c3d4c | |||
| f4a4ae7eb3 | |||
| 4b2715e97d | |||
| 983e546a64 | |||
| d7161578b0 | |||
| d8683068c1 | |||
| efcea45819 | |||
| 28f89aa0ad | |||
| 309d42fdc1 | |||
| f8f45182ce | |||
| 5f08dee0e0 | |||
| deea0f3f83 | |||
| 2090c5950f | |||
| 02dcbdba02 | |||
| ee44b1986f | |||
| 16bc7b1e75 | |||
| 65bc06b195 | |||
| 06734d6274 | |||
| e1dcd72a79 | |||
| 3429a27354 | |||
| 7af99a5ed5 | |||
| d7833cd07f | |||
| a9b885c97f | |||
| 5eb815dba7 | |||
| 9797841280 | |||
| a2382be034 | |||
| 081ce01664 | |||
| eddb8a933c | |||
| 7a019cc465 | |||
| 08e8846af8 | |||
| 67d6cc6f05 | |||
| 1946478ce4 | |||
| 5689cdbafe | |||
| 44adfdede8 | |||
| 2992e3ca64 | |||
| ffbbd44beb | |||
| 3990515dc5 | |||
| 2bd218fd95 | |||
| 1a02239dd2 | |||
| a5a5e38d5c | |||
| 9ebf2be016 | |||
| 3e488d28cd | |||
| ce311d9b17 | |||
| 843a263b3f | |||
| 7e350cac41 | |||
| 447b7b35ef | |||
| 6e9edabd94 | |||
| 68cfdc57c8 | |||
| 81e0f1d9cc | |||
| 5436775b31 | |||
| b8f5c2ddbd | |||
| da433bfb5b | |||
| 50209aa6ed | |||
| 665fbb0f6c | |||
| fd0921870d | |||
| 568ff5cb1e | |||
| 0cc78b1055 | |||
| 6dc3b5c382 | |||
| 9ac373bf0e | |||
| 02f96f9083 | |||
| c74997f306 | |||
| 58d4f22a6b | |||
| c5cf1c168e | |||
| 36638a63ca | |||
| 07de30ceea | |||
| 35e15263b0 | |||
| 420867378b | |||
| 0cc183df22 | |||
| eb557ca9bd | |||
| 72b39a5982 | |||
| b96ee6bc19 | |||
| 684fa318ec | |||
| 29faea14c6 | |||
| c25f7a13db | |||
| 715edd77e0 | |||
| 25cc825ea6 | |||
| f7e7819b84 | |||
| d305315d7e | |||
| 965d756cba | |||
| 29a19b5df6 | |||
| cb2cdd98e8 | |||
| da79a972f7 | |||
| 3c13eff2cf | |||
| 7050070310 | |||
| 1dca4e8c0a | |||
| 1163e04aaf | |||
| 73bc256ce6 | |||
| df78db5686 | |||
| b64ceaf5d4 | |||
| eb9b4cd132 | |||
| b9eec94644 | |||
| 4e388ec3d7 | |||
| a5069789b3 | |||
| 3797fd85ad | |||
| f0b0423872 | |||
| e5daf1d29f | |||
| 2b9f40a976 | |||
| 05fbf28d2b | |||
| e54d06def9 | |||
| 840eff3cc4 | |||
| a0737d0010 | |||
| 9d93df888e | |||
| 90fbb235c3 | |||
| 9be884c672 | |||
| 550a4cdecf | |||
| 0d883b76fe | |||
| e3c3101cab | |||
| cce289253d | |||
| 2102dd729c | |||
| 347a83cf0f | |||
| 1f8d573fad | |||
| 72b6c2a176 | |||
| 743e3660e9 | |||
| 2ab6a49bec | |||
| 1e31e13384 | |||
| f77fbe680f | |||
| 53c55a3f36 | |||
| 18d11e3421 | |||
| bf42834051 | |||
| ee6337276c | |||
| cdc001b43e | |||
| f3eeaddec8 | |||
| b8e1e4e21c | |||
| 64f2c83894 | |||
| f9211e17a1 | |||
| f0c952848a | |||
| c736068d0e | |||
| e0c9d43f02 | |||
| 0a4b657a85 | |||
| 0121d9601c | |||
| 371a450f5a | |||
| 2796145d26 | |||
| 5a662ac72b | |||
| 6cd62cbd0a | |||
| 299fa1a107 | |||
| c39ba2e17e | |||
| 414b5b3861 | |||
| 6f89f4acce | |||
| 5f09fd1fa3 | |||
| 00f1b0e8a3 | |||
| 4473d0f787 | |||
| d5255f91d0 | |||
| 57a3479144 | |||
| 82c4ebf375 | |||
| 23ca884684 | |||
| cdfa999b05 | |||
| 224092b30a | |||
| 8daefb2e42 | |||
| c0c0ef979d | |||
| 6f0738cebb | |||
| 3c352921bb | |||
| 4df8f18cc4 | |||
| 120acdefc6 | |||
| 7eb31085b0 | |||
| 17a3446be4 | |||
| d713c67c9b | |||
| 76d788ee66 | |||
| 1cf13fc2a1 | |||
| de08d4d32d | |||
| dce3a91156 | |||
| 38bf17c932 | |||
| 5d0ccb9a34 | |||
| b557afde2c | |||
| ea9375c20e | |||
| fa464a9f1d | |||
| b3ff6ea991 | |||
| f9dbdd4aa8 | |||
| 21d06d97ef | |||
| fb28a49537 | |||
| d124504d5b | |||
| 0c69e0c5e5 | |||
| 39aee1ce89 | |||
| b3fe87b79a | |||
| 2dfdc17523 | |||
| c208e7f72d | |||
| 8722d0a65b | |||
| 54f044dfa0 | |||
| b854a6dfef | |||
| badb99da59 | |||
| 30d99dbe54 | |||
| c44c4e8b2d | |||
| 656b2f469b | |||
| 39e17842cc | |||
| 57f7c0bb31 | |||
| 76b03fa68b | |||
| c99d6fb16f | |||
| d29ccc0aca | |||
| bf51be498b | |||
| 6d941975e2 | |||
| 0e075d28a5 | |||
| 4b5e6b574f | |||
| fc79581f8c | |||
| 6176c47e2f | |||
| 9abe0eb158 | |||
| 4d7cedb8a6 | |||
| 2b02fe06ac | |||
| cd5f530fc6 | |||
| b9085c7091 | |||
| 679ee71f89 | |||
| 536f0e038a | |||
| b087e35b30 | |||
| db3df649ce | |||
| bb708277b1 | |||
| c3b694dc6c | |||
| b9ff0b1c88 | |||
| 52be8db71f | |||
| 0e791133dd | |||
| b4f760d69f | |||
| 9bba3c9560 | |||
| bcd61e87d3 | |||
| e8c0e523e6 | |||
| af9e9a87b4 | |||
| 2d1bb6435f | |||
| 5680b8508d | |||
| df0e9197dc | |||
| 79964160ff | |||
| 0d46554b66 | |||
| 2c674896ff | |||
| 3ce1f28ae6 | |||
| 5ef145ed47 | |||
| b478cd6812 | |||
| 7e86187132 | |||
| 58b7a9515f | |||
| 370b2122aa | |||
| c6f1a7d212 | |||
| c04e425550 | |||
| 19543d7d29 | |||
| 12af602066 | |||
| 000515cda7 | |||
| 645e5a94a6 | |||
| c2f69eb03d | |||
| 93a9c41bee | |||
| 02dffc6e22 | |||
| 2658b7ca93 | |||
| 8c3335a7bf | |||
| c0e7b8e3ee | |||
| 9ef3d65aa4 | |||
| 8d188d4798 | |||
| 7bfc84c156 | |||
| 18bc47efe1 | |||
| 4593952cc3 | |||
| 1d3e30f8d3 | |||
| 6fef655e44 | |||
| 552b81c558 | |||
| 6c9a4daf9b | |||
| fbc46c54c4 | |||
| bc7aaa8b08 | |||
| 95af9902e7 | |||
| f340a13212 | |||
| 3d8f17d641 | |||
| 68f7b0f20f | |||
| c3a3060b92 | |||
| c01b96298d | |||
| 26655da185 | |||
| 9d0345303a | |||
| 33d02a0b2e | |||
| f301ab694c | |||
| baa6c0db3c | |||
| d118f54bd3 | |||
| 4a7384d371 | |||
| 6a91b8ae0f | |||
| b5fddfbbd0 | |||
| cfa3ceaae7 | |||
| 7a8f75abfc | |||
| 3db70fcbbe | |||
| 7b74d9fe47 | |||
| 553c211f24 | |||
| 3b153f5967 | |||
| 926b2d070f | |||
| 3e37731d84 | |||
| 24b5b81279 | |||
| 0534294b82 | |||
| a314404b61 | |||
| 71b81b2255 | |||
| c8cb61436e | |||
| 1006bf25c1 | |||
| cb6f03231e | |||
| 8ee2308ee1 | |||
| 719dbeef76 | |||
| 4c34333956 | |||
| bff677d607 | |||
| ba1461c874 | |||
| 7a0e885444 | |||
| 72d4ab6db5 | |||
| dfd6b61123 | |||
| 352d7d032e | |||
| ae6ba7832d | |||
| 9d63a6d0c4 | |||
| e905fb366e | |||
| 27b325f7d9 | |||
| 5c2f8c60dd | |||
| 3ac5905994 | |||
| 0e460b0778 | |||
| 4eea5b99d6 | |||
| 34c60d09f6 | |||
| 48e1ee4e7b | |||
| 46863d09a2 | |||
| ade08dcbee | |||
| e9a381068e | |||
| f5a068937a | |||
| c2bc52e474 | |||
| cd4ce2aa6b | |||
| 257e82e825 | |||
| a705f0ec53 | |||
| 46699a05ce | |||
| 9fd1855daa | |||
| 9a96fffd18 | |||
| 00d6f5e4b1 | |||
| a3adb87a6a | |||
| d0c01f1873 | |||
| 725d0b217a | |||
| 1958c6aefb | |||
| 05be092d69 | |||
| 40fccea23a | |||
| a022526e7e | |||
| 765b4c3afa | |||
| f704a29b38 | |||
| 309bb98036 | |||
| bf7b0b0a82 | |||
| 98629c5e85 | |||
| 461acbd376 | |||
| e0b70b26f3 | |||
| 4a831f4cb9 | |||
| b58bbbe705 | |||
| dc186e2e6b | |||
| 886007eae5 | |||
| 877ecbaef1 | |||
| 434bfde292 | |||
| 40c55e716d | |||
| 19e394abb8 | |||
| 7b95d991d4 | |||
| 4214c08e76 | |||
| 180c49f9d3 | |||
| 65e098e1c8 | |||
| 3978ab95f4 | |||
| d537cb2383 | |||
| dba866e5c9 | |||
| ce36dd4012 | |||
| ea2b9ef4df | |||
| a34b101a05 | |||
| b0fe7595da | |||
| 6a7ef44bdd | |||
| 4131396117 | |||
| e5f8d959ed | |||
| 6f0c9e0b59 | |||
| 051e0751a5 | |||
| 5f19f55e03 | |||
| da6cfdc4e8 | |||
| adbdc55bc4 | |||
| 6c1da15ae4 | |||
| ecf05bcd00 | |||
| 3baec32ff8 | |||
| cb95204fac | |||
| 41b940a8e9 | |||
| 3d8d612897 | |||
| b3297e3fcd | |||
| c8c93cac6e | |||
| e68e47e132 | |||
| 72f9e8ed79 | |||
| 3a2c67152e | |||
| c4c499532a | |||
| d8f043ad71 | |||
| 1706ead392 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -6,4 +6,5 @@ local.properties
|
||||
.DS_Store
|
||||
captures/
|
||||
build/
|
||||
release-app/
|
||||
release-app/
|
||||
scripts/apk-channel/
|
||||
@ -1,3 +1,5 @@
|
||||
### Ver 3.1
|
||||
|
||||
### Ver 3.0
|
||||
* 升级账号系统(登录流程/用户信息相关/用户账号相关操作(评论,礼包...))
|
||||
* 新增收藏功能(文章/工具箱)
|
||||
|
||||
52
README.md
52
README.md
@ -1,40 +1,70 @@
|
||||
# 光环助手Android客户端
|
||||
|
||||
### Sourceset/debug/release
|
||||
### sourcesets/debug/release
|
||||
|
||||
* https://developer.android.com/studio/build/build-variants.html#sourcesets
|
||||
|
||||
### 多渠道打包配置
|
||||
### APK打包配置
|
||||
|
||||
* 使用[ApkChannelPackage](https://github.com/ltlovezh/ApkChannelPackage)的方案
|
||||
* 正式打包命令:请使用./gradlew channelPubRelease打包渠道包
|
||||
* 打包命令,视情况使用:
|
||||
|
||||
> 打包Tinker基准包:`./scripts/tinker_release_base.sh`
|
||||
|
||||
> 以Tinker基准包打渠道包:`./scripts/tinker_release_channel.sh`
|
||||
|
||||
> 以Tinker基准包打补丁包:`./scripts/tinker_release_patch.sh`
|
||||
|
||||
### 混淆配置
|
||||
|
||||
* 配置文件:Android默认配置+proguard-rules.txt等
|
||||
* 参考libraries下每个项目独立的配置文件``proguard-project.txt``
|
||||
* 参考libraries下每个项目独立的配置文件`proguard-project.txt`
|
||||
|
||||
### apk大小优化
|
||||
|
||||
* 限制resConfig资源集
|
||||
* 开启ShrinkResources
|
||||
* 开启混淆,使用minifyEnabled(仅在release开启)
|
||||
* pngquant对png压缩、png/jpg->webp(未尝试)
|
||||
|
||||
### 第三方appkey等配置
|
||||
* 修改``gradle.properties``文件将各种key填入其中,实现统一管理
|
||||
|
||||
* 修改`gradle.properties`文件将各种key填入其中,实现统一管理
|
||||
* 通过gradle文件内的resValue/buildConfigField/manifestPlaceHolder方式实现编译期间修改,具体情况请参考``./build.gradle``和``./app/build.gradle``配置
|
||||
|
||||
### 拉取代码步骤
|
||||
|
||||
1. 拉取主项目代码: `git clone -b dev git@gitlab.ghzhushou.com:halo/assistant-android.git`
|
||||
2. 初始化公用类库: `bash ./scripts/init_submodules.sh`
|
||||
2. 初始化公用类库: `bash ./scripts/submodules_init.sh`
|
||||
|
||||
### submodule管理方式(只拉取master)
|
||||
|
||||
* 提交代码,需要cd到submodule文件夹去做修改
|
||||
|
||||
|
||||
* 更新远端代码,`bash ./scripts/submodules_update.sh`
|
||||
|
||||
### TODO
|
||||
|
||||
* GSON 序列化用统一的一个, GsonUtil fromJson
|
||||
* CleanApkAdapter 转化字符串size工具函数 比如SpeedUtils
|
||||
* getString 解决 字符串hardcode问题
|
||||
* Adapter 里面clicklistener 用接口传参将点击操作委托给controller
|
||||
* Adapter ViewHolder的功能,部分重写到ViewHolder类本身
|
||||
* ~~Adapter 里面clicklistener 用接口传参将点击操作委托给controller~~
|
||||
* ~~Adapter ViewHolder的功能,部分重写到ViewHolder类本身~~
|
||||
|
||||
* activity 统一入口未完成(外部入口相关)
|
||||
* ~~activity 统一入口未完成(外部入口相关),去除多余activity使用,统一toolbar~~
|
||||
* release / debug compile不同的类库,不需要再做什么开关
|
||||
|
||||
* ~~Toolbar分离,有图形按钮/没有图形按钮~~
|
||||
|
||||
### TODO Since 3.1
|
||||
|
||||
- 解决 Utils 工具类引发的内存泄漏问题
|
||||
- 把原有 EventBus 的消息 Type 统一到一个文件内
|
||||
- 明确 MVVM 中 Repository 及其衍生类的具体实现方式
|
||||
- 将实现细节从 View(Fragment、Activity) 剥离并以 MVVM 结构改造
|
||||
- 将 ListViewModel 所对应的 ListRepository 合并到 ListViewModel 中
|
||||
- 依照光环助手界面功能以大模块 - 小模块的方式去修改包结构,包内文件建议以包名摘要作为前缀
|
||||
- 使用 RxJava 的 Debounce 和 Map 操作优化搜索触发机制 参考资料:[1](https://proandroiddev.com/building-an-autocompleting-edittext-using-rxjava-f69c5c3f5a40),[2](https://medium.com/@kurtisnusbaum/rxandroid-basics-part-2-6e877af352)
|
||||
|
||||
- 把 ListViewModel 的数据结构类型转换方式换为抽象方法,让继承的类实现,避免出现无响应的问题
|
||||
|
||||
- 上传图片改为用Retrofit上传
|
||||
@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
apply plugin: 'org.jetbrains.kotlin.android.extensions'
|
||||
apply plugin: 'kotlin-android' // kotlin
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
// apkChannelPackage
|
||||
apply plugin: 'channel'
|
||||
@ -9,9 +11,17 @@ apply from: 'tinker-support.gradle'
|
||||
|
||||
android {
|
||||
|
||||
androidExtensions {
|
||||
experimental = true
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
dexOptions {
|
||||
@ -115,12 +125,9 @@ android {
|
||||
buildConfigField "String", "LIBAO_HOST", "\"${LIBAO_HOST}\""
|
||||
buildConfigField "String", "MESSAGE_HOST", "\"${MESSAGE_HOST}\""
|
||||
buildConfigField "String", "DATA_HOST", "\"${DATA_HOST}\""
|
||||
buildConfigField "String", "USERSEA_HOST", "\"${USERSEA_HOST}\""
|
||||
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${BUGLY_APPID}\""
|
||||
|
||||
buildConfigField "String", "USERSEA_APP_ID", "\"${USERSEA_APP_ID}\""
|
||||
buildConfigField "String", "USERSEA_APP_SECRET", "\"${USERSEA_APP_SECRET}\""
|
||||
}
|
||||
// internal test dev host
|
||||
internal {
|
||||
@ -131,12 +138,8 @@ android {
|
||||
buildConfigField "String", "LIBAO_HOST", "\"${DEV_LIBAO_HOST}\""
|
||||
buildConfigField "String", "MESSAGE_HOST", "\"${DEV_MESSAGE_HOST}\""
|
||||
buildConfigField "String", "DATA_HOST", "\"${DEV_DATA_HOST}\""
|
||||
buildConfigField "String", "USERSEA_HOST", "\"${DEV_USERSEA_HOST}\""
|
||||
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${DEBUG_BUGLY_APPID}\""
|
||||
|
||||
buildConfigField "String", "USERSEA_APP_ID", "\"${DEV_USERSEA_APP_ID}\""
|
||||
buildConfigField "String", "USERSEA_APP_SECRET", "\"${DEV_USERSEA_APP_SECRET}\""
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,9 +179,10 @@ dependencies {
|
||||
implementation "com.android.support:design:${androidSupport}"
|
||||
implementation "com.android.support:support-v4:${androidSupport}"
|
||||
implementation "com.android.support:appcompat-v7:${androidSupport}"
|
||||
implementation "com.android.support:cardview-v7:${androidSupport}"
|
||||
implementation "com.android.support:support-annotations:${androidSupport}"
|
||||
implementation "com.android.support:percent:${androidSupport}"
|
||||
|
||||
implementation "com.android.support.constraint:constraint-layout:${constraintLayout}"
|
||||
implementation "com.kyleduo.switchbutton:library:${switchButton}"
|
||||
implementation "com.readystatesoftware.systembartint:systembartint:${systemBarTint}"
|
||||
|
||||
@ -199,6 +203,8 @@ dependencies {
|
||||
|
||||
implementation "com.jakewharton:butterknife:${butterKnife}"
|
||||
annotationProcessor "com.jakewharton:butterknife-compiler:${butterKnife}"
|
||||
kapt "com.jakewharton:butterknife-compiler:${butterKnife}"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
|
||||
|
||||
implementation "org.greenrobot:eventbus:${eventbus}"
|
||||
annotationProcessor "org.greenrobot:eventbus-annotation-processor:${eventbusApt}"
|
||||
@ -226,20 +232,36 @@ dependencies {
|
||||
implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
|
||||
|
||||
implementation "pub.devrel:easypermissions:${easypermissions}"
|
||||
// mvvm
|
||||
implementation "android.arch.lifecycle:runtime:${archLifecycleVersion}"
|
||||
kapt "android.arch.lifecycle:compiler:${archLifecycleVersion}"
|
||||
implementation "android.arch.lifecycle:extensions:${archLifecycleVersion}"
|
||||
implementation "android.arch.persistence.room:runtime:${archRoomVersion}"
|
||||
kapt "android.arch.persistence.room:compiler:${archRoomVersion}"
|
||||
|
||||
implementation project(':libraries:MiPush')
|
||||
implementation 'com.google.android:flexbox:0.2.2'
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
kapt 'com.android.databinding:compiler:3.0.1'
|
||||
|
||||
implementation 'com.contrarywind:Android-PickerView:4.1.3'
|
||||
|
||||
implementation "com.scwang.smartrefresh:SmartRefreshLayout:${smartRefreshLayout}"
|
||||
implementation "net.cachapa.expandablelayout:expandablelayout:${expandableLayout}"
|
||||
|
||||
implementation project(':libraries:LGLibrary')
|
||||
implementation project(':libraries:MTA')
|
||||
implementation project(':libraries:QQShare')
|
||||
implementation project(':libraries:TalkingData')
|
||||
implementation project(':libraries:UmengPush')
|
||||
implementation project(':libraries:WechatShare')
|
||||
implementation project(':libraries:iosched')
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation project(':libraries:LogHub')
|
||||
|
||||
}
|
||||
File propFile = file('sign.properties')
|
||||
if (propFile.exists()) {
|
||||
def Properties props = new Properties()
|
||||
Properties props = new Properties()
|
||||
props.load(new FileInputStream(propFile))
|
||||
|
||||
if (props.containsKey('keyAlias') && props.containsKey('keyPassword') &&
|
||||
|
||||
@ -140,6 +140,7 @@
|
||||
-keep class com.gh.common.view.** {*;}
|
||||
-keep class com.gh.gamecenter.db.info.** {*;}
|
||||
-keep class com.gh.gamecenter.entity.** {*;}
|
||||
-keep class com.gh.gamecenter.qa.entity.** {*;}
|
||||
-keep class com.gh.gamecenter.retrofit.** {*;}
|
||||
-keep class com.gh.gamecenter.eventbus.** {*;}
|
||||
-keep class * extends rx.Subscriber
|
||||
@ -189,4 +190,11 @@
|
||||
# 重命名文件为SourceFile,再配合mapping符号表,可以拿到真实的类名
|
||||
-renamesourcefileattribute SourceFile
|
||||
# 保留源文件行号
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
-ignorewarnings
|
||||
|
||||
-keep @android.support.annotation.Keep class *
|
||||
-keepclassmembers class ** {
|
||||
@android.support.annotation.Keep *;
|
||||
}
|
||||
@ -4,7 +4,6 @@ import android.app.Application;
|
||||
|
||||
import com.facebook.stetho.Stetho;
|
||||
import com.facebook.stetho.okhttp3.StethoInterceptor;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
@ -35,33 +34,11 @@ public class Injection {
|
||||
}
|
||||
|
||||
public static OkHttpClient.Builder provideRetrofitBuilder() {
|
||||
// HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
|
||||
//
|
||||
// @Override
|
||||
// public void log(String message) {
|
||||
// //分段打印retrofit日志
|
||||
// if (message.startsWith("{") || message.startsWith("["))
|
||||
// if (message.length() > 4000) {
|
||||
// for (int i = 0; i < message.length(); i += 4000) {
|
||||
// if (i + 4000 < message.length())
|
||||
// Utils.log("OkHttp_Body::" + i, message.substring(i, i + 4000));
|
||||
// else
|
||||
// Utils.log("OkHttp_Body::" + i, message.substring(i, message.length()));
|
||||
// }
|
||||
// } else
|
||||
// Utils.log("OkHttp_Body::", message);
|
||||
// }
|
||||
// });
|
||||
// loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
builder.addNetworkInterceptor(interceptor);
|
||||
builder.addNetworkInterceptor(new StethoInterceptor());
|
||||
// if (BuildConfig.DEBUG) {
|
||||
// builder.addNetworkInterceptor(loggingInterceptor);
|
||||
// }
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools = "http://schemas.android.com/tools"
|
||||
package = "com.gh.gamecenter" >
|
||||
|
||||
<!-- 允许应用程序访问网络连接 -->
|
||||
@ -60,7 +61,9 @@
|
||||
android:allowBackup = "true"
|
||||
android:icon = "@drawable/logo"
|
||||
android:label = "@string/app_name"
|
||||
android:theme = "@style/AppCompatTheme.APP" >
|
||||
android:resizeableActivity = "true"
|
||||
android:theme = "@style/AppCompatTheme.APP"
|
||||
tools:targetApi = "n" >
|
||||
|
||||
<!--android:launchMode = "singleTask"-->
|
||||
<activity
|
||||
@ -75,15 +78,6 @@
|
||||
<category android:name = "android.intent.category.LAUNCHER" />
|
||||
</intent-filter >
|
||||
|
||||
<!-- MTA可视化启动连接接口 -->
|
||||
<intent-filter >
|
||||
<data android:scheme = "${tencentAppScheme}" />
|
||||
<action android:name = "android.intent.action.VIEW" />
|
||||
|
||||
<category android:name = "android.intent.category.DEFAULT" />
|
||||
<category android:name = "android.intent.category.BROWSABLE" />
|
||||
</intent-filter >
|
||||
|
||||
</activity >
|
||||
|
||||
<activity
|
||||
@ -97,9 +91,8 @@
|
||||
android:launchMode = "singleTask"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.ViewImageActivity"
|
||||
android:theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" />
|
||||
<!--android:theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" 退出时屏幕抖动 -->
|
||||
<activity android:name = "com.gh.gamecenter.ViewImageActivity" />
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.SearchActivity"
|
||||
android:configChanges = "keyboardHidden"
|
||||
@ -207,6 +200,15 @@
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.InstallActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = ".category.CategoryDirectoryActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = ".category.CategoryListActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.LoginActivity"
|
||||
android:screenOrientation = "portrait"
|
||||
@ -235,10 +237,98 @@
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.KaiFuActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.NormalActivity"
|
||||
android:name = "com.gh.gamecenter.qa.search.AskSearchActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = ".qa.answer.fold.AnswerFoldActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.ConcernInfoActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.InfoActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.MessageKeFuActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.select.CommunitiesSelectActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.subject.CommunitySubjectActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.MessageInviteActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.MessageVoteActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = ".qa.questions.invite.QuestionsInviteActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.myqa.MyAskActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.column.order.AskTabOrderActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.ask.QuestionEditActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.kaifu.add.AddKaiFuActivity"
|
||||
android:screenOrientation = "portrait"
|
||||
android:windowSoftInputMode = "stateHidden"/>
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.kaifu.patch.PatchKaifuActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.BlockActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.NetworkDiagnosisActivity"
|
||||
android:screenOrientation = "portrait" />
|
||||
|
||||
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.PushProxyActivity"
|
||||
android:exported = "true"
|
||||
android:theme = "@android:style/Theme.Translucent" />
|
||||
|
||||
<activity
|
||||
android:name = "com.gh.gamecenter.SkipActivity"
|
||||
android:theme = "@style/Theme.AppCompat.Light.Fullscreen.Transparent" >
|
||||
@ -264,13 +354,7 @@
|
||||
<data android:scheme = "package" />
|
||||
</intent-filter >
|
||||
</receiver >
|
||||
<receiver
|
||||
android:name = "com.gh.gamecenter.receiver.NotificationReceiver"
|
||||
android:exported = "false" >
|
||||
<intent-filter >
|
||||
<action android:name = "com.gh.gamecenter.NOTIFICATION" />
|
||||
</intent-filter >
|
||||
</receiver >
|
||||
|
||||
<receiver
|
||||
android:name = "com.gh.gamecenter.receiver.DownloadReceiver"
|
||||
android:exported = "false" >
|
||||
|
||||
24
app/src/main/assets/content.js
Normal file
24
app/src/main/assets/content.js
Normal file
@ -0,0 +1,24 @@
|
||||
function requestContentFocus() {
|
||||
$('#editor').focus();
|
||||
}
|
||||
|
||||
function setupWhenContentEditable() {
|
||||
var editor = $('#editor');
|
||||
if (!editor[0].hasAttribute('contenteditable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// paste 回调只会获取粘贴之前的光标位置,需要自己手动加上粘贴文本的长度,并保证粘贴的是纯文本
|
||||
editor.on('paste', function(e) {
|
||||
e.preventDefault();
|
||||
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
text = text.replace(/\n/g, '<br>');
|
||||
document.execCommand("insertHTML", false, text);
|
||||
});
|
||||
|
||||
requestContentFocus();
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
setupWhenContentEditable();
|
||||
});
|
||||
15
app/src/main/assets/editor.html
Normal file
15
app/src/main/assets/editor.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="user-scalable=no">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="editor" contenteditable="true"></div>
|
||||
<script type="text/javascript" src="zepto.min.js"></script>
|
||||
<script type="text/javascript" src="rich_editor.js"></script>
|
||||
<script type="text/javascript" src="content.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
413
app/src/main/assets/normalize.css
vendored
Normal file
413
app/src/main/assets/normalize.css
vendored
Normal file
@ -0,0 +1,413 @@
|
||||
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
|
||||
|
||||
/**
|
||||
* 1. Set default font family to sans-serif.
|
||||
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||
* Correct `block` display not defined for `details` or `summary` in IE 10/11
|
||||
* and Firefox.
|
||||
* Correct `block` display not defined for `main` in IE 11.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
menu,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct `inline-block` display not defined in IE 8/9.
|
||||
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block; /* 1 */
|
||||
vertical-align: baseline; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address `[hidden]` styling not present in IE 8/9/10.
|
||||
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
|
||||
*/
|
||||
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Links
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background color from active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in Safari and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address variable `h1` font-size and margin within `section` and `article`
|
||||
* contexts in Firefox 4+, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove border when inside `a` element in IE 8/9/10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct overflow not hidden in IE 9/10/11.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address margin not present in IE 8/9 and Safari.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address differences between Firefox and other browsers.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contain overflow in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address odd `em`-unit font size rendering in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||
* styling of `select`, unless a `border` property is set.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 1. Correct color not being inherited.
|
||||
* Known issue: affects color of disabled elements.
|
||||
* 2. Correct font properties not being inherited.
|
||||
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
color: inherit; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||
*/
|
||||
|
||||
button {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
* All other form control elements do not inherit `text-transform` values.
|
||||
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||
* Correct `select` style inheritance in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Correct inability to style clickable `input` types in iOS.
|
||||
* 3. Improve usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* It's recommended that you don't attempt to style these elements.
|
||||
* Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||
*
|
||||
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||
* 2. Remove excess padding in IE 8/9/10.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||
* `font-size` values of the `input`, it causes the cursor style of the
|
||||
* decrement button to change from `default` to `text`.
|
||||
*/
|
||||
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
|
||||
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||
* Safari (but not Chrome) clips the cancel button when the search input has
|
||||
* padding (and `textfield` appearance).
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove default vertical scrollbar in IE 8/9/10/11.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't inherit the `font-weight` (applied by a rule above).
|
||||
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
|
||||
*/
|
||||
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Tables
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
407
app/src/main/assets/rich_editor.js
Normal file
407
app/src/main/assets/rich_editor.js
Normal file
@ -0,0 +1,407 @@
|
||||
/**
|
||||
* Copyright (C) 2017 Wasabeef
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var RE = {};
|
||||
|
||||
RE.currentSelection = {
|
||||
"startContainer": 0,
|
||||
"startOffset": 0,
|
||||
"endContainer": 0,
|
||||
"endOffset": 0};
|
||||
|
||||
RE.editor = document.getElementById('editor');
|
||||
|
||||
document.addEventListener("selectionchange", function() { RE.backuprange(); });
|
||||
|
||||
// Initializations
|
||||
RE.callback = function() {
|
||||
window.location.href = "re-callback://" + encodeURI(RE.getHtml());
|
||||
}
|
||||
|
||||
RE.setHtml = function(contents) {
|
||||
RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));
|
||||
}
|
||||
|
||||
RE.getHtml = function() {
|
||||
return RE.editor.innerHTML;
|
||||
}
|
||||
|
||||
RE.getText = function() {
|
||||
return RE.editor.innerText;
|
||||
}
|
||||
|
||||
RE.setBaseTextColor = function(color) {
|
||||
RE.editor.style.color = color;
|
||||
}
|
||||
|
||||
RE.setBaseFontSize = function(size) {
|
||||
RE.editor.style.fontSize = size;
|
||||
}
|
||||
|
||||
RE.setPadding = function(left, top, right, bottom) {
|
||||
RE.editor.style.paddingLeft = left;
|
||||
RE.editor.style.paddingTop = top;
|
||||
RE.editor.style.paddingRight = right;
|
||||
RE.editor.style.paddingBottom = bottom;
|
||||
}
|
||||
|
||||
RE.setBackgroundColor = function(color) {
|
||||
document.body.style.backgroundColor = color;
|
||||
}
|
||||
|
||||
RE.setBackgroundImage = function(image) {
|
||||
RE.editor.style.backgroundImage = image;
|
||||
}
|
||||
|
||||
RE.setWidth = function(size) {
|
||||
RE.editor.style.minWidth = size;
|
||||
}
|
||||
|
||||
RE.setHeight = function(size) {
|
||||
RE.editor.style.height = size;
|
||||
}
|
||||
|
||||
RE.setTextAlign = function(align) {
|
||||
RE.editor.style.textAlign = align;
|
||||
}
|
||||
|
||||
RE.setVerticalAlign = function(align) {
|
||||
RE.editor.style.verticalAlign = align;
|
||||
}
|
||||
|
||||
RE.setPlaceholder = function(placeholder) {
|
||||
RE.editor.setAttribute("placeholder", placeholder);
|
||||
}
|
||||
|
||||
RE.setEditorFocus = function() {
|
||||
RE.editor.focus();
|
||||
}
|
||||
|
||||
RE.setInputEnabled = function(inputEnabled) {
|
||||
RE.editor.contentEditable = String(inputEnabled);
|
||||
}
|
||||
|
||||
RE.setFocusByEnd = function() {
|
||||
//alert("111111")
|
||||
// var txt =RE.editor.createTextRange();
|
||||
// ("22222")
|
||||
// txt.moveStart('character',-1);
|
||||
// ("333333")
|
||||
// txt.collapse(true);
|
||||
// ("444444")
|
||||
// txt.select();
|
||||
// alert("ddddddd")
|
||||
}
|
||||
|
||||
RE.undo = function() {
|
||||
document.execCommand('undo', false, null);
|
||||
}
|
||||
|
||||
RE.redo = function() {
|
||||
document.execCommand('redo', false, null);
|
||||
}
|
||||
|
||||
RE.setBold = function() {
|
||||
document.execCommand('bold', false, null);
|
||||
}
|
||||
|
||||
RE.setItalic = function() {
|
||||
document.execCommand('italic', false, null);
|
||||
}
|
||||
|
||||
RE.setSubscript = function() {
|
||||
document.execCommand('subscript', false, null);
|
||||
}
|
||||
|
||||
RE.setSuperscript = function() {
|
||||
document.execCommand('superscript', false, null);
|
||||
}
|
||||
|
||||
RE.setStrikeThrough = function() {
|
||||
document.execCommand('strikeThrough', false, null);
|
||||
}
|
||||
|
||||
RE.setUnderline = function() {
|
||||
document.execCommand('underline', false, null);
|
||||
}
|
||||
|
||||
RE.setBullets = function() {
|
||||
document.execCommand('insertUnorderedList', false, null);
|
||||
}
|
||||
|
||||
RE.setNumbers = function() {
|
||||
document.execCommand('insertOrderedList', false, null);
|
||||
}
|
||||
|
||||
RE.setTextColor = function(color) {
|
||||
RE.restorerange();
|
||||
document.execCommand("styleWithCSS", null, true);
|
||||
document.execCommand('foreColor', false, color);
|
||||
document.execCommand("styleWithCSS", null, false);
|
||||
}
|
||||
|
||||
RE.setTextBackgroundColor = function(color) {
|
||||
RE.restorerange();
|
||||
document.execCommand("styleWithCSS", null, true);
|
||||
document.execCommand('hiliteColor', false, color);
|
||||
document.execCommand("styleWithCSS", null, false);
|
||||
}
|
||||
|
||||
RE.setFontSize = function(fontSize){
|
||||
document.execCommand("fontSize", false, fontSize);
|
||||
}
|
||||
|
||||
RE.setHeading = function(heading) {
|
||||
document.execCommand('formatBlock', false, '<h'+heading+'>');
|
||||
}
|
||||
|
||||
RE.setIndent = function() {
|
||||
document.execCommand('indent', false, null);
|
||||
}
|
||||
|
||||
RE.setOutdent = function() {
|
||||
document.execCommand('outdent', false, null);
|
||||
}
|
||||
|
||||
RE.setJustifyLeft = function() {
|
||||
document.execCommand('justifyLeft', false, null);
|
||||
}
|
||||
|
||||
RE.setJustifyCenter = function() {
|
||||
document.execCommand('justifyCenter', false, null);
|
||||
}
|
||||
|
||||
RE.setJustifyRight = function() {
|
||||
document.execCommand('justifyRight', false, null);
|
||||
}
|
||||
|
||||
RE.setBlockquote = function() {
|
||||
document.execCommand('formatBlock', false, '<blockquote>');
|
||||
}
|
||||
|
||||
RE.insertImage = function(url) {
|
||||
var html = "<div><img src =\"" + url + "\" style=\" max-width: 100%; display:block; margin:8px auto; height: auto;\"></div><br>"
|
||||
RE.insertHTML(html);
|
||||
}
|
||||
|
||||
RE.replaceTbImage = function() {
|
||||
var imgs = document.getElementsByTagName("img");
|
||||
for (var i = 0; i < imgs.length; i++) {
|
||||
var img = imgs[i];
|
||||
if(img.src.indexOf("/tb/") > 0) continue;
|
||||
var imgArr = img.src.split("/");
|
||||
var tbImg = ""
|
||||
for (var j = 0; j < imgArr.length; j++) {
|
||||
if (j == imgArr.length - 1) {
|
||||
tbImg += "tb/" + imgArr[j];
|
||||
} else {
|
||||
tbImg += imgArr[j] + "/";
|
||||
}
|
||||
}
|
||||
img.style.cssText = "max-width: 30%; display:block; margin:8px auto; height: auto;"
|
||||
img.src = tbImg;
|
||||
|
||||
if (i == 0) {
|
||||
var bigImg = document.createElement('img');
|
||||
bigImg.src = "file:///android_asset/web_load_dfimg_icon.png";
|
||||
bigImg.style.cssText = "max-width: 20%; margin:8px 0 0 0; height: auto;"
|
||||
img.parentNode.insertBefore(bigImg, img.parentNode.childNodes[0]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RE.replaceAllDfImage = function() {
|
||||
var imgs = document.getElementsByTagName("img");
|
||||
for (var i = 0; i < imgs.length; i++) {
|
||||
var img = imgs[i];
|
||||
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
|
||||
img.parentNode.removeChild(img.parentNode.childNodes[0]);
|
||||
i--;
|
||||
} else {
|
||||
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
|
||||
img.src = img.src.replace("/tb/", "/");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RE.hideShowBigPic = function() {
|
||||
var imgs = document.getElementsByTagName("img");
|
||||
var j = 0;
|
||||
for (var i = 0; i < imgs.length; i++) {
|
||||
var img = imgs[i];
|
||||
if(img.src.indexOf("/tb/") > 0) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j == 0) {
|
||||
RE.replaceAllDfImage();
|
||||
}
|
||||
}
|
||||
|
||||
RE.replaceDfImageByUrl = function(imgUrl) {
|
||||
var imgs = document.getElementsByTagName("img");
|
||||
for (var i = 0; i < imgs.length; i++) {
|
||||
var img = imgs[i];
|
||||
if (img.src == imgUrl) {
|
||||
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
|
||||
img.src = img.src.replace("/tb/", "/");
|
||||
}
|
||||
}
|
||||
RE.hideShowBigPic();
|
||||
}
|
||||
|
||||
RE.ImageClickListener = function() {
|
||||
var imgs = document.getElementsByTagName("img");
|
||||
for (var i = 0; i < imgs.length; i++) {
|
||||
var img = imgs[i];
|
||||
window.imagelistener.imageArr(img.src);
|
||||
img.onclick = function() {
|
||||
window.imagelistener.imageClick(this.src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RE.insertHTML = function(html) {
|
||||
RE.restorerange();
|
||||
document.execCommand('insertHTML', false, html);
|
||||
}
|
||||
|
||||
RE.insertLink = function(url, title) {
|
||||
RE.restorerange();
|
||||
var sel = document.getSelection();
|
||||
if (sel.toString().length == 0) {
|
||||
document.execCommand("insertHTML",false,"<a href='"+url+"'>"+title+"</a>");
|
||||
} else if (sel.rangeCount) {
|
||||
var el = document.createElement("a");
|
||||
el.setAttribute("href", url);
|
||||
el.setAttribute("title", title);
|
||||
|
||||
var range = sel.getRangeAt(0).cloneRange();
|
||||
range.surroundContents(el);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}
|
||||
RE.callback();
|
||||
}
|
||||
|
||||
RE.setTodo = function(text) {
|
||||
var html = '<input type="checkbox" name="'+ text +'" value="'+ text +'"/> ';
|
||||
document.execCommand('insertHTML', false, html);
|
||||
}
|
||||
|
||||
RE.prepareInsert = function() {
|
||||
RE.backuprange();
|
||||
}
|
||||
|
||||
RE.backuprange = function(){
|
||||
var selection = window.getSelection();
|
||||
if (selection.rangeCount > 0) {
|
||||
var range = selection.getRangeAt(0);
|
||||
RE.currentSelection = {
|
||||
"startContainer": range.startContainer,
|
||||
"startOffset": range.startOffset,
|
||||
"endContainer": range.endContainer,
|
||||
"endOffset": range.endOffset};
|
||||
}
|
||||
}
|
||||
|
||||
RE.restorerange = function(){
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
var range = document.createRange();
|
||||
range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
|
||||
range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
RE.enabledEditingItems = function(e) {
|
||||
var items = [];
|
||||
if (document.queryCommandState('bold')) {
|
||||
items.push('bold');
|
||||
}
|
||||
if (document.queryCommandState('italic')) {
|
||||
items.push('italic');
|
||||
}
|
||||
if (document.queryCommandState('subscript')) {
|
||||
items.push('subscript');
|
||||
}
|
||||
if (document.queryCommandState('superscript')) {
|
||||
items.push('superscript');
|
||||
}
|
||||
if (document.queryCommandState('strikeThrough')) {
|
||||
items.push('strikeThrough');
|
||||
}
|
||||
if (document.queryCommandState('underline')) {
|
||||
items.push('underline');
|
||||
}
|
||||
if (document.queryCommandState('insertOrderedList')) {
|
||||
items.push('orderedList');
|
||||
}
|
||||
if (document.queryCommandState('insertUnorderedList')) {
|
||||
items.push('unorderedList');
|
||||
}
|
||||
if (document.queryCommandState('justifyCenter')) {
|
||||
items.push('justifyCenter');
|
||||
}
|
||||
if (document.queryCommandState('justifyFull')) {
|
||||
items.push('justifyFull');
|
||||
}
|
||||
if (document.queryCommandState('justifyLeft')) {
|
||||
items.push('justifyLeft');
|
||||
}
|
||||
if (document.queryCommandState('justifyRight')) {
|
||||
items.push('justifyRight');
|
||||
}
|
||||
if (document.queryCommandState('insertHorizontalRule')) {
|
||||
items.push('horizontalRule');
|
||||
}
|
||||
var formatBlock = document.queryCommandValue('formatBlock');
|
||||
if (formatBlock.length > 0) {
|
||||
items.push(formatBlock);
|
||||
}
|
||||
|
||||
window.location.href = "re-state://" + encodeURI(items.join(','));
|
||||
}
|
||||
|
||||
RE.focus = function() {
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(RE.editor);
|
||||
range.collapse(false);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
RE.editor.focus();
|
||||
}
|
||||
|
||||
RE.blurFocus = function() {
|
||||
RE.editor.blur();
|
||||
}
|
||||
|
||||
RE.removeFormat = function() {
|
||||
document.execCommand('removeFormat', false, null);
|
||||
}
|
||||
|
||||
// Event Listeners
|
||||
RE.editor.addEventListener("input", RE.callback);
|
||||
RE.editor.addEventListener("keyup", function(e) {
|
||||
var KEY_LEFT = 37, KEY_RIGHT = 39;
|
||||
if (e.which == KEY_LEFT || e.which == KEY_RIGHT) {
|
||||
RE.enabledEditingItems(e);
|
||||
}
|
||||
});
|
||||
RE.editor.addEventListener("click", RE.enabledEditingItems);
|
||||
43
app/src/main/assets/style.css
Normal file
43
app/src/main/assets/style.css
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (C) 2017 Wasabeef
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@charset "UTF-8";
|
||||
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: scroll;
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
min-height:100%;
|
||||
}
|
||||
|
||||
#editor {
|
||||
display: table-cell;
|
||||
outline: 0px solid transparent;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
#editor[placeholder]:empty:not(:focus):before {
|
||||
content: attr(placeholder);
|
||||
opacity: .5;
|
||||
}}
|
||||
BIN
app/src/main/assets/web_load_dfimg_icon.png
Normal file
BIN
app/src/main/assets/web_load_dfimg_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
2
app/src/main/assets/zepto.min.js
vendored
Normal file
2
app/src/main/assets/zepto.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -11,13 +11,12 @@ import android.util.Log;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.util.DataCollectionUtils;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.gamecenter.SplashScreenActivity;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.AppManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.stat.StatService;
|
||||
import com.tendcloud.tenddata.TCAgent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
@ -118,23 +117,7 @@ public class AppUncaughtHandler implements UncaughtExceptionHandler {
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
// MTA主动上传错误
|
||||
try {
|
||||
StatService.reportException(context, throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
// //bugly 作为默认处理异常的类库,已经上报了,此处不重复上报
|
||||
// try {
|
||||
// CrashReport.postCatchedException(throwable);
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
|
||||
//talkingdata
|
||||
try {
|
||||
TCAgent.onError(context, throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
DataUtils.onError(context, throwable);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.arch.lifecycle.Lifecycle;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
@ -15,10 +15,11 @@ import com.gh.common.util.ShareUtils;
|
||||
import com.gh.common.util.StringUtils;
|
||||
import com.gh.gamecenter.LoginActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.SuggestionActivity;
|
||||
import com.gh.gamecenter.eventbus.EBShowDialog;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.AppManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.tauth.Tencent;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
@ -26,92 +27,96 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
|
||||
import static com.gh.common.util.EntranceUtils.KEY_DATA;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
|
||||
|
||||
public abstract class BaseActivity extends BaseAppCompatToolBarActivity implements EasyPermissions.PermissionCallbacks{
|
||||
public abstract class BaseActivity extends BaseToolBarActivity implements EasyPermissions.PermissionCallbacks {
|
||||
|
||||
protected String mEntrance;
|
||||
|
||||
private boolean mIsPause;
|
||||
private boolean mIsExistLogoutDialog;
|
||||
|
||||
protected final Handler mBaseHandler = new BaseHandler(this);
|
||||
|
||||
protected static class BaseHandler extends Handler {
|
||||
private final WeakReference<BaseActivity> mActivityWeakReference;
|
||||
|
||||
BaseHandler(BaseActivity activity) {
|
||||
mActivityWeakReference = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
BaseActivity activity = mActivityWeakReference.get();
|
||||
if (activity != null) activity.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleMessage(Message msg) {
|
||||
|
||||
}
|
||||
|
||||
//接收QQ或者QQ空间分享回调
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == com.tencent.connect.common.Constants.REQUEST_QQ_SHARE
|
||||
|| requestCode == com.tencent.connect.common.Constants.REQUEST_QZONE_SHARE) {
|
||||
Tencent.onActivityResultData(requestCode, resultCode, data, ShareUtils.getInstance(this).QqShareListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
init(mContentView);
|
||||
AppManager.getInstance().addActivity(this);
|
||||
EventBus.getDefault().register(this);
|
||||
ButterKnife.bind(this);
|
||||
mEntrance = getIntent().getStringExtra(KEY_ENTRANCE);
|
||||
if (getIntent().getBundleExtra(KEY_DATA) != null) {
|
||||
mEntrance = getIntent().getBundleExtra(KEY_DATA).getString(KEY_ENTRANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
mBaseHandler.removeCallbacksAndMessages(null);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onNavigationIconClicked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void init(View contentView) {
|
||||
setContentView(contentView);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
View back = findViewById(R.id.actionbar_rl_back);
|
||||
if (back != null)
|
||||
back.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void initTitle(String title) {
|
||||
TextView actionbar_tv_title = (TextView) findViewById(R.id.actionbar_tv_title);
|
||||
actionbar_tv_title.setText(title);
|
||||
// setNavigationTitle(title);
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void toast(String msg) {
|
||||
Utils.toast(this, msg);
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
|
||||
Utils.toast(this, msg);
|
||||
}
|
||||
|
||||
public void toast(int msg) {
|
||||
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
|
||||
toast(getString(msg));
|
||||
}
|
||||
|
||||
//如果是游戏分享,newsTitle默认为空
|
||||
public void showShare(String url, String gameName, String icon, String newsTitle, ArrayList<String> tag, boolean isToolsBox) {
|
||||
public void showShare(String url, String icon, String shareTitle, String shareSummary, ShareUtils.ShareType shareType) {
|
||||
|
||||
//判断是否是官方版
|
||||
boolean isPlugin = false;
|
||||
if (tag != null) {
|
||||
for (String s : tag) {
|
||||
if (!"官方版".equals(s)) {
|
||||
isPlugin = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ShareUtils.getInstance(this).showShareWindows(this, getWindow().getDecorView(), url, icon, shareTitle, shareSummary, shareType);
|
||||
|
||||
ShareUtils.getInstance(this).showShareWindows(getWindow().getDecorView(), url, gameName, icon, newsTitle, isPlugin, true, isToolsBox);
|
||||
|
||||
if (newsTitle == null) {
|
||||
DataUtils.onEvent(this, "内容分享", gameName);
|
||||
if (shareType == ShareUtils.ShareType.game || shareType == ShareUtils.ShareType.plugin) {
|
||||
DataUtils.onEvent(this, "内容分享", shareTitle + shareSummary);
|
||||
} else {
|
||||
DataUtils.onEvent(this, "内容分享", newsTitle);
|
||||
DataUtils.onEvent(this, "内容分享", shareTitle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(final EBShowDialog showDialog) {
|
||||
//TODO 改为缓存到UI可见时才调用,参考beier-assist
|
||||
if (!mIsPause && this.getClass().getName().equals(RunningUtils.getTopActivity(this))) {
|
||||
if ("hijack".equals(showDialog.getType())) {
|
||||
DialogUtils.showQqSessionDialog(this, "2586716223");// 建议用户联系客服
|
||||
@ -120,13 +125,15 @@ public abstract class BaseActivity extends BaseAppCompatToolBarActivity implemen
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
if (FileUtils.isEmptyFile(showDialog.getPath())) {
|
||||
Utils.toast(BaseActivity.this, getString(R.string.install_failure_hint));
|
||||
toast(R.string.install_failure_hint);
|
||||
} else {
|
||||
startActivity(PackageUtils.getUninstallIntent(BaseActivity.this, showDialog.getPath()));
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if ("loginException".equals(showDialog.getType())) {
|
||||
if (mIsExistLogoutDialog) return;
|
||||
mIsExistLogoutDialog = true;
|
||||
try {
|
||||
JSONObject object = new JSONObject(showDialog.getPath());
|
||||
JSONObject device = object.getJSONObject("device");
|
||||
@ -135,41 +142,36 @@ public abstract class BaseActivity extends BaseAppCompatToolBarActivity implemen
|
||||
DialogUtils.showAlertDialog(this, "你的账号已在另外一台设备登录"
|
||||
, StringUtils.buildString("(", manufacturer, " - ", model, ")")
|
||||
, "知道了", "重新登录"
|
||||
, null, new DialogUtils.CancelListener() {
|
||||
@Override
|
||||
public void onCancel() {
|
||||
startActivity(LoginActivity.getIntent(BaseActivity.this, false));
|
||||
}
|
||||
});
|
||||
, null
|
||||
, () -> startActivity(LoginActivity.getIntent(BaseActivity.this))
|
||||
);
|
||||
mBaseHandler.postDelayed(() -> mIsExistLogoutDialog = false, 5000);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
} else if ("notfound".equals(showDialog.getType())) {
|
||||
DialogUtils.showAlertDialog(this, "下载失败", "下载链接已失效,建议提交反馈"
|
||||
, "立即反馈", "取消"
|
||||
, () -> {
|
||||
SuggestionActivity.startSuggestionActivity(this, 4,
|
||||
null, showDialog.getPath() + ",问题反馈:下载链接失效");
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
EventBus.getDefault().unregister(this);
|
||||
AppManager.getInstance().finishActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
// DataUtils.onPause(this);
|
||||
mIsPause = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// DataUtils.onResume(this);
|
||||
mIsPause = false;
|
||||
// DownloadManager.getInstance(this).initGameMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
import com.lightgame.BaseAppCompatActivity;
|
||||
|
||||
/**
|
||||
* Created by csheng on 15-10-12.
|
||||
*/
|
||||
|
||||
public abstract class BaseAppCompatToolBarActivity extends BaseAppCompatActivity {
|
||||
|
||||
private Toolbar mToolbar;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
initToolbar();
|
||||
}
|
||||
|
||||
private void initToolbar() {
|
||||
mToolbar = (Toolbar) findViewById(R.id.toolbar_navigation);
|
||||
if (mToolbar != null) {
|
||||
setSupportActionBar(mToolbar);
|
||||
mToolbar.addView(View.inflate(this, R.layout.reuse_actionbar, null));
|
||||
getSupportActionBar().setHomeButtonEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
return onNavigationIconClicked();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
protected abstract boolean onNavigationIconClicked();
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ import butterknife.ButterKnife;
|
||||
|
||||
public abstract class BaseRecyclerViewHolder<T> extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
|
||||
private T data;
|
||||
private T mData;
|
||||
private OnListClickListener mListClickListener;
|
||||
|
||||
public BaseRecyclerViewHolder(View itemView) {
|
||||
@ -25,19 +25,33 @@ public abstract class BaseRecyclerViewHolder<T> extends RecyclerView.ViewHolder
|
||||
|
||||
/**
|
||||
* 具体的设置监听在childViewHolder 设置
|
||||
*
|
||||
* @param itemView
|
||||
* @param data 一般情况下只传列表数据
|
||||
* @param listClickListener 列表事件接口
|
||||
*/
|
||||
public BaseRecyclerViewHolder(View itemView, T data, OnListClickListener listClickListener) {
|
||||
this(itemView);
|
||||
this.data = data;
|
||||
this.mData = data;
|
||||
this.mListClickListener = listClickListener;
|
||||
}
|
||||
|
||||
public BaseRecyclerViewHolder(View itemView, OnListClickListener listClickListener) {
|
||||
this(itemView);
|
||||
this.mListClickListener = listClickListener;
|
||||
}
|
||||
|
||||
public void setClickData(T clickData) {
|
||||
this.mData = clickData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mListClickListener.onListClick(view, getAdapterPosition(), data);
|
||||
try {
|
||||
mListClickListener.onListClick(view, getAdapterPosition(), mData);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
111
app/src/main/java/com/gh/base/BaseToolBarActivity.java
Normal file
111
app/src/main/java/com/gh/base/BaseToolBarActivity.java
Normal file
@ -0,0 +1,111 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.normal.ToolbarController;
|
||||
import com.lightgame.BaseAppCompatActivity;
|
||||
import com.lightgame.OnTitleClickListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by csheng on 15-10-12.
|
||||
*/
|
||||
|
||||
public abstract class BaseToolBarActivity extends BaseAppCompatActivity implements ToolbarController, Toolbar.OnMenuItemClickListener {
|
||||
|
||||
private Toolbar mToolbar;
|
||||
private TextView mTitleTv;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
initToolbar();
|
||||
}
|
||||
|
||||
private void initToolbar() {
|
||||
mToolbar = findViewById(R.id.normal_toolbar);
|
||||
mTitleTv = findViewById(R.id.normal_title);
|
||||
if (mToolbar != null) {
|
||||
// setSupportActionBar(mToolbar); // 替换actionBar后 toolBar无法控制
|
||||
mToolbar.setNavigationIcon(provideNavigationIcon());
|
||||
mToolbar.setNavigationOnClickListener(view -> onBackPressed());
|
||||
mTitleTv.setOnClickListener(view -> {
|
||||
final List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
|
||||
for (Fragment fragment : fragmentList) {
|
||||
if (fragment instanceof OnTitleClickListener) {
|
||||
((OnTitleClickListener) fragment).onTitleClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
public int provideNavigationIcon() {
|
||||
return R.drawable.ic_bar_back; // default navigation icon
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNavigationTitle(String title) {
|
||||
if (mTitleTv != null) mTitleTv.setText(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNavigationTitle(@StringRes int res) {
|
||||
setNavigationTitle(getString(res));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToolbarMenu(int res) {
|
||||
if (mToolbar == null) return;
|
||||
mToolbar.inflateMenu(res);
|
||||
mToolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
Menu menu = mToolbar.getMenu();
|
||||
for (int i = 0; i < menu.size(); i++) {
|
||||
MenuItem menuItem = menu.getItem(i);
|
||||
// menu设置actionLayout后,无法捕捉点击事件,以icon为tag,如果icon is null 手动设置menuItem点击事件
|
||||
if (menuItem != null && menuItem.getIcon() == null) {
|
||||
if (menuItem.getActionView() != null) {
|
||||
menuItem.getActionView().setOnClickListener((v) -> this.onMenuItemClick(menuItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuItem getMenuItem(int res) {
|
||||
if (mToolbar == null) return null; //后续页面做好判断
|
||||
return mToolbar.getMenu().findItem(res);
|
||||
}
|
||||
|
||||
public Menu getMenu() {
|
||||
return mToolbar.getMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
return onNavigationIconClicked();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
protected abstract boolean onNavigationIconClicked();
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ import android.os.Bundle;
|
||||
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.lightgame.utils.AppManager;
|
||||
|
||||
/**
|
||||
* 1、写点针对生命周期的统计代码
|
||||
@ -18,10 +19,10 @@ import com.gh.download.DownloadManager;
|
||||
*/
|
||||
public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallbacks {
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
|
||||
AppManager.getInstance().addActivity(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -33,6 +34,7 @@ public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallba
|
||||
public void onActivityResumed(Activity activity) {
|
||||
|
||||
DataUtils.onResume(activity);
|
||||
//FIXME 这里应该只是部分Activity需要
|
||||
try {
|
||||
// 初始化gameMap
|
||||
DownloadManager.getInstance(activity).initGameMap();
|
||||
@ -58,7 +60,7 @@ public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallba
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
|
||||
AppManager.getInstance().finishActivity(activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,322 +0,0 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.gh.common.util.AppDebugConfig;
|
||||
import com.gh.common.util.EntranceUtils;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.TokenUtils;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.xiaomi.mipush.sdk.ErrorCode;
|
||||
import com.xiaomi.mipush.sdk.MiPushClient;
|
||||
import com.xiaomi.mipush.sdk.MiPushCommandMessage;
|
||||
import com.xiaomi.mipush.sdk.MiPushMessage;
|
||||
import com.xiaomi.mipush.sdk.PushMessageReceiver;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.gh.common.util.EntranceUtils.ENTRANCE_MIPUSH;
|
||||
import static com.gh.common.util.EntranceUtils.HOST_ARTICLE;
|
||||
import static com.gh.common.util.EntranceUtils.HOST_GAME;
|
||||
import static com.gh.common.util.EntranceUtils.HOST_WEB;
|
||||
import static com.gh.common.util.EntranceUtils.HOST_COLUMN;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_GAMEID;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_ID;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_NEWSID;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_TARGET;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_TO;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_TYPE;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_URL;
|
||||
|
||||
/**
|
||||
* 1、PushMessageReceiver是个抽象类,该类继承了BroadcastReceiver。
|
||||
* 2、需要将自定义的DemoMessageReceiver注册在AndroidManifest.xml文件中 <receiver
|
||||
* android:exported="true"
|
||||
* android:name="com.xiaomi.mipushdemo.DemoMessageReceiver"> <intent-filter>
|
||||
* <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" /> </intent-filter>
|
||||
* <intent-filter> <action android:name="com.xiaomi.mipush.ERROR" />
|
||||
* </intent-filter> <intent-filter> <action
|
||||
* android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" /></intent-filter>
|
||||
* </receiver>
|
||||
* 3、DemoMessageReceiver的onReceivePassThroughMessage方法用来接收服务器向客户端发送的透传消息
|
||||
* 4、DemoMessageReceiver的onNotificationMessageClicked方法用来接收服务器向客户端发送的通知消息,
|
||||
* 这个回调方法会在用户手动点击通知后触发
|
||||
* 5、DemoMessageReceiver的onNotificationMessageArrived方法用来接收服务器向客户端发送的通知消息,
|
||||
* 这个回调方法是在通知消息到达客户端时触发。另外应用在前台时不弹出通知的通知消息到达客户端也会触发这个回调函数
|
||||
* 6、DemoMessageReceiver的onCommandResult方法用来接收客户端向服务器发送命令后的响应结果
|
||||
* 7、DemoMessageReceiver的onReceiveRegisterResult方法用来接收客户端向服务器发送注册命令后的响应结果
|
||||
* 8、以上这些方法运行在非UI线程中
|
||||
*
|
||||
* @author mayixiang
|
||||
* //TODO 请勿更改此类路径,若需更改时请注意更改./libraries/MiPush/proguard-library.txt混淆对应配置
|
||||
*/
|
||||
public class GHPushMessageReceiver extends PushMessageReceiver {
|
||||
|
||||
private String mAlias;
|
||||
|
||||
@Override
|
||||
public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
AppDebugConfig.logMethodWithParams(this, message);
|
||||
}
|
||||
// 1判断notifyid是否为4
|
||||
try {
|
||||
//TODO what is magic number 4?
|
||||
if (message.getNotifyId() == 4) {
|
||||
JSONObject jsonObject = new JSONObject(message.getContent());
|
||||
Utils.log(jsonObject.toString());
|
||||
String channel = jsonObject.getString("channel");
|
||||
Utils.log("channel = " + channel);
|
||||
|
||||
// 1判断渠道号是否一致或是否为ALL
|
||||
String packageChannel = HaloApp.getInstance().getChannel();
|
||||
if ("ALL".equals(channel) || channel.equalsIgnoreCase(packageChannel)) {
|
||||
String type = jsonObject.getString(KEY_TYPE);
|
||||
Utils.log("type = " + type);
|
||||
JSONArray jsonArray;
|
||||
ArrayMap<String, Boolean> map;
|
||||
switch (type) {
|
||||
case "NEWS":
|
||||
// 新闻推送
|
||||
jsonArray = jsonObject.getJSONArray("package");
|
||||
map = getInstalledMapFromLocal(context);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
Boolean b = map.get(jsonArray.getString(i));
|
||||
if (b != null) {
|
||||
// 显示推送的消息
|
||||
showNotification(context, jsonObject, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "PLUGIN_UPDATE":
|
||||
// 插件更新推送
|
||||
jsonArray = jsonObject.getJSONArray("apk");
|
||||
map = getInstalledMapFromLocal(context);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject apk = jsonArray.getJSONObject(i);
|
||||
String packageName = apk.getString("package");
|
||||
Boolean b = map.get(packageName);
|
||||
if (b != null) {
|
||||
// 判断是否gh_version是否相同
|
||||
String gh_version = (String) PackageUtils
|
||||
.getMetaData(context, packageName, "gh_version");
|
||||
if (gh_version != null) {
|
||||
gh_version = gh_version.substring(2);
|
||||
// 判断gh_version是否相同
|
||||
if (gh_version.equals(apk.getString("gh_version"))) {
|
||||
// 判断version是否相同
|
||||
String version = PackageUtils.getVersionByPackage(context, packageName);
|
||||
if (apk.getString("version").equals(version)) {
|
||||
// 版本相同,无需显示插件更新,继续查看是否有可更新的游戏包
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 显示推送的消息
|
||||
showNotification(context, jsonObject, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "NEW_GAME":
|
||||
// 新游推送
|
||||
showNotification(context, jsonObject, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayMap<String, Boolean> getInstalledMapFromLocal(Context context) {
|
||||
ArrayMap<String, Boolean> map = new ArrayMap<>();
|
||||
ArrayList<String> list = getAllPackageName(context);
|
||||
for (String str : list) {
|
||||
map.put(str, true);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void showNotification(Context context, JSONObject jsonObject, int id) throws JSONException {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.gh.gamecenter.NOTIFICATION");
|
||||
intent.putExtra("notifyId", id);
|
||||
intent.putExtra("notifyData", jsonObject.toString());
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
|
||||
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
RemoteViews remoteViews = null;
|
||||
|
||||
if (Build.MANUFACTURER.equals("Meizu") &&
|
||||
(Build.MODEL.startsWith("m") || Build.MODEL.startsWith("MX"))) {
|
||||
remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_meizu);
|
||||
SimpleDateFormat format = new SimpleDateFormat("HH:mm", Locale.getDefault());
|
||||
remoteViews.setTextViewText(R.id.time, format.format(new Date()));
|
||||
} else if (Build.MANUFACTURER.equals("Xiaomi") &&
|
||||
(Build.MODEL.startsWith("MI") || Build.MODEL.startsWith("HM") || Build.MODEL.startsWith("Redmi"))) {
|
||||
// 小米系统
|
||||
remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_xiaomi);
|
||||
SimpleDateFormat format = new SimpleDateFormat("ah:mm", Locale.getDefault());
|
||||
remoteViews.setTextViewText(R.id.time, format.format(new Date()));
|
||||
} else if (Build.MANUFACTURER.equals("HUAWEI")) {
|
||||
// 华为系统
|
||||
remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_huawei);
|
||||
}
|
||||
|
||||
String url = jsonObject.getString("icon");
|
||||
String path = context.getCacheDir() + File.separator + url.substring(url.lastIndexOf("/") + 1);
|
||||
int result = FileUtils.downloadFile(url, path);
|
||||
if (result != 200) {
|
||||
// 下载出错,使用光环logo
|
||||
path = null;
|
||||
}
|
||||
|
||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setTicker(jsonObject.getString("pushTitle"))
|
||||
.setContentTitle(jsonObject.getString("pushTitle"))
|
||||
.setContentText(jsonObject.getString("pushDesc"))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setDefaults(Notification.DEFAULT_SOUND) // 添加系统默认声音
|
||||
.setAutoCancel(true); // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。
|
||||
|
||||
if (remoteViews != null) {
|
||||
if (path == null) {
|
||||
remoteViews.setImageViewBitmap(R.id.icon, BitmapFactory.decodeResource(context.getResources(), R.drawable.logo));
|
||||
} else {
|
||||
remoteViews.setImageViewBitmap(R.id.icon, BitmapFactory.decodeFile(path));
|
||||
}
|
||||
remoteViews.setTextViewText(R.id.title, jsonObject.getString("pushTitle"));
|
||||
remoteViews.setTextViewText(R.id.intro, jsonObject.getString("pushDesc"));
|
||||
|
||||
builder.setSmallIcon(R.drawable.logo);
|
||||
builder.setCustomContentView(remoteViews);
|
||||
|
||||
} else {
|
||||
builder.setSmallIcon(R.drawable.logo_black);
|
||||
if (path == null) {
|
||||
builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.logo));
|
||||
} else {
|
||||
builder.setLargeIcon(BitmapFactory.decodeFile(path));
|
||||
}
|
||||
}
|
||||
|
||||
nManager.notify(((int) System.currentTimeMillis() / 1000), builder.build());// 通过通知管理器来发起通知。如果id不同,则每click,在status哪里增加一个提示
|
||||
}
|
||||
|
||||
private ArrayList<String> getAllPackageName(Context context) {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
List<PackageInfo> packageInfos = context.getPackageManager().getInstalledPackages(0);
|
||||
for (PackageInfo packageInfo : packageInfos) {
|
||||
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
list.add(packageInfo.packageName);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationMessageClicked(Context context, MiPushMessage message) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
AppDebugConfig.logMethodWithParams(this, message);
|
||||
}
|
||||
try {
|
||||
String content = message.getContent();
|
||||
JSONObject response = new JSONObject(content);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTRANCE, ENTRANCE_MIPUSH);
|
||||
String type = response.getString(KEY_TYPE);
|
||||
String target = response.getString(KEY_TARGET);
|
||||
|
||||
switch (type) {
|
||||
case HOST_ARTICLE:
|
||||
bundle.putString(KEY_TO, "NewsDetailActivity");
|
||||
bundle.putString(KEY_NEWSID, target);
|
||||
break;
|
||||
case HOST_GAME:
|
||||
bundle.putString(KEY_TO, "GameDetailActivity");
|
||||
bundle.putString(KEY_GAMEID, target);
|
||||
break;
|
||||
case HOST_COLUMN:
|
||||
bundle.putString(KEY_TO, "SubjectActivity");
|
||||
bundle.putString(KEY_ID, target);
|
||||
break;
|
||||
case HOST_WEB:
|
||||
bundle.putString(KEY_TO, "WebActivity");
|
||||
bundle.putString(KEY_URL, target);
|
||||
break;
|
||||
}
|
||||
EntranceUtils.jumpActivity(context, bundle);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationMessageArrived(Context context, MiPushMessage message) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
AppDebugConfig.logMethodWithParams(this, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
AppDebugConfig.logMethodWithParams(this, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandResult(Context context, MiPushCommandMessage message) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
AppDebugConfig.logMethodWithParams(this, message);
|
||||
}
|
||||
|
||||
String command = message.getCommand();
|
||||
List<String> arguments = message.getCommandArguments();
|
||||
|
||||
if (MiPushClient.COMMAND_SET_ALIAS.equals(command)) {
|
||||
if (message.getResultCode() == ErrorCode.SUCCESS) {
|
||||
mAlias = arguments.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(mAlias)) {
|
||||
//添加别名
|
||||
MiPushClient.setAlias(context, TokenUtils.getDeviceId(context), null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,6 +4,10 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.gh.common.util.EntranceUtils;
|
||||
import com.gh.gamecenter.GameDetailActivity;
|
||||
import com.gh.gamecenter.NewsDetailActivity;
|
||||
import com.gh.gamecenter.SubjectActivity;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
import com.umeng.message.UmengNotificationClickHandler;
|
||||
import com.umeng.message.entity.UMessage;
|
||||
|
||||
@ -26,19 +30,19 @@ public class GHUmengNotificationClickHandler extends UmengNotificationClickHandl
|
||||
String target = response.getString(EntranceUtils.KEY_TARGET);
|
||||
switch (type) {
|
||||
case EntranceUtils.HOST_ARTICLE:
|
||||
bundle.putString(EntranceUtils.KEY_TO, "NewsDetailActivity");
|
||||
bundle.putString(EntranceUtils.KEY_TO, NewsDetailActivity.class.getSimpleName());
|
||||
bundle.putString(EntranceUtils.KEY_NEWSID, target);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME:
|
||||
bundle.putString(EntranceUtils.KEY_TO, "GameDetailActivity");
|
||||
bundle.putString(EntranceUtils.KEY_TO, GameDetailActivity.class.getSimpleName());
|
||||
bundle.putString(EntranceUtils.KEY_GAMEID, target);
|
||||
break;
|
||||
case EntranceUtils.HOST_COLUMN:
|
||||
bundle.putString(EntranceUtils.KEY_TO, "SubjectActivity");
|
||||
bundle.putString(EntranceUtils.KEY_TO, SubjectActivity.class.getSimpleName());
|
||||
bundle.putString(EntranceUtils.KEY_ID, target);
|
||||
break;
|
||||
case EntranceUtils.HOST_WEB:
|
||||
bundle.putString(EntranceUtils.KEY_TO, "WebActivity");
|
||||
bundle.putString(EntranceUtils.KEY_TO, WebActivity.class.getSimpleName());
|
||||
bundle.putString(EntranceUtils.KEY_URL, target);
|
||||
break;
|
||||
}
|
||||
|
||||
7
app/src/main/java/com/gh/base/OnViewClickListener.java
Normal file
7
app/src/main/java/com/gh/base/OnViewClickListener.java
Normal file
@ -0,0 +1,7 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface OnViewClickListener {
|
||||
void onClick(View v, Object data);
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
//package com.gh.base;
|
||||
//
|
||||
//import java.io.Serializable;
|
||||
//
|
||||
//public enum SuggestionType implements Serializable {
|
||||
//
|
||||
// FEEDBACK("普通反馈", 1),
|
||||
// SUGGESTION("功能建议", 2),
|
||||
// CRASH("发生闪退", 3),
|
||||
// GAME("游戏问题", 4),
|
||||
// COLLECT("游戏收录", 5),
|
||||
// POST("文章投稿", 6);
|
||||
//
|
||||
// private String mName;
|
||||
// private int mIndex;
|
||||
//
|
||||
// private SuggestionType(String name, int index) {
|
||||
// mName = name;
|
||||
// mIndex = index;
|
||||
// }
|
||||
//
|
||||
// public static String getName(int index) {
|
||||
// for (SuggestionType c : SuggestionType.values()) {
|
||||
// if (c.mIndex == index) {
|
||||
// return c.mName;
|
||||
// }
|
||||
// }
|
||||
// return "";
|
||||
// }
|
||||
//
|
||||
// public static int getIndex(String name) {
|
||||
// for (SuggestionType c : SuggestionType.values()) {
|
||||
// if (c.mName == name) {
|
||||
// return c.mIndex;
|
||||
// }
|
||||
// }
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// public int getIndex() {
|
||||
// return mIndex;
|
||||
// }
|
||||
//
|
||||
// public String getName() {
|
||||
// return mName;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.base.adapter;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
@ -14,11 +15,19 @@ public class FragmentAdapter extends FragmentPagerAdapter {
|
||||
|
||||
private List<Fragment> mFragmentList;
|
||||
|
||||
private List<String> mTitleList;
|
||||
|
||||
public FragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) {
|
||||
super(fm);
|
||||
this.mFragmentList = fragmentList;
|
||||
}
|
||||
|
||||
public FragmentAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> titleList) {
|
||||
super(fm);
|
||||
this.mFragmentList = fragmentList;
|
||||
this.mTitleList = titleList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return mFragmentList.get(position);
|
||||
@ -29,4 +38,12 @@ public class FragmentAdapter extends FragmentPagerAdapter {
|
||||
return mFragmentList.size();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
if (mTitleList != null && mTitleList.size() > position) {
|
||||
return mTitleList.get(position);
|
||||
}
|
||||
return super.getPageTitle(position);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.gh.base.adapter;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by khy on 7/12/28.
|
||||
*/
|
||||
public class FragmentStateAdapter extends FragmentStatePagerAdapter {
|
||||
|
||||
private List<Fragment> mFragmentList;
|
||||
|
||||
public FragmentStateAdapter(FragmentManager fm, List<Fragment> fragmentList) {
|
||||
super(fm);
|
||||
this.mFragmentList = fragmentList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return mFragmentList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mFragmentList.size();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.arch.lifecycle.Lifecycle;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.gh.common.util.ClickUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.lightgame.utils.RuntimeUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
* @Date 17/05/2017
|
||||
* @Time 4:30 PM
|
||||
*/
|
||||
|
||||
public class BaseDialogFragment extends DialogFragment {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Dialog dialog = new Dialog(getActivity(), R.style.DialogWindowTransparent);
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && ClickUtils.isFastDoubleClick()) { //会多次响应??
|
||||
return onBack();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
dialog.setCancelable(false);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public void toast(@StringRes int res) {
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
|
||||
toast(getString(res));
|
||||
}
|
||||
|
||||
public void toast(String msg) {
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
|
||||
Utils.toast(getContext(), msg);
|
||||
}
|
||||
|
||||
public void toastLong(@StringRes int msg) {
|
||||
toastLong(getString(msg));
|
||||
}
|
||||
|
||||
public void toastLong(String msg) {
|
||||
RuntimeUtils.getInstance().toastLong(getContext(), msg);
|
||||
}
|
||||
|
||||
public boolean onBack() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
/**
|
||||
* Wrap another fragment with dialog fragment.
|
||||
*/
|
||||
public class BaseDialogWrapperFragment extends BaseDialogFragment {
|
||||
|
||||
private Fragment mFragmentToWrap;
|
||||
|
||||
public static BaseDialogWrapperFragment getInstance(Fragment fragmentToWrap) {
|
||||
BaseDialogWrapperFragment fragment = new BaseDialogWrapperFragment();
|
||||
fragment.mFragmentToWrap = fragmentToWrap;
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static BaseDialogWrapperFragment getInstance(Fragment fragmentToWrap, boolean isCancelable) {
|
||||
BaseDialogWrapperFragment fragment = new BaseDialogWrapperFragment();
|
||||
fragment.mFragmentToWrap = fragmentToWrap;
|
||||
fragment.setCancelable(isCancelable);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_dialog_wrapper, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (mFragmentToWrap != null) {
|
||||
getChildFragmentManager().beginTransaction().replace(R.id.fragment_placeholder, mFragmentToWrap).commitNowAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
getDialog().getWindow().setGravity(Gravity.BOTTOM);
|
||||
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||
dialog.setCanceledOnTouchOutside(true);
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,23 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
import android.arch.lifecycle.Lifecycle;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.gh.base.OnListClickListener;
|
||||
import com.gh.base.OnRequestCallBackListener;
|
||||
import com.gh.common.util.EntranceUtils;
|
||||
import com.gh.gamecenter.eventbus.EBMiPush;
|
||||
import com.lightgame.OnTitleClickListener;
|
||||
import com.lightgame.utils.RuntimeUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
@ -19,28 +25,60 @@ import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/9/4.
|
||||
* Fragment 基类
|
||||
*/
|
||||
public abstract class BaseFragment<T> extends Fragment implements OnRequestCallBackListener<T>,
|
||||
View.OnClickListener, OnListClickListener{
|
||||
View.OnClickListener, OnListClickListener, OnTitleClickListener {
|
||||
|
||||
// TODO private view
|
||||
protected View view;
|
||||
protected View mCachedView;
|
||||
|
||||
protected boolean isEverPause;
|
||||
|
||||
protected String mEntrance;
|
||||
|
||||
protected final Handler mBaseHandler = new BaseFragment.BaseHandler(this);
|
||||
|
||||
protected static class BaseHandler extends Handler {
|
||||
private final WeakReference<BaseFragment> mFragmentWeakReference;
|
||||
|
||||
BaseHandler(BaseFragment fragment) {
|
||||
mFragmentWeakReference = new WeakReference<>(fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
BaseFragment fragment = mFragmentWeakReference.get();
|
||||
if (fragment != null) fragment.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleMessage(Message msg) {
|
||||
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
protected abstract int getLayoutId();
|
||||
|
||||
/**
|
||||
* 提供 Inflated 的 view ,可用于 data binding.
|
||||
*/
|
||||
protected View getInflatedLayout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 责任链,谁处理了就返回true,否则返回super.handleOnClick(View view)
|
||||
*
|
||||
@ -55,6 +93,7 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
handleOnClick(v);
|
||||
}
|
||||
|
||||
|
||||
protected void initView(View view) {
|
||||
}
|
||||
|
||||
@ -70,12 +109,21 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mEntrance = getActivity().getIntent().getStringExtra(EntranceUtils.KEY_ENTRANCE);
|
||||
final Intent intent = getActivity().getIntent();
|
||||
mEntrance = intent.getStringExtra(KEY_ENTRANCE);
|
||||
|
||||
isEverPause = false;
|
||||
EventBus.getDefault().register(this);
|
||||
view = View.inflate(getContext(), getLayoutId(), null);
|
||||
ButterKnife.bind(this, view);
|
||||
initView(view);
|
||||
|
||||
// For data binding.
|
||||
if (getInflatedLayout() != null) {
|
||||
mCachedView = getInflatedLayout();
|
||||
} else {
|
||||
mCachedView = View.inflate(getContext(), getLayoutId(), null);
|
||||
}
|
||||
ButterKnife.bind(this, mCachedView);
|
||||
|
||||
initView(mCachedView);
|
||||
}
|
||||
|
||||
//TODO 尴尬,必须的有subscribe才能register
|
||||
@ -88,9 +136,9 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
if (container != null) {
|
||||
container.removeView(view);
|
||||
container.removeView(mCachedView);
|
||||
}
|
||||
return view;
|
||||
return mCachedView;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -108,12 +156,27 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mBaseHandler.removeCallbacksAndMessages(null);
|
||||
RuntimeUtils.getInstance().removeRunnable();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
public void toast(@StringRes int res) {
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
|
||||
toast(getString(res));
|
||||
}
|
||||
|
||||
public void toast(String msg) {
|
||||
Utils.toast(getContext(), msg);
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
|
||||
Utils.toast(getContext(), msg);
|
||||
}
|
||||
|
||||
public void toastLong(@StringRes int msg) {
|
||||
toastLong(getString(msg));
|
||||
}
|
||||
|
||||
public void toastLong(String msg) {
|
||||
RuntimeUtils.getInstance().toastLong(getContext(), msg);
|
||||
}
|
||||
|
||||
public boolean isEverPause() {
|
||||
@ -126,7 +189,7 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadDone(Object obj) {
|
||||
public void loadDone(T obj) {
|
||||
|
||||
}
|
||||
|
||||
@ -141,7 +204,7 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void onListClick(View view, int position, T data) {
|
||||
public <LIST> void onListClick(View view, int position, LIST data) {
|
||||
|
||||
}
|
||||
|
||||
@ -149,4 +212,22 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
|
||||
}
|
||||
|
||||
// 将所有的Fragment都置为隐藏状态。
|
||||
protected void hideFragments(FragmentTransaction transaction) {
|
||||
List<Fragment> list = getChildFragmentManager().getFragments();
|
||||
for (Fragment fragment : list) {
|
||||
transaction.hide(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTitleClick() {
|
||||
List<Fragment> list = getChildFragmentManager().getFragments();
|
||||
for (Fragment fragment : list) {
|
||||
if (fragment instanceof OnTitleClickListener) {
|
||||
((OnTitleClickListener) fragment).onTitleClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.View;
|
||||
|
||||
import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.lightgame.view.NoScrollableViewPager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
|
||||
/**
|
||||
* Created by khy on 15/03/18.
|
||||
*/
|
||||
|
||||
public abstract class BaseFragment_TabLayout extends NormalFragment implements ViewPager.OnPageChangeListener {
|
||||
|
||||
public static final String PAGE_INDEX = "PAGE_INDEX";
|
||||
|
||||
@BindView(R.id.fragment_tab_layout)
|
||||
protected TabLayout mTabLayout;
|
||||
@BindView(R.id.fragment_view_pager)
|
||||
protected NoScrollableViewPager mViewPager;
|
||||
@BindView(R.id.fragment_tab_indicator)
|
||||
protected TabIndicatorView mTabIndicatorView;
|
||||
|
||||
protected List<Fragment> mFragmentsList;
|
||||
|
||||
protected List<String> mTabTitleList;
|
||||
|
||||
protected int mCheckedIndex = 0;
|
||||
|
||||
protected abstract void initFragmentList(List<Fragment> fragments);
|
||||
|
||||
protected abstract void initTabTitleList(List<String> tabTitleList);
|
||||
|
||||
protected int provideIndicatorWidth() {
|
||||
return 65;
|
||||
}
|
||||
|
||||
protected View provideTabView(int position, String tabTitle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.fragment_taglyout_viewpager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) mCheckedIndex = getArguments().getInt(PAGE_INDEX, 0);
|
||||
mFragmentsList = new ArrayList<>();
|
||||
initFragmentList(mFragmentsList);
|
||||
mTabTitleList = new ArrayList<>();
|
||||
initTabTitleList(mTabTitleList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mViewPager.setOffscreenPageLimit(mFragmentsList.size());
|
||||
mViewPager.addOnPageChangeListener(this);
|
||||
mViewPager.setAdapter(new FragmentAdapter(getChildFragmentManager(), mFragmentsList, mTabTitleList));
|
||||
mViewPager.setCurrentItem(mCheckedIndex);
|
||||
mTabLayout.setupWithViewPager(mViewPager);
|
||||
mTabIndicatorView.setupWithTabLayout(mTabLayout);
|
||||
mTabIndicatorView.setupWithViewPager(mViewPager);
|
||||
mTabIndicatorView.setIndicatorWidth(provideIndicatorWidth());
|
||||
|
||||
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
|
||||
TabLayout.Tab tab = mTabLayout.getTabAt(i);
|
||||
if (tab == null) continue;
|
||||
View tabView = provideTabView(i, tab.getText() != null ? tab.getText().toString() : "");
|
||||
if (tabView == null) continue;
|
||||
tab.setCustomView(tabView);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,7 @@ import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.View;
|
||||
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.lightgame.adapter.BaseFragmentPagerAdapter;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.view.DoubleTapTextView;
|
||||
@ -33,9 +34,9 @@ import java.util.List;
|
||||
* @author CsHeng
|
||||
* @date 2013-3-6
|
||||
*/
|
||||
public abstract class BaseFragment_ViewPager extends BaseFragment implements DoubleTapTextView.OnDoubleTapListener {
|
||||
public abstract class BaseFragment_ViewPager extends NormalFragment implements DoubleTapTextView.OnDoubleTapListener {
|
||||
|
||||
protected static final String ARGS_INDEX = "index";
|
||||
public static final String ARGS_INDEX = "index";
|
||||
protected int mCheckedIndex = 0;
|
||||
protected PagerAdapter mAdapter;
|
||||
protected List<Fragment> mFragmentsList;
|
||||
@ -67,11 +68,6 @@ public abstract class BaseFragment_ViewPager extends BaseFragment implements Dou
|
||||
mViewPager = (ViewPager) view.findViewById(getViewPagerId());
|
||||
mViewPager.setOffscreenPageLimit(mFragmentsList.size());
|
||||
mViewPager.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
if (mCheckedIndex < mFragmentsList.size()) {
|
||||
mViewPager.setCurrentItem(mCheckedIndex, false);
|
||||
}
|
||||
@ -116,10 +112,15 @@ public abstract class BaseFragment_ViewPager extends BaseFragment implements Dou
|
||||
}
|
||||
List<Fragment> fragments = getChildFragmentManager().getFragments();
|
||||
if (fragments != null) {
|
||||
Fragment curFragment = fragments.get(mViewPager.getCurrentItem());
|
||||
curFragment.onActivityResult(requestCode, resultCode, data);
|
||||
for (Fragment fragment : fragments) {
|
||||
fragment.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getCurrentItem() {
|
||||
return mViewPager != null ? mViewPager.getCurrentItem() : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
public interface OnDialogBackListener {
|
||||
void onBack();
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
* @Date 17/05/2017
|
||||
* @Time 4:27 PM
|
||||
*/
|
||||
public class WaitingDialogFragment extends BaseDialogFragment {
|
||||
|
||||
public static final String KEY_MSG = "msg";
|
||||
|
||||
private OnDialogBackListener mBackListener;
|
||||
|
||||
public static WaitingDialogFragment newInstance(String message) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(KEY_MSG, message);
|
||||
WaitingDialogFragment fragment = new WaitingDialogFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static WaitingDialogFragment newInstance(String message, boolean isCancelable) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(KEY_MSG, message);
|
||||
WaitingDialogFragment fragment = new WaitingDialogFragment();
|
||||
fragment.setArguments(args);
|
||||
fragment.setCancelable(isCancelable);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
final View view = inflater.inflate(R.layout.set_wait_dialog, null);
|
||||
final TextView message = (TextView) view.findViewById(R.id.set_wait_message);
|
||||
message.setText(getArguments().getString(KEY_MSG));
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(FragmentManager manager, String tag) {
|
||||
try {
|
||||
super.show(manager, tag);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void show(FragmentManager manager, String tag, OnDialogBackListener backListener) {
|
||||
show(manager, tag);
|
||||
this.mBackListener = backListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBack() {
|
||||
if (mBackListener != null) {
|
||||
mBackListener.onBack();
|
||||
return true;
|
||||
}
|
||||
return super.onBack();
|
||||
}
|
||||
|
||||
public static class WaitingDialogData {
|
||||
private String msg;
|
||||
|
||||
private boolean isShow;
|
||||
|
||||
public WaitingDialogData(String msg, boolean isShow) {
|
||||
this.msg = msg;
|
||||
this.isShow = isShow;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public boolean isShow() {
|
||||
return isShow;
|
||||
}
|
||||
|
||||
public void setShow(boolean show) {
|
||||
isShow = show;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
app/src/main/java/com/gh/base/onDoubleTapListener.java
Normal file
33
app/src/main/java/com/gh/base/onDoubleTapListener.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by khy on 25/04/18.
|
||||
*/
|
||||
|
||||
public abstract class onDoubleTapListener implements View.OnTouchListener {
|
||||
private GestureDetector mGestureDetector;
|
||||
|
||||
public onDoubleTapListener(Context context) {
|
||||
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent e) {
|
||||
onDoubleTapListener.this.onDoubleTap();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
mGestureDetector.onTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void onDoubleTap();
|
||||
}
|
||||
@ -4,8 +4,15 @@ package com.gh.common.constant;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.entity.NewsEntity;
|
||||
import com.gh.gamecenter.entity.SettingsEntity;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Config {
|
||||
|
||||
@ -15,7 +22,6 @@ public class Config {
|
||||
public static final String DATA_HOST = BuildConfig.DATA_HOST;
|
||||
public static final String LIBAO_HOST = BuildConfig.LIBAO_HOST;
|
||||
public static final String MESSAGE_HOST = BuildConfig.MESSAGE_HOST;
|
||||
public static final String USERSEA_HOST = BuildConfig.USERSEA_HOST;
|
||||
|
||||
/**
|
||||
* 需要配置的请使用{@link PreferenceManager#getDefaultSharedPreferences(Context)}
|
||||
@ -34,17 +40,29 @@ public class Config {
|
||||
public static final String TALKINGDATA_APPID = BuildConfig.TD_APPID;// TalkingData
|
||||
public static final String UMENG_APPKEY = BuildConfig.UMENG_APPKEY;
|
||||
public static final String UMENG_MESSAGE_SECRET = BuildConfig.UMENG_MESSAGE_SECRET;
|
||||
public static final String USERSEA_APP_ID = BuildConfig.USERSEA_APP_ID; // 登录验证
|
||||
public static final String USERSEA_APP_SECRET = BuildConfig.USERSEA_APP_SECRET; // 登录验证
|
||||
public static final String BUGLY_APPID = BuildConfig.BUGLY_APPID;
|
||||
public static final String PATCH_VERSION_NAME = BuildConfig.PATCH_VERSION_NAME; // 补丁包版本 对应关于->版本号
|
||||
// http://www.ghzs666.com/article/${articleId}.html
|
||||
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // TODO ghzs/ghzs666 统一
|
||||
public static final String PATCHES = "patches";
|
||||
|
||||
public static boolean isShow(Context context) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return sp.getBoolean("isShow", true);
|
||||
private static SettingsEntity mSettingsEntity;
|
||||
|
||||
public static boolean isShow() {
|
||||
if (PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication())
|
||||
.getBoolean("isFixDownload", false)) return true;
|
||||
|
||||
if (!isExistDownloadFilter()) return false;
|
||||
|
||||
for (SettingsEntity.Download entity : mSettingsEntity.getDownload()) {
|
||||
if ("all".equals(entity.getGame())) {
|
||||
if (entity.isPluginfy() && "normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getExceptionMsg(Context context) {
|
||||
@ -56,4 +74,105 @@ public class Config {
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("errMsg", errMsg).apply();
|
||||
}
|
||||
|
||||
public static boolean isShowDownload(String gameId) {
|
||||
|
||||
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
|
||||
return false;
|
||||
|
||||
for (SettingsEntity.Download entity : mSettingsEntity.getDownload()) {
|
||||
if (gameId.equals(entity.getGame())) {
|
||||
if ("normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ("all".equals(entity.getGame())) {
|
||||
if ("normal".equals(entity.getPolicy()) && filterTime(entity.getTime())
|
||||
|| PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).getBoolean("isFixDownload", false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isShowPlugin(String gameId) {
|
||||
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
|
||||
return false;
|
||||
|
||||
for (SettingsEntity.Download entity : mSettingsEntity.getDownload()) {
|
||||
if (gameId.equals(entity.getGame())) {
|
||||
if (entity.isPluginfy() && filterTime(entity.getTime())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ("all".equals(entity.getGame())) {
|
||||
if (entity.isPluginfy() && filterTime(entity.getTime())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isShowPlugin() {
|
||||
if (!isExistDownloadFilter())
|
||||
return false;
|
||||
|
||||
for (SettingsEntity.Download entity : mSettingsEntity.getDownload()) {
|
||||
if ("all".equals(entity.getGame())) {
|
||||
if (entity.isPluginfy() && filterTime(entity.getTime())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean filterTime(SettingsEntity.Download.TimeEntity timeEntity) {
|
||||
long end = timeEntity.getEnd();
|
||||
long start = timeEntity.getStart();
|
||||
long curTime = Utils.getTime(HaloApp.getInstance().getApplication());
|
||||
|
||||
if ((start == 0 || curTime >= start) && (end == 0 || curTime <= end)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setSettings(SettingsEntity settingsEntity) {
|
||||
mSettingsEntity = settingsEntity;
|
||||
}
|
||||
|
||||
public static SettingsEntity getSettings() {
|
||||
return mSettingsEntity;
|
||||
}
|
||||
|
||||
private static boolean isExistDownloadFilter() {
|
||||
if (mSettingsEntity == null || mSettingsEntity.getDownload() == null || mSettingsEntity.getDownload().size() == 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void filterPluginArticle(List<NewsEntity> list) {
|
||||
if (isShowPlugin() || list == null) return;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
NewsEntity newsEntity = list.get(i);
|
||||
String title = newsEntity.getTitle();
|
||||
if (!TextUtils.isEmpty(title) && title.contains("插件")) {
|
||||
list.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,11 @@ public class Constants {
|
||||
|
||||
public final static int NOT_NETWORK_CODE = 504; // 没有网络的状态码(应该是这个吧!)
|
||||
|
||||
public static final String LOGIN_TOKEN_ID = "userToken_id"; // 用户ID 与服务器无关
|
||||
|
||||
public static final String USER_TOKEN_KEY = "userTokenKey";
|
||||
public static final String USER_INFO_KEY = "userInfoKey";
|
||||
|
||||
//手机号码匹配规则
|
||||
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
||||
public static final String REGEX_ACCOUNT = "^[a-zA-Z_]\\w{5,17}$";
|
||||
|
||||
@ -8,6 +8,7 @@ public class ItemViewType {
|
||||
public static final int COLUMN_HEADER = 0; // 专题头部布局
|
||||
public static final int GAME_SLIDE = 1; // 滚动图布局
|
||||
public static final int GAME_NORMAL = 2; // 正常游戏布局
|
||||
public static final int GAME_SUBJECT = 19;
|
||||
public static final int GAME_TEST = 3; // 测试游戏布局
|
||||
public static final int GAME_IMAGE = 4; // 游戏大图布局
|
||||
public static final int NEWS_HEADER = 5; // 新闻头部布局
|
||||
@ -22,6 +23,16 @@ public class ItemViewType {
|
||||
public static final int LIBAO_NORMAL = 15; // 礼包正常布局
|
||||
public static final int LIBAO_SKIP_CONCERN = 16; // 跳转关注管理页面布局
|
||||
public static final int KC_HINT = 17;
|
||||
public static final int GAME_PULGIN = 18; // 游戏插件模块
|
||||
public static final int GAME_PLUGIN = 18; // 游戏插件模块
|
||||
public static final int ASK_REFRESH = 19; // 问答精选 刷新
|
||||
public static final int ITEM_EMPTY = 20;
|
||||
|
||||
/**
|
||||
* 普通列表
|
||||
*/
|
||||
public static final int ITEM_BODY = 100;
|
||||
public static final int ITEM_FOOTER = 101;
|
||||
public static final int ITEM_TOP = 102;
|
||||
|
||||
|
||||
}
|
||||
|
||||
473
app/src/main/java/com/gh/common/databind/BindingAdapters.java
Normal file
473
app/src/main/java/com/gh/common/databind/BindingAdapters.java
Normal file
@ -0,0 +1,473 @@
|
||||
package com.gh.common.databind;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.databinding.BindingAdapter;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.base.OnViewClickListener;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.exposure.ExposureUtils;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.common.util.GameUtils;
|
||||
import com.gh.common.util.GameViewUtils;
|
||||
import com.gh.common.util.KaiFuUtils;
|
||||
import com.gh.common.util.NetworkUtils;
|
||||
import com.gh.common.util.NewsUtils;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.StringUtils;
|
||||
import com.gh.common.view.DownloadDialog;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.baselist.LoadStatus;
|
||||
import com.gh.gamecenter.databinding.KaifuAddItemBinding;
|
||||
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.KaiFuCalendarEntity;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.manager.PackageManager;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by khy on 12/02/18.
|
||||
*/
|
||||
|
||||
public class BindingAdapters {
|
||||
|
||||
@BindingAdapter("imageUrl")
|
||||
public static void loadImage(SimpleDraweeView view, String imageUrl) {
|
||||
view.setImageURI(imageUrl);
|
||||
}
|
||||
|
||||
@BindingAdapter({"addDetailKaiFuView", "addDetailKaiFuViewListener", "isReadyPatch"})
|
||||
public static void addDetailKaiFuView(LinearLayout view, List<KaiFuCalendarEntity> list
|
||||
, OnViewClickListener listener, Boolean isReadyPatch) {
|
||||
if (list == null) return;
|
||||
view.removeAllViews();
|
||||
for (int i = 0; i < list.size() + 1; i++) { // 1 is Title
|
||||
View inflate = LayoutInflater.from(view.getContext()).inflate(R.layout.kaifu_detail_item_row, null);
|
||||
KaifuDetailItemRowBinding binding = KaifuDetailItemRowBinding.bind(inflate);
|
||||
binding.setIsCloseBottom(i == list.size());
|
||||
binding.setIsReadyPatch(isReadyPatch);
|
||||
if (i == 0) {
|
||||
binding.setIsTitle(true);
|
||||
} else {
|
||||
KaiFuCalendarEntity serverEntity = list.get(i - 1);
|
||||
binding.setEntity(serverEntity);
|
||||
binding.getRoot().setOnClickListener(v -> {
|
||||
listener.onClick(v, isReadyPatch != null && isReadyPatch ? serverEntity : null);
|
||||
});
|
||||
|
||||
// 滑动冲突处理
|
||||
binding.getRoot().setOnTouchListener((v, event) -> {
|
||||
if (list.size() > 5) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
EventBus.getDefault().post(new EBReuse("CalenderDown"));
|
||||
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
EventBus.getDefault().post(new EBReuse("CalenderCancel"));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
view.addView(inflate);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"addKaiFuView", "clickListener"})
|
||||
public static void addKaiFuView(LinearLayout view, List<KaiFuCalendarEntity> list, OnViewClickListener listener) {
|
||||
if (list == null) return;
|
||||
view.removeAllViews();
|
||||
view.addView(LayoutInflater.from(view.getContext()).inflate(R.layout.kaifu_add_item_title, null));
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
View inflate = LayoutInflater.from(view.getContext()).inflate(R.layout.kaifu_add_item, null);
|
||||
KaifuAddItemBinding binding = KaifuAddItemBinding.bind(inflate);
|
||||
binding.setClickListener(listener);
|
||||
binding.setEntity(list.get(i));
|
||||
binding.setPosition(i);
|
||||
binding.setIsCloseBottom(list.size() - 1 == i);
|
||||
view.addView(inflate);
|
||||
|
||||
binding.kaifuAddName.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (hasFocus) {
|
||||
binding.kaifuAddName.setHint("");
|
||||
} else {
|
||||
binding.kaifuAddName.setHint("点击填写");
|
||||
}
|
||||
});
|
||||
binding.kaifuAddRemark.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (hasFocus) {
|
||||
binding.kaifuAddRemark.setHint("");
|
||||
} else {
|
||||
binding.kaifuAddRemark.setHint("点击填写");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"addKaiFuTime", "addKaiFuPosition"})
|
||||
public static void addKaiFuTime(EditText view, Long time, Integer position) {
|
||||
if (time == 0) {
|
||||
view.setHint("点击选择");
|
||||
view.setText("");
|
||||
} else {
|
||||
String pattern;
|
||||
if (position == 0) {
|
||||
pattern = "yyy-MM-dd HH:mm +";
|
||||
} else {
|
||||
pattern = "yyy-MM-dd HH:mm";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA);
|
||||
view.setText(format.format(time * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"kaiFuTextColor", "kaiFuTextPosition"})
|
||||
public static void kaiFuTextColor(EditText view, Integer dataMark, Integer position) {
|
||||
if (dataMark == 1 && view.getId() == R.id.kaifu_add_time
|
||||
|| dataMark == 2 && view.getId() == R.id.kaifu_add_name
|
||||
|| dataMark == 3 && view.getId() == R.id.kaifu_add_remark
|
||||
|| dataMark == 4 && (view.getId() == R.id.kaifu_add_time || view.getId() == R.id.kaifu_add_name)) {
|
||||
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.red));
|
||||
view.setHintTextColor(ContextCompat.getColor(view.getContext(), R.color.red));
|
||||
} else if (position == 0) {
|
||||
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.hint));
|
||||
view.setHintTextColor(ContextCompat.getColor(view.getContext(), R.color.hint));
|
||||
} else {
|
||||
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.title));
|
||||
view.setHintTextColor(ContextCompat.getColor(view.getContext(), R.color.hint));
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("visibleGone")
|
||||
public static void showHide(View view, Boolean show) {
|
||||
if (show != null && show) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("messageUnread")
|
||||
public static void setMessageUnread(TextView view, int unreadCount) {
|
||||
if (unreadCount < 100) {
|
||||
view.setText(String.valueOf(unreadCount));
|
||||
} else {
|
||||
view.setText("99+");
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("serverTypePadding")
|
||||
public static void setServerTypePadding(TextView view, String serverType) {
|
||||
int paddRight = 0;
|
||||
if (TextUtils.isEmpty(serverType)) {
|
||||
} else {
|
||||
if ("删档内测".equals(serverType) || "不删档内测".equals(serverType)) {
|
||||
if ("删档内测".equals(serverType)) {
|
||||
paddRight = DisplayUtils.dip2px(view.getContext(), 50);
|
||||
} else {
|
||||
paddRight = DisplayUtils.dip2px(view.getContext(), 60);
|
||||
}
|
||||
} else {
|
||||
paddRight = DisplayUtils.dip2px(view.getContext(), 30);
|
||||
}
|
||||
}
|
||||
view.setPadding(0, 0, paddRight, 0);
|
||||
}
|
||||
|
||||
@BindingAdapter("serverType")
|
||||
public static void setServerType(TextView view, String serverType) {
|
||||
view.setText(serverType);
|
||||
if ("删档内测".equals(serverType) || "不删档内测".equals(serverType)) {
|
||||
view.setBackgroundResource(R.drawable.textview_server_tag);
|
||||
} else {
|
||||
view.setBackgroundResource(R.drawable.textview_orange_up);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("articleType")
|
||||
public static void setArticleType(TextView view, String articleType) {
|
||||
NewsUtils.setNewsType(view, articleType, 0, 0);
|
||||
}
|
||||
|
||||
@BindingAdapter("detailDownloadText")
|
||||
public static void setDetailDownloadText(TextView view, GameEntity gameEntity) {
|
||||
if (gameEntity == null || gameEntity.getApk().isEmpty()) {
|
||||
view.setBackgroundResource(R.drawable.game_item_btn_pause_style);
|
||||
view.setTextColor(0xFF999999);
|
||||
view.setClickable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("liBaoBtn")
|
||||
public static void setLiBaoBtn(TextView view, String status) {
|
||||
if (TextUtils.isEmpty(status)) return;
|
||||
switch (status) {
|
||||
case "coming":
|
||||
view.setText(R.string.libao_coming);
|
||||
view.setBackgroundResource(R.drawable.textview_blue_style);
|
||||
break;
|
||||
case "ling":
|
||||
view.setText(R.string.libao_ling);
|
||||
view.setBackgroundResource(R.drawable.textview_green_style);
|
||||
break;
|
||||
case "tao":
|
||||
view.setText(R.string.libao_tao);
|
||||
view.setBackgroundResource(R.drawable.textview_orange_style);
|
||||
break;
|
||||
case "used_up":
|
||||
view.setText(R.string.libao_used_up);
|
||||
view.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
break;
|
||||
case "finish":
|
||||
view.setText(R.string.libao_finish);
|
||||
view.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
break;
|
||||
case "linged":
|
||||
view.setText(R.string.libao_linged);
|
||||
view.setBackgroundResource(R.drawable.libao_linged_style);
|
||||
view.setTextColor(ContextCompat.getColorStateList(view.getContext(), R.color.libao_linged_selector));
|
||||
break;
|
||||
case "taoed":
|
||||
view.setText(R.string.libao_taoed);
|
||||
view.setBackgroundResource(R.drawable.libao_taoed_style);
|
||||
view.setTextColor(ContextCompat.getColorStateList(view.getContext(), R.color.libao_taoed_selector));
|
||||
break;
|
||||
case "copy":
|
||||
view.setText(R.string.libao_copy);
|
||||
view.setBackgroundResource(R.drawable.textview_blue_style);
|
||||
break;
|
||||
case "repeatLing":
|
||||
view.setText(R.string.libao_repeat_ling);
|
||||
view.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
break;
|
||||
case "repeatLinged":
|
||||
view.setText(R.string.libao_repeat_ling);
|
||||
view.setBackgroundResource(R.drawable.textview_green_style);
|
||||
break;
|
||||
case "repeatTao":
|
||||
view.setText(R.string.libao_repeat_tao);
|
||||
view.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
break;
|
||||
case "repeatTaoed":
|
||||
view.setText(R.string.libao_repeat_tao);
|
||||
view.setBackgroundResource(R.drawable.textview_orange_style);
|
||||
break;
|
||||
case "unshelve":
|
||||
view.setBackgroundResource(R.drawable.textview_cancel_style);
|
||||
view.setText(R.string.libao_unshelve);
|
||||
break;
|
||||
default:
|
||||
view.setBackgroundResource(R.drawable.textview_cancel_style);
|
||||
view.setText("异常");
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"downloadButton", "traceEvent"})
|
||||
public static void setDownloadButton(DownloadProgressBar progressBar, GameEntity gameEntity, ExposureEvent traceEvent) {
|
||||
// 判断是否显示按钮
|
||||
if (gameEntity != null
|
||||
&& Config.isShowDownload(gameEntity.getId())
|
||||
&& !"光环助手".equals(gameEntity.getName())) {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示下载按钮状态
|
||||
if (gameEntity.getApk().isEmpty()) {
|
||||
progressBar.setText("暂无下载");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
} else {
|
||||
String status = GameUtils.getDownloadBtnText(progressBar.getContext(), gameEntity);
|
||||
switch (status) {
|
||||
case "插件化":
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.PLUGIN);
|
||||
break;
|
||||
case "打开":
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
status = "启动";
|
||||
}
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
|
||||
break;
|
||||
default:
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NORMAL);
|
||||
break;
|
||||
}
|
||||
progressBar.setText(status);
|
||||
}
|
||||
|
||||
// 显示下载过程状态
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance(progressBar.getContext()).getDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
progressBar.setProgress((int) (downloadEntity.getPercent() * 10));
|
||||
switch (downloadEntity.getStatus()) {
|
||||
case downloading:
|
||||
case pause:
|
||||
case timeout:
|
||||
case neterror:
|
||||
case waiting:
|
||||
progressBar.setText(R.string.downloading);
|
||||
if (downloadEntity.isPluggable() && PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN);
|
||||
} else {
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL);
|
||||
}
|
||||
break;
|
||||
case done:
|
||||
progressBar.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
}
|
||||
break;
|
||||
case cancel:
|
||||
case hijack:
|
||||
case notfound:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 点击事件
|
||||
progressBar.setOnClickListener(v -> {
|
||||
switch (progressBar.getDownloadType()) {
|
||||
case DOWNLOADING_PLUGIN:
|
||||
case DOWNLOADING_NORMAL:
|
||||
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
|
||||
gameEntity.getApk().get(0).getUrl(), "(我的光环:我的游戏)");
|
||||
v.getContext().startActivity(intent);
|
||||
break;
|
||||
case NONE:
|
||||
Utils.toast(v.getContext(), "该游戏已关闭下载");
|
||||
break;
|
||||
case NORMAL:
|
||||
case PLUGIN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
if (NetworkUtils.isWifiConnected(v.getContext())) {
|
||||
download(progressBar, gameEntity, traceEvent);
|
||||
} else {
|
||||
DialogUtils.showDownloadDialog(v.getContext(), () -> {
|
||||
download(progressBar, gameEntity, traceEvent);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
|
||||
"(我的光环:我的游戏)", "我的光环-我的游戏:" + gameEntity.getName(), traceEvent);
|
||||
}
|
||||
break;
|
||||
case LAUNCH_OR_OPEN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), "我的光环-我的游戏");
|
||||
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
|
||||
"(我的光环:我的游戏)", "我的光环-我的游戏:" + gameEntity.getName(), traceEvent);
|
||||
}
|
||||
break;
|
||||
case INSTALL_PLUGIN:
|
||||
case INSTALL_NORMAL:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance(progressBar.getContext()).getDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
PackageUtils.launchSetup(v.getContext(), downloadEntity.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 开始下载
|
||||
private static void download(DownloadProgressBar progressBar, GameEntity
|
||||
gameEntity, ExposureEvent traceEvent) {
|
||||
String str = progressBar.getText();
|
||||
String method;
|
||||
if (str.contains("更新")) {
|
||||
method = "更新";
|
||||
} else if (str.contains("插件化")) {
|
||||
method = "插件化";
|
||||
} else {
|
||||
method = progressBar.getContext().getString(R.string.download);
|
||||
}
|
||||
ApkEntity apkEntity = gameEntity.getApk().get(0);
|
||||
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(progressBar.getContext(), gameEntity.getName(), apkEntity.getPlatform(), "(我的光环:我的游戏)", "下载开始");
|
||||
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.INSTANCE.logADownloadExposureEvent(gameEntity, apkEntity.getPlatform(), traceEvent, ExposureUtils.DownloadType.DOWNLOAD);
|
||||
|
||||
DownloadManager.createDownload(progressBar.getContext(),
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
method,
|
||||
StringUtils.buildString("(我的光环:我的游戏)"), "我的光环-我的游戏:" + gameEntity.getName(),
|
||||
downloadExposureEvent);
|
||||
|
||||
progressBar.setProgress(0);
|
||||
progressBar.setDownloadType("插件化".equals(method) ?
|
||||
DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN : DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL);
|
||||
} else {
|
||||
Utils.toast(progressBar.getContext(), msg);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"gameLabelList", "subjectTag"})
|
||||
public static void setGameLabelList(LinearLayout layout, GameEntity gameEntity, String subjectTag) {
|
||||
if (gameEntity == null) return;
|
||||
if (gameEntity.getTest() != null) {
|
||||
layout.removeAllViews();
|
||||
View testView = LayoutInflater.from(layout.getContext()).inflate(R.layout.game_test_label, null);
|
||||
TextView testType = testView.findViewById(R.id.test_type);
|
||||
TextView testTime = testView.findViewById(R.id.test_time);
|
||||
String type = gameEntity.getTest().getType();
|
||||
KaiFuUtils.setKaiFuType(testType, type);
|
||||
|
||||
if (gameEntity.getTest().getStart() == 0) {
|
||||
testTime.setVisibility(View.GONE);
|
||||
} else {
|
||||
testTime.setText(GameViewUtils.getGameTestDate(gameEntity.getTest().getStart()));
|
||||
}
|
||||
layout.addView(testView);
|
||||
} else {
|
||||
GameViewUtils.setLabelList(layout.getContext(), layout, gameEntity.getTag(), subjectTag, gameEntity.getTagStyle());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@BindingAdapter("isRefreshing")
|
||||
public static void isRefreshing(SwipeRefreshLayout layout, LoadStatus status) {
|
||||
if (status == LoadStatus.INIT_LOADING) {
|
||||
layout.setRefreshing(true);
|
||||
} else {
|
||||
layout.setRefreshing(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.arch.persistence.room.TypeConverter
|
||||
import com.gh.common.exposure.meta.Meta
|
||||
import com.google.gson.Gson
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ExposureConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun convertPayload2String(any: ExposureEntity): String {
|
||||
return Gson().toJson(any)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertString2Payload(string: String): ExposureEntity {
|
||||
return Gson().fromJson(string, ExposureEntity::class.java)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertSource2String(sourceList: List<ExposureSource>): String {
|
||||
return Gson().toJson(sourceList)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertString2Source(sourceList: String): List<ExposureSource> {
|
||||
return ArrayList(Arrays.asList(Gson().fromJson(sourceList, Array<ExposureSource>::class.java))) as List<ExposureSource>
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertETrace2String(sourceList: List<ExposureEvent>?): String {
|
||||
return Gson().toJson(sourceList)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertStringToETrace(sourceList: String): List<ExposureEvent> {
|
||||
return ArrayList(Arrays.asList(Gson().fromJson(sourceList, Array<ExposureEvent>::class.java))) as List<ExposureEvent>
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertExposeType2String(exposureType: ExposureType): String {
|
||||
return exposureType.toString()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertStringToExposeType(exposureType: String): ExposureType {
|
||||
return ExposureType.valueOf(exposureType)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertMeta2String(any: Meta): String {
|
||||
return Gson().toJson(any)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun convertString2Meta(string: String): Meta {
|
||||
return Gson().fromJson(string, Meta::class.java)
|
||||
}
|
||||
|
||||
}
|
||||
23
app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt
Normal file
23
app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.arch.persistence.room.Database
|
||||
import android.arch.persistence.room.Room
|
||||
import android.arch.persistence.room.RoomDatabase
|
||||
import android.arch.persistence.room.TypeConverters
|
||||
import android.content.Context
|
||||
|
||||
@TypeConverters(ExposureConverters::class)
|
||||
@Database(entities = [ExposureEvent::class], version = 1, exportSchema = false)
|
||||
abstract class ExposureDatabase : RoomDatabase() {
|
||||
companion object {
|
||||
private const val DATABASE = "exposure_database"
|
||||
|
||||
fun buildDatabase(context: Context): ExposureDatabase {
|
||||
return Room.databaseBuilder(context, ExposureDatabase::class.java, DATABASE)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun logHubEventDao(): ExposureEventDao
|
||||
}
|
||||
18
app/src/main/java/com/gh/common/exposure/ExposureEntity.kt
Normal file
18
app/src/main/java/com/gh/common/exposure/ExposureEntity.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.os.Parcelable
|
||||
import android.support.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Keep
|
||||
@Parcelize
|
||||
data class ExposureEntity(
|
||||
@SerializedName("game_id")
|
||||
val gameId: String? = "",
|
||||
val gameName: String? = "",
|
||||
val sequence: Int? = 0,
|
||||
val platform: String? = "",
|
||||
val downloadType: String? = "",
|
||||
val downloadCompleteType: String? = ""
|
||||
) : Parcelable
|
||||
40
app/src/main/java/com/gh/common/exposure/ExposureEvent.kt
Normal file
40
app/src/main/java/com/gh/common/exposure/ExposureEvent.kt
Normal file
@ -0,0 +1,40 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.arch.persistence.room.Entity
|
||||
import android.arch.persistence.room.PrimaryKey
|
||||
import android.os.Parcelable
|
||||
import android.support.annotation.Keep
|
||||
import com.gh.common.exposure.meta.Meta
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.exposure.time.TimeUtil
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import java.util.*
|
||||
|
||||
@Keep
|
||||
@Parcelize
|
||||
@Entity(tableName = "exposureEvent")
|
||||
data class ExposureEvent(
|
||||
val payload: ExposureEntity,
|
||||
val source: List<ExposureSource>,
|
||||
var eTrace: List<ExposureEvent>? = arrayListOf(),
|
||||
val event: ExposureType,
|
||||
val meta: Meta = MetaUtil.getMeta(),
|
||||
val time: Int = TimeUtil.currentTime(),
|
||||
@PrimaryKey
|
||||
val id: String = UUID.randomUUID().toString()) : Parcelable {
|
||||
companion object {
|
||||
fun createEvent(gameEntity: GameEntity?, source: List<ExposureSource>, eTrace: List<ExposureEvent>?, event: ExposureType): ExposureEvent {
|
||||
return ExposureEvent(
|
||||
ExposureEntity(gameId = gameEntity?.id,
|
||||
gameName = gameEntity?.name,
|
||||
sequence = gameEntity?.sequence,
|
||||
platform = gameEntity?.platform,
|
||||
downloadType = gameEntity?.downloadType,
|
||||
downloadCompleteType = gameEntity?.downloadCompleteType),
|
||||
source = source,
|
||||
eTrace = eTrace,
|
||||
event = event)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
app/src/main/java/com/gh/common/exposure/ExposureEventDao.kt
Normal file
19
app/src/main/java/com/gh/common/exposure/ExposureEventDao.kt
Normal file
@ -0,0 +1,19 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.arch.persistence.room.*
|
||||
|
||||
@Dao
|
||||
interface ExposureEventDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertMany(eventList: List<ExposureEvent>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(event: ExposureEvent)
|
||||
|
||||
@Query("SELECT * FROM exposureEvent")
|
||||
fun getAll(): List<ExposureEvent>
|
||||
|
||||
@Delete
|
||||
fun deleteMany(eventList: List<ExposureEvent>)
|
||||
}
|
||||
70
app/src/main/java/com/gh/common/exposure/ExposureListener.kt
Normal file
70
app/src/main/java/com/gh/common/exposure/ExposureListener.kt
Normal file
@ -0,0 +1,70 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import rx.functions.Action1
|
||||
|
||||
/**
|
||||
* Exposure Event Listener for RecyclerView
|
||||
*
|
||||
* TODO 1. Pull down refresh change in first page without scroll down action
|
||||
* TODO 2. Item change not triggered by user scroll action (vm data change etc.)
|
||||
*/
|
||||
class ExposureListener(var fragment: Fragment, var exposable: IExposable) : RecyclerView.OnScrollListener() {
|
||||
|
||||
var throttleBus: ExposureThrottleBus? = null
|
||||
var layoutManager: LinearLayoutManager? = null
|
||||
var visibleState: ExposureThrottleBus.VisibleState? = null
|
||||
|
||||
init {
|
||||
fragment.fragmentManager?.registerFragmentLifecycleCallbacks(
|
||||
object : FragmentManager.FragmentLifecycleCallbacks() {
|
||||
override fun onFragmentResumed(fm: FragmentManager?, f: Fragment?) {
|
||||
throttleBus = ExposureThrottleBus(Action1 { commitExposure(it) }, Action1(Throwable::printStackTrace))
|
||||
}
|
||||
|
||||
override fun onFragmentPaused(fm: FragmentManager?, f: Fragment?) {
|
||||
visibleState?.let { commitExposure(it) }
|
||||
throttleBus?.unsubscribe()
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor items in display when scrolling, record those newly displayed as well as
|
||||
* those newly disappeared. And finally trigger commitExposure().
|
||||
*/
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
|
||||
if (layoutManager == null) layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
|
||||
layoutManager?.run {
|
||||
visibleState = ExposureThrottleBus.VisibleState(findFirstCompletelyVisibleItemPosition(), findLastCompletelyVisibleItemPosition())
|
||||
throttleBus?.postVisibleState(visibleState!!)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check disappearMap items together with according data in displayMap,
|
||||
* log any items displayed long enough to be called a EXPOSURE
|
||||
*/
|
||||
private fun commitExposure(visibleState: ExposureThrottleBus.VisibleState) {
|
||||
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
|
||||
for (pos in visibleState.firstCompletelyVisible..visibleState.lastCompletelyVisible) {
|
||||
try {
|
||||
exposable.getEventByPosition(pos)?.let { eventList.add(it) }
|
||||
exposable.getEventListByPosition(pos)?.let { eventList.addAll(it) }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
ExposureManager.log(eventList)
|
||||
}
|
||||
|
||||
}
|
||||
199
app/src/main/java/com/gh/common/exposure/ExposureManager.kt
Normal file
199
app/src/main/java/com/gh/common/exposure/ExposureManager.kt
Normal file
@ -0,0 +1,199 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.app.Application
|
||||
import com.aliyun.sls.android.sdk.LogException
|
||||
import com.aliyun.sls.android.sdk.model.LogGroup
|
||||
import com.gh.common.exposure.aliyun.LGLOG
|
||||
import com.gh.common.exposure.aliyun.LGLOGClient
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.exposure.time.TimeUtil
|
||||
import com.google.gson.Gson
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
/**
|
||||
* ExposureManager tool to commit logs to aliyun loghub
|
||||
* TODO handle logs that failed to be committed multiple times
|
||||
*/
|
||||
object ExposureManager {
|
||||
|
||||
private var TAG: String = ExposureManager::class.java.simpleName
|
||||
|
||||
private const val ACCESS_KEY_ID = "LTAIV3i0sNc4TPK1"
|
||||
private const val ACCESS_KEY_SECRET = "8dKtTPeE5WYA6ZCeuIBcIVp7eB0ir4"
|
||||
private const val ENDPOINT = "cn-qingdao.log.aliyuncs.com"
|
||||
private const val PROJECT = "ghzs"
|
||||
private const val LOG_STORE = "exposure"
|
||||
private const val STORE_SIZE = 100
|
||||
private const val STORE_FORCE_UPLOAD_PERIOD = 300 * 1000L
|
||||
|
||||
private lateinit var client: LGLOGClient
|
||||
private lateinit var db: ExposureEventDao
|
||||
private val storeList = arrayListOf<ExposureEvent>()
|
||||
private val storeOpThread = Executors.newSingleThreadExecutor()
|
||||
private val gson = Gson()
|
||||
|
||||
private val exposureCache = FixedSizeLinkedHashSet<String>(20)
|
||||
|
||||
/**
|
||||
* Must be called early to init object then real use (for example in Application)
|
||||
*/
|
||||
fun init(application: Application) {
|
||||
|
||||
client = LGLOGClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET, PROJECT)
|
||||
db = ExposureDatabase.buildDatabase(application).logHubEventDao()
|
||||
|
||||
storeOpThread.execute({
|
||||
val eventList = db.getAll()
|
||||
storeList.addAll(eventList)
|
||||
})
|
||||
|
||||
fixedRateTimer(name = "ExposureManager-Store-Checker", initialDelay = 500, period = STORE_FORCE_UPLOAD_PERIOD) {
|
||||
checkAndUploadFromStore(true)
|
||||
}
|
||||
|
||||
MetaUtil.init(application)
|
||||
TimeUtil.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an Event
|
||||
*/
|
||||
fun log(event: ExposureEvent, uploadImmediately: Boolean = false) {
|
||||
when (uploadImmediately) {
|
||||
false -> store(event)
|
||||
true -> upload(event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log Many Events
|
||||
*/
|
||||
fun log(eventList: List<ExposureEvent>, uploadImmediately: Boolean = false) {
|
||||
when (uploadImmediately) {
|
||||
false -> store(eventList)
|
||||
true -> upload(eventList)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an Event to storeList, upload when storeList size exceeds STORE_SIZE
|
||||
*/
|
||||
private fun store(event: ExposureEvent) {
|
||||
storeOpThread.execute({
|
||||
if (!exposureCache.contains(event.id)) {
|
||||
storeList.add(event)
|
||||
db.insert(event)
|
||||
exposureCache.add(event.id)
|
||||
}
|
||||
})
|
||||
checkAndUploadFromStore()
|
||||
}
|
||||
|
||||
/**
|
||||
* Store Many Events to storeList, upload when storeList size exceeds STORE_SIZE
|
||||
*/
|
||||
private fun store(eventList: List<ExposureEvent>) {
|
||||
storeOpThread.execute({
|
||||
for (event in eventList) {
|
||||
if (!exposureCache.contains(event.id)) {
|
||||
storeList.add(event)
|
||||
db.insert(event)
|
||||
exposureCache.add(event.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
checkAndUploadFromStore()
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload an Event
|
||||
*/
|
||||
private fun upload(event: ExposureEvent) {
|
||||
storeOpThread.execute({
|
||||
client.PostLog(buildLogGroup(event), LOG_STORE)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload Many Events
|
||||
*/
|
||||
private fun upload(eventList: List<ExposureEvent>) {
|
||||
storeOpThread.execute({
|
||||
client.PostLog(buildLogGroup(eventList), LOG_STORE)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload Events From Store, and removed them
|
||||
*/
|
||||
private fun checkAndUploadFromStore(isForceUpload: Boolean = false) {
|
||||
if (storeList.size < STORE_SIZE && !isForceUpload || storeList.size == 0) return
|
||||
storeOpThread.execute({
|
||||
if (storeList.size < STORE_SIZE && !isForceUpload || storeList.size == 0) return@execute
|
||||
val uploaded = storeList.toList()
|
||||
try {
|
||||
client.PostLog(buildLogGroup(uploaded), LOG_STORE)
|
||||
} catch (exception: LogException) {
|
||||
// Return to insure no logs lost because of online commit failure
|
||||
return@execute
|
||||
}
|
||||
storeList.removeAll(uploaded)
|
||||
db.deleteMany(uploaded)
|
||||
})
|
||||
}
|
||||
|
||||
private fun buildLog(event: ExposureEvent): LGLOG {
|
||||
val log = LGLOG()
|
||||
|
||||
log.PutContent("id", event.id)
|
||||
log.PutContent("payload", gson.toJson(event.payload))
|
||||
log.PutContent("event", event.event.toString())
|
||||
log.PutContent("source", eliminateMultipleBrackets(gson.toJson(event.source)))
|
||||
log.PutContent("meta", gson.toJson(event.meta))
|
||||
log.PutContent("e-traces", if (event.eTrace != null) eliminateMultipleBrackets(gson.toJson(event.eTrace)) else "")
|
||||
log.PutTime(event.time)
|
||||
|
||||
return log
|
||||
}
|
||||
|
||||
private fun eliminateMultipleBrackets(jsonWithMultipleBracket: String): String {
|
||||
return jsonWithMultipleBracket.replace("[[", "[").replace("]]", "]")
|
||||
}
|
||||
|
||||
private fun buildLogGroup(event: ExposureEvent): LogGroup {
|
||||
|
||||
val logGroup = LogGroup("sls android", "no ip")
|
||||
|
||||
logGroup.PutLog(buildLog(event))
|
||||
|
||||
return logGroup
|
||||
}
|
||||
|
||||
private fun buildLogGroup(eventList: List<ExposureEvent>): LogGroup {
|
||||
|
||||
val logGroup = LogGroup("sls android", "no ip")
|
||||
|
||||
eventList.forEach { event ->
|
||||
logGroup.PutLog(buildLog(event))
|
||||
}
|
||||
|
||||
return logGroup
|
||||
}
|
||||
|
||||
internal class FixedSizeLinkedHashSet<T>(var maxSize: Int) : LinkedHashSet<T>() {
|
||||
override fun add(element: T): Boolean {
|
||||
if (size == maxSize) {
|
||||
pop()
|
||||
}
|
||||
return super.add(element);
|
||||
}
|
||||
|
||||
private fun pop() {
|
||||
if (size > 0) {
|
||||
remove(iterator().next())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.os.Parcelable
|
||||
import android.support.annotation.Keep
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Keep
|
||||
@Parcelize
|
||||
data class ExposureSource(var k: String, var v: String): Parcelable
|
||||
@ -0,0 +1,60 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import rx.Subscription
|
||||
import rx.functions.Action1
|
||||
import rx.schedulers.Schedulers
|
||||
import rx.subjects.PublishSubject
|
||||
import rx.subjects.Subject
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ExposureThrottleBus(var onSuccess: Action1<VisibleState>, var onError: Action1<Throwable>) {
|
||||
|
||||
companion object {
|
||||
private const val THRESHOLD_TIME = 300L
|
||||
}
|
||||
|
||||
private val mPublishSubject: Subject<VisibleState, VisibleState>
|
||||
private val mSubscription: Subscription
|
||||
|
||||
init {
|
||||
mPublishSubject = PublishSubject.create()
|
||||
|
||||
/**
|
||||
* Since onScroll() callback will be triggered multiple times for every swipe, we use
|
||||
* distinctUntilChanged() to prevent committing the same visibleState event and
|
||||
* throttleWithTimeout() to pass a visibleState event with a delay and drop current event if another event arrives before the timeout.
|
||||
*/
|
||||
mSubscription = mPublishSubject
|
||||
.distinctUntilChanged()
|
||||
.throttleWithTimeout(THRESHOLD_TIME, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(onSuccess, onError)
|
||||
}
|
||||
|
||||
fun unsubscribe() {
|
||||
mSubscription.unsubscribe()
|
||||
}
|
||||
|
||||
fun postVisibleState(visibleState: VisibleState) {
|
||||
mPublishSubject.onNext(visibleState)
|
||||
}
|
||||
|
||||
class VisibleState(val firstCompletelyVisible: Int, val lastCompletelyVisible: Int) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
||||
val that = other as VisibleState
|
||||
|
||||
if (firstCompletelyVisible != that.firstCompletelyVisible) return false
|
||||
|
||||
return lastCompletelyVisible == that.lastCompletelyVisible
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = firstCompletelyVisible
|
||||
result = 31 * result + lastCompletelyVisible
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
object ExposureTraceUtils {
|
||||
|
||||
fun appendTrace(event: ExposureEvent?): List<ExposureEvent> {
|
||||
val traceList = arrayListOf<ExposureEvent>()
|
||||
|
||||
event?.let {
|
||||
if (event.eTrace == null) {
|
||||
traceList.add(event)
|
||||
} else {
|
||||
traceList.addAll(event.eTrace!!)
|
||||
traceList.add(flattenTrace(event))
|
||||
}
|
||||
}
|
||||
|
||||
return traceList
|
||||
}
|
||||
|
||||
private fun flattenTrace(event: ExposureEvent): ExposureEvent {
|
||||
event.eTrace = arrayListOf()
|
||||
return event
|
||||
}
|
||||
|
||||
}
|
||||
11
app/src/main/java/com/gh/common/exposure/ExposureType.kt
Normal file
11
app/src/main/java/com/gh/common/exposure/ExposureType.kt
Normal file
@ -0,0 +1,11 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
enum class ExposureType {
|
||||
EXPOSURE,
|
||||
|
||||
CLICK,
|
||||
|
||||
DOWNLOAD,
|
||||
|
||||
DOWNLOAD_COMPLETE
|
||||
}
|
||||
42
app/src/main/java/com/gh/common/exposure/ExposureUtils.kt
Normal file
42
app/src/main/java/com/gh/common/exposure/ExposureUtils.kt
Normal file
@ -0,0 +1,42 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.google.gson.Gson
|
||||
import java.util.*
|
||||
|
||||
object ExposureUtils {
|
||||
|
||||
fun logADownloadExposureEvent(entity: GameEntity, platform: String?, traceEvent: ExposureEvent?, downloadType: DownloadType): ExposureEvent {
|
||||
val gameEntity = entity.clone()
|
||||
gameEntity.platform = platform
|
||||
gameEntity.downloadType = downloadType.toString()
|
||||
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
event = ExposureType.DOWNLOAD)
|
||||
ExposureManager.log(exposureEvent, false)
|
||||
return exposureEvent
|
||||
}
|
||||
|
||||
fun logADownloadCompleteExposureEvent(entity: GameEntity, platform: String?, trace: String?, downloadType: DownloadType) {
|
||||
val gameEntity = entity.clone()
|
||||
gameEntity.platform = platform
|
||||
gameEntity.downloadCompleteType = downloadType.toString()
|
||||
val traceEvent = Gson().fromJson(trace, ExposureEvent::class.java)
|
||||
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
event = ExposureType.DOWNLOAD_COMPLETE)
|
||||
ExposureManager.log(exposureEvent, false)
|
||||
}
|
||||
|
||||
enum class DownloadType {
|
||||
DOWNLOAD,
|
||||
|
||||
UPDATE,
|
||||
|
||||
PLUGIN_UPDATE,
|
||||
|
||||
PLUGIN_DOWNLOAD
|
||||
}
|
||||
}
|
||||
7
app/src/main/java/com/gh/common/exposure/IExposable.kt
Normal file
7
app/src/main/java/com/gh/common/exposure/IExposable.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
interface IExposable {
|
||||
fun getEventByPosition(pos: Int): ExposureEvent?
|
||||
|
||||
fun getEventListByPosition(pos: Int): List<ExposureEvent>?
|
||||
}
|
||||
42
app/src/main/java/com/gh/common/exposure/aliyun/LGLOG.java
Normal file
42
app/src/main/java/com/gh/common/exposure/aliyun/LGLOG.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.gh.common.exposure.aliyun;
|
||||
|
||||
import com.aliyun.sls.android.sdk.model.Log;
|
||||
import com.gh.common.exposure.time.TimeUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Extend to change __time__ field in mContent to use the correct time from TimeUtil
|
||||
*/
|
||||
public class LGLOG extends Log {
|
||||
|
||||
private Map<String, Object> mContent = new HashMap<String, Object>();
|
||||
|
||||
public LGLOG() {
|
||||
mContent.put("__time__", TimeUtil.INSTANCE.currentTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void PutTime(int time) {
|
||||
mContent.put("__time__", time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void PutContent(String key, String value) {
|
||||
if (key == null || key.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (value == null) {
|
||||
mContent.put(key, "");
|
||||
} else {
|
||||
mContent.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> GetContent() {
|
||||
return mContent;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.gh.common.exposure.aliyun;
|
||||
|
||||
import com.aliyun.sls.android.sdk.LOGClient;
|
||||
import com.aliyun.sls.android.sdk.LogException;
|
||||
import com.gh.common.exposure.time.TimeUtil;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Extend to override GetHttpHeadersFrom, so we can change "Date" header attribute using
|
||||
* correct time from TimeUtil.
|
||||
* And accordingly, the value of "Authorization" attribute should also be re-calculate
|
||||
* since the sign became different as before.
|
||||
*/
|
||||
public class LGLOGClient extends LOGClient {
|
||||
|
||||
private String mAccessKeyID;
|
||||
private String mAccessKeySecret;
|
||||
private String mAccessToken;
|
||||
|
||||
public LGLOGClient(String endPoint, String accessKeyID, String accessKeySecret, String projectName) {
|
||||
super(endPoint, accessKeyID, accessKeySecret, projectName);
|
||||
this.mAccessKeyID = accessKeyID;
|
||||
this.mAccessKeySecret = accessKeySecret;
|
||||
this.mAccessToken = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> GetHttpHeadersFrom(String logStoreName, byte[] body, byte[] bodyZipped) throws LogException {
|
||||
|
||||
Map<String, String> headers = super.GetHttpHeadersFrom(logStoreName, body, bodyZipped);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("GMT")); // 设置时区为GMT
|
||||
String str = sdf.format(new Date(TimeUtil.INSTANCE.currentTimeMillis()));
|
||||
headers.put("Date", str);
|
||||
|
||||
StringBuilder signStringBuf = new StringBuilder("POST" + "\n").
|
||||
append(headers.get("Content-MD5") + "\n").
|
||||
append(headers.get("Content-Type") + "\n").
|
||||
append(headers.get("Date") + "\n");
|
||||
String token = mAccessToken;
|
||||
if (token != null && token != "") {
|
||||
headers.put("x-acs-security-token", token);
|
||||
signStringBuf.append("x-acs-security-token:" + headers.get("x-acs-security-token") + "\n");
|
||||
}
|
||||
signStringBuf.append("x-log-apiversion:0.6.0\n").
|
||||
append("x-log-bodyrawsize:" + headers.get("x-log-bodyrawsize") + "\n").
|
||||
append("x-log-compresstype:deflate\n").
|
||||
append("x-log-signaturemethod:hmac-sha1\n").
|
||||
append("/logstores/" + logStoreName + "/shards/lb");
|
||||
String signString = signStringBuf.toString();
|
||||
try {
|
||||
String sign = hmac_sha1(signString, mAccessKeySecret);
|
||||
headers.put("Authorization", "LOG " + mAccessKeyID + ":" + sign);
|
||||
} catch (Exception e) {
|
||||
throw new LogException("LogClientError", "fail to get encode signature", e, "");
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
23
app/src/main/java/com/gh/common/exposure/meta/Meta.kt
Normal file
23
app/src/main/java/com/gh/common/exposure/meta/Meta.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package com.gh.common.exposure.meta
|
||||
|
||||
import android.os.Parcelable
|
||||
import android.support.annotation.Keep
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Keep
|
||||
@Parcelize
|
||||
data class Meta(
|
||||
val mac: String? = "",
|
||||
val imei: String? = "",
|
||||
val model: String? = "",
|
||||
val manufacturer: String? = "",
|
||||
val android_id: String? = "",
|
||||
val android_sdk: Int? = -1,
|
||||
val android_version: String? = "",
|
||||
val network: String? = "",
|
||||
val ip: String? = "",
|
||||
val os: String? = "",
|
||||
val channel: String? = "",
|
||||
val appVersion: String? = "",
|
||||
val userId: String? = ""
|
||||
) : Parcelable
|
||||
165
app/src/main/java/com/gh/common/exposure/meta/MetaUtil.kt
Normal file
165
app/src/main/java/com/gh/common/exposure/meta/MetaUtil.kt
Normal file
@ -0,0 +1,165 @@
|
||||
package com.gh.common.exposure.meta
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.telephony.TelephonyManager
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.leon.channel.helper.ChannelReaderUtil
|
||||
import java.io.File
|
||||
|
||||
object MetaUtil {
|
||||
|
||||
private lateinit var application: Application
|
||||
private var channel = ""
|
||||
|
||||
private var m: Meta? = null
|
||||
|
||||
fun init(application: Application) {
|
||||
MetaUtil.application = application
|
||||
}
|
||||
|
||||
fun refreshMeta() {
|
||||
m = Meta(getMac(), getIMEI(), getModel(), getManufacturer(), getAndroidId(), getAndroidSDK(),
|
||||
getAndroidVersion(), getNetwork(), getIP(), getOS(), getChannel(), BuildConfig.VERSION_NAME, UserManager.getInstance().userId)
|
||||
}
|
||||
|
||||
fun getMeta(): Meta {
|
||||
if (m == null) {
|
||||
refreshMeta()
|
||||
}
|
||||
return m!!
|
||||
}
|
||||
|
||||
private fun getChannel(): String? {
|
||||
if (TextUtils.isEmpty(channel)) {
|
||||
channel = if (ChannelReaderUtil.getChannel(application) != null) ChannelReaderUtil.getChannel(application) else ""
|
||||
}
|
||||
return channel
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MAC address
|
||||
* TODO check > 6.0 results
|
||||
*/
|
||||
fun getMac(): String? {
|
||||
|
||||
var mac: String
|
||||
|
||||
//Plan A
|
||||
try {
|
||||
mac = File("/sys/class/net/wlan0/address").inputStream().bufferedReader().use { it.readText() }
|
||||
if (!TextUtils.isEmpty(mac)) return mac.trim()
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
// Plan B
|
||||
try {
|
||||
mac = File("/sys/class/net/eth0/address").inputStream().bufferedReader().use { it.readText() }
|
||||
if (!TextUtils.isEmpty(mac)) return mac.trim()
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
// Plan C
|
||||
val wifiManager = application.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
mac = wifiManager.connectionInfo.macAddress
|
||||
return mac.trim()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMEI
|
||||
*/
|
||||
fun getIMEI(): String? {
|
||||
|
||||
if (application.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED)
|
||||
return ""
|
||||
|
||||
val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
return "!" + telephonyManager.imei
|
||||
}
|
||||
|
||||
return telephonyManager.getDeviceId()
|
||||
|
||||
}
|
||||
|
||||
fun getModel(): String? {
|
||||
return Build.MODEL
|
||||
}
|
||||
|
||||
fun getManufacturer(): String? {
|
||||
return Build.MANUFACTURER
|
||||
}
|
||||
|
||||
fun getAndroidId(): String? {
|
||||
var android_id: String = ""
|
||||
try {
|
||||
android_id = Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return android_id
|
||||
}
|
||||
|
||||
fun getAndroidSDK(): Int? {
|
||||
return Build.VERSION.SDK_INT
|
||||
}
|
||||
|
||||
fun getAndroidVersion(): String? {
|
||||
return Build.VERSION.RELEASE
|
||||
}
|
||||
|
||||
fun getNetwork(): String? {
|
||||
|
||||
if (application.checkCallingOrSelfPermission(Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)
|
||||
return "unknown"
|
||||
|
||||
val activeNetwork = (application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
|
||||
?: return "unknown"
|
||||
|
||||
return when (activeNetwork.type) {
|
||||
ConnectivityManager.TYPE_WIFI -> "Wifi"
|
||||
ConnectivityManager.TYPE_WIMAX -> "WifiMax"
|
||||
ConnectivityManager.TYPE_MOBILE -> {
|
||||
val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
if (telephonyManager.simState != TelephonyManager.SIM_STATE_READY) return "unknown"
|
||||
when (telephonyManager.networkType) {
|
||||
// Unknown
|
||||
TelephonyManager.NETWORK_TYPE_UNKNOWN -> "Cellular - Unknown"
|
||||
// Cellular Data–2G
|
||||
TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_CDMA,
|
||||
TelephonyManager.NETWORK_TYPE_IDEN, TelephonyManager.NETWORK_TYPE_1xRTT -> "Cellular - 2G"
|
||||
// Cellular Data–3G
|
||||
TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSPA,
|
||||
TelephonyManager.NETWORK_TYPE_HSPAP, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_EVDO_0,
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B -> "Cellular - 3G"
|
||||
// Cellular Data–4G
|
||||
TelephonyManager.NETWORK_TYPE_LTE -> "Cellular - 4G"
|
||||
else -> "Cellular - Unknown Generation"
|
||||
}
|
||||
|
||||
}
|
||||
else -> "unknown"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getIP(): String {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
fun getOS(): String {
|
||||
return "android"
|
||||
}
|
||||
}
|
||||
27
app/src/main/java/com/gh/common/exposure/time/Corrector.kt
Normal file
27
app/src/main/java/com/gh/common/exposure/time/Corrector.kt
Normal file
@ -0,0 +1,27 @@
|
||||
package com.gh.common.exposure.time
|
||||
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import rx.schedulers.Schedulers
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
class Corrector {
|
||||
|
||||
companion object {
|
||||
const val TIME_CORRECTOR_ADJUST_PERIOD: Long = 600000
|
||||
}
|
||||
|
||||
var delta: Long = 0
|
||||
|
||||
init {
|
||||
fixedRateTimer("TimeUtil-Corrector-Checker", initialDelay = 0, period = TIME_CORRECTOR_ADJUST_PERIOD) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe({
|
||||
val serverTime = java.lang.Long.parseLong(it.string())
|
||||
delta = serverTime * 1000 - System.currentTimeMillis()
|
||||
}, Throwable::printStackTrace)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
22
app/src/main/java/com/gh/common/exposure/time/TimeUtil.kt
Normal file
22
app/src/main/java/com/gh/common/exposure/time/TimeUtil.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package com.gh.common.exposure.time
|
||||
|
||||
object TimeUtil {
|
||||
|
||||
private lateinit var corrector: Corrector
|
||||
|
||||
fun currentTimeMillis(): Long {
|
||||
return corrector.delta + System.currentTimeMillis()
|
||||
}
|
||||
|
||||
fun currentTime(): Int {
|
||||
return ( ( corrector.delta + System.currentTimeMillis() ) / 1000 ).toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called early then real use (for example in Application)
|
||||
*/
|
||||
fun init() {
|
||||
corrector = Corrector()
|
||||
}
|
||||
|
||||
}
|
||||
@ -22,7 +22,7 @@ public class ApkActiveUtils {
|
||||
ApkEntity apkEntity = apkList.get(i);
|
||||
String packageName = apkEntity.getPackageName();
|
||||
String id = gameEntity.getId();
|
||||
if (!apkEntity.isActive() && !PackageManager.isCanPluggable(id, packageName)) {
|
||||
if (!apkEntity.isActive() && !PackageManager.INSTANCE.isCanPluggable(id, packageName)) {
|
||||
apkList.remove(i);
|
||||
i--;
|
||||
}
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import retrofit2.HttpException;
|
||||
|
||||
/**
|
||||
* Created by khy on 28/12/17.
|
||||
*/
|
||||
|
||||
public class AskErrorResponseUtils {
|
||||
|
||||
public static void errorResponseControl(Context context, HttpException e) {
|
||||
if (e == null) return;
|
||||
int code = e.code();
|
||||
try {
|
||||
if (code == 403) {
|
||||
JSONObject object = new JSONObject(e.response().errorBody().string());
|
||||
int errorCode = object.getInt("code");
|
||||
switch (errorCode) {
|
||||
case 403001:
|
||||
Utils.toast(context, "标签名称太长了");
|
||||
break;
|
||||
case 403002:
|
||||
Utils.toast(context, "已经被邀请了");
|
||||
break;
|
||||
case 403003:
|
||||
Utils.toast(context, "每天最多只能邀请10次");
|
||||
break;
|
||||
case 403004:
|
||||
Utils.toast(context, "客户端提供的ID无效(空/无效ID)");
|
||||
break;
|
||||
case 403005:
|
||||
Utils.toast(context, "已经回答过了(限制频率)");
|
||||
break;
|
||||
case 403006:
|
||||
Utils.toast(context, "图片数量达到限制点");
|
||||
break;
|
||||
case 403007:
|
||||
Utils.toast(context, "不合法的用户");
|
||||
break;
|
||||
case 403008:
|
||||
Utils.toast(context, "已投票");
|
||||
break;
|
||||
case 403009:
|
||||
Utils.toast(context, "已经收藏过了");
|
||||
break;
|
||||
case 403010:
|
||||
Utils.toast(context, "无效的标签栏");
|
||||
break;
|
||||
case 403011:
|
||||
Utils.toast(context, "标题内容过长");
|
||||
break;
|
||||
case 403012:
|
||||
Utils.toast(context, "描述内容过长");
|
||||
break;
|
||||
case 403013:
|
||||
Utils.toast(context, "无效的标签");
|
||||
break;
|
||||
case 403014:
|
||||
Utils.toast(context, "标签数量太多了");
|
||||
break;
|
||||
case 403015:
|
||||
Utils.toast(context, "已经关注过了");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "网络错误");
|
||||
break;
|
||||
}
|
||||
} else if (code == 401) {
|
||||
JSONObject object = new JSONObject(e.response().errorBody().string());
|
||||
int errorCode = object.getInt("code");
|
||||
if (errorCode == 404001) {
|
||||
Utils.toast(context, "请求的资源不存在");
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, "网络错误");
|
||||
}
|
||||
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
122
app/src/main/java/com/gh/common/util/AskLogUtils.java
Normal file
122
app/src/main/java/com/gh/common/util/AskLogUtils.java
Normal file
@ -0,0 +1,122 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.qa.entity.Questions;
|
||||
import com.gh.loghub.LogHubUtils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Created by khy on 2/01/18.
|
||||
*/
|
||||
public class AskLogUtils {
|
||||
|
||||
|
||||
public static void uploadQuestions(Context context, String tracers, Questions questions) {
|
||||
if (context == null) return;
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("community_id", UserManager.getInstance().getCommunity().getId());
|
||||
object.put("community_name", UserManager.getInstance().getCommunity().getName());
|
||||
object.put("question_id", questions.getId());
|
||||
object.put("question_name", questions.getTitle());
|
||||
object.put("subject", "question");
|
||||
object.put("tracers", tracers);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
upload(context, object);
|
||||
}
|
||||
|
||||
public static void uploadAnswers(Context context, String tracers, Questions questions, String answerId) {
|
||||
if (context == null) return;
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("community_id", UserManager.getInstance().getCommunity().getId());
|
||||
object.put("community_name", UserManager.getInstance().getCommunity().getName());
|
||||
object.put("question_id", questions.getId());
|
||||
object.put("question_name", questions.getTitle());
|
||||
object.put("subject", "answer");
|
||||
object.put("tracers", tracers);
|
||||
object.put("answer_id", answerId);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
upload(context, object);
|
||||
}
|
||||
|
||||
public static void uploadSearch(Context context, String searchKey) {
|
||||
if (TextUtils.isEmpty(searchKey) || context == null) return;
|
||||
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("community_id", UserManager.getInstance().getCommunity().getId());
|
||||
object.put("community_name", UserManager.getInstance().getCommunity().getName());
|
||||
object.put("keyword", searchKey);
|
||||
object.put("subject", "search");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
upload(context, object);
|
||||
}
|
||||
|
||||
|
||||
public static void communityRefresh(Context context, int dataCount) {
|
||||
if (context == null) return;
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("subject", "community_refresh");
|
||||
object.put("community_id", UserManager.getInstance().getCommunity().getId());
|
||||
object.put("refresh_type", "recommend");
|
||||
object.put("data_count", dataCount);
|
||||
object.put("user_id", UserManager.getInstance().getUserId());
|
||||
object.put("network", DeviceUtils.getNetwork(context));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
upload(context, object);
|
||||
}
|
||||
|
||||
public static void login(Context context, String loginStep, String loginType) {
|
||||
if (context == null) return;
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("subject", "login");
|
||||
object.put("step", loginStep);
|
||||
object.put("login_type", loginType);
|
||||
object.put("network", DeviceUtils.getNetwork(context));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
upload(context, object);
|
||||
}
|
||||
|
||||
private static void upload(Context context, JSONObject object) {
|
||||
if (context == null) return;
|
||||
try {
|
||||
object.put("version", BuildConfig.PATCH_VERSION_NAME);
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("imei", Util_System_Phone_State.getDeviceId(context));
|
||||
object.put("time", Utils.getTime(context));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
LogHubUtils.uploadLog(DeviceUtils.getIPAddress(context), object);
|
||||
}
|
||||
}
|
||||
50
app/src/main/java/com/gh/common/util/AskUtils.java
Normal file
50
app/src/main/java/com/gh/common/util/AskUtils.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/12/17.
|
||||
*/
|
||||
|
||||
public class AskUtils {
|
||||
|
||||
public static String voteCountFormat(int voteCount) {
|
||||
String vote;
|
||||
if (voteCount >= 10000) {
|
||||
DecimalFormat df = new DecimalFormat("#.0万");
|
||||
vote = df.format(voteCount / 10000f);
|
||||
} else {
|
||||
vote = String.valueOf(voteCount);
|
||||
}
|
||||
return vote;
|
||||
}
|
||||
|
||||
public static String stripHtml(String htmlStr) {
|
||||
|
||||
|
||||
if (TextUtils.isEmpty(htmlStr)) return "";
|
||||
|
||||
String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
|
||||
String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
|
||||
String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
|
||||
|
||||
Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_script = p_script.matcher(htmlStr);
|
||||
htmlStr = m_script.replaceAll(""); //过滤script标签
|
||||
|
||||
Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_style = p_style.matcher(htmlStr);
|
||||
htmlStr = m_style.replaceAll(""); //过滤style标签
|
||||
|
||||
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_html = p_html.matcher(htmlStr);
|
||||
htmlStr = m_html.replaceAll(""); //过滤html标签
|
||||
|
||||
return htmlStr.trim(); //返回文本字符串
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,6 +9,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.media.ExifInterface;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -27,13 +28,16 @@ public class BitmapUtils {
|
||||
*/
|
||||
public static boolean savePicture(String newPath, String filePath) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
// options.inSampleSize = 2;
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(filePath, options);
|
||||
options.inSampleSize = 2;
|
||||
options.inJustDecodeBounds = false;
|
||||
|
||||
File file = new File(newPath);
|
||||
int quality = 80;
|
||||
do {
|
||||
try {
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
|
||||
bos.flush();
|
||||
@ -51,6 +55,62 @@ public class BitmapUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存图片
|
||||
*
|
||||
* @param newPath
|
||||
* @param filePath
|
||||
* @return
|
||||
*/
|
||||
public static boolean savePicture(String newPath, String filePath, int compressSize) {
|
||||
if (compressSize > new File(filePath).length()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(filePath, options);
|
||||
options.inSampleSize = 2;
|
||||
options.inJustDecodeBounds = false;
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
float zoom = (float) Math.sqrt(compressSize / (float) bos.toByteArray().length);
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setScale(zoom, zoom);
|
||||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
bos.reset();
|
||||
bitmap.recycle();
|
||||
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
while (bos.toByteArray().length > compressSize) {
|
||||
matrix.setScale(0.9f, 0.9f);
|
||||
|
||||
result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);
|
||||
bos.reset();
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
}
|
||||
|
||||
File file = new File(newPath);
|
||||
try {
|
||||
BufferedOutputStream fbos = new BufferedOutputStream(new FileOutputStream(file));
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 85, fbos);
|
||||
fbos.flush();
|
||||
fbos.close();
|
||||
|
||||
result.recycle();
|
||||
} catch (Exception e) {
|
||||
file.delete();
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件路径返回bitmap
|
||||
*
|
||||
|
||||
@ -5,6 +5,7 @@ import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.gamecenter.LoginActivity;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
|
||||
/**
|
||||
* Created by khy on 28/06/17.
|
||||
@ -12,24 +13,29 @@ import com.gh.gamecenter.LoginActivity;
|
||||
|
||||
public class CheckLoginUtils {
|
||||
|
||||
public static void checkLogin(final Context context, OnLoggenInListener listener) {
|
||||
String token = LoginUtils.getToken(context);
|
||||
if (TextUtils.isEmpty(token)) {
|
||||
public static void checkLogin(final Context context, OnLoginListener listener) {
|
||||
// String token = LoginUtils.getToken(context);
|
||||
if (TextUtils.isEmpty(UserManager.getInstance().getToken())) {
|
||||
AskLogUtils.login(context, "dialog", null);
|
||||
DialogUtils.showWarningDialog(context, "登录提示", "需要登录才能使用该功能喔!", "取消", "快速登录",
|
||||
new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
Intent intent = LoginActivity.getIntent(context, false);
|
||||
AskLogUtils.login(context, "activity", null);
|
||||
Intent intent = LoginActivity.getIntent(context);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}, null);
|
||||
} else {
|
||||
listener.onLoggedIn();
|
||||
listener.onLogin();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isLogin() {
|
||||
return !TextUtils.isEmpty(UserManager.getInstance().getToken());
|
||||
}
|
||||
|
||||
public interface OnLoggenInListener {
|
||||
void onLoggedIn();
|
||||
public interface OnLoginListener {
|
||||
void onLogin();
|
||||
}
|
||||
}
|
||||
|
||||
44
app/src/main/java/com/gh/common/util/ClickUtils.java
Normal file
44
app/src/main/java/com/gh/common/util/ClickUtils.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class ClickUtils {
|
||||
|
||||
private static long lastClickTime = 0;
|
||||
private static long DIFF = 800;
|
||||
private static int lastButtonId = -1;
|
||||
|
||||
/**
|
||||
* 判断两次点击的间隔,如果小于800,则认为是多次无效点击 * * @return
|
||||
*/
|
||||
public static boolean isFastDoubleClick() {
|
||||
return isFastDoubleClick(-1, DIFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两次点击的间隔,如果小于800,则认为是多次无效点击 * * @return
|
||||
*/
|
||||
public static boolean isFastDoubleClick(int buttonId) {
|
||||
return isFastDoubleClick(buttonId, DIFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两次点击的间隔,如果小于diff,则认为是多次无效点击 * * @param diff * @return
|
||||
*/
|
||||
public static boolean isFastDoubleClick(int buttonId, long diff) {
|
||||
long time = System.currentTimeMillis();
|
||||
long timeD = time - lastClickTime;
|
||||
if (lastButtonId == buttonId && lastClickTime > 0 && timeD < diff) {
|
||||
Log.v("isFastDoubleClick", "短时间内按钮多次触发");
|
||||
return true;
|
||||
}
|
||||
lastClickTime = time;
|
||||
lastButtonId = buttonId;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void releaseInterval() {
|
||||
lastButtonId = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,10 +2,9 @@ package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.eventbus.EBCollectionChanged
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONObject
|
||||
@ -20,15 +19,15 @@ import rx.schedulers.Schedulers
|
||||
object CollectionUtils {
|
||||
|
||||
enum class CollectionType {
|
||||
toolkit, article
|
||||
toolkit, article, answer
|
||||
}
|
||||
|
||||
fun postCollection(context: Context, content: String, type: CollectionType, listener: OnCollectionListener) {
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), content)
|
||||
val postCollection = when (type) {
|
||||
CollectionType.article -> RetrofitManager.getInstance(context).getApi().postCollectionArticle(body)
|
||||
CollectionType.toolkit -> RetrofitManager.getInstance(context).getApi().postCollectionTools(body)
|
||||
CollectionType.article -> RetrofitManager.getInstance(context).getApi().postCollectionArticle(UserManager.getInstance().userId, content)
|
||||
CollectionType.toolkit -> RetrofitManager.getInstance(context).getApi().postCollectionTools(UserManager.getInstance().userId, content)
|
||||
CollectionType.answer -> RetrofitManager.getInstance(context).getApi().postCollectionAnswer(UserManager.getInstance().userId, content)
|
||||
}
|
||||
postCollection
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -37,7 +36,8 @@ object CollectionUtils {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
listener.onSuccess()
|
||||
EventBus.getDefault().post(EBCollectionChanged(JSONObject(content).getString("_id"), true, type))
|
||||
if(type != CollectionType.answer)
|
||||
EventBus.getDefault().post(EBCollectionChanged(content, true, type))
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
@ -46,7 +46,7 @@ object CollectionUtils {
|
||||
try {
|
||||
val string = e.response()?.errorBody()?.string()
|
||||
val errorBody = JSONObject(string)
|
||||
if (errorBody.getInt("status") == 40031) {
|
||||
if (errorBody.getInt("detail") == 403009) {
|
||||
listener.onSuccess()
|
||||
return
|
||||
}
|
||||
@ -63,8 +63,9 @@ object CollectionUtils {
|
||||
|
||||
val postCollection: Observable<ResponseBody>
|
||||
when (type) {
|
||||
CollectionType.article -> postCollection = RetrofitManager.getInstance(context).getApi().deletaCollectionArticle(id)
|
||||
CollectionType.toolkit -> postCollection = RetrofitManager.getInstance(context).getApi().deleteCollectionTools(id)
|
||||
CollectionType.article -> postCollection = RetrofitManager.getInstance(context).getApi().deletaCollectionArticle(UserManager.getInstance().userId, id)
|
||||
CollectionType.toolkit -> postCollection = RetrofitManager.getInstance(context).getApi().deleteCollectionTools(UserManager.getInstance().userId, id)
|
||||
CollectionType.answer -> postCollection = RetrofitManager.getInstance(context).getApi().deleteCollectionAnswer(UserManager.getInstance().userId, id)
|
||||
}
|
||||
postCollection
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -73,6 +74,7 @@ object CollectionUtils {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
listener.onSuccess()
|
||||
if(type != CollectionType.answer)
|
||||
EventBus.getDefault().post(EBCollectionChanged(id, false, type))
|
||||
}
|
||||
|
||||
@ -83,17 +85,6 @@ object CollectionUtils {
|
||||
})
|
||||
}
|
||||
|
||||
fun patchCollection(context: Context, id: String, type: CollectionType) {
|
||||
val postCollection = when (type) {
|
||||
CollectionType.article -> RetrofitManager.getInstance(context).getApi().patchCollectionArticle(id)
|
||||
CollectionType.toolkit -> RetrofitManager.getInstance(context).getApi().patchCollectionTools(id)
|
||||
}
|
||||
postCollection
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>() {})
|
||||
}
|
||||
|
||||
|
||||
interface OnCollectionListener {
|
||||
fun onSuccess()
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
@ -17,8 +18,9 @@ import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.OnCommentCallBackListener;
|
||||
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.entity.UserDataEntity;
|
||||
import com.gh.gamecenter.entity.MeEntity;
|
||||
import com.gh.gamecenter.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -69,7 +71,7 @@ public class CommentUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showReportDialog(final CommentEntity commentEntity, final Context context,
|
||||
public static void showReportDialog(final CommentEntity commentEntity, final Context context, final boolean showConversation,
|
||||
final OnCommentCallBackListener listener, final String newsId) {
|
||||
|
||||
final Dialog dialog = new Dialog(context);
|
||||
@ -81,14 +83,14 @@ public class CommentUtils {
|
||||
|
||||
List<String> dialogType = new ArrayList<>();
|
||||
|
||||
if (commentEntity.getUserData() == null || !commentEntity.getUserData().isCommentOwn()) {
|
||||
if (commentEntity.getMe() == null || !commentEntity.getMe().isCommentOwn()) {
|
||||
dialogType.add("回复");
|
||||
}
|
||||
|
||||
dialogType.add("复制");
|
||||
dialogType.add("举报");
|
||||
|
||||
if (commentEntity.getParent() != null) {
|
||||
if (commentEntity.getParent() != null && showConversation) {
|
||||
dialogType.add("查看对话");
|
||||
}
|
||||
|
||||
@ -111,33 +113,25 @@ public class CommentUtils {
|
||||
dialog.cancel();
|
||||
switch (reportTv.getText().toString()) {
|
||||
case "回复":
|
||||
CheckLoginUtils.checkLogin(context, new CheckLoginUtils.OnLoggenInListener() {
|
||||
@Override
|
||||
public void onLoggedIn() {
|
||||
if (listener != null) {
|
||||
listener.onCommentCallback(commentEntity);
|
||||
} else if (!TextUtils.isEmpty(newsId)) {
|
||||
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, newsId));
|
||||
} else {
|
||||
Utils.toast(context, "缺少关键属性");
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, () -> {
|
||||
if (listener != null) {
|
||||
listener.onCommentCallback(commentEntity);
|
||||
} else if (!TextUtils.isEmpty(newsId)) {
|
||||
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, newsId));
|
||||
} else {
|
||||
Utils.toast(context, "缺少关键属性");
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "复制":
|
||||
LibaoUtils.copyLink(commentEntity.getContent(), context);
|
||||
copyText(commentEntity.getContent(), context);
|
||||
break;
|
||||
case "举报":
|
||||
CheckLoginUtils.checkLogin(context, new CheckLoginUtils.OnLoggenInListener() {
|
||||
@Override
|
||||
public void onLoggedIn() {
|
||||
showReportTypeDialog(commentEntity, context);
|
||||
}
|
||||
});
|
||||
CheckLoginUtils.checkLogin(context, () -> showReportTypeDialog(commentEntity, context));
|
||||
|
||||
break;
|
||||
case "查看对话":
|
||||
context.startActivity(CommentDetailActivity.getCommentDetailIntent(context, commentEntity.getId()));
|
||||
context.startActivity(CommentDetailActivity.getIntent(context, commentEntity.getId(), null));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -150,27 +144,147 @@ public class CommentUtils {
|
||||
|
||||
}
|
||||
|
||||
private static void showReportTypeDialog(final CommentEntity commentEntity, final Context mContext) {
|
||||
public static void showAnswerCommentOptions(final CommentEntity commentEntity, final Context context,
|
||||
final OnCommentCallBackListener listener, final String id, boolean showConversation, String answerId) {
|
||||
|
||||
final Dialog dialog = new Dialog(context);
|
||||
|
||||
LinearLayout container = new LinearLayout(context);
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
container.setBackgroundColor(Color.WHITE);
|
||||
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
|
||||
|
||||
List<String> dialogType = new ArrayList<>();
|
||||
|
||||
if (commentEntity.getMe() == null || !commentEntity.getMe().isAnswerCommented()) {
|
||||
dialogType.add("回复");
|
||||
}
|
||||
|
||||
dialogType.add("复制");
|
||||
dialogType.add("举报");
|
||||
|
||||
if (commentEntity.getParentUser() != null && showConversation) {
|
||||
dialogType.add("查看对话");
|
||||
}
|
||||
|
||||
for (String s : dialogType) {
|
||||
final TextView reportTv = new TextView(context);
|
||||
reportTv.setText(s);
|
||||
reportTv.setTextSize(17);
|
||||
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
|
||||
reportTv.setBackgroundResource(R.drawable.textview_white_style);
|
||||
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
|
||||
reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
reportTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
|
||||
0, DisplayUtils.dip2px(context, 12));
|
||||
container.addView(reportTv);
|
||||
|
||||
reportTv.setOnClickListener(v -> {
|
||||
dialog.cancel();
|
||||
switch (reportTv.getText().toString()) {
|
||||
case "回复":
|
||||
CheckLoginUtils.checkLogin(context, () -> {
|
||||
if (listener != null) {
|
||||
listener.onCommentCallback(commentEntity);
|
||||
} else if (!TextUtils.isEmpty(id)) {
|
||||
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, id));
|
||||
} else {
|
||||
Utils.toast(context, "缺少关键属性");
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "复制":
|
||||
copyText(commentEntity.getContent(), context);
|
||||
break;
|
||||
case "举报":
|
||||
CheckLoginUtils.checkLogin(context, () -> showAnswerReportDialog(answerId, commentEntity, context));
|
||||
break;
|
||||
case "查看对话":
|
||||
context.startActivity(CommentDetailActivity.getAnswerCommentIntent(context, commentEntity.getId(), answerId));
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(container);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private static void showAnswerReportDialog(final String answerId, final CommentEntity commentEntity, final Context context) {
|
||||
final String[] arrReportType = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息",
|
||||
"违法有害信息", "其它"};
|
||||
int widthPixels = mContext.getResources().getDisplayMetrics().widthPixels;
|
||||
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
|
||||
|
||||
final Dialog reportTypeDialog = new Dialog(mContext);
|
||||
LinearLayout container = new LinearLayout(mContext);
|
||||
final Dialog reportTypeDialog = new Dialog(context);
|
||||
LinearLayout container = new LinearLayout(context);
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
container.setPadding(0, DisplayUtils.dip2px(mContext, 12), 0, DisplayUtils.dip2px(mContext, 12));
|
||||
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
|
||||
container.setBackgroundColor(Color.WHITE);
|
||||
|
||||
for (final String s : arrReportType) {
|
||||
TextView reportTypeTv = new TextView(mContext);
|
||||
TextView reportTypeTv = new TextView(context);
|
||||
reportTypeTv.setText(s);
|
||||
reportTypeTv.setTextSize(17);
|
||||
reportTypeTv.setTextColor(ContextCompat.getColor(mContext, R.color.title));
|
||||
reportTypeTv.setTextColor(ContextCompat.getColor(context, R.color.title));
|
||||
reportTypeTv.setBackgroundResource(R.drawable.textview_white_style);
|
||||
reportTypeTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
reportTypeTv.setPadding(DisplayUtils.dip2px(mContext, 20), DisplayUtils.dip2px(mContext, 12),
|
||||
0, DisplayUtils.dip2px(mContext, 12));
|
||||
reportTypeTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
|
||||
0, DisplayUtils.dip2px(context, 12));
|
||||
container.addView(reportTypeTv);
|
||||
|
||||
reportTypeTv.setOnClickListener(v -> {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("reason", s);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
PostCommentUtils.postAnswerReportData(context, commentEntity.getId(), answerId, jsonObject.toString(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
Utils.toast(context, "感谢您的举报");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable error) {
|
||||
Utils.toast(context, error.toString());
|
||||
}
|
||||
});
|
||||
reportTypeDialog.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
reportTypeDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
reportTypeDialog.setContentView(container);
|
||||
reportTypeDialog.show();
|
||||
}
|
||||
|
||||
private static void showReportTypeDialog(final CommentEntity commentEntity, final Context context) {
|
||||
final String[] arrReportType = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息",
|
||||
"违法有害信息", "其它"};
|
||||
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
|
||||
|
||||
final Dialog reportTypeDialog = new Dialog(context);
|
||||
LinearLayout container = new LinearLayout(context);
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
|
||||
container.setBackgroundColor(Color.WHITE);
|
||||
|
||||
for (final String s : arrReportType) {
|
||||
TextView reportTypeTv = new TextView(context);
|
||||
reportTypeTv.setText(s);
|
||||
reportTypeTv.setTextSize(17);
|
||||
reportTypeTv.setTextColor(ContextCompat.getColor(context, R.color.title));
|
||||
reportTypeTv.setBackgroundResource(R.drawable.textview_white_style);
|
||||
reportTypeTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
reportTypeTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
|
||||
0, DisplayUtils.dip2px(context, 12));
|
||||
container.addView(reportTypeTv);
|
||||
|
||||
reportTypeTv.setOnClickListener(new View.OnClickListener() {
|
||||
@ -184,16 +298,16 @@ public class CommentUtils {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
PostCommentUtils.addReportData(mContext, jsonObject.toString(),
|
||||
PostCommentUtils.addReportData(context, commentEntity.getId(), jsonObject.toString(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
Utils.toast(mContext, "感谢您的举报");
|
||||
Utils.toast(context, "感谢您的举报");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable error) {
|
||||
Utils.toast(mContext, "举报失败,请检查网络设置");
|
||||
Utils.toast(context, "举报失败,请检查网络设置");
|
||||
}
|
||||
});
|
||||
reportTypeDialog.cancel();
|
||||
@ -208,73 +322,125 @@ public class CommentUtils {
|
||||
|
||||
public static void postVote(final Context context, final CommentEntity commentEntity,
|
||||
final TextView commentLikeCountTv, final ImageView commentLikeIv, final OnVoteListener listener) {
|
||||
CheckLoginUtils.checkLogin(context, new CheckLoginUtils.OnLoggenInListener() {
|
||||
@Override
|
||||
public void onLoggedIn() {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
return;
|
||||
}
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
commentLikeIv.setImageResource(R.drawable.ic_like_select);
|
||||
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
|
||||
PostCommentUtils.addCommentVoto(context, commentEntity.getId(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
if (listener != null) {
|
||||
listener.onVote();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable e) {
|
||||
|
||||
commentEntity.setVote(commentEntity.getVote() - 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
commentLikeIv.setImageResource(R.drawable.ic_like_unselect);
|
||||
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
|
||||
if (commentEntity.getVote() == 0) {
|
||||
commentLikeCountTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (e instanceof HttpException) {
|
||||
HttpException exception = (HttpException) e;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "网络异常,点赞失败");
|
||||
}
|
||||
});
|
||||
CheckLoginUtils.checkLogin(context, () -> {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
return;
|
||||
}
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
commentLikeIv.setImageResource(R.drawable.ic_like_select);
|
||||
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
|
||||
PostCommentUtils.addCommentVoto(context, commentEntity.getId(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
if (listener != null) {
|
||||
listener.onVote();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable e) {
|
||||
|
||||
commentEntity.setVote(commentEntity.getVote() - 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
commentLikeIv.setImageResource(R.drawable.ic_like_unselect);
|
||||
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
|
||||
if (commentEntity.getVote() == 0) {
|
||||
commentLikeCountTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (e instanceof HttpException) {
|
||||
HttpException exception = (HttpException) e;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "网络异常,点赞失败");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static void postVoteToAnswerComment(final Context context, String answerId, final CommentEntity commentEntity,
|
||||
final TextView commentLikeCountTv, final ImageView commentLikeIv, final OnVoteListener listener) {
|
||||
CheckLoginUtils.checkLogin(context, () -> {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
return;
|
||||
}
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
commentLikeIv.setImageResource(R.drawable.ic_like_select);
|
||||
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
|
||||
PostCommentUtils.voteAnswerComment(context, answerId, commentEntity.getId(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
if (listener != null) {
|
||||
listener.onVote();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable e) {
|
||||
|
||||
commentEntity.setVote(commentEntity.getVote() - 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
commentLikeIv.setImageResource(R.drawable.ic_like_unselect);
|
||||
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
|
||||
if (commentEntity.getVote() == 0) {
|
||||
commentLikeCountTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (e instanceof HttpException) {
|
||||
HttpException exception = (HttpException) e;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "网络异常,点赞失败");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 设置评论item 用户相关的view(点赞/头像/用户名)
|
||||
public static void setCommentUserView(Context mContext, CommentViewHolder holder, CommentEntity entity) {
|
||||
UserDataEntity userDataEntity = entity.getUserData();
|
||||
MeEntity userDataEntity = entity.getMe();
|
||||
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.hint));
|
||||
holder.commentLikeIv.setImageResource(R.drawable.ic_like_unselect);
|
||||
|
||||
if (entity.getVote() == 0) {
|
||||
holder.commentLikeCountTv.setVisibility(View.GONE);
|
||||
} else { // 检查是否已点赞
|
||||
if (userDataEntity != null && userDataEntity.isCommentVoted()) {
|
||||
if (userDataEntity != null && (userDataEntity.isCommentVoted() || userDataEntity.isAnswerCommentVoted())) {
|
||||
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
|
||||
holder.commentLikeIv.setImageResource(R.drawable.ic_like_select);
|
||||
}
|
||||
@ -283,12 +449,20 @@ public class CommentUtils {
|
||||
}
|
||||
|
||||
//检查是否是自身评论
|
||||
UserInfoEntity userInfo = LoginUtils.getUserInfo(mContext);
|
||||
UserInfoEntity userInfo = UserManager.getInstance().getUserInfoEntity();
|
||||
if (userDataEntity != null && userDataEntity.isCommentOwn() && userInfo != null) {
|
||||
holder.commentUserNameTv.setText(userInfo.getName());
|
||||
if (entity.getMe() != null && entity.getMe().isAnswerOwn()) {
|
||||
holder.commentUserNameTv.setText(userInfo.getName() + "(作者)");
|
||||
} else {
|
||||
holder.commentUserNameTv.setText(userInfo.getName());
|
||||
}
|
||||
ImageUtils.Companion.display(holder.commentUserIconDv, userInfo.getIcon());
|
||||
} else {
|
||||
holder.commentUserNameTv.setText(entity.getUser().getName());
|
||||
if (entity.getMe() != null && entity.getMe().isAnswerOwn()) {
|
||||
holder.commentUserNameTv.setText(entity.getUser().getName() + "(作者)");
|
||||
} else {
|
||||
holder.commentUserNameTv.setText(entity.getUser().getName());
|
||||
}
|
||||
if (TextUtils.isEmpty(entity.getUser().getIcon())) {
|
||||
ImageUtils.Companion.display(holder.commentUserIconDv, R.drawable.user_default_icon_comment);
|
||||
} else {
|
||||
@ -297,6 +471,15 @@ public class CommentUtils {
|
||||
}
|
||||
}
|
||||
|
||||
//复制文字
|
||||
public static void copyText(String copyContent, Context context) {
|
||||
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(copyContent);
|
||||
|
||||
Utils.toast(context, "复制成功");
|
||||
}
|
||||
|
||||
|
||||
public interface OnVoteListener {
|
||||
void onVote();
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.eventbus.EBConcernChanged
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import okhttp3.MediaType
|
||||
@ -20,14 +21,14 @@ import rx.schedulers.Schedulers
|
||||
object ConcernUtils {
|
||||
|
||||
fun postConcernGameId(context: Context, gameId: String, listener: onConcernListener?) {
|
||||
val params = JSONArray()
|
||||
params.put(gameId)
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), params.toString())
|
||||
// val params = JSONArray()
|
||||
// params.put(gameId)
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), params.toString())
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.postConcern(body)
|
||||
.postConcern(UserManager.getInstance().userId, gameId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>(){
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
listener?.onSuccess()
|
||||
@ -43,10 +44,10 @@ object ConcernUtils {
|
||||
|
||||
fun deleteConcernData(context: Context, gameId: String, listener: onConcernListener?) {
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.deleteConcern(gameId)
|
||||
.deleteConcern(UserManager.getInstance().userId, gameId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>(){
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
listener?.onSuccess()
|
||||
@ -64,7 +65,7 @@ object ConcernUtils {
|
||||
val body = RequestBody.create(MediaType.parse("application/json"),
|
||||
data.toString())
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.putConcern(body)
|
||||
.putConcern(UserManager.getInstance().userId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
@ -75,6 +76,44 @@ object ConcernUtils {
|
||||
})
|
||||
}
|
||||
|
||||
fun deleteConcernQuestions(context: Context, questionsId: String, listener: onConcernListener?) {
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.deleteConcernQuestions(UserManager.getInstance().userId, questionsId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
listener?.onSuccess()
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
super.onFailure(e)
|
||||
listener?.onError()
|
||||
AskErrorResponseUtils.errorResponseControl(context, e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun postConcernQuestions(context: Context, questionsId: String, listener: onConcernListener?) {
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.postConcernQuestions(UserManager.getInstance().userId, questionsId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
listener?.onSuccess()
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
super.onFailure(e)
|
||||
listener?.onError()
|
||||
AskErrorResponseUtils.errorResponseControl(context, e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
interface onConcernListener {
|
||||
fun onSuccess()
|
||||
|
||||
@ -3,17 +3,14 @@ package com.gh.common.util;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.gh.gamecenter.db.info.ConcernInfo;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.NewsDetailEntity;
|
||||
import com.gh.gamecenter.manager.ConcernManager;
|
||||
import com.gh.gamecenter.manager.DataCollectionManager;
|
||||
import com.gh.gamecenter.manager.PackageManager;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -118,18 +115,10 @@ public class DataCollectionUtils {
|
||||
|
||||
// 上传用户数据
|
||||
public static void uploadUser(Context context) {
|
||||
ConcernManager concernManager = new ConcernManager(context);
|
||||
ArrayList<String> concernList = new ArrayList<>();
|
||||
for (ConcernInfo entity : concernManager.getAllConcern()) {
|
||||
if (entity.isConcern()) {
|
||||
concernList.add(entity.getGameName());
|
||||
}
|
||||
}
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("type", Build.MODEL);
|
||||
map.put("system", Build.VERSION.SDK_INT + "=" + Build.VERSION.RELEASE);
|
||||
map.put("install", PackageManager.getInstalledList());
|
||||
map.put("concern", concernList);
|
||||
map.put("install", PackageManager.INSTANCE.getInstalledList());
|
||||
DataCollectionManager.upsert(context, "user", map);
|
||||
}
|
||||
|
||||
|
||||
@ -3,18 +3,20 @@ package com.gh.common.util;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.halo.assistant.TinkerApp;
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
import com.tencent.mta.track.StatisticsDataAPI;
|
||||
import com.tencent.stat.MtaSDkException;
|
||||
import com.tencent.stat.StatConfig;
|
||||
import com.tencent.stat.StatCrashReporter;
|
||||
import com.tencent.stat.StatReportStrategy;
|
||||
import com.tencent.stat.StatService;
|
||||
import com.tencent.tinker.lib.tinker.Tinker;
|
||||
import com.tendcloud.tenddata.TCAgent;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -31,14 +33,16 @@ public class DataUtils {
|
||||
* 初始化各种统计工具,仅在release build(非debug)模式启用统计
|
||||
*
|
||||
* @param context
|
||||
* @param debug 是否debug模式
|
||||
* @param channel
|
||||
*/
|
||||
public static void init(final Application context, final boolean debug, String channel) {
|
||||
public static void init(final Application context, String channel) {
|
||||
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
return;
|
||||
}
|
||||
//TalkingData
|
||||
try {
|
||||
TCAgent.LOG_ON = debug;
|
||||
TCAgent.LOG_ON = false;
|
||||
TCAgent.init(context, Config.TALKINGDATA_APPID, channel);
|
||||
/**
|
||||
*
|
||||
@ -61,10 +65,11 @@ public class DataUtils {
|
||||
crashReporter.setJavaCrashHandlerStatus(false);
|
||||
// crashReporter.setEnableInstantReporting(true);
|
||||
|
||||
StatConfig.setDebugEnable(debug);
|
||||
StatConfig.setDebugEnable(false);
|
||||
|
||||
// 设置数据上报策略
|
||||
if (debug) {
|
||||
// 测试渠道的时候即时上传,方便查看日志
|
||||
if ("GH_TEST".equals(HaloApp.getInstance().getChannel())) {
|
||||
StatConfig.setStatSendStrategy(StatReportStrategy.INSTANT);
|
||||
} else {
|
||||
StatConfig.setStatSendStrategy(StatReportStrategy.PERIOD);
|
||||
@ -74,25 +79,22 @@ public class DataUtils {
|
||||
// 设置启用Tlink
|
||||
StatConfig.setTLinkStatus(true);
|
||||
|
||||
// 设置启用可视化埋点
|
||||
StatisticsDataAPI.instance(context);
|
||||
|
||||
StatConfig.init(context);
|
||||
StatConfig.setInstallChannel(channel);
|
||||
StatConfig.setAntoActivityLifecycleStat(true);
|
||||
StatConfig.setAppVersion(PackageUtils.getPatchVersionName());
|
||||
|
||||
StatService.setContext(context);
|
||||
StatService.registerActivityLifecycleCallbacks(context);
|
||||
// 开启收集服务
|
||||
StatService.startStatService(context, Config.MTA_APPKEY, com.tencent.stat.common.StatConstants.VERSION);
|
||||
StatService.registerActivityLifecycleCallbacks(context);
|
||||
|
||||
} catch (MtaSDkException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// init bugly
|
||||
try {
|
||||
CrashReport.setIsDevelopmentDevice(context, debug);
|
||||
CrashReport.setIsDevelopmentDevice(context, "GH_TEST".equals(channel));
|
||||
|
||||
CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
|
||||
strategy.setEnableANRCrashMonitor(false);
|
||||
@ -100,7 +102,7 @@ public class DataUtils {
|
||||
strategy.setAppChannel(channel);
|
||||
strategy.setAppVersion(PackageUtils.getPatchVersionName());
|
||||
|
||||
CrashReport.initCrashReport(context, Config.BUGLY_APPID, debug, strategy);
|
||||
CrashReport.initCrashReport(context, Config.BUGLY_APPID, false, strategy);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -108,9 +110,29 @@ public class DataUtils {
|
||||
|
||||
}
|
||||
|
||||
// MTA ->【次数统计】Key-Value参数的事件
|
||||
public static void onMtaEvent(Context context, String eventId, String... kv) {
|
||||
// if (CommonDebug.IS_DEBUG && (kv == null || kv.length % 2 != 0)) {
|
||||
// throw new IllegalStateException("onEvent kv 必须不为空且数量为偶数");
|
||||
// }
|
||||
Properties prop = new Properties();
|
||||
for (int i = 0; i < kv.length; i++) {
|
||||
if (i % 2 != 0 || i != 0) {
|
||||
String key = kv[i - 1];
|
||||
String value = kv[i];
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
StatService.trackCustomKVEvent(context, eventId, prop);
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2) {
|
||||
TCAgent.onEvent(var0, var1, var2);
|
||||
StatService.trackCustomEvent(var0, var1, var2);
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty(var1, var2);
|
||||
StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
public static void onPause(Activity var0) {
|
||||
@ -144,20 +166,24 @@ public class DataUtils {
|
||||
// 游戏下载
|
||||
public static void onGameDownloadEvent(Context context, String gameName, String platform, String entrance, String status) {
|
||||
Map<String, Object> kv = new HashMap<>();
|
||||
|
||||
platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
|
||||
|
||||
kv.put("版本", platform);
|
||||
kv.put("状态", status);
|
||||
kv.put("用户机型", Build.MODEL);
|
||||
kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
|
||||
kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
kv.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
onEvent(context, "游戏下载", gameName, kv);
|
||||
|
||||
Map<String, Object> kv2 = new HashMap<>();
|
||||
kv2.put("版本", platform);
|
||||
kv2.put("状态", status);
|
||||
kv2.put("位置", entrance);
|
||||
kv2.put("游戏分平台", gameName + "-" + platform);
|
||||
kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
onEvent(context, "游戏下载位置", gameName, kv2);
|
||||
|
||||
Map<String, Object> kv3 = new HashMap<>();
|
||||
kv3.put(entrance, "下载数");
|
||||
kv3.put(entrance, status);
|
||||
onEvent(context, "应用数据", gameName, kv3);
|
||||
}
|
||||
|
||||
// 游戏更新
|
||||
@ -168,4 +194,24 @@ public class DataUtils {
|
||||
onEvent(context, "游戏更新", gameName, kv);
|
||||
}
|
||||
|
||||
public static void onError(Context context, Throwable throwable) {
|
||||
// MTA主动上传错误
|
||||
try {
|
||||
StatService.reportException(context, throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
// //bugly 作为默认处理异常的类库,已经上报了,此处不重复上报
|
||||
// try {
|
||||
// CrashReport.postCatchedException(throwable);
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
|
||||
//talkingdata
|
||||
try {
|
||||
TCAgent.onError(context, throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,22 +1,15 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.view.DownloadDialog;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.manager.PackageManager;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/06/17.
|
||||
@ -26,118 +19,56 @@ import com.lightgame.utils.Utils;
|
||||
public class DetailDownloadUtils {
|
||||
|
||||
public static void detailInitDownload(DetailViewHolder viewHolder, boolean isCheck) {
|
||||
if (Config.isShow(viewHolder.context)) {
|
||||
|
||||
if (viewHolder.gameEntity != null
|
||||
&& Config.isShowDownload(viewHolder.gameEntity.getId())
|
||||
&& !"光环助手".equals(viewHolder.gameEntity.getName())) {
|
||||
viewHolder.downloadBottom.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewHolder.downloadBottom.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
if (viewHolder.gameEntity != null && "光环助手".equals(viewHolder.gameEntity.getName())) {
|
||||
viewHolder.downloadBottom.setVisibility(View.GONE);
|
||||
} else if (viewHolder.gameEntity == null || viewHolder.gameEntity.getApk().isEmpty()) {
|
||||
viewHolder.downloadTv.setVisibility(View.VISIBLE);
|
||||
viewHolder.downloadPb.setVisibility(View.GONE);
|
||||
viewHolder.downloadPer.setVisibility(View.GONE);
|
||||
if (TextUtils.isEmpty(viewHolder.downloadOffText)) {
|
||||
viewHolder.downloadTv.setText("暂无下载");
|
||||
} else {
|
||||
viewHolder.downloadTv.setText(viewHolder.downloadOffText);
|
||||
}
|
||||
viewHolder.downloadTv.setBackgroundResource(R.drawable.game_item_btn_pause_style);
|
||||
viewHolder.downloadTv.setTextColor(0xFF999999);
|
||||
viewHolder.downloadTv.setClickable(false);
|
||||
} else {
|
||||
viewHolder.downloadTv.setVisibility(View.VISIBLE);
|
||||
viewHolder.downloadPb.setVisibility(View.GONE);
|
||||
viewHolder.downloadPer.setVisibility(View.GONE);
|
||||
boolean isInstalled = false;
|
||||
if (viewHolder.gameEntity.getApk().size() == 1
|
||||
&& PackageManager.isInstalled(viewHolder.gameEntity.getApk().get(0).getPackageName())) {
|
||||
isInstalled = true;
|
||||
}
|
||||
if (isInstalled) {
|
||||
if (PackageManager.isCanUpdate(viewHolder.gameEntity.getId(), viewHolder.gameEntity.getApk().get(0).getPackageName())) {
|
||||
if (viewHolder.isNewsDetail) {
|
||||
viewHolder.downloadTv.setText(R.string.update);
|
||||
} else if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
viewHolder.downloadTv.setText(String.format("更新《%s》",
|
||||
viewHolder.gameEntity.getName()));
|
||||
} else {
|
||||
viewHolder.downloadTv.setText(String.format("更新《%s》%s",
|
||||
viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
}
|
||||
viewHolder.downloadTv.setBackgroundResource(
|
||||
R.drawable.game_item_btn_download_style);
|
||||
} else {
|
||||
if (viewHolder.gameEntity.getTag() != null && viewHolder.gameEntity.getTag().size() != 0
|
||||
&& !TextUtils.isEmpty(viewHolder.gameEntity.getApk().get(0).getGhVersion())
|
||||
&& !PackageUtils.isSignature(viewHolder.context, viewHolder.gameEntity.getApk().get(0).getPackageName())) {
|
||||
if (viewHolder.isNewsDetail) {
|
||||
viewHolder.downloadTv.setText(R.string.pluggable);
|
||||
} else if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
viewHolder.downloadTv.setText(String.format("插件化《%s》",
|
||||
viewHolder.gameEntity.getName()));
|
||||
} else {
|
||||
viewHolder.downloadTv.setText(String.format("插件化《%s》%s",
|
||||
viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
}
|
||||
viewHolder.downloadTv.setBackgroundResource(
|
||||
R.drawable.game_item_btn_plugin_style);
|
||||
} else {
|
||||
if (viewHolder.isNewsDetail) {
|
||||
viewHolder.downloadTv.setText(R.string.launch);
|
||||
} else if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
viewHolder.downloadTv.setText(String.format("启动《%s》",
|
||||
viewHolder.gameEntity.getName()));
|
||||
} else {
|
||||
viewHolder.downloadTv.setText(String.format("启动《%s》%s",
|
||||
viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
}
|
||||
viewHolder.downloadTv.setBackgroundResource(
|
||||
R.drawable.game_item_btn_launch_style);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity);
|
||||
switch (status) {
|
||||
case "插件化":
|
||||
viewHolder.downloadTv.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
|
||||
break;
|
||||
case "打开":
|
||||
viewHolder.downloadTv.setBackgroundResource(R.drawable.game_item_btn_launch_style);
|
||||
break;
|
||||
default:
|
||||
viewHolder.downloadTv.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
break;
|
||||
}
|
||||
|
||||
if (viewHolder.isNewsDetail) {
|
||||
viewHolder.downloadTv.setText(status);
|
||||
} else if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
viewHolder.downloadTv.setText(String.format(status + "《%s》",
|
||||
viewHolder.gameEntity.getName()));
|
||||
} else {
|
||||
viewHolder.downloadTv.setText(String.format(status + "《%s》%s",
|
||||
viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
}
|
||||
if (viewHolder.gameEntity.getApk().isEmpty()) {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.downloadOffText) ? "暂无下载" : viewHolder.downloadOffText);
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
} else {
|
||||
String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity);
|
||||
switch (status) {
|
||||
case "插件化":
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.PLUGIN);
|
||||
break;
|
||||
case "打开":
|
||||
if (viewHolder.gameEntity.getApk().size() == 1) {
|
||||
status = "启动";
|
||||
}
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
|
||||
break;
|
||||
default:
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NORMAL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (viewHolder.isNewsDetail) {
|
||||
viewHolder.mDownloadPb.setText(status);
|
||||
} else if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
viewHolder.mDownloadPb.setText(String.format(status + "《%s》", viewHolder.gameEntity.getName()));
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(String.format(status + "《%s》%s", viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
}
|
||||
}
|
||||
if (isCheck && viewHolder.gameEntity != null
|
||||
&& viewHolder.gameEntity.getApk().size() == 1) {
|
||||
if (isCheck && viewHolder.gameEntity.getApk().size() == 1) {
|
||||
String url = viewHolder.gameEntity.getApk().get(0).getUrl();
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance(viewHolder.context).getDownloadEntityByUrl(url);
|
||||
if (downloadEntity != null) {
|
||||
viewHolder.downloadEntity = downloadEntity;
|
||||
viewHolder.downloadTv.setVisibility(View.GONE);
|
||||
viewHolder.downloadPb.setVisibility(View.VISIBLE);
|
||||
viewHolder.downloadPer.setVisibility(View.VISIBLE);
|
||||
detailInvalidate(viewHolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void detailInvalidate(DetailViewHolder viewHolder) {
|
||||
viewHolder.downloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
|
||||
viewHolder.downloadPer.setTextColor(0xFFFFFFFF);
|
||||
viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
|
||||
DownloadEntity downloadEntity = viewHolder.downloadEntity;
|
||||
switch (downloadEntity.getStatus()) {
|
||||
case downloading:
|
||||
@ -145,15 +76,20 @@ public class DetailDownloadUtils {
|
||||
case timeout:
|
||||
case neterror:
|
||||
case waiting:
|
||||
viewHolder.downloadPer.setText(R.string.downloading);
|
||||
viewHolder.mDownloadPb.setText(R.string.downloading);
|
||||
if (downloadEntity.isPluggable() && PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL);
|
||||
}
|
||||
break;
|
||||
case done:
|
||||
viewHolder.downloadPer.setText("安装");
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackageManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.downloadPb.setProgressDrawable(ContextCompat.getDrawable(viewHolder.context, R.drawable.progressbar_plugin_radius_style));
|
||||
&& PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.downloadPb.setProgressDrawable(ContextCompat.getDrawable(viewHolder.context, R.drawable.progressbar_normal_radius_style));
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
}
|
||||
break;
|
||||
case cancel:
|
||||
@ -166,94 +102,5 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static class OnDetailDownloadClickListener implements View.OnClickListener {
|
||||
private DetailViewHolder mViewHolder;
|
||||
private GameEntity mGameEntity;
|
||||
private DownloadEntity mDownloadEntity;
|
||||
private String mEntrance;
|
||||
private String mName;
|
||||
private String mTitle;
|
||||
|
||||
public OnDetailDownloadClickListener(DetailViewHolder viewHolder, String entrance, String name, String title) {
|
||||
mViewHolder = viewHolder;
|
||||
mGameEntity = viewHolder.gameEntity;
|
||||
mDownloadEntity = viewHolder.downloadEntity;
|
||||
mEntrance = entrance;
|
||||
mName = name;
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v == mViewHolder.downloadTv) {
|
||||
if (mGameEntity != null && !mGameEntity.getApk().isEmpty()) {
|
||||
if (mGameEntity.getApk().size() == 1) {
|
||||
String str = mViewHolder.downloadTv.getText().toString();
|
||||
if (str.contains("启动")) {
|
||||
DataUtils.onGameLaunchEvent(mViewHolder.context, mGameEntity.getName(), mGameEntity.getApk().get(0).getPlatform(), mName);
|
||||
PackageUtils.launchApplicationByPackageName(mViewHolder.context, mGameEntity.getApk().get(0).getPackageName());
|
||||
} else if (NetworkUtils.isWifiConnected(mViewHolder.context)) {
|
||||
download();
|
||||
} else {
|
||||
DialogUtils.showDownloadDialog(mViewHolder.context, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
download();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
DownloadDialog.getInstance(mViewHolder.context)
|
||||
.showPopupWindow(v, mGameEntity, StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), mName + ":" + mTitle);
|
||||
}
|
||||
} else {
|
||||
Utils.toast(mViewHolder.context, "稍等片刻~!游戏正在上传中...");
|
||||
}
|
||||
} else if (v == mViewHolder.downloadPb || v == mViewHolder.downloadPer) {
|
||||
String str = mViewHolder.downloadPer.getText().toString();
|
||||
if ("下载中".equals(str)) {
|
||||
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(mViewHolder.context,
|
||||
mGameEntity.getApk().get(0).getUrl(), StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"));
|
||||
mViewHolder.context.startActivity(intent);
|
||||
} else if ("安装".equals(str)) {
|
||||
if (mDownloadEntity == null) {
|
||||
mDownloadEntity = DownloadManager.getInstance(mViewHolder.context).getDownloadEntityByUrl(mGameEntity.getApk().get(0).getUrl());
|
||||
}
|
||||
|
||||
if (mDownloadEntity != null) {
|
||||
PackageUtils.launchSetup(mViewHolder.context, mDownloadEntity.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void download() {
|
||||
String str = mViewHolder.downloadTv.getText().toString();
|
||||
String method;
|
||||
if (str.contains("更新")) {
|
||||
method = "更新";
|
||||
} else if (str.contains("插件化")) {
|
||||
method = "插件化";
|
||||
} else {
|
||||
method = mViewHolder.context.getString(R.string.download);
|
||||
}
|
||||
ApkEntity apkEntity = mGameEntity.getApk().get(0);
|
||||
String msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity.getSize());
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(mViewHolder.context, mGameEntity.getName(), apkEntity.getPlatform(), StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), "下载开始");
|
||||
|
||||
DownloadManager.createDownload(mViewHolder.context, apkEntity, mGameEntity, method, StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), mName + ":" + mTitle);
|
||||
|
||||
mViewHolder.downloadTv.setVisibility(View.GONE);
|
||||
mViewHolder.downloadPb.setVisibility(View.VISIBLE);
|
||||
mViewHolder.downloadPer.setVisibility(View.VISIBLE);
|
||||
mViewHolder.downloadPb.setProgress(0);
|
||||
mViewHolder.downloadPer.setText("0.0%");
|
||||
|
||||
// DownloadManager.getInstance(mViewHolder.context).putStatus(apkEntity.getUrl(), "downloading");
|
||||
} else {
|
||||
Utils.toast(mViewHolder.context, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.gh.gamecenter.kuaichuan.WifiMgr;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
@ -16,7 +17,10 @@ import com.tencent.stat.StatConfig;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
@ -70,7 +74,7 @@ public class DeviceUtils {
|
||||
return object;
|
||||
}
|
||||
|
||||
private static String getMac(Context context) {
|
||||
public static String getMac(Context context) {
|
||||
String str = "";
|
||||
String macSerial = "";
|
||||
try {
|
||||
@ -79,7 +83,7 @@ public class DeviceUtils {
|
||||
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
|
||||
LineNumberReader input = new LineNumberReader(ir);
|
||||
|
||||
for (; null != str;) {
|
||||
while (null != str) {
|
||||
str = input.readLine();
|
||||
if (str != null) {
|
||||
macSerial = str.trim();// 去空格
|
||||
@ -93,9 +97,10 @@ public class DeviceUtils {
|
||||
try {
|
||||
return loadFileAsString("/sys/class/net/eth0/address")
|
||||
.toUpperCase().substring(0, 17);
|
||||
} catch (FileNotFoundException e) {
|
||||
// do nothing
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -124,7 +129,7 @@ public class DeviceUtils {
|
||||
}
|
||||
|
||||
|
||||
private static String getIPAddress(Context context) {
|
||||
public static String getIPAddress(Context context) {
|
||||
NetworkInfo info = ((ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
|
||||
if (info != null && info.isConnected()) {
|
||||
@ -152,7 +157,7 @@ public class DeviceUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getNetwork(Context context) {
|
||||
public static String getNetwork(Context context) {
|
||||
NetworkInfo info = ((ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
|
||||
if (info != null && info.isConnected()) {
|
||||
@ -194,4 +199,44 @@ public class DeviceUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// get sim
|
||||
public static String getSim(Context context) {
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String imsi = tm.getSubscriberId();
|
||||
if (imsi == null) {
|
||||
return "";
|
||||
}
|
||||
if (imsi.startsWith("46000") || imsi.startsWith("46002") || imsi.startsWith("46007")) {
|
||||
return "中国移动";
|
||||
}
|
||||
if (imsi.startsWith("46001")) {
|
||||
return "中国联通";
|
||||
}
|
||||
if (imsi.startsWith("46003")) {
|
||||
return "中国电信";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// ping domain
|
||||
public static String ping(String domain) {
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("ping -c 5 " + domain);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
String line;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
builder.append("\n");
|
||||
}
|
||||
return builder.toString();
|
||||
} catch (IOException e) {
|
||||
return Log.getStackTraceString(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.gamecenter.KcSelectGameActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.kuaichuan.WifiMgr;
|
||||
import com.halo.assistant.HaloApp;
|
||||
@ -55,7 +56,7 @@ public class DialogUtils {
|
||||
// 快传成绩单
|
||||
public static void showKuaiChuanResult(final Activity activity, Handler handler, int requestCode, final String picName) {
|
||||
|
||||
HaloApp.remove("FileInfo");
|
||||
HaloApp.remove(KcSelectGameActivity.KEY_FILE_INFO);
|
||||
|
||||
List<Map<String, String>> mapList = (List<Map<String, String>>) HaloApp.get("sendData", true);
|
||||
if (mapList == null || mapList.size() == 0) return;
|
||||
@ -69,8 +70,7 @@ public class DialogUtils {
|
||||
int filesSize = 0;
|
||||
int sendTime = 0;
|
||||
|
||||
View view = View.inflate(activity
|
||||
, R.layout.dialog_kuaichuan, null);
|
||||
View view = View.inflate(activity, R.layout.dialog_kuaichuan, null);
|
||||
final LinearLayout mShareLl = (LinearLayout) view.findViewById(R.id.kuaichuan_dialog_ll);
|
||||
final LinearLayout mShareBottomLl = (LinearLayout) view.findViewById(R.id.kuaichuan_dialog_share_rl);
|
||||
LinearLayout shareIconLl = (LinearLayout) view.findViewById(R.id.kuaichuan_icon_ll);
|
||||
@ -192,7 +192,7 @@ public class DialogUtils {
|
||||
mShareLl.buildDrawingCache();
|
||||
Bitmap drawingCache = mShareLl.getDrawingCache();
|
||||
saveBitmap(drawingCache, activity, picName);
|
||||
MessageShareUtils.getInstance(activity).showShareWindows(mShareBottomLl, drawingCache, picName, 2);
|
||||
MessageShareUtils.getInstance(activity).showShareWindows(activity, mShareBottomLl, drawingCache, picName, 2);
|
||||
mShareBottomLl.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}, 200);
|
||||
@ -325,6 +325,10 @@ public class DialogUtils {
|
||||
}
|
||||
|
||||
public static void showWarningDialog(Context context, String title, CharSequence msg, final ConfirmListener listener) {
|
||||
//TODO fix this
|
||||
if (!(context instanceof Activity)) {
|
||||
return;
|
||||
}
|
||||
showWarningDialog(context, title, msg, "取消", "确定", listener, null);
|
||||
}
|
||||
|
||||
@ -366,30 +370,6 @@ public class DialogUtils {
|
||||
showWarningDialog(context, "插件化安装", spanned, listener);
|
||||
}
|
||||
|
||||
public static void showDisclaimerDialog(Context context, String content) {
|
||||
final Dialog disclaimerDialog = new Dialog(context);
|
||||
View view = View.inflate(context, R.layout.dialog_disclaimer, null);
|
||||
|
||||
// TextView title = (TextView) view.findViewById(R.id.disclaimer_title);
|
||||
// title.setText("免责声明");
|
||||
|
||||
TextView message = (TextView) view.findViewById(R.id.disclaimer_message);
|
||||
Spanned spanned = Html.fromHtml(content);
|
||||
message.setText(spanned);
|
||||
|
||||
view.findViewById(R.id.disclaimer_confirm).setOnClickListener(
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
disclaimerDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
disclaimerDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
disclaimerDialog.setContentView(view);
|
||||
disclaimerDialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Material Design 风格弹窗
|
||||
*
|
||||
@ -401,46 +381,9 @@ public class DialogUtils {
|
||||
* @param cmListener 确认按钮监听
|
||||
* @param clListener 取消按钮监听
|
||||
*/
|
||||
|
||||
public static void showAlertDialog(Context context, String title, CharSequence message
|
||||
public static Dialog showAlertDialog(Context context, String title, CharSequence message
|
||||
, String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
|
||||
|
||||
// AlertDialog alertDialog = new AlertDialog.Builder(context, R.style.GhAlertDialog)
|
||||
// .setTitle(title)
|
||||
// .setMessage(message)
|
||||
// .setPositiveButton(positive, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// if (cmListener != null) {
|
||||
// cmListener.onConfirm();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .setNegativeButton(negative, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// if (clListener != null) {
|
||||
// clListener.onCancel();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .create();
|
||||
// alertDialog.show();
|
||||
//
|
||||
// TextView mesage = (TextView) alertDialog.findViewById(android.R.id.message);
|
||||
// Button positiveBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE);
|
||||
// Button negativeBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_NEGATIVE);
|
||||
//
|
||||
// positiveBtn.setTextSize(14);
|
||||
// positiveBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
// negativeBtn.setTextSize(14);
|
||||
// negativeBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
// if (mesage != null) {
|
||||
// mesage.setTextSize(14);
|
||||
// mesage.setTextColor(ContextCompat.getColor(context, R.color.system_bar));
|
||||
// mesage.setLineSpacing(1.0f, 1.3f);
|
||||
// }
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
|
||||
@ -477,7 +420,7 @@ public class DialogUtils {
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -491,38 +434,8 @@ public class DialogUtils {
|
||||
* @param cmListener
|
||||
*/
|
||||
|
||||
// TODO: 8/10/17 将下面几个弹窗整理在一起
|
||||
public static void showAlertDialog(Context context, String title, CharSequence message
|
||||
, String positive, String negative, final ConfirmListener cmListener) {
|
||||
|
||||
// AlertDialog alertDialog = new AlertDialog.Builder(context, R.style.GhAlertDialog)
|
||||
// .setTitle(title)
|
||||
// .setMessage(message)
|
||||
// .setPositiveButton(positive, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// if (cmListener != null) {
|
||||
// cmListener.onConfirm();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .setNegativeButton(negative, null)
|
||||
// .create();
|
||||
// alertDialog.show();
|
||||
//
|
||||
// TextView mesage = (TextView) alertDialog.findViewById(android.R.id.message);
|
||||
// Button positiveBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE);
|
||||
// Button negativeBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_NEGATIVE);
|
||||
//
|
||||
// positiveBtn.setTextSize(14);
|
||||
// positiveBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
// negativeBtn.setTextSize(14);
|
||||
// negativeBtn.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
// if (mesage != null) {
|
||||
// mesage.setTextSize(14);
|
||||
// mesage.setTextColor(ContextCompat.getColor(context, R.color.system_bar));
|
||||
// mesage.setLineSpacing(1.0f, 1.3f);
|
||||
// }
|
||||
public static void showCancelAlertDialog(Context context, String title, CharSequence message
|
||||
, String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
@ -541,6 +454,9 @@ public class DialogUtils {
|
||||
negativeTv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (clListener != null) {
|
||||
clListener.onCancel();
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
@ -568,48 +484,6 @@ public class DialogUtils {
|
||||
public static void showCancelListenerDialog(Context context, String title, CharSequence message
|
||||
, String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
|
||||
|
||||
// AlertDialog alertDialog = new AlertDialog.Builder(context, R.style.GhAlertDialog)
|
||||
// .setTitle(title)
|
||||
// .setMessage(message)
|
||||
// .setPositiveButton(positive, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// if (cmListener != null) {
|
||||
// cmListener.onConfirm();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .setNegativeButton(negative, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// if (clListener != null) {
|
||||
// clListener.onCancel();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
// @Override
|
||||
// public void onCancel(DialogInterface dialogInterface) {
|
||||
// clListener.onCancel();
|
||||
// }
|
||||
// })
|
||||
// .create();
|
||||
//
|
||||
// alertDialog.show();
|
||||
//
|
||||
// TextView mesage = (TextView) alertDialog.findViewById(android.R.id.message);
|
||||
// Button positiveBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE);
|
||||
// Button negativeBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_NEGATIVE);
|
||||
//
|
||||
// positiveBtn.setTextSize(14);
|
||||
// positiveBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
// negativeBtn.setTextSize(14);
|
||||
// negativeBtn.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
// if (mesage != null) {
|
||||
// mesage.setTextSize(14);
|
||||
// mesage.setTextColor(ContextCompat.getColor(context, R.color.system_bar));
|
||||
// mesage.setLineSpacing(1.0f, 1.3f);
|
||||
// }
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
@ -651,7 +525,7 @@ public class DialogUtils {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialogInterface) {
|
||||
if (clListener != null)
|
||||
clListener.onCancel();
|
||||
clListener.onCancel();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
@ -797,6 +671,36 @@ public class DialogUtils {
|
||||
|
||||
}
|
||||
|
||||
public static void showSignDialog(Context context, String title, CharSequence message, CharSequence message2
|
||||
, String positive, final ConfirmListener cmListener) {
|
||||
final Dialog dialog = new Dialog(context);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_sign, null);
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
|
||||
TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
|
||||
TextView content2Tv = contentView.findViewById(R.id.dialog_content2);
|
||||
|
||||
contentTv.setText(Html.fromHtml(message.toString()));
|
||||
content2Tv.setText(Html.fromHtml(message2.toString()));
|
||||
titleTv.setText(title);
|
||||
positiveTv.setText(positive);
|
||||
|
||||
negativeTv.setOnClickListener(view -> dialog.dismiss());
|
||||
|
||||
positiveTv.setOnClickListener(view -> {
|
||||
if (cmListener != null) {
|
||||
cmListener.onConfirm();
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public interface ConfirmListener {
|
||||
void onConfirm();
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@ package com.gh.common.util;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.halo.assistant.HaloApp;
|
||||
|
||||
public class DisplayUtils {
|
||||
|
||||
/**
|
||||
@ -21,6 +23,15 @@ public class DisplayUtils {
|
||||
return (int) (pxValue / scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
|
||||
*/
|
||||
public static int dip2px(float dpValue) {
|
||||
final float scale = HaloApp.getInstance().getApplication().getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将px值转换为sp值,保证文字大小不变
|
||||
*
|
||||
|
||||
@ -3,6 +3,7 @@ package com.gh.common.util;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
@ -11,6 +12,8 @@ import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.exposure.ExposureUtils;
|
||||
import com.gh.common.view.DownloadDialog;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
@ -60,9 +63,10 @@ public class DownloadItemUtils {
|
||||
gameEntity.setEntryMap(entryMap);
|
||||
}
|
||||
entryMap.put(platform, downloadEntity);
|
||||
if (!"pause".equals(DownloadManager.getInstance(context).getStatus(downloadEntity.getUrl()))) {
|
||||
adapter.notifyItemChanged(index);
|
||||
}
|
||||
adapter.notifyItemChanged(index);
|
||||
// if (!DownloadStatus.pause.equals(DownloadManager.getInstance(context).getStatus(downloadEntity.getUrl()))) {
|
||||
// adapter.notifyItemChanged(index);
|
||||
// }
|
||||
} else {
|
||||
if (!queue.contains(platform)) {
|
||||
queue.offer(platform);
|
||||
@ -84,7 +88,7 @@ public class DownloadItemUtils {
|
||||
gameEntity.setEntryMap(entryMap);
|
||||
}
|
||||
entryMap.put(platform, downloadEntity);
|
||||
if (!"pause".equals(DownloadManager.getInstance(context).getStatus(downloadEntity.getUrl()))) {
|
||||
if (!DownloadStatus.pause.equals(DownloadManager.getInstance(context).getStatus(downloadEntity.getUrl()))) {
|
||||
adapter.notifyItemChanged(index);
|
||||
}
|
||||
}
|
||||
@ -94,7 +98,7 @@ public class DownloadItemUtils {
|
||||
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder, boolean isShowPlatform) {
|
||||
|
||||
// 控制是否显示下载按钮
|
||||
if (!Config.isShow(context) || context.getString(R.string.app_name).equals(gameEntity.getName())) {
|
||||
if (!Config.isShowDownload(gameEntity.getId()) || context.getString(R.string.app_name).equals(gameEntity.getName())) {
|
||||
holder.gameDownloadBtn.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.gameDownloadBtn.setVisibility(View.VISIBLE);
|
||||
@ -110,8 +114,9 @@ public class DownloadItemUtils {
|
||||
holder.gameDes.setVisibility(View.VISIBLE);
|
||||
holder.gameProgressbar.setVisibility(View.GONE);
|
||||
holder.gameInfo.setVisibility(View.GONE);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_pause_style);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.news_detail_comment);
|
||||
holder.gameDownloadBtn.setText("暂无");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
|
||||
holder.gameDownloadBtn.setClickable(false);
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
updateNormalItem(context, holder, gameEntity, isShowPlatform);
|
||||
@ -149,19 +154,24 @@ public class DownloadItemUtils {
|
||||
if (gameEntity.isPluggable()) {
|
||||
holder.gameDownloadBtn.setText(R.string.pluggable);
|
||||
setwhat(context, holder, apkEntity, packageName);
|
||||
} else if (PackageManager.isInstalled(packageName)) {
|
||||
if (PackageManager.isCanUpdate(gameEntity.getId(), packageName)) {
|
||||
} else if (PackageManager.INSTANCE.isInstalled(packageName)) {
|
||||
if (PackageManager.INSTANCE.isCanUpdate(gameEntity.getId(), packageName)) {
|
||||
holder.gameDownloadBtn.setText(R.string.update);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
} else {
|
||||
Object gh_id = PackageUtils.getMetaData(context, packageName, "gh_id");
|
||||
if (gameEntity.getTag() != null && gameEntity.getTag().size() != 0
|
||||
&& !TextUtils.isEmpty(apkEntity.getGhVersion())
|
||||
&& !PackageUtils.isSignature(context, packageName)) {
|
||||
holder.gameDownloadBtn.setText(R.string.pluggable);
|
||||
setwhat(context, holder, apkEntity, packageName);
|
||||
} else {
|
||||
} else if (gh_id == null || gh_id.equals(gameEntity.getId())) {
|
||||
holder.gameDownloadBtn.setText(R.string.launch);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_launch_style);
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.detail_download_open_style);
|
||||
} else {
|
||||
holder.gameDownloadBtn.setText(R.string.download);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -230,7 +240,7 @@ public class DownloadItemUtils {
|
||||
|
||||
DownloadStatus status = downloadEntity.getStatus();
|
||||
if (status.equals(DownloadStatus.downloading)) {
|
||||
if (!"pause".equals(DownloadManager.getInstance(context).getStatus(downloadEntity.getUrl()))) {
|
||||
if (!DownloadStatus.pause.equals(DownloadManager.getInstance(context).getStatus(downloadEntity.getUrl()))) {
|
||||
holder.gameProgressbar.setProgress((int) (downloadEntity.getPercent() * 10));
|
||||
if (isShowPlatform && platform != null) {
|
||||
holder.gameDownloadSpeed.setText(String.format("%s - %s(剩%s)", platform,
|
||||
@ -291,7 +301,7 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setText("安装");
|
||||
holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackageManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
&& PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
|
||||
} else {
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
@ -308,20 +318,22 @@ public class DownloadItemUtils {
|
||||
final String entrance,
|
||||
final String location) {
|
||||
|
||||
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, location, null);
|
||||
}
|
||||
|
||||
public static void setOnClickListener(final Context context,
|
||||
final TextView downloadBtn,
|
||||
final GameEntity gameEntity,
|
||||
final int position,
|
||||
final RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter,
|
||||
final String entrance,
|
||||
final String location,
|
||||
final ExposureEvent traceEvent) {
|
||||
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
downloadBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location);
|
||||
}
|
||||
});
|
||||
downloadBtn.setOnClickListener(v -> onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent));
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
DownloadDialog.getInstance(context).showPopupWindow(v, gameEntity, entrance, location);
|
||||
}
|
||||
});
|
||||
downloadBtn.setOnClickListener(v -> DownloadDialog.getInstance(context).showPopupWindow(v, gameEntity, entrance, location, traceEvent));
|
||||
}
|
||||
|
||||
}
|
||||
@ -333,37 +345,44 @@ public class DownloadItemUtils {
|
||||
final RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter,
|
||||
final String entrance,
|
||||
final String location) {
|
||||
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, null);
|
||||
}
|
||||
|
||||
public static void onNormalClick(final Context context,
|
||||
final TextView downloadBtn,
|
||||
final GameEntity gameEntity,
|
||||
final int position,
|
||||
final RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter,
|
||||
final String entrance,
|
||||
final String location,
|
||||
@Nullable final ExposureEvent traceEvent) {
|
||||
|
||||
String str = downloadBtn.getText().toString();
|
||||
switch (str) {
|
||||
case "下载":
|
||||
if (NetworkUtils.isWifiConnected(context)) {
|
||||
download(context, gameEntity, downloadBtn, entrance, location);
|
||||
download(context, gameEntity, downloadBtn, entrance, location, traceEvent);
|
||||
} else {
|
||||
DialogUtils.showDownloadDialog(context, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
download(context, gameEntity, downloadBtn, entrance, location);
|
||||
}
|
||||
});
|
||||
DialogUtils.showDownloadDialog(context, () -> download(context, gameEntity, downloadBtn, entrance, location, traceEvent));
|
||||
}
|
||||
break;
|
||||
case "插件化":
|
||||
if (entrance.contains("我的游戏")) {
|
||||
DataUtils.onMtaEvent(context, "我的游戏_启动", "插件化", gameEntity.getName());
|
||||
}
|
||||
if (NetworkUtils.isWifiConnected(context)) {
|
||||
plugin(context, gameEntity, downloadBtn, entrance, location);
|
||||
plugin(context, gameEntity, downloadBtn, entrance, location, traceEvent);
|
||||
} else {
|
||||
DialogUtils.showDownloadDialog(context, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
plugin(context, gameEntity, downloadBtn, entrance, location);
|
||||
}
|
||||
});
|
||||
DialogUtils.showDownloadDialog(context, () -> plugin(context, gameEntity, downloadBtn, entrance, location, traceEvent));
|
||||
}
|
||||
break;
|
||||
case "安装":
|
||||
install(context, gameEntity, position, adapter);
|
||||
break;
|
||||
case "启动":
|
||||
if (entrance.contains("我的游戏")) {
|
||||
DataUtils.onMtaEvent(context, "我的游戏_启动", "启动", gameEntity.getName());
|
||||
}
|
||||
DataUtils.onGameLaunchEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
|
||||
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk().get(0).getPackageName());
|
||||
@ -373,15 +392,13 @@ public class DownloadItemUtils {
|
||||
DownloadManagerActivity.getDownloadMangerIntent(context, gameEntity.getApk().get(0).getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
|
||||
break;
|
||||
case "更新":
|
||||
if (entrance.contains("我的游戏")) {
|
||||
DataUtils.onMtaEvent(context, "我的游戏_启动", "更新", gameEntity.getName());
|
||||
}
|
||||
if (NetworkUtils.isWifiConnected(context)) {
|
||||
update(context, gameEntity, entrance, location);
|
||||
update(context, gameEntity, entrance, location, traceEvent);
|
||||
} else {
|
||||
DialogUtils.showDownloadDialog(context, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
update(context, gameEntity, entrance, location);
|
||||
}
|
||||
});
|
||||
DialogUtils.showDownloadDialog(context, () -> update(context, gameEntity, entrance, location, traceEvent));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -392,12 +409,15 @@ public class DownloadItemUtils {
|
||||
GameEntity gameEntity,
|
||||
TextView downloadBtn,
|
||||
String entrance,
|
||||
String location) {
|
||||
String location,
|
||||
@Nullable ExposureEvent traceEvent) {
|
||||
String msg = FileUtils.isCanDownload(context, gameEntity.getApk().get(0).getSize());
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), entrance, "下载开始");
|
||||
|
||||
DownloadManager.createDownload(context, gameEntity, context.getString(R.string.download), entrance, location);
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.INSTANCE.logADownloadExposureEvent(gameEntity, gameEntity.getApk().get(0).getPlatform(), traceEvent, ExposureUtils.DownloadType.DOWNLOAD);
|
||||
|
||||
DownloadManager.createDownload(context, gameEntity, context.getString(R.string.download), entrance, location, downloadExposureEvent);
|
||||
Utils.toast(context, gameEntity.getName() + "已加入下载队列");
|
||||
|
||||
downloadBtn.setText(R.string.downloading);
|
||||
@ -412,12 +432,14 @@ public class DownloadItemUtils {
|
||||
|
||||
//插件化
|
||||
private static void plugin(Context context, GameEntity gameEntity, TextView downloadBtn, String entrance,
|
||||
String location) {
|
||||
String location, @Nullable ExposureEvent traceEvent) {
|
||||
String msg = FileUtils.isCanDownload(context, gameEntity.getApk().get(0).getSize());
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), entrance, "下载开始");
|
||||
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location);
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.INSTANCE.logADownloadExposureEvent(gameEntity, gameEntity.getApk().get(0).getPlatform(), traceEvent, ExposureUtils.DownloadType.PLUGIN_DOWNLOAD);
|
||||
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, downloadExposureEvent);
|
||||
Utils.toast(context, gameEntity.getName() + "已加入下载队列");
|
||||
|
||||
downloadBtn.setText(R.string.downloading);
|
||||
@ -438,7 +460,7 @@ public class DownloadItemUtils {
|
||||
if (downloadEntity != null) {
|
||||
final String path = downloadEntity.getPath();
|
||||
if (FileUtils.isEmptyFile(path)) {
|
||||
Utils.toast(context, context.getString(R.string.install_failure_hint));
|
||||
Utils.toast(context, R.string.install_failure_hint);
|
||||
DownloadManager.getInstance(context).cancel(downloadEntity.getUrl());
|
||||
if (gameEntity.getEntryMap() != null) {
|
||||
gameEntity.getEntryMap().remove(apkEntity.getPlatform());
|
||||
@ -451,9 +473,10 @@ public class DownloadItemUtils {
|
||||
}
|
||||
|
||||
//更新
|
||||
private static void update(Context context, GameEntity gameEntity, String entrance, String location) {
|
||||
private static void update(Context context, GameEntity gameEntity, String entrance, String location, @Nullable ExposureEvent traceEvent) {
|
||||
DataUtils.onGameUpdateEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), "下载开始");
|
||||
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location);
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.INSTANCE.logADownloadExposureEvent(gameEntity, gameEntity.getApk().get(0).getPlatform(), traceEvent, ExposureUtils.DownloadType.UPDATE);
|
||||
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, downloadExposureEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,7 +6,9 @@ import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.gamecenter.MainActivity;
|
||||
import com.gh.gamecenter.NormalActivity;
|
||||
import com.gh.gamecenter.SplashScreenActivity;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
@ -28,6 +30,8 @@ public class EntranceUtils {
|
||||
public static final String HOST_WEB = "web";
|
||||
public static final String HOST_DOWNLOAD = "download";
|
||||
public static final String HOST_SUGGESTION = "suggestion";
|
||||
public static final String HOST_ANSWER = "answer";
|
||||
public static final String HOST_QUESTION = "question";
|
||||
public static final String KEY_DATA = "data";
|
||||
public static final String KEY_TYPE = "type";
|
||||
public static final String KEY_NAME = "name";
|
||||
@ -56,6 +60,29 @@ public class EntranceUtils {
|
||||
public static final String KEY_PROLIST = "provinceList";
|
||||
public static final String KEY_ORDER = "order";
|
||||
public static final String KEY_TAGTYPE = "tagType";
|
||||
public static final String KEY_ANSWER_ID = "answerId";
|
||||
public static final String KEY_ANSWER_CONTENT = "answerContent";
|
||||
public static final String KEY_QUESTIONS_ID = "questionsId";
|
||||
public static final String KEY_QUESTIONS_TITLE = "questionsTitle";
|
||||
public static final String KEY_ANSWER_OPEN_IN_NEW_PAGE = "openInNewPage";
|
||||
public static final String KEY_QUESTIONS_PATCH = "questionsPatch";
|
||||
public static final String KEY_INVITE_SEARCH_KEY = "inviteSearchKey";
|
||||
public static final String KEY_MESSAGE_TYPE = "messageType";
|
||||
public static final String KEY_QUESTIONS_SEARCH_KEY = "questionsSearchKey";
|
||||
public static final String KEY_SHOW_ANSWER_COMMENT = "showAnswerComment";
|
||||
public static final String KEY_VERSION_UPDATE = "versionUpdate";
|
||||
public static final String KEY_CHECK_QUESTION_CONCERN = "check_question_concern";
|
||||
public static final String KEY_DRAFT_ID = "draft_id";
|
||||
public static final String KEY_KAIFU_LIST = "kaifuList";
|
||||
public static final String KEY_CATEGORY_ID = "category_id";
|
||||
public static final String KEY_CATEGORY_TITLE = "category_title";
|
||||
public static final String KEY_CATEGORY_INIT_TITLE = "category_init_title";
|
||||
public static final String KEY_BLOCK_DATA = "blockData";
|
||||
public static final String KEY_ASK_TAG = "askTag";
|
||||
public static final String KEY_ASK_COLUMN_TAG = "askColumnTag";
|
||||
public static final String KEY_COMMUNITY_DATA = "communityData";
|
||||
public static final String KEY_TRACE_EVENT = "trace_event";
|
||||
public static final String KEY_SUBJECT_DATA = "subjectData";
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
|
||||
@ -67,10 +94,14 @@ public class EntranceUtils {
|
||||
if (!TextUtils.isEmpty(to)) {
|
||||
Class<?> clazz = ClassUtils.forName(to);
|
||||
if (clazz != null) {
|
||||
Intent intent1 = new Intent(context, clazz);
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent1.putExtra(KEY_DATA, bundle);
|
||||
context.startActivity(intent1);
|
||||
if (NormalFragment.class.isAssignableFrom(clazz)) { // 兼容NormalFragment
|
||||
NormalActivity.startFragmentNewTask(context, (Class<? extends NormalFragment>) clazz, bundle);
|
||||
} else {
|
||||
Intent intent1 = new Intent(context, clazz);
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent1.putExtras(bundle);
|
||||
context.startActivity(intent1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -2,12 +2,14 @@ package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.GameCollectionEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.gh.gamecenter.manager.PackageManager;
|
||||
@ -51,7 +53,8 @@ public class GameUtils {
|
||||
if ("插件化".equals(status)) {
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
|
||||
} else if ("打开".equals(status)) {
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_launch_style);
|
||||
downloadBtn.setBackgroundResource(R.drawable.detail_downloading_normal_style);
|
||||
downloadBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
|
||||
} else {
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
}
|
||||
@ -68,6 +71,15 @@ public class GameUtils {
|
||||
DownloadEntity downloadEntity;
|
||||
Object gh_id;
|
||||
for (ApkEntity apkEntity : gameEntity.getApk()) {
|
||||
|
||||
// 去除下载合集判断
|
||||
boolean isCollection = false;
|
||||
for (GameCollectionEntity collectionEntity : gameEntity.getCollection()) {
|
||||
if (collectionEntity.getPackage().contains(apkEntity.getPackageName()))
|
||||
isCollection = true;
|
||||
}
|
||||
if (isCollection) continue;
|
||||
|
||||
downloadEntity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.getUrl());
|
||||
if (downloadEntity != null) {
|
||||
if (downloadEntity.getStatus().equals(DownloadStatus.done)) {
|
||||
@ -78,10 +90,10 @@ public class GameUtils {
|
||||
updateCount++;
|
||||
}
|
||||
}
|
||||
if (PackageManager.isCanUpdate(gameEntity.getId(), apkEntity.getPackageName())) {
|
||||
if (PackageManager.INSTANCE.isCanUpdate(gameEntity.getId(), apkEntity.getPackageName())) {
|
||||
updateCount++;
|
||||
}
|
||||
if (PackageManager.isInstalled(apkEntity.getPackageName())) {
|
||||
if (PackageManager.INSTANCE.isInstalled(apkEntity.getPackageName())) {
|
||||
gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
|
||||
if (gameEntity.getTag() != null && gameEntity.getTag().size() != 0
|
||||
&& !TextUtils.isEmpty(apkEntity.getGhVersion())
|
||||
|
||||
@ -12,6 +12,7 @@ import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.TagStyleEntity;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -30,17 +31,17 @@ import java.util.TimeZone;
|
||||
*/
|
||||
public class GameViewUtils {
|
||||
|
||||
public static void setLabelList(Context context, LinearLayout labelLayout, List<String> tag, String tagType) {
|
||||
public static void setLabelList(Context context, LinearLayout labelLayout, List<String> tag, String tagType, List<TagStyleEntity> tagStyle) {
|
||||
labelLayout.removeAllViews();
|
||||
if (tag == null || tag.isEmpty()) {
|
||||
labelLayout.addView(getGameTagView(context, "官方版", 0, tagType));
|
||||
labelLayout.addView(getGameTagView(context, "官方版", 0, tagType, null));
|
||||
} else {
|
||||
for (int i = 0, size = tag.size(); i < size; i++) {
|
||||
View view;
|
||||
if (i == size - 1) {
|
||||
view = getGameTagView(context, tag.get(i), 0, tagType);
|
||||
view = getGameTagView(context, tag.get(i), 0, tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
|
||||
} else {
|
||||
view = getGameTagView(context, tag.get(i), DisplayUtils.dip2px(context, 6), tagType);
|
||||
view = getGameTagView(context, tag.get(i), DisplayUtils.dip2px(context, 6), tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
|
||||
}
|
||||
if (view != null) {
|
||||
labelLayout.addView(view);
|
||||
@ -52,7 +53,7 @@ public class GameViewUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static TextView getGameTagView(Context context, String tagStr, int rightMargin, String tagType) {
|
||||
private static TextView getGameTagView(Context context, String tagStr, int rightMargin, String tagType, TagStyleEntity tagEntity) {
|
||||
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
|
||||
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
lparams.rightMargin = rightMargin;
|
||||
@ -65,22 +66,33 @@ public class GameViewUtils {
|
||||
tag.setTextColor(ContextCompat.getColor(context, R.color.tag_green));
|
||||
} else {
|
||||
String colorStr;
|
||||
if (!TextUtils.isEmpty(tagType) && "type".equals(tagType)) { // 游戏标签
|
||||
colorStr = "#ff6a28";
|
||||
|
||||
if (!TextUtils.isEmpty(tagType) && "type".equals(tagType) && tagEntity != null) { // 游戏标签
|
||||
colorStr = "#" + tagEntity.getColor();
|
||||
GradientDrawable gradientDrawable = new GradientDrawable();
|
||||
|
||||
if ("border".equals(tagEntity.getStyle())) {
|
||||
gradientDrawable.setColor(Color.TRANSPARENT);
|
||||
gradientDrawable.setStroke(DisplayUtils.dip2px(context, 0.6f), Color.parseColor(colorStr));
|
||||
tag.setTextColor(Color.parseColor(colorStr));
|
||||
} else {
|
||||
gradientDrawable.setColor(Color.parseColor(colorStr));
|
||||
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
|
||||
tag.setTextColor(Color.WHITE);
|
||||
}
|
||||
tag.setBackgroundDrawable(gradientDrawable);
|
||||
} else {
|
||||
colorStr = TagUtils.getInstance(context).getColor(tagStr);
|
||||
if (colorStr == null) {
|
||||
return null;
|
||||
}
|
||||
int color = Color.parseColor(colorStr);
|
||||
GradientDrawable gradientDrawable = new GradientDrawable();
|
||||
gradientDrawable.setColor(Color.TRANSPARENT);
|
||||
gradientDrawable.setStroke(DisplayUtils.dip2px(context, 0.6f), color);
|
||||
tag.setBackgroundDrawable(gradientDrawable);
|
||||
tag.setTextColor(color);
|
||||
}
|
||||
|
||||
if (colorStr == null) {
|
||||
return null;
|
||||
}
|
||||
int color = Color.parseColor(colorStr);
|
||||
GradientDrawable gradientDrawable = new GradientDrawable();
|
||||
gradientDrawable.setColor(Color.TRANSPARENT);
|
||||
gradientDrawable.setStroke(DisplayUtils.dip2px(context, 0.6f), color);
|
||||
tag.setBackgroundDrawable(gradientDrawable);
|
||||
// tag.setBackgroundResource(R.drawable.border_blue_bg);
|
||||
tag.setTextColor(color);
|
||||
}
|
||||
tag.setLayoutParams(lparams);
|
||||
tag.setPadding(DisplayUtils.dip2px(context, 3),
|
||||
|
||||
@ -6,6 +6,8 @@ import android.content.Intent;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.user.LoginTag;
|
||||
import com.lightgame.utils.RuntimeUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.sina.weibo.sdk.WbSdk;
|
||||
@ -89,7 +91,7 @@ public class GetLoginDataUtils {
|
||||
content.put("access_token_expire", Utils.getTime(mContext) + jsonObject.getLong("expires_in"));
|
||||
content.put("access_token", jsonObject.getString("access_token"));
|
||||
if (mLoginListener != null) {
|
||||
mLoginListener.OnLoginData(content, LoginUtils.LoginTag.qq);// QQ 登录回调
|
||||
mLoginListener.OnLoginData(content, LoginTag.qq);// QQ 登录回调
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
@ -161,7 +163,7 @@ public class GetLoginDataUtils {
|
||||
|
||||
SendAuth.Req req = new SendAuth.Req();
|
||||
req.scope = "snsapi_userinfo";
|
||||
req.state = "光环助手";
|
||||
req.state = mContext.getString(R.string.app_name);
|
||||
boolean b = mIWXAPI.sendReq(req);
|
||||
Utils.log(GetLoginDataUtils.class.getSimpleName(), "微信注册状态::" + register + "\n 发送状态::" + b);
|
||||
if (!register || !b) {
|
||||
@ -171,7 +173,9 @@ public class GetLoginDataUtils {
|
||||
}
|
||||
|
||||
public void WCLofinCallBack(JSONObject content) {
|
||||
mLoginListener.OnLoginData(content, LoginUtils.LoginTag.wechat);
|
||||
if (mLoginListener != null) {
|
||||
mLoginListener.OnLoginData(content, LoginTag.wechat);
|
||||
}
|
||||
}
|
||||
|
||||
public void onWeiboCallback(int requestCode, int resultCode, Intent data) {
|
||||
@ -219,7 +223,7 @@ public class GetLoginDataUtils {
|
||||
content.put("refresh_token", token.getRefreshToken());
|
||||
// content.put("refresh_token_expire", Utils.getTime(mContext) + 86400 * 30); // refresh_token 有效期30天
|
||||
if (mLoginListener != null) {
|
||||
mLoginListener.OnLoginData(content, LoginUtils.LoginTag.weibo);// 微博 登录回调
|
||||
mLoginListener.OnLoginData(content, LoginTag.weibo);// 微博 登录回调
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -293,7 +297,7 @@ public class GetLoginDataUtils {
|
||||
|
||||
// 登录成功回调
|
||||
public interface OnLoginDataListener {
|
||||
void OnLoginData(JSONObject content, LoginUtils.LoginTag loginTag);
|
||||
void OnLoginData(JSONObject content, LoginTag loginTag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import android.graphics.drawable.ColorDrawable
|
||||
import android.net.Uri
|
||||
import android.support.annotation.DrawableRes
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.text.TextUtils
|
||||
import com.facebook.common.executors.CallerThreadExecutor
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.drawee.controller.BaseControllerListener
|
||||
@ -18,33 +19,76 @@ import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
||||
import com.facebook.imagepipeline.image.ImageInfo
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.lightgame.config.CommonDebug
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import rx.Observable
|
||||
import rx.Observer
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import java.io.File
|
||||
import java.net.HttpURLConnection
|
||||
|
||||
class ImageUtils private constructor() {
|
||||
|
||||
|
||||
fun display(simpleDraweeView: SimpleDraweeView?, url: String?, listener: BaseControllerListener<ImageInfo>) {
|
||||
simpleDraweeView?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(url)
|
||||
.setControllerListener(listener)
|
||||
.build()
|
||||
}
|
||||
|
||||
// 自适应图片宽高
|
||||
fun display(simpleDraweeView: SimpleDraweeView, url: String?, width: Int) {
|
||||
fun display(simpleDraweeView: SimpleDraweeView?, url: String?, width: Int) {
|
||||
val listener = object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
if (imageInfo == null) {
|
||||
return
|
||||
}
|
||||
val layoutParams = simpleDraweeView.layoutParams
|
||||
val layoutParams = simpleDraweeView?.layoutParams
|
||||
val scale = imageInfo.height.toFloat() / imageInfo.width.toFloat()
|
||||
layoutParams.height = (width * scale).toInt()
|
||||
simpleDraweeView.layoutParams = layoutParams
|
||||
layoutParams?.height = (width * scale).toInt()
|
||||
simpleDraweeView?.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
simpleDraweeView.controller = Fresco.newDraweeControllerBuilder()
|
||||
simpleDraweeView?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(url)
|
||||
.setControllerListener(listener)
|
||||
.build()
|
||||
}
|
||||
|
||||
// 自适应图片宽高
|
||||
fun displayScale(simpleDraweeView: SimpleDraweeView?, url: String?, height: Int) {
|
||||
val listener = object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
if (imageInfo == null) {
|
||||
return
|
||||
}
|
||||
val layoutParams = simpleDraweeView?.layoutParams
|
||||
val scale = imageInfo.width.toFloat() / imageInfo.height.toFloat()
|
||||
layoutParams?.width = (height * scale).toInt()
|
||||
simpleDraweeView?.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
simpleDraweeView?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(url)
|
||||
.setControllerListener(listener)
|
||||
.build()
|
||||
}
|
||||
|
||||
// 设置缩放类型,设置按压状态下的叠加图
|
||||
fun display(resources: Resources, simpleDraweeView: SimpleDraweeView,
|
||||
scaleType: ScalingUtils.ScaleType, url: String?) {
|
||||
val context = simpleDraweeView.context
|
||||
fun display(resources: Resources?, simpleDraweeView: SimpleDraweeView?,
|
||||
scaleType: ScalingUtils.ScaleType?, url: String?) {
|
||||
if (simpleDraweeView == null) return
|
||||
val context = simpleDraweeView.context ?: return
|
||||
simpleDraweeView.hierarchy = GenericDraweeHierarchyBuilder(resources)
|
||||
.setFadeDuration(500)
|
||||
.setPressedStateOverlay(ColorDrawable(ContextCompat.getColor(context, R.color.pressed_bg)))
|
||||
@ -57,8 +101,9 @@ class ImageUtils private constructor() {
|
||||
}
|
||||
|
||||
// 设置占位符
|
||||
fun display(resources: Resources, simpleDraweeView: SimpleDraweeView, url: String?, placeholderImage: Int) {
|
||||
val context = simpleDraweeView.context
|
||||
fun display(resources: Resources?, simpleDraweeView: SimpleDraweeView?, url: String?, placeholderImage: Int) {
|
||||
if (simpleDraweeView == null) return
|
||||
val context = simpleDraweeView.context ?: return
|
||||
simpleDraweeView.hierarchy = GenericDraweeHierarchyBuilder(resources)
|
||||
.setFadeDuration(500)
|
||||
.setPressedStateOverlay(ColorDrawable(ContextCompat.getColor(context, R.color.pressed_bg)))
|
||||
@ -70,9 +115,9 @@ class ImageUtils private constructor() {
|
||||
}
|
||||
|
||||
// 图片下载监听和设置低高分辨率图片
|
||||
fun display(simpleDraweeView: SimpleDraweeView, url: String?, lowUrl: String?,
|
||||
fun display(simpleDraweeView: SimpleDraweeView?, url: String?, lowUrl: String?,
|
||||
listener: ControllerListener<in ImageInfo>) {
|
||||
simpleDraweeView.controller = Fresco.newDraweeControllerBuilder()
|
||||
simpleDraweeView?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(ImageRequest.fromUri(url))
|
||||
.setControllerListener(listener)
|
||||
.setLowResImageRequest(ImageRequest.fromUri(lowUrl)) // 低分辨率图片
|
||||
@ -80,7 +125,7 @@ class ImageUtils private constructor() {
|
||||
}
|
||||
|
||||
// 获取bitmap
|
||||
fun display(context: Context, url: String?, dataSubscriber: BaseBitmapDataSubscriber) {
|
||||
fun display(context: Context?, url: String?, dataSubscriber: BaseBitmapDataSubscriber) {
|
||||
val imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(Uri.parse(url))
|
||||
.setProgressiveRenderingEnabled(true)
|
||||
@ -92,6 +137,7 @@ class ImageUtils private constructor() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val RESPONSE403: String = "RESPONSE403"
|
||||
|
||||
fun getInstance(): ImageUtils {
|
||||
return Inner.anotherSingle
|
||||
@ -102,15 +148,101 @@ class ImageUtils private constructor() {
|
||||
}
|
||||
|
||||
fun display(simpleDraweeView: SimpleDraweeView, url: String?) {
|
||||
// if (url.startsWith("http://image.ghzs666.com") && url.endsWith(".jpg")) {
|
||||
// url = url + "?x-oss-process=image/format,webp";
|
||||
// }
|
||||
simpleDraweeView.setImageURI(url)
|
||||
}
|
||||
|
||||
fun display(draweeView: SimpleDraweeView, @DrawableRes res: Int?) {
|
||||
draweeView.setImageURI("res:///" + res)
|
||||
}
|
||||
|
||||
fun postImageArr(context: Context, imgArr: List<String>, listener: OnPostArrImageListener) {
|
||||
val imgMap: HashMap<String, String> = HashMap()
|
||||
|
||||
Observable.create(Observable.OnSubscribe<JSONObject> { subscriber ->
|
||||
var path: String
|
||||
var index = 0
|
||||
for (s in imgArr) {
|
||||
path = context.getCacheDir().path + File.separator + System.currentTimeMillis() + index + ".jpg"
|
||||
if (BitmapUtils.savePicture(path, s, 1024 * 1024)) {
|
||||
subscriber.onNext(FileUtils.uploadFile(Config.API_HOST + "images?type=community", path, s, UserManager.getInstance().token))
|
||||
index++
|
||||
} else {
|
||||
subscriber.onNext(FileUtils.uploadFile(Config.API_HOST + "images?type=community", s, s, UserManager.getInstance().token))
|
||||
}
|
||||
}
|
||||
subscriber.onCompleted()
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<JSONObject> {
|
||||
override fun onCompleted() {
|
||||
Utils.log("图片上传完成")
|
||||
listener.postSuccess(imgMap)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Utils.log("图片上传失败" + e.toString())
|
||||
listener.postError()
|
||||
}
|
||||
|
||||
override fun onNext(result: JSONObject?) {
|
||||
if (result != null) {
|
||||
try {
|
||||
val statusCode = result.getInt("statusCode")
|
||||
if (statusCode == HttpURLConnection.HTTP_OK) {
|
||||
imgMap.put(result.getString("realPath"), result.getString("icon"))
|
||||
} else if (statusCode == 403) {
|
||||
imgMap.put(result.getString("realPath"), RESPONSE403)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun postImage(context: Context?, picturePath: String?, listener: OnPostImageListener): Subscription? {
|
||||
if (context == null || TextUtils.isEmpty(picturePath)) return null
|
||||
return Observable.create(Observable.OnSubscribe<JSONObject> { subscriber ->
|
||||
val path = context.getCacheDir().path + File.separator + System.currentTimeMillis() + ".jpg"
|
||||
if (BitmapUtils.savePicture(path, picturePath, 1024 * 1024)) {
|
||||
subscriber.onNext(FileUtils.uploadFile(Config.API_HOST + "images?type=community", path, UserManager.getInstance().token))
|
||||
} else {
|
||||
subscriber.onNext(FileUtils.uploadFile(Config.API_HOST + "images?type=community", picturePath, UserManager.getInstance().token))
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<JSONObject>() {
|
||||
override fun onResponse(response: JSONObject?) {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
Utils.log("postImage:onResponse=>" + response.toString())
|
||||
}
|
||||
listener.postSuccess(response)
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
listener.postError()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface OnPostImageListener {
|
||||
fun postSuccess(response: JSONObject?)
|
||||
|
||||
fun postError()
|
||||
}
|
||||
|
||||
interface OnPostArrImageListener {
|
||||
/**
|
||||
* key: 图片本地路径
|
||||
* value: 图片提交成功后的链接
|
||||
*/
|
||||
fun postSuccess(imgMap: HashMap<String, String>)
|
||||
|
||||
fun postError()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,8 +7,11 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
@ -59,7 +62,17 @@ public class InstallUtils {
|
||||
keys.add(packageName);
|
||||
} else if (list.contains(packageName)) {
|
||||
keys.add(packageName);
|
||||
EventBus.getDefault().post(new EBPackage("安装", packageName));
|
||||
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance(context).getDownloadEntityByPackageName(packageName);
|
||||
String installVersion = PackageUtils.getVersionByPackage(context, packageName);
|
||||
if (!TextUtils.isEmpty(installVersion) && downloadEntity != null &&
|
||||
installVersion.equals(downloadEntity.getVersionName())) {
|
||||
if (!downloadEntity.isPluggable() || PackageUtils.isSignature(context, packageName)) {
|
||||
EventBus.getDefault().post(new EBPackage("安装", packageName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (String key : keys) {
|
||||
@ -72,7 +85,7 @@ public class InstallUtils {
|
||||
long time = uninstallMap.get(packageName);
|
||||
if (System.currentTimeMillis() - time >= MAX_TIME) {
|
||||
keys.add(packageName);
|
||||
} else if (list.contains(packageName)) {
|
||||
} else if (!list.contains(packageName)) {
|
||||
keys.add(packageName);
|
||||
EventBus.getDefault().post(new EBPackage("卸载", packageName));
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.gh.gamecenter.category.CategoryListActivity;
|
||||
import com.gh.gamecenter.entity.CategoryEntity;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
* @Date 17/05/2017
|
||||
@ -53,4 +56,9 @@ public class IntentUtils {
|
||||
"http://www.ghzs.com/link?source=appshare333");
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void startCategoryListActivity(Context context, String categoryTitle, CategoryEntity category) {
|
||||
DataUtils.onMtaEvent(context, "分类大全", categoryTitle, category.getName());
|
||||
context.startActivity(CategoryListActivity.Companion.getIntent(context, categoryTitle, category, "全部"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,20 +11,22 @@ import com.gh.gamecenter.R;
|
||||
public class KaiFuUtils {
|
||||
|
||||
public static void setKaiFuType(TextView textView, String type) {
|
||||
if (type == null) return;
|
||||
textView.setText(type);
|
||||
switch (type) {
|
||||
case "不删档内测":
|
||||
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.content));
|
||||
break;
|
||||
case "删档内测":
|
||||
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.content));
|
||||
break;
|
||||
case "公测":
|
||||
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
|
||||
break;
|
||||
default:
|
||||
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
|
||||
break;
|
||||
}
|
||||
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
|
||||
// switch (type) {
|
||||
// case "不删档内测":
|
||||
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.content));
|
||||
// break;
|
||||
// case "删档内测":
|
||||
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.content));
|
||||
// break;
|
||||
// case "公测":
|
||||
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
|
||||
// break;
|
||||
// default:
|
||||
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,12 +20,13 @@ import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.LibaoDetailAdapter;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.entity.UserDataEntity;
|
||||
import com.gh.gamecenter.entity.MeEntity;
|
||||
import com.gh.gamecenter.entity.UserDataLibaoEntity;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.eventbus.EBUISwitch;
|
||||
import com.gh.gamecenter.geetest.GeetestListener;
|
||||
import com.gh.gamecenter.geetest.GeetestUtils;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.retrofit.JSONObjectResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
@ -118,7 +119,7 @@ public class LibaoUtils {
|
||||
|
||||
public static void deleteLibaoCode(final Context context, final String code,
|
||||
final PostLibaoListener listener) {
|
||||
RetrofitManager.getInstance(context).getApi().deleteLibaoCode(code)
|
||||
RetrofitManager.getInstance(context).getApi().deleteLibaoCode(UserManager.getInstance().getUserId(), code)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@ -135,7 +136,7 @@ public class LibaoUtils {
|
||||
}
|
||||
|
||||
public static void getLibaoStatus(Context context, String ids, final PostLibaoListener listener) {
|
||||
RetrofitManager.getInstance(context).getApi().getLibaoStatus(ids)
|
||||
RetrofitManager.getInstance(context).getApi().getLibaoStatus(UrlFilterUtils.getFilterQuery("libao_ids", ids))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<List<LibaoStatusEntity>>() {
|
||||
@ -151,148 +152,236 @@ public class LibaoUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static void initLibaoBtn(final Context context, final TextView libaoBtn, final LibaoEntity libaoEntity,
|
||||
final boolean isInstallRequired, final LibaoDetailAdapter adapter, final String entrance) {
|
||||
|
||||
public static void setLiBaoBtnStatus(final TextView libaoBtn, String status, Context context) {
|
||||
libaoBtn.setTextColor(Color.WHITE);
|
||||
final String status = libaoEntity.getStatus();
|
||||
if (TextUtils.isEmpty(status)) return;
|
||||
switch (status) {
|
||||
case "coming":
|
||||
libaoBtn.setText(R.string.libao_coming);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_blue_style);
|
||||
break;
|
||||
case "ling":
|
||||
libaoBtn.setText(R.string.libao_ling);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_green_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
break;
|
||||
case "tao":
|
||||
libaoBtn.setText(R.string.libao_tao);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_orange_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
break;
|
||||
case "coming":
|
||||
libaoBtn.setText(R.string.libao_coming);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
|
||||
break;
|
||||
case "used_up":
|
||||
libaoBtn.setText(R.string.libao_used_up);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
|
||||
break;
|
||||
case "finish":
|
||||
libaoBtn.setText(R.string.libao_finish);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
break;
|
||||
case "linged":
|
||||
libaoBtn.setText(R.string.libao_linged);
|
||||
libaoBtn.setBackgroundResource(R.drawable.libao_linged_style);
|
||||
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_linged_selector));
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
|
||||
break;
|
||||
case "taoed":
|
||||
libaoBtn.setText(R.string.libao_taoed);
|
||||
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
|
||||
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
|
||||
break;
|
||||
case "copy":
|
||||
libaoBtn.setText(R.string.libao_copy);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_blue_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
break;
|
||||
case "repeatLing":
|
||||
libaoBtn.setText(R.string.libao_repeat_ling);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
|
||||
break;
|
||||
case "repeatLinged":
|
||||
libaoBtn.setText(R.string.libao_repeat_ling);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_green_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
break;
|
||||
|
||||
case "repeatTao":
|
||||
libaoBtn.setText(R.string.libao_repeat_tao);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_cancel_up);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
|
||||
break;
|
||||
case "repeatTaoed":
|
||||
libaoBtn.setText(R.string.libao_repeat_tao);
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_orange_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
break;
|
||||
case "unshelve":
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_cancel_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
|
||||
libaoBtn.setText(R.string.libao_unshelve);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
break;
|
||||
default:
|
||||
libaoBtn.setBackgroundResource(R.drawable.textview_cancel_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
|
||||
libaoBtn.setText("异常");
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void initLibaoBtn(final Context context, final TextView libaoBtn, final LibaoEntity libaoEntity,
|
||||
final boolean isInstallRequired, final LibaoDetailAdapter adapter, final String entrance) {
|
||||
String status = libaoEntity.getStatus();
|
||||
setLiBaoBtnStatus(libaoBtn, status, context);
|
||||
|
||||
libaoBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
CheckLoginUtils.checkLogin(context, new CheckLoginUtils.OnLoggenInListener() {
|
||||
@Override
|
||||
public void onLoggedIn() {
|
||||
// 领取限制
|
||||
if ("领取".equals(libaoBtn.getText().toString()) || "淘号".equals(libaoBtn.getText().toString())) {
|
||||
if (isInstallRequired && !isAppInstalled(context, libaoEntity.getPackageName())) {
|
||||
String platform;
|
||||
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
|
||||
platform = "";
|
||||
} else {
|
||||
platform = PlatformUtils.getInstance(context)
|
||||
.getPlatformName(libaoEntity.getPlatform()) + "版";
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, () -> {
|
||||
// 领取限制
|
||||
if ("领取".equals(libaoBtn.getText().toString()) || "淘号".equals(libaoBtn.getText().toString())) {
|
||||
if (isInstallRequired && !isAppInstalled(context, libaoEntity.getPackageName())) {
|
||||
String platform;
|
||||
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
|
||||
platform = "";
|
||||
} else {
|
||||
platform = PlatformUtils.getInstance(context)
|
||||
.getPlatformName(libaoEntity.getPlatform()) + "版";
|
||||
}
|
||||
|
||||
String dialogContent = context.getString(R.string.ling_rules_dialog, libaoEntity.getGame().getName(), platform);
|
||||
DialogUtils.showWarningDialog(context, "条件不符",
|
||||
Html.fromHtml(dialogContent), "关闭", "立即安装"
|
||||
, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
adapter.openDownload();
|
||||
}
|
||||
}, null);
|
||||
String dialogContent = context.getString(R.string.ling_rules_dialog, libaoEntity.getGame().getName(), platform);
|
||||
DialogUtils.showWarningDialog(context, "条件不符",
|
||||
Html.fromHtml(dialogContent), "关闭", "立即安装"
|
||||
, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
adapter.openDownload();
|
||||
}
|
||||
}, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (libaoBtn.getText().toString()) {
|
||||
case "未开始":
|
||||
Utils.toast(context, "还没到开始领取时间");
|
||||
break;
|
||||
case "查看":
|
||||
Intent intent = LibaoDetailActivity.getIntent(context, libaoEntity, entrance);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
case "再领一个":
|
||||
case "领取":
|
||||
if ("repeatLing".equals(status)) {
|
||||
DialogUtils.showWarningDialog(context, "礼包刷新提醒"
|
||||
, "礼包每天0点刷新,换新区或者换新角色需要继续领取礼包的童鞋,请于明天0点之后回来即可[再领一个]"
|
||||
, null, "知道了", null, null);
|
||||
} else {
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance);
|
||||
}
|
||||
break;
|
||||
case "再淘一个":
|
||||
case "淘号":
|
||||
if ("repeatTao".equals(status)) {
|
||||
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "淘号中...");
|
||||
postLibaoTao(context, libaoEntity.getId(), new PostLibaoListener() {
|
||||
@Override
|
||||
public void postSucced(Object response) {
|
||||
|
||||
switch (libaoBtn.getText().toString()) {
|
||||
case "未开始":
|
||||
Utils.toast(context, "还没到开始领取时间");
|
||||
break;
|
||||
case "查看":
|
||||
Intent intent = LibaoDetailActivity.getIntent(context, libaoEntity, entrance);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
case "再领一个":
|
||||
case "领取":
|
||||
if ("repeatLing".equals(status)) {
|
||||
DialogUtils.showWarningDialog(context, "礼包刷新提醒"
|
||||
, "礼包每天0点刷新,换新区或者换新角色需要继续领取礼包的童鞋,请于明天0点之后回来即可[再领一个]"
|
||||
, null, "知道了", null, null);
|
||||
} else {
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance);
|
||||
}
|
||||
break;
|
||||
case "再淘一个":
|
||||
case "淘号":
|
||||
if ("repeatTao".equals(status)) {
|
||||
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
|
||||
return;
|
||||
}
|
||||
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "淘号中...");
|
||||
postLibaoTao(context, libaoEntity.getId(), new PostLibaoListener() {
|
||||
@Override
|
||||
public void postSucced(Object response) {
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
JSONObject responseBody = (JSONObject) response;
|
||||
String libaoCode = null;
|
||||
try {
|
||||
libaoCode = responseBody.getString("code");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
JSONObject responseBody = (JSONObject) response;
|
||||
Utils.log("postLibaoTao=====" + responseBody);
|
||||
String libaoCode = null;
|
||||
if (TextUtils.isEmpty(libaoCode)) {
|
||||
try {
|
||||
libaoCode = responseBody.getString("code");
|
||||
String detail = responseBody.getString("detail");
|
||||
switch (detail) {
|
||||
case "maintaining":
|
||||
Utils.toast(context, "网络状态异常,请稍后再试");
|
||||
break;
|
||||
case "fail to compete":
|
||||
Utils.toast(context, "淘号失败,稍后重试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "淘号异常");
|
||||
break;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(libaoCode)) {
|
||||
Utils.toast(context, "淘号成功");
|
||||
|
||||
libaoEntity.setStatus("taoed");
|
||||
|
||||
EventBus.getDefault().post(new EBReuse("libaoChanged"));
|
||||
|
||||
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "tao", Utils.getTime(context)));
|
||||
|
||||
final String finalLibaoCode = libaoCode;
|
||||
|
||||
DialogUtils.showWarningDialog(context, "淘号成功"
|
||||
, Html.fromHtml(context.getString(R.string.taoed_dialog, libaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
copyLink(finalLibaoCode, context);
|
||||
if (isInstallRequired) {
|
||||
libaoBtn.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Spanned msg = Html.fromHtml(
|
||||
context.getString(R.string.taoed_copy_dialog
|
||||
, finalLibaoCode));
|
||||
lunningAppDialog(context
|
||||
, msg, libaoEntity);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable error) {
|
||||
Utils.log("---" + error.toString());
|
||||
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
if (error instanceof HttpException) {
|
||||
HttpException exception = (HttpException) error;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = responseBody.getString("detail");
|
||||
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
|
||||
String detail = errorJson.getString("detail");
|
||||
// Utils.toast(context, "返回::" + detail);
|
||||
switch (detail) {
|
||||
case "coming":
|
||||
Utils.toast(context, "礼包领取时间未开始");
|
||||
break;
|
||||
case "finish":
|
||||
Utils.toast(context, "礼包领取时间已结束");
|
||||
break;
|
||||
case "fetched":
|
||||
Utils.toast(context, "你今天已领过这个礼包了, 不能再淘号");
|
||||
|
||||
libaoBtn.setText("已淘号");
|
||||
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
|
||||
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
|
||||
libaoEntity.setStatus("taoed");
|
||||
break;
|
||||
case "try tao":
|
||||
case "used up":
|
||||
DialogUtils.showHintDialog(context, "礼包已领光"
|
||||
, "手速不够快,礼包已经被抢光了,十分抱歉", "知道了");
|
||||
break;
|
||||
case "maintaining":
|
||||
Utils.toast(context, "网络状态异常,请稍后再试");
|
||||
break;
|
||||
@ -300,104 +389,21 @@ public class LibaoUtils {
|
||||
Utils.toast(context, "淘号失败,稍后重试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "淘号异常");
|
||||
Utils.toast(context, "操作失败");
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Utils.toast(context, "礼包处理异常" + ex.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Utils.toast(context, "淘号成功");
|
||||
|
||||
libaoEntity.setStatus("taoed");
|
||||
|
||||
EventBus.getDefault().post(new EBReuse("libaoChanged"));
|
||||
|
||||
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "tao", Utils.getTime(context)));
|
||||
|
||||
final String finalLibaoCode = libaoCode;
|
||||
|
||||
DialogUtils.showWarningDialog(context, "淘号成功"
|
||||
, Html.fromHtml(context.getString(R.string.taoed_dialog, libaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, new DialogUtils.ConfirmListener() {
|
||||
@Override
|
||||
public void onConfirm() {
|
||||
copyLink(finalLibaoCode, context);
|
||||
if (isInstallRequired) {
|
||||
libaoBtn.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Spanned msg = Html.fromHtml(
|
||||
context.getString(R.string.taoed_copy_dialog
|
||||
, finalLibaoCode));
|
||||
lunningAppDialog(context
|
||||
, msg, libaoEntity);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable error) {
|
||||
Utils.log("---" + error.toString());
|
||||
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
if (error instanceof HttpException) {
|
||||
HttpException exception = (HttpException) error;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
|
||||
String detail = errorJson.getString("detail");
|
||||
// Utils.toast(context, "返回::" + detail);
|
||||
switch (detail) {
|
||||
case "coming":
|
||||
Utils.toast(context, "礼包领取时间未开始");
|
||||
break;
|
||||
case "finish":
|
||||
Utils.toast(context, "礼包领取时间已结束");
|
||||
break;
|
||||
case "fetched":
|
||||
Utils.toast(context, "你今天已领过这个礼包了, 不能再淘号");
|
||||
|
||||
libaoBtn.setText("已淘号");
|
||||
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
|
||||
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
|
||||
libaoEntity.setStatus("taoed");
|
||||
break;
|
||||
case "try tao":
|
||||
case "used up":
|
||||
DialogUtils.showHintDialog(context, "礼包已领光"
|
||||
, "手速不够快,礼包已经被抢光了,十分抱歉", "知道了");
|
||||
break;
|
||||
case "maintaining":
|
||||
Utils.toast(context, "网络状态异常,请稍后再试");
|
||||
break;
|
||||
case "fail to compete":
|
||||
Utils.toast(context, "淘号失败,稍后重试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "操作失败");
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Utils.toast(context, "礼包处理异常" + ex.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "发生异常");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
Utils.toast(context, "发生异常");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -419,7 +425,6 @@ public class LibaoUtils {
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
JSONObject responseBody = (JSONObject) response;
|
||||
Utils.log("postLibaoLing=====" + responseBody);
|
||||
String libaoCode = null;
|
||||
try {
|
||||
libaoCode = responseBody.getString("code");
|
||||
@ -472,7 +477,6 @@ public class LibaoUtils {
|
||||
String string = exception.response().errorBody().string();
|
||||
JSONObject errorJson = new JSONObject(string);
|
||||
String detail = errorJson.getString("detail");
|
||||
Utils.log("=======detail ::" + errorJson.toString());
|
||||
switch (detail) {
|
||||
case "coming":
|
||||
Utils.toast(context, "礼包领取时间未开始");
|
||||
@ -484,7 +488,8 @@ public class LibaoUtils {
|
||||
Utils.toast(context, "你已领过这个礼包了");
|
||||
int countdown = 0;
|
||||
if (errorJson.toString().contains("countdown")) {
|
||||
countdown = errorJson.getInt("countdown");
|
||||
JSONObject data = errorJson.getJSONObject("data");
|
||||
countdown = data.getInt("countdown");
|
||||
}
|
||||
if (countdown > 0 && countdown < 60 * 10) {
|
||||
EventBus.getDefault().post(new EBUISwitch(REFRESH_LIBAO_TIME, countdown));
|
||||
@ -581,7 +586,7 @@ public class LibaoUtils {
|
||||
libaoEntity.setBeforeStatus(libaoStatusEntity.getStatus());
|
||||
libaoStatusEntity.setBeforeStatus(libaoStatusEntity.getStatus());
|
||||
|
||||
UserDataEntity userData = libaoEntity.getUserData();
|
||||
MeEntity userData = libaoEntity.getMe();
|
||||
if (userData != null && userData.getUserDataLibaoList() != null && userData.getUserDataLibaoList().size() > 0) {
|
||||
List<UserDataLibaoEntity> userDataLibaoList = userData.getUserDataLibaoList();
|
||||
UserDataLibaoEntity userDataLibaoEntity = userDataLibaoList.get(userDataLibaoList.size() - 1);
|
||||
@ -606,7 +611,7 @@ public class LibaoUtils {
|
||||
libaoEntity.setBeforeStatus(libaoStatusEntity.getStatus());
|
||||
libaoStatusEntity.setBeforeStatus(libaoStatusEntity.getStatus());
|
||||
|
||||
UserDataEntity userData = libaoEntity.getUserData();
|
||||
MeEntity userData = libaoEntity.getMe();
|
||||
if (userData != null && userData.getUserDataLibaoList() != null && userData.getUserDataLibaoList().size() > 0) {
|
||||
List<UserDataLibaoEntity> userDataLibaoList = userData.getUserDataLibaoList();
|
||||
UserDataLibaoEntity userDataLibaoEntity = userDataLibaoList.get(userDataLibaoList.size() - 1);
|
||||
|
||||
@ -1,37 +1,20 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.LoginResponseEntity;
|
||||
import com.gh.gamecenter.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.manager.RefreshTokenManager;
|
||||
import com.gh.gamecenter.personal.PersonalFragment;
|
||||
import com.gh.gamecenter.retrofit.JSONObjectResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.HttpException;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
@ -39,55 +22,52 @@ import rx.schedulers.Schedulers;
|
||||
* Created by khy on 7/07/17.
|
||||
*/
|
||||
|
||||
// TODO: 1/12/17 逐步整理 删除
|
||||
public class LoginUtils {
|
||||
|
||||
public enum LoginTag {
|
||||
qq, wechat, weibo, phone, refresh, oldUserPhone
|
||||
}
|
||||
|
||||
public static void checkPhoneNum(final Context context, final String phoneName, final onCaptchaCallBackListener listener) { // 老用户登录检查手机是否登录过
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.checkPhoneNum(phoneName)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(ResponseBody response) {
|
||||
super.onResponse(response);
|
||||
try {
|
||||
JSONObject content = new JSONObject(response.string());
|
||||
String status = content.getString("status");
|
||||
if ("ok".equals(status)) {
|
||||
getPhoneCaptcha(context, phoneName, listener);
|
||||
} else {
|
||||
DialogUtils.showWarningDialog(context, null, "手机号已存在,请使用未登录过的手机号,以保证数据正常同步到新账号上"
|
||||
, null, "我知道了", null, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
super.onFailure(e);
|
||||
if (e == null) {
|
||||
Utils.toast(context, "请检查网络是否可用");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ResponseBody responseBody = e.response().errorBody();
|
||||
String string = responseBody.string();
|
||||
JSONObject content = new JSONObject(string);
|
||||
int code = content.getInt("code");
|
||||
outputErrorHint(context, code);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
// public static void checkPhoneNum(final Context context, final String phoneName, final onCaptchaCallBackListener listener) { // 老用户登录检查手机是否登录过
|
||||
// RetrofitManager.getInstance(context).getApi()
|
||||
// .checkPhoneNum(phoneName)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(new Response<ResponseBody>() {
|
||||
// @Override
|
||||
// public void onResponse(ResponseBody response) {
|
||||
// super.onResponse(response);
|
||||
// try {
|
||||
// JSONObject content = new JSONObject(response.string());
|
||||
// String status = content.getString("status");
|
||||
// if ("ok".equals(status)) {
|
||||
// getPhoneCaptcha(context, phoneName, listener);
|
||||
// } else {
|
||||
// DialogUtils.showWarningDialog(context, null, "手机号已存在,请使用未登录过的手机号,以保证数据正常同步到新账号上"
|
||||
// , null, "我知道了", null, null);
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(HttpException e) {
|
||||
// super.onFailure(e);
|
||||
// if (e == null) {
|
||||
// Utils.toast(context, "请检查网络是否可用");
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// ResponseBody responseBody = e.response().errorBody();
|
||||
// String string = responseBody.string();
|
||||
// JSONObject content = new JSONObject(string);
|
||||
// int code = content.getInt("code");
|
||||
// outputErrorHint(context, code);
|
||||
// } catch (Exception e1) {
|
||||
// e1.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// }
|
||||
|
||||
// 获取验证码
|
||||
public static void getPhoneCaptcha(final Context context, String phoneNum, final onCaptchaCallBackListener listener) {
|
||||
@ -101,7 +81,7 @@ public class LoginUtils {
|
||||
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), content.toString());
|
||||
RetrofitManager.getInstance(context)
|
||||
.getUsersea()
|
||||
.getApi()
|
||||
.loginByCaptcha(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -111,6 +91,7 @@ public class LoginUtils {
|
||||
super.onResponse(response);
|
||||
try {
|
||||
listener.onCaptcha(response.getString("service_id"));
|
||||
Utils.toast(context, "验证码短信已发送,请注意查收");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -128,7 +109,11 @@ public class LoginUtils {
|
||||
String string = responseBody.string();
|
||||
JSONObject content = new JSONObject(string);
|
||||
int code = content.getInt("code");
|
||||
outputErrorHint(context, code);
|
||||
if (code == 403202) {
|
||||
captchaErrorHint(context, content);
|
||||
} else {
|
||||
outputErrorHint(context, code);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
Utils.toast(context, "无法获取验证码,请检查你的网络状态");
|
||||
@ -138,123 +123,11 @@ public class LoginUtils {
|
||||
}
|
||||
|
||||
|
||||
// 登录前,做好body判断
|
||||
public static void login(final Context context, final JSONObject content, final LoginTag loginTag,
|
||||
final onLoginCallBackListener listener) {
|
||||
|
||||
Observable<LoginResponseEntity> observable = null;
|
||||
String userToken = null;
|
||||
|
||||
try {
|
||||
JSONObject device = DeviceUtils.getLoginDevice(context.getApplicationContext());
|
||||
content.put("device", device);
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), content.toString());
|
||||
|
||||
if (loginTag == LoginTag.weibo) {
|
||||
userToken = content.getString("uid");
|
||||
observable = RetrofitManager.getInstance(context).getUsersea().loginByWeibo(body);
|
||||
} else if (loginTag == LoginTag.qq) {
|
||||
userToken = content.getString("openid");
|
||||
observable = RetrofitManager.getInstance(context).getUsersea().loginByQQ(body);
|
||||
} else if (loginTag == LoginTag.wechat) {
|
||||
userToken = content.getString("openid");
|
||||
observable = RetrofitManager.getInstance(context).getUsersea().loginByWechat(body);
|
||||
} else if (loginTag == LoginTag.phone || loginTag == LoginTag.oldUserPhone) {
|
||||
userToken = content.getString("mobile");
|
||||
observable = RetrofitManager.getInstance(context).getUsersea().loginByMobile(body);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (observable == null) return;
|
||||
|
||||
final String finalUserToken = userToken;
|
||||
observable
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<LoginResponseEntity>() {
|
||||
@Override
|
||||
public void onResponse(LoginResponseEntity response) {
|
||||
super.onResponse(response);
|
||||
if (loginTag.equals(LoginTag.phone) || loginTag.equals(LoginTag.oldUserPhone)) {
|
||||
try {
|
||||
response.setLoginType(content.getString("mobile"));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
response.setLoginType(loginTag.name());
|
||||
}
|
||||
response.setUserToken(finalUserToken);
|
||||
saveLoginToken(context, response);
|
||||
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String syncDeviceID = sp.getString("syncDeviceID", null);
|
||||
if (!TextUtils.isEmpty(syncDeviceID)) {
|
||||
syncUserData(context, syncDeviceID, listener, loginTag);
|
||||
sp.edit().putString("syncDeviceID", null).apply(); // 清空
|
||||
} else {
|
||||
getUserData(context, false, listener, loginTag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
super.onFailure(e);
|
||||
if (listener != null) {
|
||||
listener.onLoginFailure();
|
||||
}
|
||||
try {
|
||||
ResponseBody responseBody = e.response().errorBody();
|
||||
String string = responseBody.string();
|
||||
JSONObject content = new JSONObject(string);
|
||||
int code = content.getInt("code");
|
||||
|
||||
if (loginTag.equals(LoginTag.phone)) {
|
||||
outputErrorHint(context, code);
|
||||
} else {
|
||||
if (loginTag.equals(LoginTag.qq)) {
|
||||
GetLoginDataUtils.getInstance(context).QQLogout();
|
||||
}
|
||||
Utils.toast(context, context.getString(R.string.login_failure_hint));
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
Utils.toast(context, context.getString(R.string.login_failure_hint));
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void syncUserData(final Context context, String syncDeviceID,
|
||||
final onLoginCallBackListener listener,
|
||||
final LoginTag loginTag) {
|
||||
|
||||
String loginType;
|
||||
if (LoginTag.phone.equals(loginTag)) {
|
||||
loginType = "mobile";
|
||||
} else {
|
||||
loginType = loginTag.toString();
|
||||
}
|
||||
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("device_id", syncDeviceID);
|
||||
map.put("login_type", loginType);
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), new JSONObject(map).toString());
|
||||
RetrofitManager.getInstance(context).getApi().syncUserData(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(userInfoResponse(context, loginTag, listener));
|
||||
}
|
||||
|
||||
// 注销登录
|
||||
public static void logout(final Context context, final OnLogoutListener listener) {
|
||||
|
||||
RetrofitManager.getInstance(context)
|
||||
.getUsersea()
|
||||
.getApi()
|
||||
.logout()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -274,300 +147,106 @@ public class LoginUtils {
|
||||
});
|
||||
}
|
||||
|
||||
// 清除本地用户相关信息
|
||||
public static void cleanUserData(Context context) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = sp.edit();
|
||||
edit.putString("user_info", null);
|
||||
edit.putString("login_token", null);
|
||||
edit.apply();
|
||||
|
||||
GetLoginDataUtils.getInstance(context).QQLogout();
|
||||
|
||||
EventBus.getDefault().post(new EBReuse(PersonalFragment.LOGOUT_TAG));
|
||||
public static boolean userPostErrorToast(Throwable throwable, Context context, boolean isComment) {
|
||||
if (throwable instanceof HttpException) {
|
||||
HttpException exception = (HttpException) throwable;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
|
||||
int errorCode = errorJson.getInt("code");
|
||||
switch (errorCode) {
|
||||
case 403019:
|
||||
if (isComment) {
|
||||
Utils.toast(context, R.string.comment_failed_userblocked);
|
||||
} else {
|
||||
Utils.toast(context, R.string.comment_failed_userbanned);
|
||||
}
|
||||
break;
|
||||
case 403020:
|
||||
Utils.toast(context, R.string.comment_failed_toofrequent);
|
||||
break;
|
||||
case 403021:
|
||||
Utils.toast(context, R.string.comment_failed_illegal);
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, R.string.comment_failed_unknown);
|
||||
break;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Utils.toast(context, "无法识别错误类型");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查本地是否有缓存token,有则马上登录
|
||||
public static void checkLogin(Context context, onLoginCallBackListener listener) {
|
||||
LoginResponseEntity loginToken = getLoginToken(context);
|
||||
|
||||
if (loginToken != null && loginToken.getAccessToken() != null) {
|
||||
LoginResponseEntity.AccessToken accessToken = loginToken.getAccessToken();
|
||||
Long accessExpire = accessToken.getExpire();
|
||||
if (accessExpire != null && accessExpire > Utils.getTime(context)) {
|
||||
getUserData(context, false, listener, null);
|
||||
public static void captchaErrorHint(Context context, JSONObject content) {
|
||||
try {
|
||||
JSONObject detail = content.getJSONObject("detail");
|
||||
if ("isv.BUSINESS_LIMIT_CONTROL".equals(detail.getString("sub_code"))) {
|
||||
Utils.toast(context, "获取验证码太频繁,请稍后再试");
|
||||
} else {
|
||||
LoginResponseEntity.RefreshToken refreshToken = loginToken.getRefreshToken();
|
||||
Long refreshExpire = refreshToken.getExpire();
|
||||
if (refreshExpire != null && refreshExpire > Utils.getTime(context)) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("refresh_token", refreshToken.getValue());
|
||||
RefreshTokenManager.getInstance().refreshToken(context, false, new JSONObject(params), listener);
|
||||
} else {
|
||||
// 重新登录
|
||||
cleanUserData(context);
|
||||
}
|
||||
Utils.toast(context, detail.getString("sub_msg"));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Response<UserInfoEntity> userInfoResponse(final Context context,
|
||||
final LoginTag loginTag,
|
||||
final onLoginCallBackListener listener) {
|
||||
return new Response<UserInfoEntity>() {
|
||||
@Override
|
||||
public void onResponse(UserInfoEntity response) {
|
||||
super.onResponse(response);
|
||||
|
||||
saveUserInfo(context, response);
|
||||
if (listener != null) {
|
||||
listener.onLogin(response, loginTag);
|
||||
}
|
||||
|
||||
if (loginTag != null && !LoginTag.refresh.equals(loginTag)) {
|
||||
Utils.toast(context, "登录成功");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
super.onFailure(e);
|
||||
if (listener != null) {
|
||||
listener.onLoginFailure();
|
||||
}
|
||||
if (loginTag != null) {
|
||||
Utils.toast(context, context.getString(R.string.login_failure_hint));
|
||||
}
|
||||
if (loginTag != null && loginTag.equals(LoginTag.qq)) {
|
||||
GetLoginDataUtils.getInstance(context).QQLogout();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
public static void getUserData(final Context context, boolean isRunMainThread, final onLoginCallBackListener listener, final LoginTag loginTag) {
|
||||
|
||||
Observable<UserInfoEntity> observable;
|
||||
if (isRunMainThread) {
|
||||
observable = RetrofitManager.getInstance(context)
|
||||
.getApi()
|
||||
.getUserInfo();
|
||||
} else {
|
||||
observable = RetrofitManager.getInstance(context)
|
||||
.getApi()
|
||||
.getUserInfo()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
}
|
||||
observable.subscribe(userInfoResponse(context, loginTag, listener));
|
||||
}
|
||||
|
||||
// 获取本地缓存用户信息
|
||||
public static UserInfoEntity getUserInfo(Context context) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String loginData = sp.getString("user_info", null);
|
||||
if (!TextUtils.isEmpty(loginData)) {
|
||||
Type listType = new TypeToken<UserInfoEntity>() {
|
||||
}.getType();
|
||||
return new Gson().fromJson(loginData, listType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// 在本地缓存用户信息
|
||||
public static void saveUserInfo(Context context, UserInfoEntity entity) {
|
||||
if (entity != null) {
|
||||
String region = entity.getRegion();
|
||||
if (region != null && region.contains("中国")) { // 转换地区格式
|
||||
String replace = region.replace("中国 ", "");
|
||||
entity.setRegion(replace);
|
||||
}
|
||||
|
||||
String s = new Gson().toJson(entity);
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = sp.edit();
|
||||
edit.putString("user_info", s);
|
||||
edit.apply();
|
||||
}
|
||||
}
|
||||
|
||||
//获取本地缓存用户token
|
||||
public static LoginResponseEntity getLoginToken(Context context) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String loginData = sp.getString("login_token", null);
|
||||
if (!TextUtils.isEmpty(loginData)) {
|
||||
Type listType = new TypeToken<LoginResponseEntity>() {
|
||||
}.getType();
|
||||
return new Gson().fromJson(loginData, listType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//获取本地缓存用户token
|
||||
public static String getToken(Context context) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String loginData = sp.getString("login_token", null);
|
||||
if (!TextUtils.isEmpty(loginData)) {
|
||||
Type listType = new TypeToken<LoginResponseEntity>() {
|
||||
}.getType();
|
||||
LoginResponseEntity entity = new Gson().fromJson(loginData, listType);
|
||||
if (entity != null && entity.getAccessToken() != null) {
|
||||
return entity.getAccessToken().getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 在本地缓存用户token
|
||||
public static void saveLoginToken(Context context, LoginResponseEntity entity) {
|
||||
if (entity != null) {
|
||||
if (TextUtils.isEmpty(entity.getLoginType())) {
|
||||
LoginResponseEntity loginToken = getLoginToken(context);
|
||||
if (loginToken != null) {
|
||||
entity.setLoginType(loginToken.getLoginType());
|
||||
}
|
||||
}
|
||||
|
||||
String s = new Gson().toJson(entity);
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = sp.edit();
|
||||
edit.putString("login_token", s);
|
||||
edit.apply();
|
||||
}
|
||||
}
|
||||
|
||||
//更改用户信息
|
||||
public static void changeUserInfo(final onChangeUserInfoListener listener, final Context context,
|
||||
final String content, final String editType) {
|
||||
final UserInfoEntity entity = getUserInfo(context);
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(editType, content);
|
||||
|
||||
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "正在修改信息...");
|
||||
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"),
|
||||
new JSONObject(map).toString());
|
||||
RetrofitManager.getInstance(context)
|
||||
.getUsersea()
|
||||
.changeUserInfo(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(ResponseBody response) {
|
||||
super.onResponse(response);
|
||||
if (loadingDialog != null) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
switch (editType) {
|
||||
case "name":
|
||||
entity.setName(content);
|
||||
break;
|
||||
case "contact":
|
||||
entity.setContact(content);
|
||||
break;
|
||||
case "gender":
|
||||
entity.setGender(content);
|
||||
break;
|
||||
case "region":
|
||||
entity.setRegion(content);
|
||||
break;
|
||||
case "icon":
|
||||
entity.setIcon(content);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
saveUserInfo(context, entity);
|
||||
|
||||
|
||||
listener.onChange();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
super.onFailure(e);
|
||||
if (loadingDialog != null) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
Utils.toast(context, "修改失败");
|
||||
|
||||
if (e == null) {
|
||||
Utils.toast(context, "请检查网络是否可用");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ResponseBody responseBody = e.response().errorBody();
|
||||
String string = responseBody.string();
|
||||
JSONObject content = new JSONObject(string);
|
||||
int code = content.getInt("code");
|
||||
outputErrorHint(context, code);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void outputErrorHint(Context context, int code) {
|
||||
|
||||
public static void outputErrorHint(Context context, int code) {
|
||||
switch (code) {
|
||||
case 40000:
|
||||
Utils.toast(context, "参数不全");
|
||||
break;
|
||||
case 40001:
|
||||
case 400001:
|
||||
Utils.toast(context, "验证码获取过快,请稍后重试");// 已经发送过短信
|
||||
break;
|
||||
case 40002:
|
||||
case 400002:
|
||||
Utils.toast(context, "请求第三方开放平台时发生错误");
|
||||
break;
|
||||
case 40003:
|
||||
case 400003:
|
||||
Utils.toast(context, "上传用户头像时发生错误");
|
||||
break;
|
||||
case 40101:
|
||||
case 400101:
|
||||
Utils.toast(context, "缺少参数 app_id");
|
||||
break;
|
||||
case 40102:
|
||||
case 400102:
|
||||
Utils.toast(context, "缺少签名验证的头信息");
|
||||
break;
|
||||
case 40104:
|
||||
case 400104:
|
||||
Utils.toast(context, "缺少token");
|
||||
break;
|
||||
case 40105:
|
||||
case 400105:
|
||||
Utils.toast(context, "缺少手机号码");
|
||||
break;
|
||||
case 40106:
|
||||
case 400106:
|
||||
Utils.toast(context, "缺少用户名");
|
||||
break;
|
||||
case 40107:
|
||||
case 400107:
|
||||
Utils.toast(context, "缺少密码参数");
|
||||
break;
|
||||
case 40202:
|
||||
case 400202:
|
||||
Utils.toast(context, "无效的手机号码");
|
||||
break;
|
||||
case 40203:
|
||||
case 400203:
|
||||
Utils.toast(context, "无效的用户名");
|
||||
break;
|
||||
case 40204:
|
||||
case 400204:
|
||||
Utils.toast(context, "无效的头像地址");
|
||||
break;
|
||||
case 40205:
|
||||
case 400205:
|
||||
Utils.toast(context, "无效的性别参数");
|
||||
break;
|
||||
case 40206:
|
||||
case 400206:
|
||||
Utils.toast(context, "无效的地区参数");
|
||||
break;
|
||||
case 40208:
|
||||
case 400208:
|
||||
Utils.toast(context, "无效的密码");
|
||||
break;
|
||||
case 40209:
|
||||
case 400209:
|
||||
Utils.toast(context, "无效的URL 地址");
|
||||
break;
|
||||
case 42000:
|
||||
@ -585,68 +264,80 @@ public class LoginUtils {
|
||||
case 42004:
|
||||
Utils.toast(context, "无效的请求");
|
||||
break;
|
||||
case 40301:
|
||||
case 400301:
|
||||
Utils.toast(context, "签名验证失败");
|
||||
break;
|
||||
case 40302:
|
||||
case 400302:
|
||||
Utils.toast(context, "验证码错误");
|
||||
break;
|
||||
case 40303:
|
||||
case 400303:
|
||||
Utils.toast(context, "密码错误");
|
||||
break;
|
||||
case 40304:
|
||||
case 400304:
|
||||
Utils.toast(context, "不支持该种方式登录");
|
||||
break;
|
||||
case 40305:
|
||||
case 400305:
|
||||
Utils.toast(context, "错误的状态值(应用只有两种状态: working / stop)");
|
||||
break;
|
||||
case 40306:
|
||||
case 400306:
|
||||
Utils.toast(context, "传递了无法识别的参数");
|
||||
break;
|
||||
case 40401:
|
||||
case 400401:
|
||||
Utils.toast(context, "token过期");
|
||||
break;
|
||||
case 40402:
|
||||
case 400402:
|
||||
Utils.toast(context, "Service_id过期,主要原因是:收到手机短信验证码后长时间没有进行登录操作");
|
||||
break;
|
||||
case 40403:
|
||||
case 400403:
|
||||
Utils.toast(context, "验证码已过期");
|
||||
break;
|
||||
case 40501:
|
||||
case 400501:
|
||||
Utils.toast(context, "同名应用已经存在");
|
||||
break;
|
||||
case 40502:
|
||||
Utils.toast(context, "用户名已存在");
|
||||
case 400502:
|
||||
Utils.toast(context, "昵称已存在");
|
||||
break;
|
||||
case 40503:
|
||||
case 400503:
|
||||
Utils.toast(context, "名称已经存在");
|
||||
break;
|
||||
case 40601:
|
||||
case 400601:
|
||||
Utils.toast(context, "应用不存在");
|
||||
break;
|
||||
case 40602:
|
||||
case 400602:
|
||||
Utils.toast(context, "用户不存在");
|
||||
break;
|
||||
case 40603:
|
||||
case 400603:
|
||||
Utils.toast(context, "用户系统不存在");
|
||||
break;
|
||||
case 40604:
|
||||
case 400604:
|
||||
Utils.toast(context, "用户已被冻结");
|
||||
break;
|
||||
case 40605:
|
||||
case 400605:
|
||||
Utils.toast(context, "用户没有冻结");
|
||||
break;
|
||||
case 40606:
|
||||
case 400606:
|
||||
Utils.toast(context, "该应用被停止运行了");
|
||||
break;
|
||||
case 40801:
|
||||
case 400801:
|
||||
Utils.toast(context, "访问过于频繁");
|
||||
break;
|
||||
case 403001:
|
||||
case 403007:
|
||||
Utils.toast(context, "设备异常,获取验证码失败,请更换登陆方式或明天再试");
|
||||
break;
|
||||
case 403202:
|
||||
Utils.toast(context, "403202");
|
||||
break;
|
||||
case 400213:
|
||||
Utils.toast(context, "昵称违规");
|
||||
break;
|
||||
case 403801:
|
||||
Utils.toast(context, "获取验证码太频繁,请稍后再试");
|
||||
break;
|
||||
case 403204:
|
||||
Utils.toast(context, "获取验证码太频繁,请稍后再试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "未知错误");
|
||||
Utils.toast(context, code + "");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -657,20 +348,9 @@ public class LoginUtils {
|
||||
void onCompleted();
|
||||
}
|
||||
|
||||
// 更改用户信息回调
|
||||
public interface onChangeUserInfoListener {
|
||||
void onChange();
|
||||
}
|
||||
|
||||
// 获取验证码回调
|
||||
public interface onCaptchaCallBackListener {
|
||||
void onCaptcha(String serviceId);
|
||||
}
|
||||
|
||||
// 登录回调
|
||||
public interface onLoginCallBackListener {
|
||||
void onLogin(UserInfoEntity entity, LoginTag loginTag);
|
||||
|
||||
void onLoginFailure();
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,26 +71,22 @@ public class MessageShareUtils {
|
||||
private Context mContext;
|
||||
|
||||
//TODO 干掉activity,将context变成applicationcontext
|
||||
// private Activity activity; // 用来关闭分享页面
|
||||
private Activity mActivity; // 用来关闭分享页面
|
||||
//QQ或者QQ空间分享回调处理
|
||||
public IUiListener QqShareListener = new IUiListener() {
|
||||
@Override
|
||||
public void onComplete(Object o) {
|
||||
// activity.finish();
|
||||
// activity.overridePendingTransition(0, 0);//禁止退出Activity 动画
|
||||
Utils.toast(mContext, "分享成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
Utils.toast(mContext, "分享失败");
|
||||
Utils.toast(mContext, "分享失败!请检查是否已安装QQ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
// activity.finish();
|
||||
// activity.overridePendingTransition(0, 0);//禁止退出Activity 动画
|
||||
Utils.toast(mContext, "分享已取消");
|
||||
Utils.toast(mContext, R.string.share_cancel_hint);
|
||||
}
|
||||
};
|
||||
// 适配快传成绩单分享
|
||||
@ -139,11 +135,11 @@ public class MessageShareUtils {
|
||||
return mTencent;
|
||||
}
|
||||
|
||||
public void showShareWindows(View view, Bitmap bitmap, String picName, int shareType) {
|
||||
public void showShareWindows(Activity activity, View view, Bitmap bitmap, String picName, int shareType) {
|
||||
this.shareBm = bitmap;
|
||||
this.picName = picName;
|
||||
this.shareType = shareType;
|
||||
// this.activity = (Activity) mContext;
|
||||
this.mActivity = activity;
|
||||
|
||||
if (shareType == 2) {
|
||||
contentSize = 75;
|
||||
@ -230,11 +226,11 @@ public class MessageShareUtils {
|
||||
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE,
|
||||
QQShare.SHARE_TO_QQ_TYPE_IMAGE);
|
||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, mContext.getExternalCacheDir().getPath() + "/ShareImg/" + picName);
|
||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, "光环助手");
|
||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name));
|
||||
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT,
|
||||
QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE);
|
||||
mTencent.shareToQQ(
|
||||
(Activity) mContext, params, QqShareListener);
|
||||
mActivity, params, QqShareListener);
|
||||
if (mPopupWindow == null) return;
|
||||
mPopupWindow.dismiss();
|
||||
}
|
||||
@ -246,11 +242,11 @@ public class MessageShareUtils {
|
||||
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE,
|
||||
QQShare.SHARE_TO_QQ_TYPE_IMAGE);
|
||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, mContext.getExternalCacheDir().getPath() + "/ShareImg/" + picName);
|
||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, "光环助手");
|
||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name));
|
||||
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT,
|
||||
QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
|
||||
mTencent.shareToQQ(
|
||||
(Activity) mContext, params, QqShareListener);
|
||||
mActivity, params, QqShareListener);
|
||||
if (mPopupWindow == null) return;
|
||||
mPopupWindow.dismiss();
|
||||
}
|
||||
|
||||
@ -138,4 +138,67 @@ public class NewsUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void setNewsDetailTime(TextView textView, long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
|
||||
try {
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
long day = time * 1000;
|
||||
if (day >= today && day < today + 86400 * 1000) {
|
||||
long min = new Date().getTime() / 1000 - day / 1000;
|
||||
int hour = (int) (min / (60 * 60));
|
||||
if (hour == 0) {
|
||||
if (min < 60) {
|
||||
textView.setText("刚刚");
|
||||
} else {
|
||||
textView.setText(String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60)));
|
||||
}
|
||||
} else {
|
||||
textView.setText(String.format(Locale.getDefault(), "%d小时前", hour));
|
||||
}
|
||||
} else if (day >= today - 86400 * 1000 && day < today) {
|
||||
format.applyPattern("HH:mm");
|
||||
textView.setText("昨天 ");
|
||||
} else {
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
textView.setText(format.format(day));
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
textView.setText(format.format(time * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFormattedTime(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
|
||||
try {
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
long day = time * 1000;
|
||||
if (day >= today && day < today + 86400 * 1000) {
|
||||
long min = new Date().getTime() / 1000 - day / 1000;
|
||||
int hour = (int) (min / (60 * 60));
|
||||
if (hour == 0) {
|
||||
if (min < 60) {
|
||||
return "刚刚";
|
||||
} else {
|
||||
return (String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60)));
|
||||
}
|
||||
} else {
|
||||
return (String.format(Locale.getDefault(), "%d小时前", hour));
|
||||
}
|
||||
} else if (day >= today - 86400 * 1000 && day < today) {
|
||||
format.applyPattern("HH:mm");
|
||||
return ("昨天 ");
|
||||
} else {
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
return (format.format(day));
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
return (format.format(time * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,12 +7,14 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.Signature;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
@ -35,17 +37,35 @@ public class PackageUtils {
|
||||
/*
|
||||
* 判断是否可以更新,只判断gh_version的大小
|
||||
*/
|
||||
public static boolean isCanUpdate(Context context, GameUpdateEntity gameUpdateEntity) {
|
||||
// 判断是否gh_version是否存在
|
||||
String gh_version = (String) PackageUtils.getMetaData(
|
||||
context, gameUpdateEntity.getPackageName(), "gh_version");
|
||||
if (gh_version != null) {
|
||||
gh_version = gh_version.substring(2);
|
||||
// 判断gh_version的大小
|
||||
return Long.parseLong(gh_version) < Long.parseLong(gameUpdateEntity.getGhVersion());
|
||||
} else {
|
||||
return false;
|
||||
public static List<GameUpdateEntity> isCanUpdate(Context context, GameEntity gameEntity) {
|
||||
|
||||
List<GameUpdateEntity> updateList = new ArrayList<>();
|
||||
|
||||
for (ApkEntity apkEntity : gameEntity.getApk()) {
|
||||
// 判断是否gh_version是否存在
|
||||
String gh_version = (String) PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_version");
|
||||
if (gh_version != null) {
|
||||
gh_version = gh_version.substring(2);
|
||||
if (Long.parseLong(gh_version) < Long.parseLong(apkEntity.getGhVersion()) && apkEntity.getForce()) {
|
||||
GameUpdateEntity updateEntity = new GameUpdateEntity();
|
||||
updateEntity.setId(gameEntity.getId());
|
||||
updateEntity.setName(gameEntity.getName());
|
||||
updateEntity.setIcon(gameEntity.getIcon());
|
||||
updateEntity.setPackageName(apkEntity.getPackageName());
|
||||
updateEntity.setSize(apkEntity.getSize());
|
||||
updateEntity.setVersion(apkEntity.getVersion());
|
||||
updateEntity.setGhVersion(apkEntity.getGhVersion());
|
||||
updateEntity.setUrl(apkEntity.getUrl());
|
||||
updateEntity.setPlatform(apkEntity.getPlatform());
|
||||
updateEntity.setEtag(apkEntity.getEtag());
|
||||
updateEntity.setBrief(gameEntity.getBrief());
|
||||
updateEntity.setTag(gameEntity.getTag());
|
||||
updateList.add(updateEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updateList;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -128,7 +148,7 @@ public class PackageUtils {
|
||||
if (TextUtils.isEmpty(packageName)) {
|
||||
return true;
|
||||
}
|
||||
boolean isContain = com.gh.gamecenter.manager.PackageManager.isInstalled(packageName);
|
||||
boolean isContain = com.gh.gamecenter.manager.PackageManager.INSTANCE.isInstalled(packageName);
|
||||
if (!isContain) {
|
||||
return true;
|
||||
}
|
||||
@ -148,7 +168,7 @@ public class PackageUtils {
|
||||
public static Intent getInstallIntent(Context context, String path) {
|
||||
Uri uri = Uri.fromFile(new File(path));
|
||||
Intent installIntent = new Intent(Intent.ACTION_VIEW);
|
||||
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
|
||||
InstallUtils.getInstance(context).addInstall(getPackageNameByPath(context, path));
|
||||
return installIntent;
|
||||
@ -193,6 +213,7 @@ public class PackageUtils {
|
||||
*/
|
||||
public static long getInstalledTime(Context context, String packageName) {
|
||||
try {
|
||||
if (context == null) return 0;
|
||||
PackageInfo packageInfo = context.getApplicationContext().getPackageManager()
|
||||
.getPackageInfo(packageName, 0);
|
||||
return packageInfo.firstInstallTime;
|
||||
@ -253,6 +274,20 @@ public class PackageUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 获取apk的版本
|
||||
*/
|
||||
public static Drawable getIconByPackage(Context context, String packageName) {
|
||||
try {
|
||||
PackageManager packageManager = context.getApplicationContext().getPackageManager();
|
||||
return packageManager.getApplicationIcon(packageName);
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取所有已安装的软件的包名、版本(非系统应用)
|
||||
*/
|
||||
|
||||
@ -4,17 +4,17 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.PlatformEntity;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.FileUtils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
@ -153,7 +153,7 @@ public class PlatformUtils {
|
||||
}
|
||||
}
|
||||
if (urls.size() != 0) {
|
||||
HaloApp.MAIN_EXECUTOR.execute(new Runnable() {
|
||||
HaloApp.getInstance().getMainExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int success = 0;
|
||||
@ -208,7 +208,9 @@ public class PlatformUtils {
|
||||
if (color != null) {
|
||||
return color;
|
||||
}
|
||||
return "#00B7FA";
|
||||
|
||||
int themeColor = ContextCompat.getColor(HaloApp.getInstance().getApplication(), R.color.theme);
|
||||
return String.format("#%06X", 0xFFFFFF & themeColor);
|
||||
}
|
||||
|
||||
public int getPlatformPic(String platform) {
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.retrofit.JSONObjectResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
@ -43,7 +44,63 @@ public class PostCommentUtils {
|
||||
listener.postSuccess(response);
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, "提交失败,请检查网络设置");
|
||||
Utils.toast(context, R.string.post_failure_hint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
if (listener != null) {
|
||||
listener.postFailed(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void addAnswerComment(final Context context, final String answerId, final String content,
|
||||
final CommentEntity commentEntity,
|
||||
final PostCommentListener listener) {
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), content);
|
||||
Observable<ResponseBody> observable;
|
||||
if (commentEntity != null) {
|
||||
observable = RetrofitManager.getInstance(context).getApi().postReplyToAnswerComment(answerId, commentEntity.getId(), body);
|
||||
} else {
|
||||
observable = RetrofitManager.getInstance(context).getApi().postNewCommentToAnswer(answerId, body);
|
||||
}
|
||||
observable.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new JSONObjectResponse() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
if (response.length() != 0) {
|
||||
if (listener != null) {
|
||||
listener.postSuccess(response);
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, R.string.post_failure_hint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
if (listener != null) {
|
||||
listener.postFailed(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void voteAnswerComment(final Context context,final String answerId, final String commentId,
|
||||
final PostCommentListener listener) {
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.postVoteAnswerComment(answerId,commentId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(ResponseBody response) {
|
||||
if (listener != null) {
|
||||
listener.postSuccess(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,11 +136,31 @@ public class PostCommentUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static void addReportData(final Context context, final String reportData,
|
||||
public static void addReportData(final Context context, final String commentId, final String reportData,
|
||||
final PostCommentListener listener) {
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData);
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.postReportData(body)
|
||||
.postReportData(commentId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(ResponseBody response) {
|
||||
listener.postSuccess(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
listener.postFailed(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void postAnswerReportData(final Context context, final String commentId, final String answerId, final String reportData,
|
||||
final PostCommentListener listener) {
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData);
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.postReportOfAnswerComment(answerId, commentId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
|
||||
56
app/src/main/java/com/gh/common/util/RichEditorUtils.java
Normal file
56
app/src/main/java/com/gh/common/util/RichEditorUtils.java
Normal file
@ -0,0 +1,56 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Base64;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* Created by khy on 15/12/17.
|
||||
*/
|
||||
|
||||
public class RichEditorUtils {
|
||||
|
||||
private RichEditorUtils() throws InstantiationException {
|
||||
throw new InstantiationException("This class is not for instantiation");
|
||||
}
|
||||
|
||||
public static String toBase64(Bitmap bitmap) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
return Base64.encodeToString(bytes, Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
public static Bitmap toBitmap(Drawable drawable) {
|
||||
if (drawable instanceof BitmapDrawable) {
|
||||
return ((BitmapDrawable) drawable).getBitmap();
|
||||
}
|
||||
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
width = width > 0 ? width : 1;
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
height = height > 0 ? height : 1;
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap decodeResource(Context context, int resId) {
|
||||
return BitmapFactory.decodeResource(context.getResources(), resId);
|
||||
}
|
||||
|
||||
public static long getCurrentTime() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,7 @@ import android.graphics.Matrix;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
@ -57,16 +58,14 @@ import static com.gh.common.util.GetLoginDataUtils.SCOPE;
|
||||
*/
|
||||
public class ShareUtils {
|
||||
|
||||
private static ShareUtils instance;
|
||||
private static ShareUtils sInstance;
|
||||
private IWXAPI mIWXAPI;
|
||||
private Tencent mTencent;
|
||||
private String shareUrl;
|
||||
private String shareGameName;
|
||||
private String shareIcon;
|
||||
private String shareNewsTitle; // shareNewsTitle不为空就是新闻分享,否则是游戏分享
|
||||
private boolean isPlugin = false;
|
||||
private boolean ispopupWindow;
|
||||
private boolean isToolsBox;
|
||||
private String mTitle;
|
||||
private String mSummary;
|
||||
|
||||
|
||||
private int[] arrLogo = {
|
||||
R.drawable.share_wechat_logo,
|
||||
@ -78,42 +77,57 @@ public class ShareUtils {
|
||||
R.drawable.share_copyfont_logo,
|
||||
R.drawable.share_cancel_logo
|
||||
};
|
||||
|
||||
public enum ShareType {
|
||||
news,
|
||||
game, // 普通游戏
|
||||
plugin, // 插件游戏
|
||||
tools,
|
||||
askInvite,
|
||||
askNormal, // 问答问题/答案
|
||||
shareGh
|
||||
}
|
||||
|
||||
private String[] arrLabel = {"微信好友", "朋友圈", "QQ好友", "QQ空间", "新浪微博", "短信", "复制链接", "取消"};
|
||||
|
||||
private PopupWindow popupWindow;
|
||||
|
||||
private ShareType mShareType;
|
||||
|
||||
private Activity mActivity;
|
||||
|
||||
private Context mContext;
|
||||
//QQ或者QQ空间分享回调处理
|
||||
public IUiListener QqShareListener = new IUiListener() {
|
||||
@Override
|
||||
public void onComplete(Object o) {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_success_hint));
|
||||
Utils.toast(mContext, R.string.share_success_hint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_fail_hint));
|
||||
Utils.toast(mContext, R.string.share_fail_hint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_cancel_hint));
|
||||
Utils.toast(mContext, R.string.share_cancel_hint);
|
||||
}
|
||||
};
|
||||
|
||||
private ShareUtils(Context context) {
|
||||
mTencent = Tencent.createInstance(Config.TENCENT_APPID, context); //初始化QQ分享
|
||||
mIWXAPI = WXAPIFactory.createWXAPI(context, Config.WECHAT_APPID); //初始化微信分享
|
||||
WbSdk.install(context,new AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", SCOPE));
|
||||
WbSdk.install(context, new AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", SCOPE));
|
||||
// FIXME 此处严重泄露,把Activity Context 存为static?????
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public static ShareUtils getInstance(Activity context) {
|
||||
if (instance == null) {
|
||||
instance = new ShareUtils(context);
|
||||
public static ShareUtils getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new ShareUtils(context);
|
||||
}
|
||||
return instance;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
//检查是否安装手机QQ
|
||||
@ -131,26 +145,17 @@ public class ShareUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param view ispopupWindow-true是绑定的布局, ispopupWindow-false 则是嵌套的父控件
|
||||
* @param url 分享链接
|
||||
* @param gameName 游戏名 与 新闻标题区分
|
||||
* @param icon 分享图标
|
||||
* @param newsTitle 新闻标题 与 游戏名区分
|
||||
* @param isPlugin 判断游戏是否是插件
|
||||
* @param ispopupWindow 判断是否是 PopupWindow false可直接嵌套进布局(分享光环),view是父控件
|
||||
*/
|
||||
public void showShareWindows(View view, String url, String gameName, String icon, String newsTitle,
|
||||
boolean isPlugin, boolean ispopupWindow, boolean isToolsBox) {
|
||||
this.shareIcon = icon;
|
||||
this.shareGameName = gameName;
|
||||
this.shareUrl = url;
|
||||
this.shareNewsTitle = newsTitle;
|
||||
this.isPlugin = isPlugin;
|
||||
this.ispopupWindow = ispopupWindow;
|
||||
this.isToolsBox = isToolsBox;
|
||||
|
||||
View contentView = View.inflate(mContext, R.layout.share_popup_layout, null);
|
||||
public void showShareWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType) {
|
||||
if (activity.isFinishing()) return;
|
||||
this.mActivity = activity;
|
||||
this.shareIcon = icon;
|
||||
this.shareUrl = url;
|
||||
this.mSummary = shareSummary;
|
||||
this.mTitle = shareTitle;
|
||||
this.mShareType = shareType;
|
||||
|
||||
View contentView = View.inflate(mActivity, R.layout.share_popup_layout, null);
|
||||
contentView.setFocusable(true);
|
||||
contentView.setFocusableInTouchMode(true);
|
||||
RecyclerView shareRecyclerView = (RecyclerView) contentView.findViewById(R.id.share_rv);
|
||||
@ -168,7 +173,7 @@ public class ShareUtils {
|
||||
shareRecyclerView.setLayoutManager(gridLayoutManager);
|
||||
shareRecyclerView.setAdapter(new ShareRecyclerViewAdapter());
|
||||
|
||||
if (!ispopupWindow) {
|
||||
if (mShareType == ShareType.shareGh) {
|
||||
RelativeLayout layout = (RelativeLayout) view;
|
||||
layout.addView(contentView);
|
||||
arrLabel[6] = "邮件";
|
||||
@ -186,7 +191,11 @@ public class ShareUtils {
|
||||
popupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT
|
||||
, LinearLayout.LayoutParams.MATCH_PARENT, true);
|
||||
popupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
|
||||
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
|
||||
try {
|
||||
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
contentView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -210,79 +219,52 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//QQ分享
|
||||
private void qqSahre() {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_skip));
|
||||
private void qqShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
Bundle params = new Bundle();
|
||||
|
||||
String title;
|
||||
String summary;
|
||||
|
||||
if (isToolsBox) {
|
||||
title = shareNewsTitle;
|
||||
summary = shareGameName;
|
||||
} else if (ispopupWindow) {
|
||||
if (shareNewsTitle != null) {
|
||||
title = shareNewsTitle;
|
||||
summary = "来自光环助手(最强卡牌神器)";
|
||||
} else {
|
||||
title = "向你推荐:";
|
||||
if (isPlugin) {
|
||||
summary = shareGameName + "(光环加速版)";
|
||||
} else {
|
||||
summary = shareGameName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
title = "玩手游不用肝的感觉真好";
|
||||
summary = "绿色安全的手游加速助手";
|
||||
switch (mShareType) {
|
||||
case plugin:
|
||||
mSummary += "(光环加速版)";
|
||||
break;
|
||||
case askNormal:
|
||||
mTitle += " - 光环助手";
|
||||
break;
|
||||
}
|
||||
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
|
||||
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
|
||||
|
||||
params.putString(QQShare.SHARE_TO_QQ_TITLE, mTitle);
|
||||
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, mSummary);
|
||||
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
|
||||
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, shareUrl);
|
||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, shareIcon);
|
||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, "光环助手");
|
||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name));
|
||||
|
||||
mTencent.shareToQQ(
|
||||
(Activity) mContext, params, QqShareListener);
|
||||
mTencent.shareToQQ(mActivity, params, QqShareListener);
|
||||
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
//微信好友分享
|
||||
private void wechatSahre() {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_skip));
|
||||
private void wechatShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
WXWebpageObject webpage = new WXWebpageObject();
|
||||
WXMediaMessage msg = new WXMediaMessage(webpage);
|
||||
webpage.webpageUrl = shareUrl;
|
||||
|
||||
String title;
|
||||
String summary;
|
||||
switch (mShareType) {
|
||||
case plugin:
|
||||
mSummary += "(光环加速版)";
|
||||
break;
|
||||
case askNormal:
|
||||
mTitle += " - 光环助手";
|
||||
break;
|
||||
|
||||
if (isToolsBox) {
|
||||
title = shareNewsTitle;
|
||||
summary = shareGameName;
|
||||
} else if (ispopupWindow) {
|
||||
if (shareNewsTitle != null) {
|
||||
title = shareNewsTitle;
|
||||
summary = "来自光环助手(最强卡牌神器)";
|
||||
} else {
|
||||
title = "向你推荐:";
|
||||
if (isPlugin) {
|
||||
summary = shareGameName + "(光环加速版)";
|
||||
} else {
|
||||
summary = shareGameName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
title = "玩手游不用肝的感觉真好";
|
||||
summary = "绿色安全的手游加速助手";
|
||||
}
|
||||
|
||||
msg.title = title;
|
||||
msg.description = summary;
|
||||
msg.title = mTitle;
|
||||
msg.description = mSummary;
|
||||
|
||||
SendMessageToWX.Req req = new SendMessageToWX.Req();
|
||||
req.transaction = buildTransaction("webpage");
|
||||
@ -290,7 +272,7 @@ public class ShareUtils {
|
||||
req.scene = SendMessageToWX.Req.WXSceneSession;
|
||||
|
||||
loadBitMap(shareIcon, msg, req);
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
}
|
||||
@ -304,8 +286,12 @@ public class ShareUtils {
|
||||
@Override
|
||||
protected void onNewResultImpl(Bitmap bitmap) {
|
||||
Bitmap compressBp = compressBitmap(bitmap);
|
||||
Bitmap resultBp = addBackGround(compressBp);
|
||||
msg.thumbData = Util.bmpToByteArray(resultBp, true);
|
||||
if (mShareType == ShareType.askNormal || mShareType == ShareType.askInvite) {
|
||||
msg.thumbData = Util.bmpToByteArray(compressBp, true);
|
||||
} else {
|
||||
Bitmap resultBp = addBackGround(compressBp);
|
||||
msg.thumbData = Util.bmpToByteArray(resultBp, true);
|
||||
}
|
||||
mIWXAPI.sendReq(req);
|
||||
}
|
||||
|
||||
@ -317,10 +303,10 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//压缩图片
|
||||
private Bitmap compressBitmap(Bitmap bitmap) {
|
||||
public static Bitmap compressBitmap(Bitmap bitmap) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
float zoom = (float) Math.sqrt(10 * 1024 / (float) bos.toByteArray().length);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
|
||||
float zoom = (float) Math.sqrt(9 * 1024 / (float) bos.toByteArray().length);
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setScale(zoom, zoom);
|
||||
@ -328,15 +314,14 @@ public class ShareUtils {
|
||||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
bos.reset();
|
||||
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 100, bos);
|
||||
|
||||
while (bos.toByteArray().length > 10 * 1024) {
|
||||
while (bos.toByteArray().length > 9 * 1024) {
|
||||
System.out.println(bos.toByteArray().length);
|
||||
matrix.setScale(0.9f, 0.9f);
|
||||
result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);
|
||||
bos.reset();
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
|
||||
result.compress(Bitmap.CompressFormat.JPEG, 100, bos);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -364,78 +349,61 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//QQ空间分享
|
||||
private void qZoneSahre() {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_skip));
|
||||
private void qZoneShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
Bundle params = new Bundle();
|
||||
|
||||
String title;
|
||||
String summary = null;
|
||||
|
||||
if (isToolsBox) {
|
||||
title = shareNewsTitle;
|
||||
summary = shareGameName;
|
||||
} else if (ispopupWindow) {
|
||||
if (shareNewsTitle != null) {
|
||||
title = shareNewsTitle;
|
||||
} else {
|
||||
title = "向你推荐:";
|
||||
if (isPlugin) {
|
||||
summary = shareGameName + "(光环加速版)";
|
||||
} else {
|
||||
summary = shareGameName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
title = "玩手游不用肝的感觉真好";
|
||||
summary = "绿色安全的手游加速助手";
|
||||
switch (mShareType) {
|
||||
case plugin:
|
||||
mSummary += "(光环加速版)";
|
||||
break;
|
||||
case askNormal:
|
||||
mTitle += " - 光环助手";
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<String> imageUrls = new ArrayList<>();
|
||||
imageUrls.add(shareIcon);
|
||||
|
||||
if (summary != null) {
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, summary);
|
||||
if (!TextUtils.isEmpty(mSummary)) {
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, mSummary);
|
||||
}
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, mTitle);
|
||||
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_NO_TYPE);
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, shareUrl);
|
||||
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls);
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_APP_NAME, "光环助手");
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name));
|
||||
|
||||
mTencent.shareToQzone(
|
||||
(Activity) mContext, params, QqShareListener);
|
||||
if (ispopupWindow) {
|
||||
mTencent.shareToQzone(mActivity, params, QqShareListener);
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
//微信朋友圈分享
|
||||
private void wechatMomentsSahre() {
|
||||
Utils.toast(mContext, mContext.getString(R.string.share_skip));
|
||||
private void wechatMomentsShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
WXWebpageObject webpage = new WXWebpageObject();
|
||||
WXMediaMessage msg = new WXMediaMessage(webpage);
|
||||
|
||||
webpage.webpageUrl = shareUrl;
|
||||
|
||||
String title;
|
||||
|
||||
if (isToolsBox) {
|
||||
title = shareNewsTitle;
|
||||
} else if (ispopupWindow) {
|
||||
if (shareNewsTitle != null) {
|
||||
title = shareNewsTitle;
|
||||
} else {
|
||||
if (isPlugin) {
|
||||
title = shareGameName + "(光环加速版)";
|
||||
} else {
|
||||
title = shareGameName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
title = "玩手游不用肝的感觉真好";
|
||||
switch (mShareType) {
|
||||
case plugin:
|
||||
msg.title = mSummary + "(光环加速版)";
|
||||
break;
|
||||
case game:
|
||||
msg.title = mSummary;
|
||||
break;
|
||||
case askNormal:
|
||||
msg.title = mTitle + " - 光环助手";
|
||||
break;
|
||||
default:
|
||||
msg.title = mTitle;
|
||||
break;
|
||||
}
|
||||
|
||||
msg.title = title;
|
||||
|
||||
SendMessageToWX.Req req = new SendMessageToWX.Req();
|
||||
|
||||
req.transaction = buildTransaction("webpage");
|
||||
@ -443,50 +411,57 @@ public class ShareUtils {
|
||||
req.scene = SendMessageToWX.Req.WXSceneTimeline;
|
||||
|
||||
loadBitMap(shareIcon, msg, req);
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
//新浪微博分享
|
||||
private void sinaWeiboSahre() {
|
||||
private void sinaWeiboShare() {
|
||||
Intent intent = WeiBoShareActivity.getWeiboshareIntent(mContext,
|
||||
shareNewsTitle, shareIcon, shareGameName, shareUrl, isPlugin, ispopupWindow, isToolsBox);
|
||||
shareUrl, shareIcon, mTitle, mSummary, mShareType.toString());
|
||||
mContext.startActivity(intent);
|
||||
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
//短信分享
|
||||
private void shortMessageSahre() {
|
||||
private void shortMessageShare() {
|
||||
String smsBody;
|
||||
if (isToolsBox) {
|
||||
smsBody = shareNewsTitle + shareUrl;
|
||||
} else if (ispopupWindow) {
|
||||
if (shareNewsTitle != null) {
|
||||
smsBody = shareNewsTitle + shareUrl;
|
||||
} else {
|
||||
if (isPlugin) {
|
||||
smsBody = "向你推荐:" + shareGameName + "(光环加速版)" + shareUrl;
|
||||
} else {
|
||||
smsBody = "向你推荐:" + shareGameName + shareUrl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
smsBody = "这个App可以下载各种热门卡牌手游的加速版,绿色安全,超级省心,做日常效率提高3-5倍!光环助手官网地址:" + shareUrl;
|
||||
switch (mShareType) {
|
||||
case news:
|
||||
case tools:
|
||||
smsBody = mTitle + shareUrl;
|
||||
break;
|
||||
case plugin:
|
||||
smsBody = mTitle + mSummary + "(光环加速版)" + shareUrl;
|
||||
break;
|
||||
case game:
|
||||
smsBody = mTitle + mSummary + shareUrl;
|
||||
break;
|
||||
case shareGh:
|
||||
smsBody = "这个App可以下载各种热门卡牌手游的加速版,绿色安全,超级省心,做日常效率提高3-5倍!光环助手官网地址:" + shareUrl;
|
||||
break;
|
||||
case askInvite:
|
||||
case askNormal:
|
||||
smsBody = mTitle + " - 光环助手" + shareUrl;
|
||||
break;
|
||||
default:
|
||||
smsBody = mTitle;
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Intent sendIntent = IntentUtils.getSMSIntent(smsBody);
|
||||
mContext.startActivity(sendIntent);
|
||||
} catch (Exception e) {
|
||||
Utils.toast(mContext, "系统异常,分享失败");
|
||||
Utils.toast(mContext, "设备短信服务异常,分享失败");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
}
|
||||
}
|
||||
@ -495,7 +470,7 @@ public class ShareUtils {
|
||||
private void copyLink(String copyContent) {
|
||||
ClipboardManager cmb = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(copyContent);
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
Utils.toast(mContext, "复制成功");
|
||||
popupWindow.dismiss();
|
||||
} else {
|
||||
@ -520,33 +495,42 @@ public class ShareUtils {
|
||||
public void onClick(View v) {
|
||||
switch (holder.getPosition()) {
|
||||
case 0:
|
||||
wechatSahre();
|
||||
wechatShare();
|
||||
break;
|
||||
case 1:
|
||||
wechatMomentsSahre();
|
||||
wechatMomentsShare();
|
||||
break;
|
||||
case 2:
|
||||
qqSahre();
|
||||
qqShare();
|
||||
break;
|
||||
case 3:
|
||||
qZoneSahre();
|
||||
qZoneShare();
|
||||
break;
|
||||
case 4:
|
||||
sinaWeiboSahre();
|
||||
sinaWeiboShare();
|
||||
break;
|
||||
case 5:
|
||||
shortMessageSahre();
|
||||
shortMessageShare();
|
||||
break;
|
||||
case 6:
|
||||
if (ispopupWindow) {
|
||||
if (mShareType == ShareType.askInvite) {
|
||||
copyLink(mTitle + " - 光环助手" + shareUrl);
|
||||
} else if (mShareType == ShareType.askNormal) {
|
||||
copyLink(shareUrl);
|
||||
} else if (mShareType != ShareType.shareGh) {
|
||||
copyLink(shareUrl);
|
||||
} else {
|
||||
Intent data = IntentUtils.getEmailToGHIntent();
|
||||
mContext.startActivity(data);
|
||||
try {
|
||||
Intent data = IntentUtils.getEmailToGHIntent();
|
||||
mContext.startActivity(data);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utils.toast(mContext, "设备邮件服务异常,分享失败");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (ispopupWindow) {
|
||||
if (mShareType != ShareType.shareGh) {
|
||||
popupWindow.dismiss();
|
||||
} else {
|
||||
copyLink("推荐光环助手,绿色安全的手游加速助手:" + shareUrl);
|
||||
|
||||
@ -3,8 +3,8 @@ package com.gh.common.util;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.halo.assistant.HaloApp;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -23,105 +23,59 @@ public class TimestampUtils {
|
||||
|
||||
private static void initIntervalMap() {
|
||||
intervalMap = new ArrayMap<>();
|
||||
intervalMap.put("^" + Config.API_HOST + "index/slides" + "$", 5);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/chajian" + "$", 10);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/tuijian" + "$", 15);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/.+/detail" + "$", 20);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/.+/digest" + "$", 25);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/remenkapai" + "$", 30);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/.+/news_digest" + "$", 35);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/column/.+\\?page=.+" + "$", 40);
|
||||
intervalMap.put("^" + Config.API_HOST + "support/package/.+/game/digest" + "$", 45);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/danjiyouxi\\?limit=20\\&offset=.+" + "$", 50);
|
||||
intervalMap.put("^" + Config.API_HOST + "news/.+/digest" + "$", 55);
|
||||
intervalMap.put("^" + Config.API_HOST + "news/.+/detail" + "$", 60);
|
||||
intervalMap.put("^" + Config.API_HOST + "news/.+/suggestion" + "$", 65);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/.+/news\\?limit=3" + "$", 70);
|
||||
intervalMap.put("^" + Config.API_HOST + "zixun/zixun\\?limit=20\\&offset=.+" + "$", 75);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/.+/news\\?limit=20\\&offset=.+" + "$", 80);
|
||||
intervalMap.put("^" + Config.API_HOST + "zixun/yuanchuang\\?limit=20\\&offset=.+" + "$", 85);
|
||||
intervalMap.put("^" + Config.API_HOST + "news\\?type_group=.+\\&offset=.+\\&limit=20" + "$", 90);
|
||||
intervalMap.put("^" + Config.API_HOST + "zixun/guanzhu\\?key=.+\\&limit=20\\&offset=.+" + "$", 95);
|
||||
intervalMap.put("^" + Config.API_HOST + "game/.+/news\\?limit=20\\&offset=.+\\&type=.+" + "$", 100);
|
||||
intervalMap.put("^" + Config.API_HOST + "zixun/guanzhu\\?game_id=.+\\&limit=20\\&offset=.+" + "$", 105);
|
||||
intervalMap.put("^" + Config.API_HOST + "search/news\\?game_id=.+\\&keyword=.+\\&page=.+\\&limit=20" + "$", 110);
|
||||
intervalMap.put("^" + Config.API_HOST + "search/game\\?keyword=.+" + "$", 115);
|
||||
intervalMap.put("^" + Config.API_HOST + "support/setting/platform" + "$", 120);
|
||||
intervalMap.put("^" + Config.API_HOST + "update/package/.+" + "$", 125);
|
||||
intervalMap.put("^" + Config.API_HOST + "update/game/.+/package/.+" + "$", 130);
|
||||
intervalMap.put("^" + Config.COMMENT_HOST + "article/.+/comment\\?limit=10\\&offset=.+" + "$", 135);
|
||||
intervalMap.put("^" + Config.COMMENT_HOST + "article/.+/comment\\?order=hot\\&limit=10\\&offset=.+" + "$", 140);
|
||||
intervalMap.put(".*index.*", 5);
|
||||
intervalMap.put(".*columns.*", 10);
|
||||
intervalMap.put(".*games.*", 15);
|
||||
intervalMap.put(".*articles.*", 20);
|
||||
}
|
||||
|
||||
private static void initCDMap() {
|
||||
cdMap = new ArrayMap<>();
|
||||
cdMap.put("^" + Config.API_HOST + "index/slides" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/chajian" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/tuijian" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/detail" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/digest" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/remenkapai" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/news_digest" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/column/.+\\?page=.+" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "support/package/.+/game/digest" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/danjiyouxi\\?limit=20\\&offset=.+" + "$", Constants.GAME_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "news/.+/digest" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "news/.+/detail" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "news/.+/suggestion" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/news\\?limit=3" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "zixun/zixun\\?limit=20\\&offset=.+" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/news\\?limit=20\\&offset=.+" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "zixun/yuanchuang\\?limit=10\\&offset=.+" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "news\\?type_group=.+\\&offset=.+\\&limit=20" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "zixun/guanzhu\\?key=.+\\&limit=20\\&offset=.+" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/news\\?limit=20\\&offset=.+\\&type=.+" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "zixun/guanzhu\\?game_id=.+\\&limit=20\\&offset=.+" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "search/news\\?game_id=.+\\&keyword=.+\\&page=.+\\&limit=20" + "$", Constants.NEWS_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "search/game\\?keyword=.+" + "$", Constants.SEARCH_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "support/setting/platform" + "$", Constants.PLATFORM_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "update/package/.+" + "$", Constants.UPDATE_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "update/game/.+/package/.+" + "$", Constants.UPDATE_CD);
|
||||
cdMap.put("^" + Config.COMMENT_HOST + "article/.+/comment\\?limit=10\\&offset=.+" + "$", Constants.COMMENT_CD);
|
||||
cdMap.put("^" + Config.COMMENT_HOST + "article/.+/comment\\?order=hot\\&limit=10\\&offset=.+" + "$", Constants.COMMENT_CD);
|
||||
cdMap.put("^" + Config.API_HOST + "device/.+/concern" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "device/.+/concern/.+" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "stat/download" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "disclaimer" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "search/game/default" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "support/upgrade\\?version=.+\\&channel=.+" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "support/time/current" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "support/setting/ui" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "support/download_status\\?version=.+\\&channel=.+" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "support/suggestion" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "game/.+/serverInfo" + "$", 0);
|
||||
cdMap.put("^" + Config.API_HOST + "support/package/unused\\?skip=.+" + "$", 0);
|
||||
cdMap.put(".*index.*", Constants.GAME_CD);
|
||||
cdMap.put(".*columns.*", Constants.GAME_CD);
|
||||
cdMap.put(".*games.*", Constants.GAME_CD);
|
||||
cdMap.put(".*articles.*", Constants.NEWS_CD);
|
||||
}
|
||||
|
||||
/*
|
||||
* 为url添加timestamp
|
||||
*/
|
||||
public static String addTimestamp(String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return url;
|
||||
}
|
||||
int cd = 0;
|
||||
for (String key : getCdMap().keySet()) {
|
||||
if (Pattern.matches(key, url)) {
|
||||
cd = getCdMap().get(key);
|
||||
break;
|
||||
|
||||
if ("GH_REFRESH".equals(HaloApp.getInstance().getChannel())) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return url;
|
||||
}
|
||||
if (url.contains("?")) {
|
||||
String u = url + "×tamp=" + System.currentTimeMillis();
|
||||
return u;
|
||||
} else {
|
||||
String u = url + "?timestamp=" + System.currentTimeMillis();
|
||||
return u;
|
||||
}
|
||||
}
|
||||
if (cd == 0) {
|
||||
return url;
|
||||
}
|
||||
if (url.contains("?")) {
|
||||
String u = url + "×tamp=" + getTimestamp(url, cd);
|
||||
// Utils.log("url = " + u);
|
||||
return u;
|
||||
} else {
|
||||
String u = url + "?timestamp=" + getTimestamp(url, cd);
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return url;
|
||||
}
|
||||
int cd = 0;
|
||||
for (String key : getCdMap().keySet()) {
|
||||
if (Pattern.matches(key, url)) {
|
||||
cd = getCdMap().get(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cd == 0) {
|
||||
return url;
|
||||
}
|
||||
if (url.contains("?")) {
|
||||
String u = url + "×tamp=" + getTimestamp(url, cd);
|
||||
// Utils.log("url = " + u);
|
||||
return u;
|
||||
return u;
|
||||
} else {
|
||||
String u = url + "?timestamp=" + getTimestamp(url, cd);
|
||||
// Utils.log("url = " + u);
|
||||
return u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,197 +3,21 @@ package com.gh.common.util;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.gh.gamecenter.retrofit.StringResponse;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
public class TokenUtils {
|
||||
|
||||
// 注册设备
|
||||
// public static synchronized void register(final Context context) {
|
||||
// Map<String, String> params = new HashMap<>();
|
||||
// params.put("MANUFACTURER", Build.MANUFACTURER);
|
||||
// params.put("MODEL", Build.MODEL);
|
||||
// params.put("ANDROID_SDK", String.valueOf(Build.VERSION.SDK_INT));
|
||||
// params.put("ANDROID_VERSION", Build.VERSION.RELEASE);
|
||||
// String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
// if (!TextUtils.isEmpty(android_id)) {
|
||||
// params.put("ANDROID_ID", android_id);
|
||||
// }
|
||||
// String imei = Util_System_Phone_State.getDeviceId(context);
|
||||
// if (!TextUtils.isEmpty(imei)) {
|
||||
// params.put("IMEI", imei);
|
||||
// }
|
||||
// WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
// String mac = wm.getConnectionInfo().getMacAddress();
|
||||
// if (!TextUtils.isEmpty(mac) || !":::::".equals(mac)) {
|
||||
// params.put("MAC", mac);
|
||||
// } else {
|
||||
// SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
// sp.edit().putBoolean("isUploadMac", false).apply();
|
||||
// }
|
||||
// String mid = StatConfig.getMid(context);
|
||||
// if (!TextUtils.isEmpty(mid) || !"0".equals(mid)) {
|
||||
// params.put("MTA_ID", mid);
|
||||
// } else {
|
||||
// SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
// sp.edit().putBoolean("isUploadMid", false).apply();
|
||||
// }
|
||||
// RequestBody body = RequestBody.create(MediaType.parse("application/json"), new JSONObject(params).toString());
|
||||
// RetrofitManager.getInstance(context).getApi().postRegister(body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(Schedulers.io())
|
||||
// .subscribe(new JSONObjectResponse() {
|
||||
// @Override
|
||||
// public void onResponse(JSONObject response) {
|
||||
// if (response.length() != 0) {
|
||||
// try {
|
||||
// // 保存device_id
|
||||
// saveDeviceId(context, response.getString("device_id"));
|
||||
// Utils.log("device_id = " + response.getString("device_id"));
|
||||
// } catch (JSONException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
public static synchronized void saveDeviceId(Context context, String device_id) {
|
||||
saveSharedPreferences(context, device_id);
|
||||
saveDataFile(context, device_id);
|
||||
svaeSDCard(device_id, "/gh-uuid");// SDCard根目录
|
||||
svaeSDCard(device_id, "/system"); // SDCard system目录
|
||||
svaeSDCard(device_id, "/data"); // SDCard data目录
|
||||
}
|
||||
|
||||
//将uuid存到sp
|
||||
private static void saveSharedPreferences(Context context, String device_id) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = sp.edit();
|
||||
edit.putString("uuid", device_id);
|
||||
edit.apply();
|
||||
Utils.log("saveDeviceId", "保存成功SP");
|
||||
}
|
||||
|
||||
//将uuid存到data/data/PackageName/files文件夹下
|
||||
private static void saveDataFile(Context context, String device_id) {
|
||||
FileOutputStream fops;
|
||||
try {
|
||||
fops = context.openFileOutput("uuid", Context.MODE_PRIVATE);
|
||||
fops.write(device_id.getBytes());
|
||||
fops.close();
|
||||
Utils.log("saveDeviceId", "保存成功DataFile");
|
||||
} catch (Exception e) {
|
||||
Utils.log("保存uuid到data/data/PackageName/files文件异常" + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//将uuid存到SD卡
|
||||
private static void svaeSDCard(String device_id, String saveDir) {
|
||||
File sdCardDir = Environment.getExternalStorageDirectory();
|
||||
String path = sdCardDir.getPath() + saveDir;
|
||||
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
|
||||
// 判断文件是否存在,存在则删除
|
||||
File uuidFile = new File(path + "/uuid");
|
||||
if (uuidFile.isFile() && uuidFile.exists()) {
|
||||
Utils.log(saveDir + "文件夹里的文件存在,执行删除操作");
|
||||
uuidFile.delete();
|
||||
}
|
||||
|
||||
File writeFile = new File(file, "uuid");
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
fos = new FileOutputStream(writeFile);
|
||||
fos.write(device_id.getBytes());
|
||||
fos.close();
|
||||
Utils.log("saveDeviceId", "保存成功SDCard" + "目录为:" + saveDir);
|
||||
} catch (Exception e) {
|
||||
Utils.log("保存uuid到SDCard异常" + saveDir + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// // 获取用户token
|
||||
// public static synchronized Observable<String> getToken(final Context context, boolean isCheck) {
|
||||
//
|
||||
// if (true) { // TODO TEST
|
||||
// return Observable.just(LoginUtils.getToken(context));
|
||||
// }
|
||||
//
|
||||
// String token = null;
|
||||
// if (isCheck) {
|
||||
// SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
// token = sp.getString("token", null);
|
||||
// if (token != null) {
|
||||
// long expire = sp.getLong("token_expire", 0) * 1000 - 10 * 1000;
|
||||
// long time = Utils.getTime(context);
|
||||
// // 判断token是否过期
|
||||
// if (time >= expire) {
|
||||
// // token已过期
|
||||
// token = null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (token == null) {
|
||||
// Map<String, String> params = new HashMap<>();
|
||||
// params.put("device_id", getDeviceId(context));
|
||||
// return RetrofitManager.getInstance(context).getApi()
|
||||
// .postLogin(RequestBody.create(MediaType.parse("application/json"), new JSONObject(params).toString()))
|
||||
// .flatMap(new Func1<ResponseBody, Observable<String>>() {
|
||||
// @Override
|
||||
// public Observable<String> call(ResponseBody responseBody) {
|
||||
// String value = null;
|
||||
// try {
|
||||
// SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
// Editor editor = sp.edit();
|
||||
// JSONObject response = new JSONObject(responseBody.string());
|
||||
// editor.putString("user_name", response.getString("name"));
|
||||
// editor.putString("user_icon", response.getString("icon"));
|
||||
// response = response.getJSONObject("token");
|
||||
// editor.putString("token", response.getString("value"));
|
||||
// editor.putLong("token_expire", response.getLong("expire"));
|
||||
// editor.apply();
|
||||
// // 服务器返回的token和本地已存的token相同,更新本地时间
|
||||
// getTime(context);
|
||||
// value = response.getString("value");
|
||||
// } catch (IOException | JSONException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return Observable.just(value);
|
||||
// }
|
||||
// }).onErrorResumeNext(new Func1<Throwable, Observable<? extends String>>() {
|
||||
// @Override
|
||||
// public Observable<? extends String> call(Throwable throwable) {
|
||||
// return Observable.error(throwable);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// return Observable.just(token);
|
||||
// }
|
||||
|
||||
// TODO VERSION:3.0 之后不存在deviceId
|
||||
@Deprecated
|
||||
public static synchronized String getDeviceId(Context context) {
|
||||
return loadSharedPreferences(context, false);
|
||||
return Util_System_Phone_State.getDeviceId(context); // 暂时用IMEI代替
|
||||
}
|
||||
|
||||
// 获取服务器时间
|
||||
@ -219,118 +43,4 @@ public class TokenUtils {
|
||||
});
|
||||
}
|
||||
|
||||
//读取SharedPreferences的uuid
|
||||
private static String loadSharedPreferences(Context context, boolean isCheck) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String uuid = sp.getString("uuid", null);
|
||||
if (isCheck) {
|
||||
return uuid;
|
||||
}
|
||||
if (uuid == null) {
|
||||
return loadDataFile(context, false);
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("getDeviceId", "获取成功SP" + uuid);
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
//读取data/data/PackageName/files的uuid
|
||||
private static String loadDataFile(Context context, boolean isCheck) {
|
||||
File file = new File(context.getFilesDir(), "uuid");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] b = new byte[1024];
|
||||
int count = -1;
|
||||
String uuid = null;
|
||||
while ((count = fis.read(b)) != -1) {
|
||||
uuid = new String(b, 0, count, "UTF-8");
|
||||
}
|
||||
Utils.log("getDeviceId", "获取成功DataFile" + uuid);
|
||||
return uuid;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (!isCheck) {
|
||||
String[] dirName = {"/gh-uuid", "/system", "/data"};
|
||||
for (int i = 0; i < 3; i++) {
|
||||
String s = loadSDCard(dirName[i]);
|
||||
if (s != null) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//读取SD卡的uuid
|
||||
private static String loadSDCard(String saveDir) {
|
||||
File sdCardDir = Environment.getExternalStorageDirectory();
|
||||
String path = sdCardDir.getPath() + saveDir;
|
||||
File file = new File(path, "uuid");
|
||||
if (file.exists()) {
|
||||
FileInputStream fis;
|
||||
ByteArrayOutputStream bos;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
bos = new ByteArrayOutputStream();
|
||||
byte[] array = new byte[1024];
|
||||
int len = -1;
|
||||
while ((len = fis.read(array)) != -1) {
|
||||
bos.write(array, 0, len);
|
||||
}
|
||||
bos.close();
|
||||
fis.close();
|
||||
Utils.log("getDeviceId", "获取成功SDCard" + "目录为:" + saveDir + "::" + bos.toString());
|
||||
return bos.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// // 检查设备信息是否已经上传完整
|
||||
// public static synchronized void checkDeviceInfo(Context context, String token) {
|
||||
// final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
// final HashMap<String, String> params = new HashMap<>();
|
||||
// if (!sp.getBoolean("isUploadExtra", false)) {
|
||||
// params.put("MANUFACTURER", Build.MANUFACTURER);
|
||||
// params.put("MODEL", Build.MODEL);
|
||||
// params.put("ANDROID_SDK", String.valueOf(Build.VERSION.SDK_INT));
|
||||
// params.put("ANDROID_VERSION", Build.VERSION.RELEASE);
|
||||
// }
|
||||
// if (!sp.getBoolean("isUploadMac", true)) {
|
||||
// WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
// String mac = wm.getConnectionInfo().getMacAddress();
|
||||
// if (!TextUtils.isEmpty(mac) || !":::::".equals(mac)) {
|
||||
// params.put("MAC", mac);
|
||||
// }
|
||||
// }
|
||||
// if (!sp.getBoolean("isUploadMid", true)) {
|
||||
// String mid = StatConfig.getMid(context);
|
||||
// if (!TextUtils.isEmpty(mid) || !"0".equals(mid)) {
|
||||
// params.put("MTA_ID", mid);
|
||||
// }
|
||||
// }
|
||||
// if (params.size() != 0) {
|
||||
// RequestBody body = RequestBody.create(MediaType.parse("application/json"),
|
||||
// new JSONObject(params).toString());
|
||||
// RetrofitManager.getInstance(context).getApi().postDevice(token, body, TokenUtils.getDeviceId(context))
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(new Response<ResponseBody>() {
|
||||
// @Override
|
||||
// public void onResponse(ResponseBody response) {
|
||||
// SharedPreferences.Editor editor = sp.edit();
|
||||
// editor.putBoolean("isUploadExtra", true);
|
||||
// editor.putBoolean("isUploadMac", true);
|
||||
// editor.putBoolean("isUploadMid", true);
|
||||
// editor.apply();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
30
app/src/main/java/com/gh/common/util/UrlFilterUtils.java
Normal file
30
app/src/main/java/com/gh/common/util/UrlFilterUtils.java
Normal file
@ -0,0 +1,30 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.lightgame.config.CommonDebug;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/03/18.
|
||||
*/
|
||||
|
||||
public class UrlFilterUtils {
|
||||
|
||||
// keyName,value,keyName,value......
|
||||
public static String getFilterQuery(@NonNull String... arrStr) {
|
||||
if (CommonDebug.IS_DEBUG && (arrStr.length <= 1 || arrStr.length % 2 != 0)) {
|
||||
throw new IllegalStateException("UrlFilterUtils->getFilterQuery");
|
||||
}
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < arrStr.length; i++) {
|
||||
String s = arrStr[i];
|
||||
result.append(s);
|
||||
if (i % 2 == 0) {
|
||||
result.append(":");
|
||||
} else if (i != arrStr.length - 1) {
|
||||
result.append(",");
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,295 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.scwang.smartrefresh.layout.api.RefreshInternal;
|
||||
import com.scwang.smartrefresh.layout.api.RefreshKernel;
|
||||
import com.scwang.smartrefresh.layout.api.RefreshLayout;
|
||||
import com.scwang.smartrefresh.layout.constant.SpinnerStyle;
|
||||
import com.scwang.smartrefresh.layout.internal.ArrowDrawable;
|
||||
import com.scwang.smartrefresh.layout.internal.InternalAbstract;
|
||||
import com.scwang.smartrefresh.layout.internal.ProgressDrawable;
|
||||
import com.scwang.smartrefresh.layout.util.DensityUtil;
|
||||
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import static com.scwang.smartrefresh.layout.util.SmartUtil.getColor;
|
||||
|
||||
public abstract class AbstractSwipeRefreshHeader<T extends AbstractSwipeRefreshHeader> extends InternalAbstract implements RefreshInternal {
|
||||
public static final byte ID_TEXT_TITLE = 1;
|
||||
public static final byte ID_IMAGE_ARROW = 2;
|
||||
public static final byte ID_IMAGE_PROGRESS = 3;
|
||||
|
||||
protected TextView mTitleText;
|
||||
protected ImageView mArrowView;
|
||||
protected ImageView mProgressView;
|
||||
protected LinearLayout mCenterLayout;
|
||||
protected RefreshKernel mRefreshKernel;
|
||||
protected ArrowDrawable mArrowDrawable;
|
||||
protected ProgressDrawable mProgressDrawable;
|
||||
protected Integer mAccentColor;
|
||||
protected Integer mPrimaryColor;
|
||||
protected int mBackgroundColor;
|
||||
protected int mFinishDuration = 500;
|
||||
|
||||
private DensityUtil mDensityUtil = new DensityUtil();
|
||||
|
||||
public AbstractSwipeRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
mSpinnerStyle = SpinnerStyle.Translate;
|
||||
mArrowView = new ImageView(context);
|
||||
mProgressView = new ImageView(context);
|
||||
mTitleText = new TextView(context);
|
||||
mTitleText.setTextColor(0xff5d5d5d);
|
||||
mCenterLayout = new LinearLayout(context);
|
||||
mCenterLayout.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
mCenterLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
final View thisView = this;
|
||||
final ViewGroup thisGroup = this;
|
||||
final View arrowView = mArrowView;
|
||||
final View titleView = mTitleText;
|
||||
final View progressView = mProgressView;
|
||||
final ViewGroup centerLayout = mCenterLayout;
|
||||
|
||||
titleView.setId(ID_TEXT_TITLE);
|
||||
arrowView.setId(ID_IMAGE_ARROW);
|
||||
progressView.setId(ID_IMAGE_PROGRESS);
|
||||
centerLayout.setId(android.R.id.widget_frame);
|
||||
|
||||
LinearLayout.LayoutParams lpHeaderText = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
centerLayout.addView(titleView, lpHeaderText);
|
||||
|
||||
RelativeLayout.LayoutParams lpHeaderLayout = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
lpHeaderLayout.addRule(CENTER_IN_PARENT);
|
||||
thisGroup.addView(centerLayout, lpHeaderLayout);
|
||||
|
||||
RelativeLayout.LayoutParams lpArrow = new RelativeLayout.LayoutParams(mDensityUtil.dip2px(15), mDensityUtil.dip2px(15));
|
||||
lpArrow.addRule(CENTER_VERTICAL);
|
||||
lpArrow.addRule(LEFT_OF, android.R.id.widget_frame);
|
||||
thisGroup.addView(arrowView, lpArrow);
|
||||
|
||||
RelativeLayout.LayoutParams lpProgress = new RelativeLayout.LayoutParams((ViewGroup.LayoutParams) lpArrow);
|
||||
lpProgress.addRule(CENTER_VERTICAL);
|
||||
lpProgress.addRule(LEFT_OF, android.R.id.widget_frame);
|
||||
progressView.animate().setInterpolator(new LinearInterpolator());
|
||||
thisGroup.addView(progressView, lpProgress);
|
||||
|
||||
if (thisView.isInEditMode()) {
|
||||
arrowView.setVisibility(GONE);
|
||||
} else {
|
||||
progressView.setVisibility(GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
final View arrowView = mArrowView;
|
||||
final View progressView = mProgressView;
|
||||
arrowView.animate().cancel();
|
||||
progressView.animate().cancel();
|
||||
}
|
||||
final Drawable drawable = mProgressView.getDrawable();
|
||||
if (drawable instanceof Animatable) {
|
||||
if (((Animatable) drawable).isRunning()) {
|
||||
((Animatable) drawable).stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected T self() {
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {
|
||||
mRefreshKernel = kernel;
|
||||
mRefreshKernel.requestDrawBackgroundFor(this, mBackgroundColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
|
||||
if (mProgressView.getVisibility() != VISIBLE) {
|
||||
mProgressView.setVisibility(VISIBLE);
|
||||
Drawable drawable = mProgressView.getDrawable();
|
||||
if (drawable instanceof Animatable) {
|
||||
((Animatable) drawable).start();
|
||||
} else {
|
||||
mProgressView.animate().rotation(36000).setDuration(100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
|
||||
onStartAnimator(refreshLayout, height, maxDragHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) {
|
||||
Drawable drawable = mProgressView.getDrawable();
|
||||
if (drawable instanceof Animatable) {
|
||||
if (((Animatable) drawable).isRunning()) {
|
||||
((Animatable) drawable).stop();
|
||||
}
|
||||
} else {
|
||||
mProgressView.animate().rotation(0).setDuration(0);
|
||||
}
|
||||
mProgressView.setVisibility(GONE);
|
||||
return mFinishDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setPrimaryColors(@ColorInt int... colors) {
|
||||
if (colors.length > 0) {
|
||||
final View thisView = this;
|
||||
if (!(thisView.getBackground() instanceof BitmapDrawable) && mPrimaryColor == null) {
|
||||
setPrimaryColor(colors[0]);
|
||||
mPrimaryColor = null;
|
||||
}
|
||||
if (mAccentColor == null) {
|
||||
if (colors.length > 1) {
|
||||
setAccentColor(colors[1]);
|
||||
}
|
||||
mAccentColor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T setProgressDrawable(Drawable drawable) {
|
||||
mProgressDrawable = null;
|
||||
mProgressView.setImageDrawable(drawable);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setProgressResource(@DrawableRes int resId) {
|
||||
mProgressDrawable = null;
|
||||
mProgressView.setImageResource(resId);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setArrowDrawable(Drawable drawable) {
|
||||
mArrowDrawable = null;
|
||||
mArrowView.setImageDrawable(drawable);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setArrowResource(@DrawableRes int resId) {
|
||||
mArrowDrawable = null;
|
||||
mArrowView.setImageResource(resId);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setSpinnerStyle(SpinnerStyle style) {
|
||||
this.mSpinnerStyle = style;
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setPrimaryColor(@ColorInt int primaryColor) {
|
||||
mBackgroundColor = mPrimaryColor = primaryColor;
|
||||
if (mRefreshKernel != null) {
|
||||
mRefreshKernel.requestDrawBackgroundFor(this, mPrimaryColor);
|
||||
}
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setAccentColor(@ColorInt int accentColor) {
|
||||
mAccentColor = accentColor;
|
||||
mTitleText.setTextColor(accentColor);
|
||||
if (mArrowDrawable != null) {
|
||||
mArrowDrawable.setColor(accentColor);
|
||||
}
|
||||
if (mProgressDrawable != null) {
|
||||
mProgressDrawable.setColor(accentColor);
|
||||
}
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setPrimaryColorId(@ColorRes int colorId) {
|
||||
final View thisView = this;
|
||||
setPrimaryColor(getColor(thisView.getContext(), colorId));
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setAccentColorId(@ColorRes int colorId) {
|
||||
final View thisView = this;
|
||||
setAccentColor(getColor(thisView.getContext(), colorId));
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setFinishDuration(int delay) {
|
||||
mFinishDuration = delay;
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setTextSizeTitle(float size) {
|
||||
mTitleText.setTextSize(size);
|
||||
if (mRefreshKernel != null) {
|
||||
mRefreshKernel.requestRemeasureHeightFor(this);
|
||||
}
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setDrawableMarginRight(float dp) {
|
||||
final View arrowView = mArrowView;
|
||||
final View progressView = mProgressView;
|
||||
MarginLayoutParams lpArrow = (MarginLayoutParams) arrowView.getLayoutParams();
|
||||
MarginLayoutParams lpProgress = (MarginLayoutParams) progressView.getLayoutParams();
|
||||
lpArrow.rightMargin = lpProgress.rightMargin = DensityUtil.dp2px(dp);
|
||||
arrowView.setLayoutParams(lpArrow);
|
||||
progressView.setLayoutParams(lpProgress);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setDrawableSize(float dp) {
|
||||
final View arrowView = mArrowView;
|
||||
final View progressView = mProgressView;
|
||||
ViewGroup.LayoutParams lpArrow = arrowView.getLayoutParams();
|
||||
ViewGroup.LayoutParams lpProgress = progressView.getLayoutParams();
|
||||
lpArrow.width = lpProgress.width = DensityUtil.dp2px(dp);
|
||||
lpArrow.height = lpProgress.height = DensityUtil.dp2px(dp);
|
||||
arrowView.setLayoutParams(lpArrow);
|
||||
progressView.setLayoutParams(lpProgress);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setDrawableArrowSize(float dp) {
|
||||
final View arrowView = mArrowView;
|
||||
ViewGroup.LayoutParams lpArrow = arrowView.getLayoutParams();
|
||||
lpArrow.height = lpArrow.width = DensityUtil.dp2px(dp);
|
||||
arrowView.setLayoutParams(lpArrow);
|
||||
return self();
|
||||
}
|
||||
|
||||
public T setDrawableProgressSize(float dp) {
|
||||
final View progressView = mProgressView;
|
||||
ViewGroup.LayoutParams lpProgress = progressView.getLayoutParams();
|
||||
lpProgress.height = lpProgress.width = DensityUtil.dp2px(dp);
|
||||
progressView.setLayoutParams(lpProgress);
|
||||
return self();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.view.ViewPager.OnPageChangeListener;
|
||||
import android.view.Gravity;
|
||||
@ -16,6 +15,7 @@ import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.PlatformUtils;
|
||||
@ -73,7 +73,7 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
@Override
|
||||
public void onDataChanged(DownloadEntity downloadEntity) {
|
||||
if (downloadEntity.getName().equals(gameEntity.getName())
|
||||
&& !"delete".equals(DownloadManager.getInstance(mContext).getStatus(downloadEntity.getUrl()))) {
|
||||
&& !DownloadStatus.delete.equals(DownloadManager.getInstance(mContext).getStatus(downloadEntity.getUrl()))) {
|
||||
|
||||
adapter.putDownloadEntity(downloadEntity);
|
||||
|
||||
@ -86,8 +86,9 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
private LinearLayout dialog_ll_collection_hint;
|
||||
private String entrance;
|
||||
private String location;
|
||||
private int row;
|
||||
private int column;
|
||||
private ExposureEvent traceEvent;
|
||||
private final int row = 3;
|
||||
private final int column = 3;
|
||||
private boolean isLoadPlatform;
|
||||
|
||||
private DownloadDialog() {
|
||||
@ -103,6 +104,10 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
}
|
||||
|
||||
public void showPopupWindow(View view, GameEntity gameEntity, String entrance, String location) {
|
||||
showPopupWindow(view, gameEntity, entrance, location, null);
|
||||
}
|
||||
|
||||
public void showPopupWindow(View view, GameEntity gameEntity, String entrance, String location, @Nullable ExposureEvent traceEvent) {
|
||||
|
||||
if (isShow && (popupWindow == null || !popupWindow.isShowing())) {
|
||||
isShow = false;
|
||||
@ -115,10 +120,7 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
this.gameEntity = gameEntity;
|
||||
this.entrance = entrance;
|
||||
this.location = location;
|
||||
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
row = sp.getInt("download_box_row", 3);
|
||||
column = sp.getInt("download_box_column", 3);
|
||||
this.traceEvent = traceEvent;
|
||||
|
||||
gameApk = sortApk(new ArrayList<>(gameEntity.getApk()));
|
||||
|
||||
@ -213,12 +215,12 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
downloadEntity = DownloadManager.getInstance(mContext).getDownloadEntityByUrl(apkEntity.getUrl());
|
||||
if (downloadEntity == null) {
|
||||
packageName = apkEntity.getPackageName();
|
||||
if (PackageManager.isInstalled(packageName)) {
|
||||
if (PackageManager.INSTANCE.isInstalled(packageName)) {
|
||||
gh_id = PackageUtils.getMetaData(mContext, packageName, "gh_id");
|
||||
if (gh_id == null || gh_id.equals(gameEntity.getId())) {
|
||||
if (!PackageUtils.isSignature(mContext, packageName)) {
|
||||
apkEntity.setOrder(8);
|
||||
} else if (PackageManager.isCanUpdate(gameEntity.getId(), packageName)) {
|
||||
} else if (PackageManager.INSTANCE.isCanUpdate(gameEntity.getId(), packageName)) {
|
||||
apkEntity.setOrder(5);
|
||||
} else {
|
||||
apkEntity.setOrder(2);
|
||||
@ -346,7 +348,7 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
currentItem = viewPager.getCurrentItem();
|
||||
}
|
||||
Utils.log("currentItem = " + currentItem);
|
||||
adapter = new PlatformPagerAdapter(mContext, this, gameEntity, apkList, entrance, location);
|
||||
adapter = new PlatformPagerAdapter(mContext, this, gameEntity, apkList, entrance, location, traceEvent);
|
||||
viewPager.setAdapter(adapter);
|
||||
viewPager.setCurrentItem(currentItem);
|
||||
}
|
||||
@ -434,7 +436,7 @@ public class DownloadDialog implements OnCollectionCallBackListener {
|
||||
addHintPoint(dialog_ll_collection_hint, size);
|
||||
|
||||
collectionAdapter = new PlatformPagerAdapter(
|
||||
mContext, this, gameEntity, gameCollectionEntity.getSaveApkEntity(), entrance, location);
|
||||
mContext, null, gameEntity, gameCollectionEntity.getSaveApkEntity(), entrance, location, traceEvent);
|
||||
collectionViewPager.setAdapter(collectionAdapter);
|
||||
|
||||
collectionViewPager.addOnPageChangeListener(new MyPageChangeListener(dialog_ll_collection_hint));
|
||||
|
||||
190
app/src/main/java/com/gh/common/view/DownloadProgressBar.java
Normal file
190
app/src/main/java/com/gh/common/view/DownloadProgressBar.java
Normal file
@ -0,0 +1,190 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.RectF;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
public class DownloadProgressBar extends ProgressBar {
|
||||
private static final int MAX_LENGTH = 1000;
|
||||
private static final int DOWNLOAD_NORMAL_STYLE = 0;
|
||||
private static final int DOWNLOAD_RECT_STYLE = 1;
|
||||
private static final int DOWNLOAD_IMAGE_STYLE = 2;
|
||||
|
||||
public enum DownloadType {
|
||||
NORMAL,
|
||||
NONE,
|
||||
PLUGIN,
|
||||
LAUNCH_OR_OPEN,
|
||||
INSTALL_NORMAL,
|
||||
INSTALL_PLUGIN,
|
||||
DOWNLOADING_NORMAL,
|
||||
DOWNLOADING_PLUGIN,
|
||||
}
|
||||
|
||||
private PorterDuffXfermode mDuffXFerMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private DownloadType mDownloadType;
|
||||
|
||||
private String mText;
|
||||
|
||||
private int mDownloadStyle;
|
||||
private int mDefaultColor;
|
||||
private int mTextSize;
|
||||
|
||||
public DownloadProgressBar(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public DownloadProgressBar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
if (attrs != null) {
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DownloadProgressBar);
|
||||
mDownloadStyle = ta.getInteger(R.styleable.DownloadProgressBar_downloadStyle, DOWNLOAD_NORMAL_STYLE);
|
||||
mTextSize = ta.getDimensionPixelSize(R.styleable.DownloadProgressBar_textSize, DisplayUtils.sp2px(getContext(), 14));
|
||||
ta.recycle();
|
||||
}
|
||||
setMax(MAX_LENGTH);
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.game_item_btn_download_style));
|
||||
}
|
||||
|
||||
Bitmap srcBitmap;
|
||||
Canvas srcCanvas;
|
||||
RectF rectF;
|
||||
|
||||
private void create() {
|
||||
srcBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
|
||||
srcCanvas = new Canvas(srcBitmap);
|
||||
rectF = new RectF(0, 0, getProgress() * getWidth() / MAX_LENGTH, getMeasuredHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (TextUtils.isEmpty(mText)) return;
|
||||
|
||||
mPaint.setColor(mDefaultColor == 0 ? ContextCompat.getColor(getContext(), R.color.theme) : mDefaultColor); // 初始化颜色
|
||||
mPaint.setTextSize(mTextSize);
|
||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
mPaint.setXfermode(null);
|
||||
create();
|
||||
|
||||
Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
|
||||
int baseline = (getHeight() - fontMetrics.bottom - fontMetrics.top) / 2;
|
||||
|
||||
mPaint.setTextAlign(Paint.Align.CENTER);
|
||||
srcCanvas.drawText(mText, getWidth() / 2, baseline, mPaint);
|
||||
mPaint.setXfermode(mDuffXFerMode);
|
||||
if (getProgress() != 0 && getProgress() != MAX_LENGTH) {
|
||||
mPaint.setColor(DOWNLOAD_IMAGE_STYLE == mDownloadStyle ? Color.BLACK : Color.WHITE); // 反向颜色
|
||||
}
|
||||
|
||||
srcCanvas.drawRect(rectF, mPaint);
|
||||
canvas.drawBitmap(srcBitmap, 0, 0, null);
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
mText = text;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return mText;
|
||||
}
|
||||
|
||||
public void setText(@StringRes int res) {
|
||||
setText(getResources().getString(res));
|
||||
invalidate(); // 文字绘制没有同步 就重绘多几遍吧 虽然不知到有没有用
|
||||
}
|
||||
|
||||
public void setDownloadType(DownloadType downloadType) {
|
||||
switch (downloadType) {
|
||||
case NORMAL:
|
||||
case INSTALL_NORMAL:
|
||||
switch (mDownloadStyle) {
|
||||
case DOWNLOAD_RECT_STYLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_normal_rect_style));
|
||||
mDefaultColor = Color.WHITE;
|
||||
break;
|
||||
case DOWNLOAD_IMAGE_STYLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_normal_image_style));
|
||||
mDefaultColor = Color.BLACK;
|
||||
break;
|
||||
default:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.game_item_btn_download_style));
|
||||
mDefaultColor = Color.WHITE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PLUGIN:
|
||||
case INSTALL_PLUGIN:
|
||||
setProgressDrawable(getResources().getDrawable(mDownloadStyle == DOWNLOAD_RECT_STYLE
|
||||
? R.drawable.detail_download_plugin_install_rect_style : R.drawable.game_item_btn_plugin_style));
|
||||
mDefaultColor = Color.WHITE;
|
||||
break;
|
||||
case NONE:
|
||||
setProgressDrawable(getResources().getDrawable(mDownloadStyle == DOWNLOAD_RECT_STYLE
|
||||
? R.drawable.detail_download_none_rect_style : R.drawable.news_detail_comment));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.hint);
|
||||
break;
|
||||
case LAUNCH_OR_OPEN:
|
||||
switch (mDownloadStyle) {
|
||||
case DOWNLOAD_RECT_STYLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_rect_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
|
||||
break;
|
||||
case DOWNLOAD_IMAGE_STYLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_image_style));
|
||||
mDefaultColor = Color.WHITE;
|
||||
break;
|
||||
default:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DOWNLOADING_NORMAL:
|
||||
switch (mDownloadStyle) {
|
||||
case DOWNLOAD_RECT_STYLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_rect_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
|
||||
break;
|
||||
case DOWNLOAD_IMAGE_STYLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_image_style));
|
||||
mDefaultColor = Color.WHITE;
|
||||
break;
|
||||
default:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DOWNLOADING_PLUGIN:
|
||||
setProgressDrawable(getResources().getDrawable(mDownloadStyle == DOWNLOAD_RECT_STYLE
|
||||
? R.drawable.detail_downloading_plugin_rect_style : R.drawable.detail_downloading_plugin_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.btn_plugin);
|
||||
break;
|
||||
}
|
||||
|
||||
mDownloadType = downloadType;
|
||||
}
|
||||
|
||||
public DownloadType getDownloadType() {
|
||||
return mDownloadType;
|
||||
}
|
||||
|
||||
}
|
||||
26
app/src/main/java/com/gh/common/view/DumbRefreshLayout.java
Normal file
26
app/src/main/java/com/gh/common/view/DumbRefreshLayout.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
|
||||
import com.scwang.smartrefresh.layout.constant.RefreshState;
|
||||
|
||||
public class DumbRefreshLayout extends SmartRefreshLayout {
|
||||
|
||||
public DumbRefreshLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public DumbRefreshLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public DumbRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public boolean isRefreshing() {
|
||||
return mState != RefreshState.None;
|
||||
}
|
||||
}
|
||||
113
app/src/main/java/com/gh/common/view/ExpendTextView.java
Normal file
113
app/src/main/java/com/gh/common/view/ExpendTextView.java
Normal file
@ -0,0 +1,113 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Layout;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
public class ExpendTextView extends android.support.v7.widget.AppCompatTextView {
|
||||
|
||||
private CharSequence mSnapshotText;
|
||||
|
||||
private String mExpendText = "...全文";
|
||||
|
||||
private int mMaxLines = 3; // 由于sdk版本限制(getMaxLines) 这里设置默认值
|
||||
|
||||
private boolean mInitLayout = false;
|
||||
private boolean mOpenLayout = false;
|
||||
|
||||
public ExpendTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ExpendTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ExpendTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
mMaxLines = getMaxLines();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (mInitLayout && !mOpenLayout && getLineCount() > mMaxLines) {
|
||||
mSnapshotText = getText();
|
||||
mInitLayout = false;
|
||||
showExpendButton();
|
||||
}
|
||||
}
|
||||
|
||||
public void setExpendText(String text) {
|
||||
this.mExpendText = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
mInitLayout = true;
|
||||
super.setText(text, type);
|
||||
}
|
||||
|
||||
private void showExpendButton() {
|
||||
Layout layout = getLayout();
|
||||
int start = layout.getLineStart(0);
|
||||
int lastLineEnd = layout.getLineEnd(mMaxLines - 1);
|
||||
int lastLineStart = layout.getLineStart(mMaxLines - 1);
|
||||
float lastLineRight = layout.getLineRight(mMaxLines - 1);
|
||||
|
||||
int viewWidth = getWidth() - getPaddingRight() - getPaddingLeft();
|
||||
|
||||
TextPaint paint = getPaint();
|
||||
float expendTextWidth = paint.measureText(mExpendText);
|
||||
CharSequence content = mSnapshotText.subSequence(start, lastLineEnd);
|
||||
if (viewWidth - lastLineRight > expendTextWidth) {
|
||||
content = content.toString().trim() + mExpendText;
|
||||
} else {
|
||||
CharSequence lastText = mSnapshotText.subSequence(lastLineStart, lastLineEnd);
|
||||
for (int i = lastText.length() - 1; i > 0; i--) {
|
||||
CharSequence sequence = lastText.subSequence(0, i);
|
||||
float w = paint.measureText(sequence.toString());
|
||||
if (viewWidth - w - DisplayUtils.dip2px(5) > expendTextWidth) {
|
||||
content = mSnapshotText.subSequence(start, lastLineStart + i) + mExpendText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SpannableStringBuilder msp = new SpannableStringBuilder(content);
|
||||
int length = msp.length();
|
||||
msp.replace(length - mExpendText.length(), length, mExpendText);
|
||||
msp.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setColor(ContextCompat.getColor(getContext(), R.color.theme));
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
mOpenLayout = true;
|
||||
setMaxLines(Integer.MAX_VALUE);
|
||||
setText(mSnapshotText);
|
||||
|
||||
}
|
||||
}, length - mExpendText.length(), length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
setText(msp);
|
||||
setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
}
|
||||
45
app/src/main/java/com/gh/common/view/FixedSpeedScroller.java
Normal file
45
app/src/main/java/com/gh/common/view/FixedSpeedScroller.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.Scroller;
|
||||
|
||||
/**
|
||||
* Created by khy on 20/04/18.
|
||||
*/
|
||||
|
||||
public class FixedSpeedScroller extends Scroller {
|
||||
private int mDuration = 0;
|
||||
|
||||
public FixedSpeedScroller(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public FixedSpeedScroller(Context context, Interpolator interpolator) {
|
||||
super(context, interpolator);
|
||||
}
|
||||
|
||||
public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {
|
||||
super(context, interpolator, flywheel);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
|
||||
super.startScroll(startX, startY, dx, dy, mDuration);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startScroll(int startX, int startY, int dx, int dy) {
|
||||
super.startScroll(startX, startY, dx, dy, mDuration);
|
||||
}
|
||||
|
||||
public void setmDuration(int time) {
|
||||
mDuration = time;
|
||||
}
|
||||
|
||||
public int getmDuration() {
|
||||
return mDuration;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user