Compare commits
365 Commits
delete
...
v5.30.0-95
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cfa26ff02 | |||
| a7335d21c5 | |||
| 0fd84f8b44 | |||
| 43bcf78dea | |||
| fb44391500 | |||
| 4c4de337cd | |||
| 625e448928 | |||
| 2bfefc5082 | |||
| 1538d77960 | |||
| 9f77e70c16 | |||
| 630f78e62d | |||
| dc7b103cbc | |||
| d30f51123d | |||
| 00f625c350 | |||
| 95f63bd4f2 | |||
| 07a1b2a63b | |||
| 6a36874ef8 | |||
| 285e0caafe | |||
| 0e0c6c48af | |||
| 38c02380ad | |||
| bf5608492d | |||
| 267f03fd42 | |||
| d39a62d4e0 | |||
| 5d02c40227 | |||
| 910d1eb6b7 | |||
| 755a2a0633 | |||
| 1a33e24a85 | |||
| 9a9c219082 | |||
| 3e9c3027f2 | |||
| c895965822 | |||
| 8dff7f3e69 | |||
| 5abb229fcc | |||
| d0b6d4ae5c | |||
| 772a21210d | |||
| b81df5b2ad | |||
| 07c44ef6a1 | |||
| 6aa1a0a00e | |||
| c6890cee19 | |||
| f83a4035c3 | |||
| 5fc03780a9 | |||
| ac7828c9f2 | |||
| 270a02366d | |||
| 25d96aba67 | |||
| f6558e1e13 | |||
| 7784cecdbc | |||
| ad3301e0a8 | |||
| 8f2ee5d323 | |||
| 9a999eefb7 | |||
| cdb274229b | |||
| b20a3717e1 | |||
| 3ef8dea4d2 | |||
| 17ee9752d3 | |||
| a5992750ed | |||
| 8b76b72222 | |||
| ad6b7228cf | |||
| 9a0873cf67 | |||
| 6cf461dbf7 | |||
| f33595c4c4 | |||
| f6f2db4b6f | |||
| 68252a4375 | |||
| c57a9f44a2 | |||
| 2fb90cb5d4 | |||
| 9925022660 | |||
| 5972b8b4bf | |||
| f31507ae9f | |||
| ab984d133a | |||
| 7440998d5f | |||
| 1e6351a11c | |||
| 78d9bde4c7 | |||
| dec546238e | |||
| 5715d36ad1 | |||
| 351e1d2eba | |||
| 0a067eb9dd | |||
| c62021ee64 | |||
| 7bab11d2a1 | |||
| 5bb2451750 | |||
| ef0341ad6d | |||
| a97a0d64a4 | |||
| 627190ddb7 | |||
| f1139add2a | |||
| ba59291932 | |||
| d3a8bafe8b | |||
| 4cfc98ec5a | |||
| 86b7924a55 | |||
| f645964bdf | |||
| e420b261bb | |||
| 1781f4c665 | |||
| ee79ed528b | |||
| fc9137a48d | |||
| 37a6dae3b5 | |||
| 4cbd4fe629 | |||
| 44df5dc061 | |||
| 9f144a638b | |||
| 18276c5941 | |||
| 385d197e31 | |||
| 2dceaeec3e | |||
| f59bc42539 | |||
| 5b7c98224c | |||
| 2542311341 | |||
| f4d001a821 | |||
| 2710c03112 | |||
| 3341d55f5a | |||
| bbca9c17e7 | |||
| d84cca5ab9 | |||
| 99d1185333 | |||
| 9f6611f877 | |||
| f81d315800 | |||
| 33f5badfd9 | |||
| 0407244cca | |||
| 64449ec38b | |||
| fb937e8ced | |||
| 96f9e8aceb | |||
| be294fbba5 | |||
| aabc676f94 | |||
| 24e6f93eae | |||
| 9a75e242e6 | |||
| 4c867390c2 | |||
| f9c6bb1e56 | |||
| 3a15f9af33 | |||
| 6920d682b2 | |||
| b0493502e4 | |||
| 723202d4ce | |||
| 33ed2796c8 | |||
| 6e0628b478 | |||
| 7f14555886 | |||
| c2477d2a3f | |||
| 8ff4945cfa | |||
| fcc65fdbfe | |||
| d4b0ecce98 | |||
| c4fb785e55 | |||
| 848ca0b5c6 | |||
| 8d5e6c8940 | |||
| 4f0c81420e | |||
| 0c437d32bd | |||
| 25d9771a3c | |||
| 668b54ac6d | |||
| 92b0f8fe73 | |||
| f258b71648 | |||
| f3679aa041 | |||
| 3b02c9df23 | |||
| 1034254613 | |||
| bc3e92c4a1 | |||
| c7dabaa37b | |||
| 69866eaf91 | |||
| f689dfce07 | |||
| 5a8f1d663d | |||
| 42d5d46e53 | |||
| cdccc35703 | |||
| d3e2fea019 | |||
| f343841233 | |||
| f62083eff2 | |||
| 8594e998c2 | |||
| 6865706b0f | |||
| bfb8b46ce8 | |||
| b6d8ca4d84 | |||
| 455e1f0432 | |||
| ba27c09096 | |||
| 15276cc4b3 | |||
| 130a7cdf2a | |||
| 164ec0c368 | |||
| 2be72776ce | |||
| d92f6ff164 | |||
| 756bc66f26 | |||
| e589bce5c6 | |||
| 991bd22511 | |||
| df1ab5221d | |||
| 9aaeee9b3d | |||
| 70916fd0f7 | |||
| 226d6c4f2c | |||
| 896adc9d36 | |||
| 0e33abebdd | |||
| b4e94eeabb | |||
| 6f86dd7eef | |||
| c8ed126605 | |||
| b510a329b6 | |||
| 04d001a055 | |||
| 2de1ba4e1d | |||
| e4a0f0e68b | |||
| f10b08e152 | |||
| c064f9d3a6 | |||
| 759401d9ae | |||
| e56209d15e | |||
| c466ff1f21 | |||
| e09cf299f0 | |||
| 25352ba609 | |||
| 3cd065cb6e | |||
| 5a483bb5db | |||
| 3b380c6fe3 | |||
| 919a98ffe6 | |||
| eff84218a8 | |||
| 7c9c363422 | |||
| add6448f44 | |||
| efccfaaa7f | |||
| a61057ae10 | |||
| 9472cafe48 | |||
| be83e1a2b4 | |||
| e48d7745b4 | |||
| 8b1a38214c | |||
| 2acde0af00 | |||
| daab20424e | |||
| 63f2adade2 | |||
| 201c1207f9 | |||
| 75d86b5a91 | |||
| f30d647936 | |||
| c7dd449899 | |||
| 56c8885030 | |||
| 0e9f7feff9 | |||
| 3697cd720e | |||
| 07a3c06804 | |||
| 2fce492689 | |||
| d87d12e1ec | |||
| a595730c50 | |||
| 7976355e34 | |||
| a9097793ac | |||
| 86e4ddd3f7 | |||
| b9abf2009d | |||
| a7dfd6c16c | |||
| 07dcb4aca2 | |||
| 48123ff991 | |||
| 8312d8e5fe | |||
| 98b4901d55 | |||
| a6a411f2e3 | |||
| 59976dcccd | |||
| e22a3ddcdb | |||
| ecfd133ce2 | |||
| d13ef56eb8 | |||
| 66f2d1df99 | |||
| 8555673d71 | |||
| cfe4c243e6 | |||
| c999ddf914 | |||
| f9004bf884 | |||
| 7794ef4acf | |||
| 1ef9c1fc23 | |||
| 1b1b753feb | |||
| 2561767b9a | |||
| 8bda0e178e | |||
| f634d60605 | |||
| 1dcc7654e8 | |||
| 3579b9d808 | |||
| c74663c082 | |||
| 848d352c60 | |||
| 5176766b29 | |||
| 0a90a7ddd9 | |||
| 27ca5073d7 | |||
| e3eb8178a3 | |||
| 10104812d6 | |||
| 12cb9a4883 | |||
| a30cc8c273 | |||
| 0f0620586b | |||
| b9e86dd67a | |||
| 9ce793d47e | |||
| 43cb18d6e0 | |||
| 1e87610899 | |||
| d04d486425 | |||
| 843aa4d1c8 | |||
| 1745ac91b7 | |||
| 20bc4a0dc8 | |||
| 1105f1b92a | |||
| 53f00f00d3 | |||
| b66827e216 | |||
| 485c34d402 | |||
| 330bcd72d7 | |||
| b04231772b | |||
| ec1bbdc7d5 | |||
| c685a02653 | |||
| 6594bf14df | |||
| 5a4f19dd8a | |||
| b54be8cb79 | |||
| 655380d547 | |||
| da3948228f | |||
| 5c03119c32 | |||
| 2a496b680b | |||
| db535cf281 | |||
| c199582efc | |||
| b53677a118 | |||
| 76ba3a5938 | |||
| db596a6c75 | |||
| 043f3c5d17 | |||
| 68006dda38 | |||
| b5cab193be | |||
| 6f2692296c | |||
| 0bb7a53046 | |||
| 25fe362912 | |||
| 6749d94c34 | |||
| 51f5ea1cd9 | |||
| 50a6d5e204 | |||
| 044e5646ec | |||
| 0ebf3d191d | |||
| bb81d91fd5 | |||
| 7442da80e0 | |||
| 96c28907ec | |||
| e9e7c2043e | |||
| eb5c55f046 | |||
| 8f2a1ecaa1 | |||
| 8dbe9c5772 | |||
| 6c911e09d3 | |||
| df557099ec | |||
| fedc91d37e | |||
| 27484a8306 | |||
| 42193d222a | |||
| 0a433566b1 | |||
| ff02ccd839 | |||
| d1cc0853d4 | |||
| 51eb814a42 | |||
| 6534c17cc0 | |||
| 749a76a09e | |||
| 0f59f79495 | |||
| af66a967b5 | |||
| 9a9095bcf0 | |||
| 225f2becf3 | |||
| a502fb64cb | |||
| 724fe8142c | |||
| dee5a0822d | |||
| e826346ca9 | |||
| 06b43cde77 | |||
| ae5edad87b | |||
| c8916f5f33 | |||
| 04cca95435 | |||
| 1bd3d8b044 | |||
| 4e79466cca | |||
| 88093d0a8e | |||
| 26adcc48f8 | |||
| e94e86d901 | |||
| 73355a4103 | |||
| 794377fdad | |||
| 1bff098369 | |||
| 45c7638dee | |||
| 4c57092300 | |||
| 1ddf9a667e | |||
| 84972e7ba7 | |||
| 03692ad753 | |||
| bb138fa25f | |||
| c5024e670a | |||
| fe5c92e988 | |||
| 9b31bf4164 | |||
| c670ab722f | |||
| fd4f3c25e7 | |||
| a14ea3708a | |||
| c003240f16 | |||
| 891e3d93fb | |||
| af5ec74b9e | |||
| d2c4483455 | |||
| 3a156aa8c1 | |||
| 60bd3ee9b2 | |||
| dacda1a858 | |||
| 265b5f6b57 | |||
| b4bd6f250b | |||
| 0f3ae5f085 | |||
| 3ab6cc202e | |||
| 7a154bc130 | |||
| 7cd6f2b0f4 | |||
| 8db2519f61 | |||
| 6b2902a73b | |||
| df7618bbda | |||
| 246983a097 | |||
| ca6146ad9a | |||
| c647320abc | |||
| afd738454e | |||
| 134cb327ec | |||
| f50ce741ae | |||
| 4547ba969e | |||
| 0a4af78ac8 | |||
| d38e1d1637 | |||
| 0d3456cf97 | |||
| f56529aa5b |
@ -71,8 +71,8 @@ android_build:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
- dev-5.26.0
|
||||
- dev-5.27.0
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -103,8 +103,8 @@ sonarqube_analysis:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
- dev-5.26.0
|
||||
- dev-5.27.0
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
|
||||
## 发送简易检测结果报告
|
||||
send_sonar_report:
|
||||
@ -122,8 +122,8 @@ send_sonar_report:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
- dev-5.26.0
|
||||
- dev-5.27.0
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
|
||||
oss-upload&send-email:
|
||||
tags:
|
||||
@ -155,5 +155,5 @@ oss-upload&send-email:
|
||||
- /usr/local/bin/python /ci-android-mail.py
|
||||
only:
|
||||
- dev
|
||||
- dev-5.26.0
|
||||
- dev-5.27.0
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
@ -11,7 +11,11 @@ android {
|
||||
|
||||
String CONFIG_ID = ""
|
||||
String FIRST_LAUNCH = ""
|
||||
int ACTIVATE_REPORTING_RATIO = 0
|
||||
String SDK_VERSION = ""
|
||||
String SDK_APP_ID = ""
|
||||
String SDK_APP_NAME = ""
|
||||
boolean USE_DEFAULT_CHANNEL_SDK = true
|
||||
int ACTIVATE_REPORTING_RATIO = 100
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
@ -71,9 +75,20 @@ android {
|
||||
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
|
||||
|
||||
String CORE_EVENT_GAME_CATEGORY = ""
|
||||
|
||||
// 推广用的关键事件游戏类型
|
||||
buildConfigField "String", "CORE_EVENT_GAME_CATEGORY", "\"${CORE_EVENT_GAME_CATEGORY}\""
|
||||
|
||||
// 推广用的配置 id
|
||||
buildConfigField "String", "CONFIG_ID", "\"${CONFIG_ID}\""
|
||||
|
||||
// 推广用的 SDK 版本 (仅记录使用)
|
||||
buildConfigField "String", "SDK_VERSION", "\"${SDK_VERSION}\""
|
||||
buildConfigField "String", "SDK_APP_ID", "\"${SDK_APP_ID}\""
|
||||
buildConfigField "String", "SDK_APP_NAME", "\"${SDK_APP_NAME}\""
|
||||
buildConfigField "boolean", "USE_DEFAULT_CHANNEL_SDK", "${USE_DEFAULT_CHANNEL_SDK}"
|
||||
|
||||
// 首次启动的跳转配置
|
||||
buildConfigField "String", "FIRST_LAUNCH", "\"${FIRST_LAUNCH}\""
|
||||
|
||||
@ -173,6 +188,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${DEV_VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${DEV_QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${DEV_CSJ_APPID}\""
|
||||
}
|
||||
|
||||
// publish, 发布时候使用的 flavor,接口仅包含正式环境
|
||||
@ -184,6 +200,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
}
|
||||
|
||||
tea {
|
||||
@ -194,6 +211,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
|
||||
}
|
||||
@ -201,17 +219,12 @@ android {
|
||||
kuaishou {
|
||||
dimension "env"
|
||||
|
||||
String KUAI_SHOU_APP_ID = ""
|
||||
String KUAI_SHOU_APP_NAME = ""
|
||||
|
||||
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
|
||||
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
|
||||
buildConfigField "String", "KUAI_SHOU_APP_ID", "\"${KUAI_SHOU_APP_ID}\""
|
||||
buildConfigField "String", "KUAI_SHOU_APP_NAME", "\"${KUAI_SHOU_APP_NAME}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
}
|
||||
|
||||
gdt {
|
||||
@ -222,6 +235,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -329,11 +343,19 @@ dependencies {
|
||||
implementation(project(':module_sensors_data')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
implementation(project(':module_message')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
// implementation(project(':feature:vpn'))
|
||||
implementation(project(':feature:pkg'))
|
||||
implementation(project(':feature:oaid'))
|
||||
implementation(project(':feature:floating-window'))
|
||||
implementation(project(':feature:beizi_startup_ad'))
|
||||
implementation(project(':feature:csj_ad'))
|
||||
// implementation(project(':feature:beizi_startup_ad'))
|
||||
implementation(project(':feature:xapk-installer'))
|
||||
implementation(project(':feature:qq_game')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
}
|
||||
|
||||
File propFile = file('sign.properties')
|
||||
|
||||
@ -20,12 +20,13 @@
|
||||
-keep class com.gh.gamecenter.db.info.* {*;}
|
||||
-keep class com.gh.gamecenter.entity.** {<fields>;}
|
||||
-keep class com.gh.gamecenter.qa.entity.** {<fields>;}
|
||||
-keep class com.gh.download.DownloadDataSimpleEntity {<fields>;}
|
||||
-keep class com.gh.gamecenter.floatingwindow.FloatingWindowEntity {<fields>;}
|
||||
-keep class com.gh.gamecenter.BR
|
||||
-keep class com.gh.gamecenter.retrofit.* {*;}
|
||||
-keep class com.gh.gamecenter.eventbus.* {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.GameCollectionStackLayout {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.GameCollectionStackAnimation {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.carousel.GameCollectionStackLayout {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.carousel.GameCollectionStackAnimation {*;}
|
||||
|
||||
# Prevent R8 from leaving Data object members always null
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
|
||||
@ -33,4 +33,8 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
override fun logEvent(content: String) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override fun logCoreEvent() {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -42,6 +42,10 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
GdtHelper.logAction(content)
|
||||
}
|
||||
|
||||
override fun logCoreEvent() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val GDT_DEFAULT_CHANNEL = "GDT_GHZS_01"
|
||||
}
|
||||
|
||||
Binary file not shown.
BIN
app/src/gdt/libs/GDTActionSDK.min.1.8.7.aar
Normal file
BIN
app/src/gdt/libs/GDTActionSDK.min.1.8.7.aar
Normal file
Binary file not shown.
@ -5,8 +5,8 @@ import com.kwai.monitor.log.TurboAgent
|
||||
import com.kwai.monitor.log.TurboConfig
|
||||
|
||||
object KuaishouHelper {
|
||||
private val mAppId by lazy { BuildConfig.KUAI_SHOU_APP_ID.ifEmpty { "81537" } }
|
||||
private val mAppName by lazy { BuildConfig.KUAI_SHOU_APP_NAME.ifEmpty { "guanghuanzhushou_1" } }
|
||||
private val mAppId by lazy { BuildConfig.SDK_APP_ID.ifEmpty { "81537" } }
|
||||
private val mAppName by lazy { BuildConfig.SDK_APP_NAME.ifEmpty { "guanghuanzhushou_1" } }
|
||||
|
||||
@JvmStatic
|
||||
fun init(context: Context, channel: String) {
|
||||
|
||||
@ -3,12 +3,16 @@ package com.gh.gamecenter.provider
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.KuaishouHelper
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.provider.IFlavorProvider
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.kwai.monitor.payload.TurboHelper
|
||||
import com.leon.channel.helper.ChannelReaderUtil
|
||||
|
||||
class FlavorProviderImp : IFlavorProvider {
|
||||
|
||||
@ -31,7 +35,11 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
}
|
||||
|
||||
override fun getChannelStr(application: Application): String {
|
||||
var channel = TurboHelper.getChannel(application)
|
||||
var channel = if (BuildConfig.USE_DEFAULT_CHANNEL_SDK) {
|
||||
ChannelReaderUtil.getChannel(application)
|
||||
} else {
|
||||
TurboHelper.getChannel(application)
|
||||
}
|
||||
if (channel == null || TextUtils.isEmpty(channel.trim())) {
|
||||
channel = KUAISHOU_CHANNEL
|
||||
}
|
||||
@ -42,6 +50,15 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
KuaishouHelper.onEvent(content)
|
||||
}
|
||||
|
||||
override fun logCoreEvent() {
|
||||
logEvent("EVENT_KEY_PATH_OPTIMIZATION")
|
||||
if (BuildConfig.ACTIVATE_REPORTING_RATIO == 1) {
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast("关键行为 EVENT_KEY_PATH_OPTIMIZATION")
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KUAISHOU_CHANNEL = "KS-GHZS-01"
|
||||
}
|
||||
|
||||
Binary file not shown.
BIN
app/src/kuaishou/libs/channelsdk-0.2.2.aar
Normal file
BIN
app/src/kuaishou/libs/channelsdk-0.2.2.aar
Normal file
Binary file not shown.
@ -77,7 +77,12 @@
|
||||
androidx.compose.animation.core,
|
||||
androidx.constraintlayout.compose,
|
||||
androidx.compose.ui.test.manifest,
|
||||
androidx.compose.ui.tooling.preview" />
|
||||
com.bytedance.sdk.openadsdk,
|
||||
androidx.compose.ui.tooling.preview,
|
||||
com.tencent.qqmini,
|
||||
com.tencent.qqmini.minigame.external,
|
||||
com.tencent.qqmini.minigame.opensdk,
|
||||
com.tencent.qqmini.union.ad" />
|
||||
|
||||
<!-- 去掉 SDK 一些流氓权限 -->
|
||||
<uses-permission
|
||||
@ -106,8 +111,8 @@
|
||||
android:icon="@mipmap/logo"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:resizeableActivity="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:resizeableActivity="true"
|
||||
android:theme="@style/AppCompatTheme.APP"
|
||||
tools:replace="android:name,android:allowBackup"
|
||||
tools:targetApi="n">
|
||||
@ -297,10 +302,6 @@
|
||||
android:name="com.gh.gamecenter.CollectionActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.UserInfoEditActivity"
|
||||
android:screenOrientation="portrait"
|
||||
@ -314,26 +315,10 @@
|
||||
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.MessageInviteActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageVoteActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".qa.questions.invite.QuestionsInviteActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -756,6 +741,22 @@
|
||||
android:name=".servers.gametest2.GameServerTestV2Activity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qgame.QGameHomeWrapperActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qgame.QGameSearchActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qgame.QGameSubjectActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
@ -826,6 +827,11 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name="com.gh.common.xapk.XapkInstallReceiver"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver
|
||||
android:name="com.gh.gamecenter.receiver.ActivitySkipReceiver"
|
||||
android:exported="true">
|
||||
@ -834,39 +840,6 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- 梦工厂配置 开始 -->
|
||||
<!--<meta-data
|
||||
android:name="MGC_APPID"
|
||||
android:value="1001276" />
|
||||
|
||||
<provider
|
||||
android:name="com.leto.game.base.provider.LetoFileProvider"
|
||||
android:authorities="${applicationId}.leto.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/leto_file_path"
|
||||
tools:replace="android:resource" />
|
||||
</provider>-->
|
||||
<!-- 梦工厂配置 结束 -->
|
||||
|
||||
<!-- 穿山甲配置 开始 -->
|
||||
<!--<provider
|
||||
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
|
||||
android:authorities="${applicationId}.TTFileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
|
||||
android:authorities="${applicationId}.TTMultiProvider"
|
||||
android:exported="false" />-->
|
||||
<!-- 穿山甲配置 结束 -->
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
1
app/src/main/assets/lottie/icon_fab_change.json
Normal file
1
app/src/main/assets/lottie/icon_fab_change.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":144,"h":144,"nm":"icon_change","ddd":0,"assets":[{"id":"comp_0","nm":"icon_change_detail","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"stroke1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[37.04,52.994,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.533,-0.143],[0.143,-0.533],[1.487,-1.304],[1.961,-0.258],[1.774,0.875],[0.709,0.661],[0,0],[0,0.445],[0,0],[-0.276,0],[0,0],[-0.013,0],[0,0],[0.315,-0.315],[0,0],[-0.682,-0.336],[-1.569,0.207],[-1.19,1.043],[-0.41,1.528]],"o":[[0.533,0.143],[-0.512,1.91],[-1.487,1.304],[-1.961,0.258],[-0.879,-0.433],[0,0],[-0.315,0.315],[0,0],[0,-0.276],[0,0],[0.013,0],[0,0],[0.445,0],[0,0],[0.555,0.508],[1.419,0.7],[1.569,-0.207],[1.19,-1.043],[0.143,-0.533]],"v":[[8.605,-4.301],[9.312,-3.076],[6.247,1.854],[0.958,4.25],[-4.77,3.304],[-7.163,1.652],[-8.493,2.982],[-9.347,2.628],[-9.347,-1.665],[-8.847,-2.165],[-8.161,-2.165],[-8.122,-2.165],[-4.554,-2.165],[-4.2,-1.311],[-5.748,0.237],[-3.885,1.51],[0.697,2.267],[4.928,0.35],[7.381,-3.594]],"c":true},"ix":2},"nm":"stroke1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.8,1,0.6],"ix":9}},"s":{"a":0,"k":[-5.347,-4.665],"ix":5},"e":{"a":0,"k":[8.653,-4.665],"ix":6},"t":1,"nm":"color1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"stroke1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"stroke2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34.96,19.006,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.961,0.258],[-1.774,-0.875],[-0.709,-0.661],[0,0],[0,-0.445],[0,0],[0.276,0],[0,0],[0.012,0],[0,0],[-0.315,0.315],[0,0],[0.682,0.336],[1.569,-0.207],[1.19,-1.043],[0.41,-1.528],[0.533,0.143],[-0.143,0.533],[-1.487,1.304]],"o":[[1.961,-0.258],[0.879,0.433],[0,0],[0.315,-0.315],[0,0],[0,0.276],[0,0],[-0.012,0],[0,0],[-0.445,0],[0,0],[-0.555,-0.508],[-1.419,-0.7],[-1.569,0.207],[-1.19,1.043],[-0.143,0.533],[-0.533,-0.143],[0.512,-1.91],[1.487,-1.304]],"v":[[-0.958,-4.25],[4.77,-3.304],[7.163,-1.652],[8.493,-2.982],[9.347,-2.628],[9.347,1.665],[8.847,2.165],[8.16,2.165],[8.123,2.165],[4.554,2.165],[4.2,1.311],[5.748,-0.237],[3.885,-1.51],[-0.697,-2.267],[-4.928,-0.35],[-7.381,3.594],[-8.605,4.301],[-9.312,3.076],[-6.247,-1.854]],"c":true},"ix":2},"nm":"stroke2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.8,1,0.6],"ix":9}},"s":{"a":0,"k":[5.347,4.665],"ix":5},"e":{"a":0,"k":[-8.653,4.665],"ix":6},"t":1,"nm":"color2","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"stroke2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"icon_change_detail","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[72,72,0],"ix":2,"l":2},"a":{"a":0,"k":[36,36,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":72,"h":72,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}
|
||||
1
app/src/main/assets/lottie/icon_title_change_dark.json
Normal file
1
app/src/main/assets/lottie/icon_title_change_dark.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":72,"h":72,"nm":"icon_title_change","ddd":0,"assets":[{"id":"comp_0","nm":"arrow","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"arrow_e_dark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.25,30,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.701,0.456],[-1.627,-0.674],[-0.705,-0.667],[0,0],[-0.552,0],[0,-0.552],[0,0],[0.552,0],[0,0],[0.012,0],[0,0],[0,0.552],[-0.552,0],[0,0],[0.615,0.255],[1.276,-0.342],[0.804,-1.048],[0,-1.321],[-0.804,-1.048],[-1.276,-0.342],[-1.22,0.505],[-0.66,1.144],[-0.478,-0.276],[0.276,-0.478],[1.627,-0.674],[1.701,0.456],[1.072,1.397],[0,1.761],[-1.072,1.397]],"o":[[1.701,-0.456],[0.909,0.376],[0,0],[0,-0.552],[0.552,0],[0,0],[0,0.552],[0,0],[-0.012,0],[0,0],[-0.552,0],[0,-0.552],[0,0],[-0.493,-0.435],[-1.22,-0.505],[-1.276,0.342],[-0.804,1.048],[0,1.321],[0.804,1.048],[1.276,0.342],[1.22,-0.505],[0.276,-0.478],[0.478,0.276],[-0.881,1.525],[-1.627,0.674],[-1.701,-0.456],[-1.072,-1.397],[0,-1.761],[1.072,-1.397]],"v":[[-1.821,-7.727],[3.311,-7.391],[5.75,-5.809],[5.75,-6.5],[6.75,-7.5],[7.75,-6.5],[7.75,-3.5],[6.75,-2.5],[6.331,-2.5],[6.295,-2.5],[3.75,-2.5],[2.75,-3.5],[3.75,-4.5],[4.219,-4.5],[2.546,-5.543],[-1.303,-5.796],[-4.51,-3.653],[-5.75,0],[-4.51,3.653],[-1.303,5.796],[2.546,5.543],[5.446,3],[6.812,2.634],[7.178,4],[3.311,7.391],[-1.821,7.727],[-6.097,4.87],[-7.75,0],[-6.097,-4.87]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.158117651939,0.532358944416,0.878431379795,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"arrow_e_dark","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"arrow","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[36,36,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":60,"h":60,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}
|
||||
1
app/src/main/assets/lottie/icon_title_change_light.json
Normal file
1
app/src/main/assets/lottie/icon_title_change_light.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":72,"h":72,"nm":"icon_title_change","ddd":0,"assets":[{"id":"comp_0","nm":"arrow","fr":60,"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"arrow_e_light","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.25,30,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.701,0.456],[-1.627,-0.674],[-0.705,-0.667],[0,0],[-0.552,0],[0,-0.552],[0,0],[0.552,0],[0,0],[0.012,0],[0,0],[0,0.552],[-0.552,0],[0,0],[0.615,0.255],[1.276,-0.342],[0.804,-1.048],[0,-1.321],[-0.804,-1.048],[-1.276,-0.342],[-1.22,0.505],[-0.66,1.144],[-0.478,-0.276],[0.276,-0.478],[1.627,-0.674],[1.701,0.456],[1.072,1.397],[0,1.761],[-1.072,1.397]],"o":[[1.701,-0.456],[0.909,0.376],[0,0],[0,-0.552],[0.552,0],[0,0],[0,0.552],[0,0],[-0.012,0],[0,0],[-0.552,0],[0,-0.552],[0,0],[-0.493,-0.435],[-1.22,-0.505],[-1.276,0.342],[-0.804,1.048],[0,1.321],[0.804,1.048],[1.276,0.342],[1.22,-0.505],[0.276,-0.478],[0.478,0.276],[-0.881,1.525],[-1.627,0.674],[-1.701,-0.456],[-1.072,-1.397],[0,-1.761],[1.072,-1.397]],"v":[[-1.821,-7.727],[3.311,-7.391],[5.75,-5.809],[5.75,-6.5],[6.75,-7.5],[7.75,-6.5],[7.75,-3.5],[6.75,-2.5],[6.331,-2.5],[6.295,-2.5],[3.75,-2.5],[2.75,-3.5],[3.75,-4.5],[4.219,-4.5],[2.546,-5.543],[-1.303,-5.796],[-4.51,-3.653],[-5.75,0],[-4.51,3.653],[-1.303,5.796],[2.546,5.543],[5.446,3],[6.812,2.634],[7.178,4],[3.311,7.391],[-1.821,7.727],[-6.097,4.87],[-7.75,0],[-6.097,-4.87]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141176477075,0.588235318661,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"arrow_e_light","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"arrow","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[36,36,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":60,"h":60,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}
|
||||
445
app/src/main/java/com/gh/ad/AdDelegateHelper.kt
Normal file
445
app/src/main/java/com/gh/ad/AdDelegateHelper.kt
Normal file
@ -0,0 +1,445 @@
|
||||
package com.gh.ad
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.provider.IBeiziAdProvider
|
||||
import com.gh.gamecenter.core.provider.ICsjAdProvider
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils.getToday
|
||||
import com.gh.gamecenter.entity.AdConfig
|
||||
import com.gh.gamecenter.entity.StartupAdEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* 广告实现代理类
|
||||
*
|
||||
* 由它来分发功能实现到具体的实现
|
||||
*
|
||||
* 以最复杂的开屏广告为例,有三种实现(1. 自有的广告实现 2. 穿山甲的开屏广告实现 3. Beizi 的开屏广告实现)
|
||||
*
|
||||
* 由于两个广告 SDK 有可能在一次启动中都被使用,所以会根据获取到的广告配置 config 来决定是否需要出是很好两个 SDK
|
||||
*/
|
||||
object AdDelegateHelper {
|
||||
|
||||
private var mCsjAdImpl: ICsjAdProvider? = null
|
||||
private var mBeiziAdImpl: IBeiziAdProvider? = null
|
||||
|
||||
private var mAdConfigList: ArrayList<AdConfig>? = null
|
||||
|
||||
private var mSplashAd: AdConfig? = null
|
||||
private var mDownloadManagerAd: AdConfig? = null
|
||||
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
|
||||
private var mVGameLaunchAd: AdConfig? = null
|
||||
|
||||
private var mIsCsjRequired: Boolean = false // 是否需要初始化穿山甲 SDK
|
||||
private var mIsBeiziRequired: Boolean = false // 师傅需要初始化 Beizi SDK
|
||||
|
||||
private const val AD_SDK_CSJ = "穿山甲"
|
||||
private const val AD_SDK_BEIZI = "倍孜"
|
||||
private const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
|
||||
|
||||
private const val KEY_CACHE_CONFIG = "cache_config" // 放在 SP 里的广告缓存(避免接口加载问题)
|
||||
|
||||
private val mAdConfigSp: SharedPreferences by lazy {
|
||||
HaloApp.getInstance().getSharedPreferences("AdConfig", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求接口获取广告相关配置
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun requestAdConfig(context: Context, isFromRetry: Boolean) {
|
||||
// mAdConfigList 不为空不需要重试
|
||||
if (isFromRetry && mAdConfigList != null) {
|
||||
return
|
||||
}
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.newApi
|
||||
.adConfig
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<List<AdConfig>>() {
|
||||
override fun onSuccess(data: List<AdConfig>) {
|
||||
handleAdConfig(context, data)
|
||||
|
||||
// 缓存数据到 SP 供接口请求失败用
|
||||
SPUtils.setString(mAdConfigSp, KEY_CACHE_CONFIG, data.toJson())
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
|
||||
// 若接口请求失败时,从 SP 里获取上次缓存的数据
|
||||
val cachedConfig: List<AdConfig>? = SPUtils.getString(mAdConfigSp, KEY_CACHE_CONFIG).toObject()
|
||||
if (cachedConfig != null) {
|
||||
handleAdConfig(context, cachedConfig)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取搜索页的广告列表
|
||||
*/
|
||||
fun getGameSearchAdList(): ArrayList<AdConfig> {
|
||||
return mGameSearchAdList
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载管理页的广告
|
||||
*/
|
||||
fun getDownloadManagerAd(): AdConfig? {
|
||||
return mDownloadManagerAd
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理广告配置
|
||||
*/
|
||||
fun handleAdConfig(context: Context, configList: List<AdConfig>) {
|
||||
for (config in configList) {
|
||||
// 处理返回的数据
|
||||
when (config.location) {
|
||||
"halo_launch" -> mSplashAd = config
|
||||
"download_manager" -> mDownloadManagerAd = config
|
||||
"game_search" -> config.let { mGameSearchAdList.add(it) }
|
||||
"helper_launch" -> mVGameLaunchAd = config
|
||||
}
|
||||
|
||||
// 根据返回的值里判断是否含有 Beizi 的广告
|
||||
if (!mIsBeiziRequired) {
|
||||
if (config.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
|
||||
mIsBeiziRequired = true
|
||||
}
|
||||
}
|
||||
|
||||
// 根据返回的值里判断是否含有 穿山甲 的广告
|
||||
if (!mIsCsjRequired) {
|
||||
if (config.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
|
||||
mIsCsjRequired = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化 Beizi
|
||||
if (mIsBeiziRequired && mBeiziAdImpl == null) {
|
||||
mBeiziAdImpl =
|
||||
ARouter.getInstance().build(RouteConsts.provider.beiziAd).navigation() as? IBeiziAdProvider
|
||||
mBeiziAdImpl?.initSDK(context)
|
||||
}
|
||||
|
||||
// 初始化穿山甲
|
||||
if (mIsCsjRequired && mCsjAdImpl == null) {
|
||||
mCsjAdImpl =
|
||||
ARouter.getInstance().build(RouteConsts.provider.csjAd).navigation() as? ICsjAdProvider
|
||||
mCsjAdImpl?.initSDK(context, BuildConfig.CSJ_APPID, HaloApp.getInstance().oaid)
|
||||
// 监听亮色/暗色模式切换
|
||||
DarkModeUtils.registerModeChangeListener {
|
||||
val topActivity = CurrentActivityHolder.getCurrentActivity() ?: return@registerModeChangeListener
|
||||
updateThemeStatus(context, DarkModeUtils.isDarkModeOn(topActivity))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要显示开屏广告
|
||||
*/
|
||||
fun shouldShowStartUpAd(): Boolean {
|
||||
return mSplashAd != null
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新主题样式
|
||||
*/
|
||||
private fun updateThemeStatus(context: Context, isDarkMode: Boolean) {
|
||||
mCsjAdImpl?.updateThemeStatus(context, isDarkMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求开屏广告
|
||||
*/
|
||||
@JvmStatic
|
||||
fun requestSplashAd(
|
||||
activity: Activity,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
adViewWidthInDp: Float,
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
sdkStartAdContainer: ViewGroup,
|
||||
adsViewGroup: FrameLayout,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
if (mSplashAd != null) {
|
||||
if (mSplashAd!!.displayRule.adSource == AD_TYPE_SDK) {
|
||||
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
|
||||
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
|
||||
if (isSuccess) {
|
||||
hideCallback.invoke()
|
||||
} else {
|
||||
if (mSplashAd?.displayRule?.onFailedAction == "show") {
|
||||
sdkStartAdContainer.visibility = View.GONE
|
||||
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 第三方广告的数据为空,按加载失败处理
|
||||
if (mSplashAd?.thirdPartyAd == null) {
|
||||
sdkSplashCallback.invoke(false)
|
||||
return
|
||||
}
|
||||
|
||||
if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
|
||||
sdkStartAdContainer.visibility = View.VISIBLE
|
||||
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, sdkSplashCallback)
|
||||
} else if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
|
||||
sdkStartAdContainer.visibility = View.VISIBLE
|
||||
requestCsjSplashAd(
|
||||
activity,
|
||||
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
|
||||
adViewWidthInPx,
|
||||
adViewHeightInPx,
|
||||
adViewWidthInDp,
|
||||
adViewHeightInDp,
|
||||
sdkStartAdContainer,
|
||||
sdkSplashCallback
|
||||
)
|
||||
}
|
||||
} else {
|
||||
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取穿山甲的开屏广告
|
||||
*/
|
||||
private fun requestCsjSplashAd(
|
||||
activity: Activity,
|
||||
slotId: String,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
adViewWidthInDp: Float,
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
if (mCsjAdImpl == null) {
|
||||
callback.invoke(false)
|
||||
} else {
|
||||
mCsjAdImpl?.requestSplashAd(
|
||||
activity,
|
||||
slotId,
|
||||
adViewWidthInPx,
|
||||
adViewHeightInPx,
|
||||
adViewWidthInDp,
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Beizi 的开屏广告
|
||||
*/
|
||||
private fun requestBeiziSplashAd(
|
||||
startAdContainer: View,
|
||||
adsFl: FrameLayout,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
if (mBeiziAdImpl == null) {
|
||||
callback.invoke(false)
|
||||
} else {
|
||||
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, callback)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示自有的开屏广告
|
||||
*/
|
||||
private fun requestStandardSplashAd(
|
||||
splashAd: StartupAdEntity?,
|
||||
startAdContainer: ViewGroup,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
if (splashAd == null) {
|
||||
hideCallback.invoke()
|
||||
return
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(splashAd.img)) {
|
||||
val showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "") ?: ""
|
||||
when (splashAd.rule) {
|
||||
"each" -> showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||||
"once" -> if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(splashAd.id)
|
||||
) {
|
||||
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
|
||||
"everyday" -> {
|
||||
val today = getToday()
|
||||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(today)
|
||||
|| !showedTodayTimestamp.contains(splashAd.id)
|
||||
) {
|
||||
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
else -> hideCallback.invoke()
|
||||
}
|
||||
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, splashAd.id + getToday())
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showStandardSplashAd(
|
||||
ad: StartupAdEntity,
|
||||
startAdContainer: ViewGroup,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
val jumpBtn: View = startAdContainer.findViewById(R.id.jumpBtn)
|
||||
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
|
||||
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
|
||||
startAdContainer.visibility = View.VISIBLE
|
||||
jumpDetailBtn.text = ad.desc
|
||||
jumpDetailBtn.setDrawableEnd(
|
||||
AppCompatResources.getDrawable(
|
||||
startAdContainer.context,
|
||||
R.drawable.ic_startup_ad_arrow
|
||||
), null, null
|
||||
)
|
||||
ImageUtils.display(adImage, ad.img)
|
||||
startAdContainer.setOnClickListener {
|
||||
// 拦截点击事件传递
|
||||
}
|
||||
jumpBtn.setOnClickListener {
|
||||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||||
hideCallback.invoke()
|
||||
val linkEntity = ad.jump
|
||||
logOpenScreenAdSkip(
|
||||
ad.id,
|
||||
(if (linkEntity.text != null) linkEntity.text else "")!!,
|
||||
(if (linkEntity.type != null) linkEntity.type else "")!!,
|
||||
(if (linkEntity.link != null) linkEntity.link else "")!!
|
||||
)
|
||||
}
|
||||
val sources: MutableList<ExposureSource> = ArrayList()
|
||||
sources.add(ExposureSource("开屏广告", ad.id))
|
||||
val event = createEvent(null, sources, null, ExposureType.EXPOSURE)
|
||||
ExposureManager.log(event)
|
||||
if (ad.button) {
|
||||
jumpDetailBtn.setOnClickListener { v: View ->
|
||||
directToLinkPage(v.context, ad.jump, "(启动广告)", "", event)
|
||||
v.postDelayed({
|
||||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||||
hideCallback.invoke()
|
||||
}, 1000)
|
||||
}
|
||||
jumpDetailBtn.visibility = View.VISIBLE
|
||||
LogUtils.logStartAd("watch_start_ads", ad)
|
||||
} else {
|
||||
LogUtils.logStartAd("start_ads", ad)
|
||||
}
|
||||
handler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取信息流广告
|
||||
*/
|
||||
fun requestFlowAd(
|
||||
fragment: Fragment,
|
||||
slotId: String,
|
||||
adContainerView: ViewGroup,
|
||||
expressViewWidth: Float,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Banner 广告
|
||||
*/
|
||||
fun requestBannerAd(
|
||||
fragment: Fragment,
|
||||
containerView: ViewGroup,
|
||||
ad: AdConfig.ThirdPartyAd,
|
||||
expressViewWidthInDp: Float,
|
||||
callback: (isSuccess: Boolean) -> Unit
|
||||
) {
|
||||
|
||||
val slotId = ad.slotId
|
||||
val displayRatio: Float = if (ad.displaySize.isEmpty()) {
|
||||
2F
|
||||
} else {
|
||||
val array = ad.displaySize.split("*")
|
||||
if (array.size == 2) {
|
||||
array[0].toFloat() / array[1].toFloat()
|
||||
} else {
|
||||
2F
|
||||
}
|
||||
}
|
||||
val expressViewHeightInDp = expressViewWidthInDp / displayRatio
|
||||
|
||||
mCsjAdImpl?.requestBannerAd(
|
||||
fragment,
|
||||
containerView,
|
||||
slotId,
|
||||
expressViewWidthInDp,
|
||||
expressViewHeightInDp,
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消开屏广告
|
||||
*/
|
||||
fun cancelSplashAd(context: Context) {
|
||||
mBeiziAdImpl?.cancelSplashAd(context)
|
||||
mCsjAdImpl?.cancelSplashAd(context)
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,18 +1,20 @@
|
||||
package com.gh.base
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.DownloadManagerActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils.getBoolean
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
@ -58,6 +60,7 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
|
||||
}
|
||||
val downloadMenuView = mActionMenuView.menu.findItem(R.id.menu_download).actionView
|
||||
mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
|
||||
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, "fonts/d_din_bold_only_number.ttf")
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
@ -74,19 +77,27 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
|
||||
if (mDownloadCountHint == null) return
|
||||
val count = DownloadManager.getInstance().getDownloadOrUpdateCount(updateList)
|
||||
if (count != null) {
|
||||
mDownloadCountHint!!.visibility = View.VISIBLE
|
||||
mDownloadCountHint!!.text = count
|
||||
val params = mDownloadCountHint!!.layoutParams
|
||||
if (TextUtils.isEmpty(count)) {
|
||||
params.width = DisplayUtils.dip2px(6f)
|
||||
params.height = DisplayUtils.dip2px(6f)
|
||||
} else {
|
||||
params.width = DisplayUtils.dip2px(12f)
|
||||
params.height = DisplayUtils.dip2px(12f)
|
||||
}
|
||||
mDownloadCountHint!!.layoutParams = params
|
||||
mDownloadCountHint?.visibility = View.VISIBLE
|
||||
mDownloadCountHint?.text = count
|
||||
val params = mDownloadCountHint?.layoutParams
|
||||
params?.width = if (count.isEmpty()) 6F.dip2px() else ConstraintLayout.LayoutParams.WRAP_CONTENT
|
||||
params?.height = if (count.isEmpty()) 6F.dip2px() else 14F.dip2px()
|
||||
(params as? ViewGroup.MarginLayoutParams)?.setMargins(
|
||||
0,
|
||||
if (count.isEmpty()) 0 else (-4F).dip2px(),
|
||||
if (count.isEmpty()) (-4F).dip2px() else (-8F).dip2px(),
|
||||
0
|
||||
)
|
||||
mDownloadCountHint?.setPadding(
|
||||
if (count.isEmpty()) 0 else 4F.dip2px(),
|
||||
0,
|
||||
if (count.isEmpty()) 0 else 4F.dip2px(),
|
||||
0
|
||||
)
|
||||
mDownloadCountHint?.minWidth = if (count.isEmpty()) 0 else 14F.dip2px()
|
||||
mDownloadCountHint?.layoutParams = params
|
||||
} else {
|
||||
mDownloadCountHint!!.visibility = View.GONE
|
||||
mDownloadCountHint?.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import android.app.Application
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.common.util.FloatingBackViewManager
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.SingletonWebActivity
|
||||
import com.gh.gamecenter.SkipActivity
|
||||
@ -61,6 +62,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
|
||||
) {
|
||||
VHelper.showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity)
|
||||
}
|
||||
|
||||
XapkInstaller.updateCurrentInstallStatus()
|
||||
}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
|
||||
@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.download.DownloadManager
|
||||
@ -37,6 +38,8 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.Badge
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.login.user.LoginTag
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
@ -65,12 +68,14 @@ class DefaultJsApi(
|
||||
val entrance: String = "",
|
||||
private var mFragment: Fragment? = null,
|
||||
private var mBbsId: String? = "",
|
||||
private var mOriginUrl: String?= "",
|
||||
) {
|
||||
|
||||
private var mLoginHandler: CompletionHandler<Any>? = null
|
||||
private var mDownloadWatcher: DataWatcher? = null // 下载观察者
|
||||
private var mDownloadUrlSet: HashSet<String>? = null // 下载的 url 集合
|
||||
private var mDownloadHandler: CompletionHandler<Any>? = null // 下载信息回调
|
||||
private var mExposureEvent: ExposureEvent? = null // 活动曝光实体
|
||||
|
||||
init {
|
||||
if (mFragment != null) {
|
||||
@ -213,7 +218,7 @@ class DefaultJsApi(
|
||||
VHelper.launch(context, packageName)
|
||||
}
|
||||
} else {
|
||||
PackageUtils.launchApplicationByPackageName(context, packageName)
|
||||
PackageLauncher.launchApp(context, packageName = packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -624,6 +629,33 @@ class DefaultJsApi(
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun logExposure(event: Any) {
|
||||
val simpleExposureEvent = event.toString().toObject() ?: SimpleExposureEvent()
|
||||
if (simpleExposureEvent.id.isNotEmpty()) {
|
||||
val sourceKey = if (mOriginUrl?.contains(Constants.URL_QUERY_FROM_FLOATING_WINDOW) == true) {
|
||||
"落地页"
|
||||
} else {
|
||||
"游戏活动"
|
||||
}
|
||||
|
||||
val exposureSource = ExposureSource(sourceKey, "${simpleExposureEvent.title}+${simpleExposureEvent.id}")
|
||||
mExposureEvent = ExposureEvent.createEvent(
|
||||
gameEntity = null,
|
||||
source = arrayListOf(exposureSource),
|
||||
)
|
||||
ExposureManager.log(mExposureEvent!!)
|
||||
ExposureManager.commitSavedExposureEvents(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ExposureEvent,可能为空
|
||||
*/
|
||||
fun getExposureEvent(): ExposureEvent? {
|
||||
return mExposureEvent
|
||||
}
|
||||
|
||||
private fun autoUnregisterDownloadObserverIfNeeded(fragment: Fragment?) {
|
||||
fragment?.parentFragmentManager?.registerFragmentLifecycleCallbacks(
|
||||
object : FragmentManager.FragmentLifecycleCallbacks() {
|
||||
@ -676,6 +708,9 @@ class DefaultJsApi(
|
||||
@Keep
|
||||
internal class TextShareEvent(var text: String = "", var type: String = "")
|
||||
|
||||
@Keep
|
||||
internal class SimpleExposureEvent(var title: String = "", var id: String = "")
|
||||
|
||||
@Keep
|
||||
internal class InviteFriendsEvent(
|
||||
var type: String = "",
|
||||
|
||||
@ -36,6 +36,7 @@ import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.entity.VideoLinkEntity
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity
|
||||
@ -51,14 +52,21 @@ object DefaultUrlHandler {
|
||||
|
||||
@JvmStatic
|
||||
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
|
||||
return interceptUrl(context, url, entrance, false)
|
||||
return interceptUrl(context, url, null, entrance, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并拦截部分内部处理的 url
|
||||
* @param traceEvent 供一些页面用于登记曝光来源的实体
|
||||
* @param bringAppToFront 是否需要在不匹配 host 的时候把 APP 调回到前台 (如微信调起)
|
||||
*
|
||||
* @return 是否已拦截处理
|
||||
*/
|
||||
@JvmStatic
|
||||
fun interceptUrl(context: Context, url: String, entrance: String, bringAppToFront: Boolean = false): Boolean {
|
||||
fun interceptUrl(context: Context, url: String,
|
||||
traceEvent: ExposureEvent? = null,
|
||||
entrance: String,
|
||||
bringAppToFront: Boolean = false): Boolean {
|
||||
val uri = Uri.parse(url)
|
||||
if ("ghzhushou" == uri.scheme) {
|
||||
Utils.log("url = $url")
|
||||
@ -82,6 +90,7 @@ object DefaultUrlHandler {
|
||||
id = id,
|
||||
tab = uri.getQueryParameter("to"),
|
||||
autoDownload = uri.getQueryParameter("auto_download") == "true",
|
||||
traceEvent = traceEvent,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
@ -90,6 +99,7 @@ object DefaultUrlHandler {
|
||||
id,
|
||||
uri.getQueryParameter("name"),
|
||||
false,
|
||||
null,
|
||||
entrance
|
||||
)
|
||||
|
||||
@ -467,7 +477,7 @@ object DefaultUrlHandler {
|
||||
}
|
||||
|
||||
EntranceConsts.HOST_GAME_COLLECTION_DETAIL -> {
|
||||
DirectUtils.directToGameCollectionDetail(context, id, entrance)
|
||||
DirectUtils.directToGameCollectionDetail(context, id, entrance, traceEvent = traceEvent)
|
||||
}
|
||||
|
||||
EntranceConsts.HOST_GAME_COLLECTION_SQUARE -> {
|
||||
|
||||
@ -20,7 +20,7 @@ object FixedRateJobHelper {
|
||||
private const val CHECKER_PERIOD: Long = 15 * 1000L
|
||||
private const val TIME_PERIOD: Long = 10 * 60 * 1000L
|
||||
private const val LOGHUB_PERIOD: Long = 2 * 60 * 1000L
|
||||
private const val EXPOSURE_PERIOD: Long = 5 * 60 * 1000L
|
||||
private const val EXPOSURE_PERIOD: Long = 1 * 60 * 1000L
|
||||
private const val REGION_SETTING_PERIOD: Long = 60 * 1000L
|
||||
private const val VIDEO_RECORD_PERIOD: Long = 60 * 1000L
|
||||
|
||||
@ -84,11 +84,6 @@ object FixedRateJobHelper {
|
||||
VideoRecordUtils.commitVideoRecord()
|
||||
}
|
||||
|
||||
// 获取启动广告 (第一次不需要获取)
|
||||
if (elapsedTime % STARTUP_AD == 0L && mExecuteCount != 0) {
|
||||
AdHelper.getSettingAdCache()
|
||||
}
|
||||
|
||||
mExecuteCount++
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
@ -8,14 +9,15 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
class BrowserInstallHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
BrowserInstallHelper.showBrowserInstallHintDialog(context, gameEntity.isVGame(), object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
BrowserInstallHelper.showBrowserInstallHintDialog(
|
||||
context,
|
||||
gameEntity.isVGame() || gameEntity.isSplitXApk()
|
||||
) {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
|
||||
class LandPageAddressHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
if (gameEntity.isLandPageAddressDialog()) {
|
||||
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
|
||||
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
|
||||
}
|
||||
} else {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,15 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
class OverseaDownloadHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {
|
||||
if (gameEntity.isOverseaAddressDialog()) {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {// 跳转海外下载地址弹窗
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
|
||||
class UnsupportedFeatureHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(
|
||||
context: Context, gameEntity: GameEntity
|
||||
) {
|
||||
if (shouldShowUnsupportedFeatureDialog()) {
|
||||
DialogHelper.showUnsupportedFeatureDialog(context)
|
||||
} else {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO 检查某个版本是否支持指定的功能
|
||||
*/
|
||||
private fun shouldShowUnsupportedFeatureDialog(): Boolean = false
|
||||
}
|
||||
@ -205,9 +205,6 @@ public class Config {
|
||||
|
||||
// 加载完设置后刷新下
|
||||
PackageHelper.initList();
|
||||
|
||||
// 初始化畅玩相关的东西
|
||||
VHelper.init(HaloApp.getInstance());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -308,6 +305,26 @@ public class Config {
|
||||
return mVSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求网络数据,尝试刷新畅玩相关配置
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
public static void refreshVSettingEntity() {
|
||||
RetrofitManager.getInstance()
|
||||
.getVApi().getSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new BiResponse<VSetting>() {
|
||||
@Override
|
||||
public void onSuccess(VSetting data) {
|
||||
mVSetting = data;
|
||||
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
|
||||
|
||||
VHelper.init(HaloApp.getInstance());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GameGuidePopupEntity getGameGuidePopupEntity() {
|
||||
return mGameGuidePopupEntity;
|
||||
@ -385,16 +402,7 @@ public class Config {
|
||||
}
|
||||
});
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.getVApi().getSettings(BuildConfig.VERSION_NAME)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(new BiResponse<VSetting>() {
|
||||
@Override
|
||||
public void onSuccess(VSetting data) {
|
||||
mVSetting = data;
|
||||
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
|
||||
}
|
||||
});
|
||||
refreshVSettingEntity();
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
|
||||
@ -451,7 +459,6 @@ public class Config {
|
||||
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
|
||||
DarkModeUtils.INSTANCE.initDarkMode();
|
||||
}
|
||||
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
|
||||
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.databind;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
@ -27,8 +28,10 @@ import com.gh.common.chain.CheckDownloadHandler;
|
||||
import com.gh.common.chain.CheckStoragePermissionHandler;
|
||||
import com.gh.common.chain.DownloadDialogHelperHandler;
|
||||
import com.gh.common.chain.GamePermissionHandler;
|
||||
import com.gh.common.chain.LandPageAddressHandler;
|
||||
import com.gh.common.chain.OverseaDownloadHandler;
|
||||
import com.gh.common.chain.PackageCheckHandler;
|
||||
import com.gh.common.chain.UnsupportedFeatureHandler;
|
||||
import com.gh.common.chain.ValidateVSpaceHandler;
|
||||
import com.gh.common.chain.VersionNumberHandler;
|
||||
import com.gh.common.constant.Config;
|
||||
@ -45,10 +48,12 @@ import com.gh.common.util.GameViewUtils;
|
||||
import com.gh.common.util.LogUtils;
|
||||
import com.gh.common.util.NewsUtils;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.PackageLauncher;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.ReservationHelper;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.download.server.BrowserInstallHelper;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
@ -63,6 +68,7 @@ import com.gh.gamecenter.common.view.DrawableView;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.NumberUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
|
||||
@ -398,6 +404,7 @@ public class BindingAdapters {
|
||||
}
|
||||
|
||||
ChainBuilder builder = new ChainBuilder();
|
||||
builder.addHandler(new UnsupportedFeatureHandler());
|
||||
builder.addHandler(new GamePermissionHandler());
|
||||
builder.addHandler(new CheckStoragePermissionHandler());
|
||||
builder.addHandler(new ValidateVSpaceHandler());
|
||||
@ -406,11 +413,12 @@ public class BindingAdapters {
|
||||
builder.addHandler(new DownloadDialogHelperHandler());
|
||||
builder.addHandler(new CertificationHandler());
|
||||
builder.addHandler(new VersionNumberHandler());
|
||||
builder.addHandler(new LandPageAddressHandler());
|
||||
builder.addHandler(new OverseaDownloadHandler());
|
||||
builder.addHandler(new CheckDownloadHandler());
|
||||
|
||||
builder.setProcessEndCallback(o -> {
|
||||
download(progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
|
||||
download(v.getContext(), progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
|
||||
return null;
|
||||
});
|
||||
final ChainHandler chainHandler = builder.buildHandlerChain();
|
||||
@ -419,6 +427,7 @@ public class BindingAdapters {
|
||||
}
|
||||
} else {
|
||||
ChainBuilder builder = new ChainBuilder();
|
||||
builder.addHandler(new UnsupportedFeatureHandler());
|
||||
builder.addHandler(new GamePermissionHandler());
|
||||
builder.addHandler(new CertificationHandler());
|
||||
builder.addHandler(new VersionNumberHandler());
|
||||
@ -447,7 +456,7 @@ public class BindingAdapters {
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
download(v.getContext(), progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -457,11 +466,11 @@ public class BindingAdapters {
|
||||
}
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity);
|
||||
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity, null);
|
||||
return;
|
||||
}
|
||||
|
||||
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
PackageLauncher.launchApp(v.getContext(), gameEntity, gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
@ -477,7 +486,7 @@ public class BindingAdapters {
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch(v.getContext(), gameEntity);
|
||||
VHelper.installOrLaunch(v.getContext(), gameEntity, null);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -673,12 +682,16 @@ public class BindingAdapters {
|
||||
|
||||
|
||||
// 开始下载
|
||||
private static void download(DownloadButton progressBar,
|
||||
private static void download(Context context,
|
||||
DownloadButton progressBar,
|
||||
GameEntity gameEntity,
|
||||
ExposureEvent traceEvent,
|
||||
boolean isSubscribe,
|
||||
String entrance,
|
||||
String location) {
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
|
||||
}
|
||||
String str = progressBar.getText().toString();
|
||||
String method;
|
||||
if (str.contains("更新")) {
|
||||
|
||||
@ -4,6 +4,8 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.LayoutManager
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import io.reactivex.functions.Consumer
|
||||
|
||||
@ -18,7 +20,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
Consumer(Throwable::printStackTrace)
|
||||
)
|
||||
}
|
||||
var layoutManager: LinearLayoutManager? = null
|
||||
var layoutManager: LayoutManager? = null
|
||||
var visibleState: ExposureThrottleBus.VisibleState? = null
|
||||
|
||||
init {
|
||||
@ -47,12 +49,28 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
|
||||
if (layoutManager == null) layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
layoutManager = recyclerView.layoutManager
|
||||
|
||||
layoutManager?.run {
|
||||
visibleState =
|
||||
ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
if (layoutManager != null) {
|
||||
if (layoutManager is LinearLayoutManager) {
|
||||
(layoutManager as LinearLayoutManager).run {
|
||||
visibleState =
|
||||
ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
}
|
||||
} else if (layoutManager is StaggeredGridLayoutManager) {
|
||||
(recyclerView.layoutManager as StaggeredGridLayoutManager).run {
|
||||
val firstVisibleItemArray = IntArray(2)
|
||||
val lastVisibleItemArray = IntArray(2)
|
||||
|
||||
findFirstVisibleItemPositions(firstVisibleItemArray)
|
||||
findLastVisibleItemPositions(lastVisibleItemArray)
|
||||
|
||||
visibleState =
|
||||
ExposureThrottleBus.VisibleState(firstVisibleItemArray.first(), lastVisibleItemArray.first())
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ object ExposureManager {
|
||||
fun log(eventList: List<ExposureEvent>) {
|
||||
AppExecutor.logExecutor.execute {
|
||||
for (event in eventList) {
|
||||
if (!exposureCache.contains(event.id)) {
|
||||
if (event != null && !exposureCache.contains(event.id)) {
|
||||
exposureSet.add(event)
|
||||
exposureCache.add(event.id)
|
||||
} else {
|
||||
|
||||
@ -48,6 +48,7 @@ object ExposureUtils {
|
||||
}
|
||||
if (!TextUtils.isEmpty(entity.id)) {
|
||||
ExposureManager.log(exposureEvent)
|
||||
ExposureManager.commitSavedExposureEvents(forcedUpload = true)
|
||||
}
|
||||
return exposureEvent
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import com.gh.gamecenter.feature.entity.AnswerEntity
|
||||
import com.gh.gamecenter.feature.entity.ArticleEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.NewsEntity
|
||||
import com.gh.gamecenter.feature.entity.User
|
||||
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IAppProvider
|
||||
@ -18,6 +19,10 @@ class AppProviderImpl : IAppProvider {
|
||||
return HaloApp.getInstance().getString(R.string.app_name)
|
||||
}
|
||||
|
||||
override fun getAppVersion(): String {
|
||||
return BuildConfig.VERSION_NAME
|
||||
}
|
||||
|
||||
override fun getGid(): String {
|
||||
return HaloApp.getInstance().gid ?: ""
|
||||
}
|
||||
@ -70,6 +75,10 @@ class AppProviderImpl : IAppProvider {
|
||||
return HaloApp.getInstance().flavorProvider
|
||||
}
|
||||
|
||||
override fun getFlavor(): String {
|
||||
return BuildConfig.FLAVOR
|
||||
}
|
||||
|
||||
override fun getIsBrandNewInstall(): Boolean {
|
||||
return HaloApp.getInstance().isBrandNewInstall
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
@ -24,6 +25,14 @@ class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
|
||||
BindingAdapters.setGameTags(layout, gameEntity)
|
||||
}
|
||||
|
||||
override fun setMessageUnread(view: TextView, unreadCount: Int) {
|
||||
BindingAdapters.setMessageUnread(view, unreadCount)
|
||||
}
|
||||
|
||||
override fun setGame(view: View, gameEntity: GameEntity) {
|
||||
BindingAdapters.setGame(view, gameEntity)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.CommentDetailActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ICommentDetailProvider
|
||||
import com.gh.gamecenter.feature.entity.MessageEntity
|
||||
|
||||
@Route(path = RouteConsts.provider.commentDetail, name = "CommentDetailActivity暴露服务")
|
||||
class CommentDetailProviderImpl : ICommentDetailProvider {
|
||||
|
||||
override fun getIntent(context: Context, commentId: String?, message: Parcelable): Intent {
|
||||
return CommentDetailActivity.getIntent(context, commentId, message as MessageEntity.Article)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.ICommentManagerProvider
|
||||
import com.gh.gamecenter.manager.CommentManager
|
||||
|
||||
@Route(path = RouteConsts.provider.commentManager, name = "CommentManager暴露服务")
|
||||
class CommentManagerProviderImpl : ICommentManagerProvider {
|
||||
override fun addUrl(ids: String) {
|
||||
CommentManager.getInstance().addUrl(ids)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.CommentUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ICommentUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.commentUtils, name = "CommentUtils暴露服务")
|
||||
class CommentUtilsProviderImpl : ICommentUtilsProvider {
|
||||
override fun setCommentTime(textView: TextView, time: Long) {
|
||||
CommentUtils.setCommentTime(textView, time)
|
||||
}
|
||||
|
||||
override fun getCommentTime(timestamp: Long): String {
|
||||
return CommentUtils.getCommentTime(timestamp)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.LinearLayout
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.ConcernContentUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IConcernContentUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.concernContentUtils, name = "ConcernContentUtils暴露服务")
|
||||
class ConcernContentUtilsProviderImpl : IConcernContentUtilsProvider {
|
||||
override fun addContentPic(
|
||||
context: Context,
|
||||
linearLayout: LinearLayout,
|
||||
list: List<String>,
|
||||
entrance: String,
|
||||
width: Int
|
||||
) {
|
||||
ConcernContentUtils.addContentPic(context, linearLayout, list, entrance, width)
|
||||
}
|
||||
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.ConcernActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IConcernProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.concernActivity, name = "ConcernActivity暴露服务")
|
||||
class ConcernProviderImpl : IConcernProvider {
|
||||
|
||||
override fun getIntent(context: Context, entrance: String): Intent {
|
||||
return ConcernActivity.getIntent(context, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.gh.gamecenter.feature.provider.IConfigSettingProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.configSetting, name = "Config.getSettings暴露服务")
|
||||
class ConfigSettingProviderImpl : IConfigSettingProvider {
|
||||
override fun getSettings(): SettingsEntity? {
|
||||
return Config.getSettings()
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.IDataCollectionProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.dataCollection, name = "DataCollectionUtils暴露服务")
|
||||
class DataCollectionProviderImpl : IDataCollectionProvider {
|
||||
override fun uploadClick(context: Context, vararg args: String) {
|
||||
DataCollectionUtils.uploadClick(context, *args)
|
||||
}
|
||||
|
||||
override fun uploadConcern(context: Context, vararg args: String) {
|
||||
DataCollectionUtils.uploadConcern(context, *args)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ class DefaultUrlHandlerProviderImpl : IDefaultUrlHandlerProvider {
|
||||
entrance: String,
|
||||
bringAppToFront: Boolean
|
||||
): Boolean {
|
||||
return DefaultUrlHandler.interceptUrl(context, url, entrance, bringAppToFront)
|
||||
return DefaultUrlHandler.interceptUrl(context, url, null, entrance, bringAppToFront)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
|
||||
@ -69,6 +69,56 @@ class DirectProviderImpl : IDirectProvider {
|
||||
return DirectUtils.directToQqGroup(context, groupNumber)
|
||||
}
|
||||
|
||||
override fun directToHomeActivity(context: Context, userId: String?, entrance: String?, path: String?) {
|
||||
DirectUtils.directToHomeActivity(context, userId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToAnswerDetail(context: Context, id: String, entrance: String?, path: String?) {
|
||||
DirectUtils.directToAnswerDetail(context, id, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToCommunityArticle(
|
||||
context: Context,
|
||||
articleId: String?,
|
||||
communityId: String?,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToVideoDetail(context: Context, videoId: String, entrance: String?, path: String?) {
|
||||
DirectUtils.directToVideoDetail(context, videoId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToAmway(context: Context, fixedTopAmwayCommentId: String?, entrance: String?, path: String?) {
|
||||
DirectUtils.directToAmway(context, fixedTopAmwayCommentId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToOrderCenter(context: Context) {
|
||||
DirectUtils.directToOrderCenter(context)
|
||||
}
|
||||
|
||||
override fun directToOrderDetail(context: Context, orderId: String) {
|
||||
DirectUtils.directToOrderDetail(context, orderId)
|
||||
}
|
||||
|
||||
override fun directToEnergyRecord(context: Context, position: Int) {
|
||||
DirectUtils.directToEnergyRecord(context, position)
|
||||
}
|
||||
|
||||
override fun directToMyPrizePage(context: Context) {
|
||||
DirectUtils.directToMyPrizePage(context)
|
||||
}
|
||||
|
||||
override fun directToWinOrderDetail(context: Context, orderId: String, activityId: String) {
|
||||
DirectUtils.directToWinOrderDetail(context, orderId, activityId)
|
||||
}
|
||||
|
||||
override fun directToQGame(context: Context) {
|
||||
return DirectUtils.directToQGameHome(context)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,119 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.provider.IDownloadButtonClickedProvider
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
@Route(path = RouteConsts.provider.downloadButtonClickedHandler, name = "DownloadButton点击事件暴露服务")
|
||||
class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
override fun onClicked(downloadButton: DownloadButton) {
|
||||
var gameId = ""
|
||||
var gameName = ""
|
||||
var gameCategory = ""
|
||||
var gameTypeInChinese = ""
|
||||
var downloadStatus = ""
|
||||
var downloadStatusInChinese = ""
|
||||
var gameSchemaType = ""
|
||||
var packageName = ""
|
||||
|
||||
val boundedObject = downloadButton.getObject()
|
||||
|
||||
Utils.log("DownloadButtonClickedProviderImpl", "$downloadButton onClicked ${boundedObject?.javaClass}")
|
||||
|
||||
if (boundedObject != null) {
|
||||
when (boundedObject) {
|
||||
is GameEntity -> {
|
||||
gameId = boundedObject.id
|
||||
gameName = boundedObject.name ?: ""
|
||||
gameCategory = boundedObject.category ?: ""
|
||||
downloadStatus = if (boundedObject.isVGame()) {
|
||||
"畅玩"
|
||||
} else if (boundedObject.downloadStatus == "demo") {
|
||||
"试玩"
|
||||
} else {
|
||||
"下载"
|
||||
}
|
||||
gameTypeInChinese = boundedObject.categoryChinese
|
||||
downloadStatusInChinese = boundedObject.downloadStatusChinese
|
||||
gameSchemaType = boundedObject.gameBitChinese
|
||||
packageName = boundedObject.getUniquePackageName() ?: ""
|
||||
}
|
||||
|
||||
is GameUpdateEntity -> {
|
||||
gameId = boundedObject.id
|
||||
gameName = boundedObject.name ?: ""
|
||||
// 下载管理-更新页面,把下载状态都置为下载
|
||||
downloadStatus = "下载"
|
||||
gameTypeInChinese = boundedObject.categoryChinese
|
||||
downloadStatusInChinese = boundedObject.downloadStatusChinese
|
||||
packageName = boundedObject.packageName
|
||||
}
|
||||
|
||||
is DownloadEntity -> {
|
||||
gameId = boundedObject.gameId
|
||||
gameName = boundedObject.name ?: ""
|
||||
gameCategory = boundedObject.getGameCategory()
|
||||
downloadStatus = if (boundedObject.isVGame()) "畅玩" else "下载"
|
||||
packageName = boundedObject.packageName
|
||||
}
|
||||
}
|
||||
|
||||
// 上报 UI 状态为启动的点击事件 (样式为启动,或者文案包含启动都算能启动)
|
||||
if (downloadButton.buttonStyle == DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
|
||||
|| downloadButton.text.contains("启动")) {
|
||||
|
||||
// boundedObject 里找不到游戏类型时,尝试从已安装列表中获取
|
||||
if (gameCategory.isEmpty() && packageName.isNotEmpty()) {
|
||||
gameCategory = PackageRepository.gameInstalled.find { it.packageName == packageName }?.category ?: ""
|
||||
}
|
||||
|
||||
NewFlatLogUtils.logGameLaunchButtonClicked(
|
||||
gameId = gameId,
|
||||
gameName = gameName,
|
||||
location = downloadButton.getWidgetBusinessName(),
|
||||
gameCategory = gameCategory,
|
||||
downloadStatus = downloadStatus
|
||||
)
|
||||
}
|
||||
|
||||
// 预约状态不上报
|
||||
if (downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVABLE
|
||||
&& downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVED
|
||||
) {
|
||||
|
||||
// 上报神策点击事件
|
||||
SensorsBridge.trackEvent(
|
||||
"DownLoadbuttonClick",
|
||||
"game_id", gameId,
|
||||
"game_name", gameName,
|
||||
"game_type", gameTypeInChinese,
|
||||
"download_status", downloadStatusInChinese,
|
||||
"button_name", downloadButton.text,
|
||||
"game_schema_type", gameSchemaType,
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
|
||||
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
|
||||
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
|
||||
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
|
||||
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.IGameCollectionDetailProvider
|
||||
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.gameCollectionDetail, name = "GameCollectionDetailActivity暴露服务")
|
||||
class GameCollectionDetailProviderImpl : IGameCollectionDetailProvider {
|
||||
override fun getIntent(context: Context, gameCollectionId: String, isFromSquare: Boolean): Intent {
|
||||
return GameCollectionDetailActivity.getIntent(context, gameCollectionId, isFromSquare)
|
||||
}
|
||||
|
||||
override fun getSpecifiedCommentIntent(context: Context, gameCollectionId: String, topCommentId: String): Intent {
|
||||
return GameCollectionDetailActivity.getSpecifiedCommentIntent(context, gameCollectionId, topCommentId)
|
||||
}
|
||||
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,15 @@ import com.gh.gamecenter.feature.provider.IGameDetailProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.gameDetail, name = "GameDetailActivity暴露服务")
|
||||
class GameDetailProviderImpl : IGameDetailProvider {
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameEntity: GameEntity?,
|
||||
entrance: String,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
GameDetailActivity.startGameDetailActivity(context, gameEntity, entrance, traceEvent)
|
||||
}
|
||||
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameId: String,
|
||||
@ -18,6 +27,7 @@ class GameDetailProviderImpl : IGameDetailProvider {
|
||||
) {
|
||||
GameDetailActivity.startGameDetailActivity(context, gameId, entrance, traceEvent)
|
||||
}
|
||||
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameEntity: GameEntity?,
|
||||
@ -40,6 +50,30 @@ class GameDetailProviderImpl : IGameDetailProvider {
|
||||
)
|
||||
}
|
||||
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameId: String,
|
||||
entrance: String?,
|
||||
defaultTab: Int,
|
||||
isSkipGameComment: Boolean,
|
||||
scrollToLibao: Boolean,
|
||||
openVideoStreaming: Boolean,
|
||||
openPlatformWindow: Boolean,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
GameDetailActivity.startGameDetailActivity(
|
||||
context,
|
||||
gameId,
|
||||
entrance,
|
||||
defaultTab,
|
||||
isSkipGameComment,
|
||||
scrollToLibao,
|
||||
openVideoStreaming,
|
||||
openPlatformWindow,
|
||||
traceEvent
|
||||
)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.GameTrendsHelper
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IGameTrendsHelperProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.gameTrendsHelper, name = "GameTrendsHelper暴露服务")
|
||||
class GameTrendsHelperProviderImpl : IGameTrendsHelperProvider {
|
||||
override fun updateReadPostTime() {
|
||||
GameTrendsHelper.updateReadPostTime()
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.LibaoUtils
|
||||
import com.gh.common.util.LibaoUtils.PostLibaoListener
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.ILibaoUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.libaoUtils, name = "LibaoUtils暴露服务")
|
||||
class LibaoUtilsProviderImpl : ILibaoUtilsProvider {
|
||||
override fun getLibaoStatus(ids: String, successCallback: ((Any?) -> Unit)?, failureCallback: (() -> Unit)?) {
|
||||
LibaoUtils.getLibaoStatus(ids, object : PostLibaoListener {
|
||||
override fun postSucceed(response: Any?) {
|
||||
successCallback?.invoke(response)
|
||||
}
|
||||
|
||||
override fun postFailed(error: Throwable?) {
|
||||
failureCallback?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.entity.SuggestType
|
||||
@ -62,6 +63,16 @@ class LinkDirectUtilsProviderImpl : ILinkDirectUtilsProvider {
|
||||
DirectUtils.directToSuggestion(context, type, hiddenHint)
|
||||
}
|
||||
|
||||
override fun directToCommunityColumn(
|
||||
context: Context,
|
||||
community: CommunityEntity?,
|
||||
subjectId: String,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
DirectUtils.directToCommunityColumn(context, community, subjectId, entrance, path)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.MessageDetailActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.provider.IMessageDetailProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.messageDetail, name = "MessageDetailActivity暴露服务")
|
||||
class MessageDetailProviderImpl : IMessageDetailProvider {
|
||||
|
||||
override fun getIntentById(
|
||||
context: Context,
|
||||
newsId: String,
|
||||
commentNum: Int,
|
||||
openSoftInput: Boolean,
|
||||
entrance: String
|
||||
): Intent {
|
||||
return MessageDetailActivity.getIntentById(context, newsId, commentNum, openSoftInput, entrance)
|
||||
}
|
||||
|
||||
override fun getIntentByEntity(context: Context, concernEntity: ConcernEntity, entrance: String): Intent? {
|
||||
return MessageDetailActivity.getIntentByEntity(context, concernEntity, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,13 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IMessageUnreadRepositoryProvider
|
||||
import com.gh.gamecenter.feature.entity.MessageUnreadCount
|
||||
import com.gh.gamecenter.feature.entity.MessageUnreadEntity
|
||||
import com.gh.gamecenter.feature.provider.IMessageUnreadRepositoryProvider
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
|
||||
@Route(path = RouteConsts.provider.messageUnreadRepository, name = "MessageUnreadRepository暴露服务")
|
||||
@ -13,6 +17,22 @@ class MessageUnreadRepositoryProviderImpl : IMessageUnreadRepositoryProvider {
|
||||
MessageUnreadRepository.loadMessageUnreadData()
|
||||
}
|
||||
|
||||
override fun loadMessageUnreadTotal(isRecordData: Boolean) {
|
||||
MessageUnreadRepository.loadMessageUnreadTotal(isRecordData)
|
||||
}
|
||||
|
||||
override fun getUnreadLiveData(): MediatorLiveData<MessageUnreadEntity> {
|
||||
return MessageUnreadRepository.unreadLiveData
|
||||
}
|
||||
|
||||
override fun getZixunConcernLiveData(): MutableLiveData<Boolean> {
|
||||
return MessageUnreadRepository.zixunConcern
|
||||
}
|
||||
|
||||
override fun getMessageUnreadCountLiveData(): MutableLiveData<MessageUnreadCount?> {
|
||||
return MessageUnreadRepository.messageUnreadCountLiveData
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.INewCommentDetailProvider
|
||||
import com.gh.gamecenter.qa.comment.NewCommentDetailActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.newCommentDetail, name = "NewCommentDetailActivity暴露服务")
|
||||
class NewCommentDetailProviderImpl : INewCommentDetailProvider {
|
||||
|
||||
override fun getAnswerCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
questionId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getAnswerCommentIntent(
|
||||
context,
|
||||
commentId,
|
||||
questionId,
|
||||
topCommentId,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
}
|
||||
|
||||
override fun getArticleCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
communityId: String,
|
||||
articleId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getArticleCommentIntent(
|
||||
context,
|
||||
commentId,
|
||||
communityId,
|
||||
articleId,
|
||||
topCommentId,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
}
|
||||
|
||||
override fun getVideoCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
videoId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getVideoCommentIntent(context, commentId, videoId, topCommentId, entrance, path)
|
||||
}
|
||||
|
||||
override fun getGameCollectionCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
gameCollectionId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getGameCollectionCommentIntent(
|
||||
context,
|
||||
commentId,
|
||||
gameCollectionId,
|
||||
topCommentId,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -33,6 +33,18 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
|
||||
return PackageUtils.getSideLoadedInfo()
|
||||
}
|
||||
|
||||
override fun isSignedByGh(context: Context, packageName: String): Boolean {
|
||||
return PackageUtils.isSignedByGh(context, packageName)
|
||||
}
|
||||
|
||||
override fun getInstalledTime(context: Context, packageName: String): Long {
|
||||
return PackageUtils.getInstalledTime(context, packageName)
|
||||
}
|
||||
|
||||
override fun getVersionNameByPackageName(packageName: String): String {
|
||||
return PackageUtils.getVersionNameByPackageName(packageName) ?: ""
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -3,7 +3,8 @@ package com.gh.common.provider
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IPackagesManagerProvider
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.provider.IPackagesManagerProvider
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
|
||||
@Route(path = RouteConsts.provider.packagesManager, name = "PackagesManager暴露服务")
|
||||
@ -12,6 +13,10 @@ class PackagesManagerProviderImpl: IPackagesManagerProvider {
|
||||
return PackagesManager.isCanPluggable(gameId, packageName)
|
||||
}
|
||||
|
||||
override fun getFilterSameApkInstalledList(): ArrayList<GameInstall> {
|
||||
return PackagesManager.getFilterSameApkInstalledList()
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -30,6 +30,10 @@ class RegionSettingHelperProviderImpl : IRegionSettingHelperProvider {
|
||||
return RegionSettingHelper.getIpInfo()
|
||||
}
|
||||
|
||||
override fun shouldThisGameBeFiltered(gameId: String?): Boolean {
|
||||
return RegionSettingHelper.shouldThisGameBeFiltered(gameId)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.ShareCardPicActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.provider.IShareCardPicProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.shareCardPicActivity, name = "ShareCardPicActivity暴露服务")
|
||||
class ShareCardPicProviderImpl : IShareCardPicProvider {
|
||||
override fun startShareCardPicActivity(context: Context, concernEntity: ConcernEntity, entrance: String) {
|
||||
ShareCardPicActivity.startShareCardPicActivity(context, concernEntity, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.ShareCardActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.provider.IShareCardProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.shareCardActivity, name = "ShareCardActivity暴露服务")
|
||||
class ShareCardProviderImpl : IShareCardProvider {
|
||||
override fun getIntent(context: Context, concernEntity: ConcernEntity, shareContent: String): Intent {
|
||||
return ShareCardActivity.getIntent(context, concernEntity, shareContent)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ISimpleAnswerDetailProvider
|
||||
import com.gh.gamecenter.qa.answer.detail.SimpleAnswerDetailActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.simpleAnswerDetail, name = "SimpleAnswerDetailActivity暴露服务")
|
||||
class SimpleAnswerDetailProviderImpl : ISimpleAnswerDetailProvider {
|
||||
|
||||
override fun getIntent(context: Context, answerId: String, entrance: String, path: String): Intent {
|
||||
return SimpleAnswerDetailActivity.getIntent(context, answerId, entrance, path)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ISubjectProvider
|
||||
import com.gh.gamecenter.subject.SubjectActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.subject, name = "SubjectActivity暴露服务")
|
||||
class SubjectProviderImpl : ISubjectProvider {
|
||||
override fun startSubjectActivity(
|
||||
context: Context,
|
||||
id: String?,
|
||||
name: String?,
|
||||
isOrder: Boolean,
|
||||
entrance: String?
|
||||
) {
|
||||
SubjectActivity.startSubjectActivity(context, id, name, isOrder, null, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@ import com.gh.gamecenter.manager.UpdateManager
|
||||
|
||||
@Route(path = RouteConsts.provider.updateManager, name = "UpdateManager暴露服务")
|
||||
class UpdateManagerProviderImpl: IUpdateManagerProvider {
|
||||
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler) {
|
||||
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler?) {
|
||||
UpdateManager.getInstance(context).checkUpdate(isAutoCheck, handler)
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IVisitManagerProvider
|
||||
import com.gh.gamecenter.manager.VisitManager
|
||||
|
||||
@Route(path = RouteConsts.provider.visitManager, name = "VisitManager暴露服务")
|
||||
class VisitManagerProviderImpl : IVisitManagerProvider {
|
||||
override fun updateOkhttpCache(context: Context, newsId: String) {
|
||||
VisitManager.updateOkhttpCache(context, newsId)
|
||||
}
|
||||
|
||||
override fun addUrl(ids: String) {
|
||||
VisitManager.getInstance().addUrl(ids)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,16 @@ class WebProviderImpl : IWebProvider {
|
||||
return WebActivity.getQAIntent(context, url, title, isWebPageHandleBackPressed, qaType)
|
||||
}
|
||||
|
||||
override fun getIntentByNews(
|
||||
context: Context?,
|
||||
concernLink: String?,
|
||||
concernGameName: String,
|
||||
concernId: String?,
|
||||
entrance: String?
|
||||
): Intent {
|
||||
return WebActivity.getIntentByNews(context, concernLink, concernGameName, concernId, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -19,44 +19,11 @@ object AdHelper {
|
||||
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
|
||||
const val LOCATION_SIMULATOR_GAME = "simulator_game"
|
||||
|
||||
@JvmStatic
|
||||
fun getStartUpAd(): StartupAdEntity? {
|
||||
return Config.getNewApiSettingsEntity()?.startAd
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getStartUp(): StartupAdEntity? {
|
||||
return Config.getNewApiSettingsEntity()?.startup
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun prefetchStartUpAd(settingsEntity: NewApiSettingsEntity) {
|
||||
if (settingsEntity.startAd != null && !settingsEntity.startAd?.img.isNullOrEmpty()) {
|
||||
val screenWidth = DisplayUtils.getScreenWidth()
|
||||
val transformedUrl = ImageUtils.getTransformedUrl(settingsEntity.startAd?.img, screenWidth) ?: return
|
||||
ImageUtils.prefetchToDiskCache(transformedUrl)
|
||||
}
|
||||
}
|
||||
|
||||
fun getSettingAdCache() {
|
||||
RetrofitManager.getInstance().newApi
|
||||
.getSettingAdCache(HaloApp.getInstance().channel)
|
||||
.compose(observableToMain())
|
||||
.subscribe(object : Response<NewApiSettingsEntity>() {
|
||||
override fun onResponse(response: NewApiSettingsEntity?) {
|
||||
super.onResponse(response)
|
||||
val settings = Config.getNewApiSettingsEntity()
|
||||
if (settings != null) {
|
||||
settings.startAd = response?.startAd
|
||||
Config.updateNewApiSettings(settings)
|
||||
if (response != null) {
|
||||
prefetchStartUpAd(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getAd(location: String): SettingsEntity.AD? {
|
||||
val adList = Config.getSettings()?.adList ?: return null
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.utils.ifLogin
|
||||
import com.gh.gamecenter.common.utils.showAutoOrientation
|
||||
import com.gh.gamecenter.common.view.BugFixedPopupWindow
|
||||
import com.gh.gamecenter.entity.CommentEntity
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity
|
||||
import com.gh.gamecenter.feature.entity.Permissions
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener
|
||||
|
||||
@ -29,7 +29,7 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.NumberUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.login.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.login.user.UserManager;
|
||||
|
||||
@ -57,8 +57,7 @@ public class DataUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化 Sentry 约占用 90ms,这里切换到子线程初始化
|
||||
AppExecutor.getIoExecutor().execute(() -> initSentry(context, channel));
|
||||
initSentry(context, channel);
|
||||
}
|
||||
|
||||
private static void initSentry(Context context, String channel) {
|
||||
|
||||
@ -24,6 +24,8 @@ import com.gh.vspace.VHelper;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/06/17.
|
||||
* 详情下载工具类
|
||||
@ -42,9 +44,7 @@ public class DetailDownloadUtils {
|
||||
viewHolder.mMultiVersionDownloadTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (viewHolder.gameEntity != null
|
||||
&& Config.isShowDownload(viewHolder.gameEntity.getId())
|
||||
&& !"光环助手".equals(viewHolder.gameEntity.getName())) {
|
||||
if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) && !"光环助手".equals(viewHolder.gameEntity.getName())) {
|
||||
viewHolder.downloadBottom.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewHolder.downloadBottom.setVisibility(View.GONE);
|
||||
@ -233,6 +233,13 @@ public class DetailDownloadUtils {
|
||||
DownloadEntity downloadEntity = viewHolder.downloadEntity;
|
||||
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
|
||||
|
||||
if (XapkUnzipStatus.SUCCESS.name().equals(xapkStatus) && XapkInstaller.INSTANCE.isInstalling(downloadEntity.getPath())) {
|
||||
viewHolder.mDownloadPb.setText("游戏安装中");
|
||||
viewHolder.mDownloadPb.setProgress(100);
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
|
||||
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
|
||||
viewHolder.mDownloadPb.setText("游戏解压中 " + percent + "%");
|
||||
@ -286,7 +293,7 @@ public class DetailDownloadUtils {
|
||||
viewHolder.mDownloadPb.setText(R.string.launch);
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
|
||||
} else {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
|
||||
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
@ -307,13 +314,12 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
|
||||
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
}
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
|
||||
|
||||
@ -71,8 +71,8 @@ import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.SPUtils;
|
||||
import com.gh.gamecenter.core.utils.SpanBuilder;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.databinding.DialogAddressConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.DialogBindPhoneBinding;
|
||||
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.DialogPackageParseErrorBinding;
|
||||
import com.gh.gamecenter.databinding.DialogRelievePhoneBinding;
|
||||
import com.gh.gamecenter.databinding.DialogReportReasonBinding;
|
||||
@ -732,40 +732,65 @@ public class DialogUtils {
|
||||
public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
if (gameEntity.getOverseasAddressDialog() == null
|
||||
|| gameEntity.getApk().size() == 0
|
||||
|| !gameEntity.getOverseasAddressDialog().isEnable()) {
|
||||
listener.onConfirm();
|
||||
} else {
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
binding.gameIcon.displayGameIcon(gameEntity);
|
||||
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
binding.gameIcon.displayGameIcon(gameEntity);
|
||||
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
|
||||
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
|
||||
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
|
||||
}
|
||||
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
|
||||
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + ")");
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
|
||||
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
|
||||
}
|
||||
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
|
||||
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + ")");
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
// 跳转第三方落地页下载弹窗
|
||||
public static void showLandPageAddressDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
binding.gameIcon.displayGameIcon(gameEntity);
|
||||
binding.gameNameTv.setText(context.getString(R.string.dialog_land_page_address_hint, gameEntity.getName()));
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
|
||||
binding.urlTv.setText(gameEntity.getLandPageAddressDialog().getLink());
|
||||
binding.downloadBtn.setText(context.getString(R.string.dialog_land_page_address_confirm));
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showGameH5DownloadDialog(Context context, GameEntity gameEntity, RegionSetting.GameH5Download gameH5Download) {
|
||||
@ -773,7 +798,7 @@ public class DialogUtils {
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
@ -1293,11 +1318,13 @@ public class DialogUtils {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void showReserveSuccess2WechatBindDialog(Context context, ConfirmListener confirmListener, CancelListener cancelListener) {
|
||||
public static void showReserveOrVoteSuccess2WechatBindDialog(Context context, Boolean isReserve, ConfirmListener confirmListener, CancelListener cancelListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
DialogWechatReserveSuccessBinding binding = DialogWechatReserveSuccessBinding.inflate(LayoutInflater.from(context));
|
||||
binding.titleIv.setImageResource(isReserve ? R.drawable.bg_reserve_success : R.drawable.bg_vote_success);
|
||||
binding.contentTv.setText(isReserve ? "游戏上线时,您将在消息中心收到通知。为了避免错过通知,建议您开启微信公众号提醒": "版本上线时,您将在消息中心收到通知。为了避免错过通知,亦建议您开启微信公众号提醒");
|
||||
binding.closeBtn.setOnClickListener(v -> {
|
||||
cancelListener.onCancel();
|
||||
dialog.dismiss();
|
||||
@ -1318,13 +1345,13 @@ public class DialogUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showReserveSuccessDialog(Context context) {
|
||||
public static void showReserveOrVoteSuccessDialog(Context context, Boolean isReserve) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
DialogAlertDefaultBinding binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(context));
|
||||
binding.titleTv.setText("游戏预约成功");
|
||||
binding.contentTv.setText("游戏上线时,您将在消息中心和微信公众号收到通知,不会错过任何预约的游戏");
|
||||
binding.titleTv.setText(isReserve ? "游戏预约成功" : "版本投票成功");
|
||||
binding.contentTv.setText(isReserve ? "游戏上线时,您将在消息中心和微信公众号收到通知,不会错过任何预约的游戏" : "版本上线时,您将在消息中心和微信公众号收到通知,不会错过任何投票的版本");
|
||||
binding.confirmTv.setText("我知道了");
|
||||
binding.centerDivider.setVisibility(View.GONE);
|
||||
binding.cancelTv.setVisibility(View.GONE);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
@ -9,6 +10,7 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.ExposureManager.log
|
||||
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
|
||||
@ -28,9 +30,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts.*
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.*
|
||||
import com.gh.gamecenter.common.entity.Display
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.provider.IQGameProvider
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.discovery.DiscoveryActivity
|
||||
@ -39,10 +41,12 @@ import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.feature.entity.GameDetailServer
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity
|
||||
import com.gh.gamecenter.feature.entity.MeEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.provider.IConcernInfoProvider
|
||||
import com.gh.gamecenter.forum.detail.ForumDetailActivity
|
||||
import com.gh.gamecenter.forum.home.CommunityHomeFragment
|
||||
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
|
||||
@ -51,6 +55,7 @@ import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActi
|
||||
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity
|
||||
import com.gh.gamecenter.game.upload.GameSubmissionActivity
|
||||
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
|
||||
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
|
||||
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment
|
||||
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
|
||||
@ -67,6 +72,9 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
|
||||
import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
|
||||
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
|
||||
import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
|
||||
import com.gh.gamecenter.qgame.QGameHomeWrapperActivity
|
||||
import com.gh.gamecenter.qgame.QGameSearchActivity
|
||||
import com.gh.gamecenter.qgame.QGameViewModel
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.servers.GameServerTestActivity
|
||||
import com.gh.gamecenter.servers.GameServersActivity
|
||||
@ -97,53 +105,6 @@ import kotlin.math.roundToInt
|
||||
*/
|
||||
object DirectUtils {
|
||||
|
||||
/**
|
||||
* 跳转到特定页面,根据 [type] 决定跳转页面,[path] 为跳转前的页面名称
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToSpecificPage(
|
||||
context: Context,
|
||||
type: String,
|
||||
link: String,
|
||||
text: String? = "",
|
||||
entrance: String? = null,
|
||||
path: String? = null
|
||||
) {
|
||||
when (type) {
|
||||
HOST_ARTICLE -> directToArticle(context, id = link, entrance = entrance)
|
||||
|
||||
HOST_GAME -> directToGameDetail(context, id = link, entrance = entrance)
|
||||
|
||||
HOST_GAME_DOWNLOAD -> directToGameDetail(context, id = link, entrance = entrance, autoDownload = true)
|
||||
|
||||
HOST_COLUMN -> directToSubject(context, id = link, subjectName = text, entrance = entrance)
|
||||
|
||||
HOST_QUESTION -> directToQuestionDetail(context, id = link, entrance = entrance, path = path)
|
||||
|
||||
HOST_ANSWER -> directToAnswerDetail(context, id = link, entrance = entrance, path = path)
|
||||
|
||||
HOST_WEB -> directToWebView(context, url = link, entrance = entrance)
|
||||
|
||||
HOST_DOWNLOAD -> directToDownloadManagerAndStartDownload(
|
||||
context,
|
||||
gameId = link,
|
||||
packageName = text,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
HOST_UPDATE -> directToDownloadManagerAndStartUpdate(
|
||||
context,
|
||||
gameId = link,
|
||||
packageName = text,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
HOST_LIBAO -> directToGiftDetail(context, giftId = link, entrance = entrance)
|
||||
|
||||
HOST_COMMUNITY -> directToCommunity(context, CommunityEntity(link, text!!))
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
|
||||
directToLinkPage(context, linkEntity, entrance, path, null)
|
||||
@ -219,8 +180,9 @@ object DirectUtils {
|
||||
)
|
||||
} else {
|
||||
directToGameDetail(
|
||||
context, linkEntity.link
|
||||
?: "", BaseActivity.mergeEntranceAndPath(entrance, path)
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
entrance = BaseActivity.mergeEntranceAndPath(entrance, path)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -258,7 +220,7 @@ object DirectUtils {
|
||||
path
|
||||
)
|
||||
|
||||
"web", "inurl", "web链接" -> {
|
||||
HOST_WEB, HOST_WEB_INURL, HOST_WEB_AL -> {
|
||||
when {
|
||||
linkEntity.link!!.contains("v.douyin") && PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme") -> {
|
||||
directDouyin(context, "1402577827140941")
|
||||
@ -316,7 +278,7 @@ object DirectUtils {
|
||||
)
|
||||
}
|
||||
|
||||
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
|
||||
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance, "", exposureEvent)
|
||||
|
||||
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path, exposureEvent)
|
||||
|
||||
@ -338,7 +300,7 @@ object DirectUtils {
|
||||
|
||||
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, false, "", entrance)
|
||||
|
||||
"qa", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
|
||||
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
|
||||
|
||||
"qa_collection", "Q&A合集" -> directToQaCollection(
|
||||
context, linkEntity.text
|
||||
@ -410,7 +372,7 @@ object DirectUtils {
|
||||
"column_test" -> context.startActivity(
|
||||
GameServerTestActivity.getIntent(
|
||||
context, linkEntity.link
|
||||
?: "", linkEntity.text ?: "", entrance
|
||||
?: "", linkEntity.text ?: "", entrance, exposureEvent
|
||||
)
|
||||
)
|
||||
|
||||
@ -438,13 +400,13 @@ object DirectUtils {
|
||||
|
||||
//"h5_game_center" -> directLetoGameCenter(context)
|
||||
|
||||
"game_list" -> directToGameCollectionSquare(context, entrance, "", "", "")
|
||||
"game_list" -> directToGameCollectionSquare(context, entrance, traceEvent = exposureEvent)
|
||||
|
||||
"game_list_detail" -> directToGameCollectionDetail(
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
entrance,
|
||||
exposureEvent = exposureEvent
|
||||
traceEvent = exposureEvent
|
||||
)
|
||||
|
||||
"explore_column", "game_explore" -> context.startActivity(
|
||||
@ -463,6 +425,8 @@ object DirectUtils {
|
||||
)
|
||||
)
|
||||
|
||||
"qq_mini_game_column" -> directToQGameHome(context)
|
||||
|
||||
"" -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -513,7 +477,8 @@ object DirectUtils {
|
||||
id: String,
|
||||
position: Int = -1,
|
||||
entrance: String,
|
||||
columnName: String = ""
|
||||
columnName: String = "",
|
||||
exposureEvent: ExposureEvent? = null
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
@ -522,6 +487,9 @@ object DirectUtils {
|
||||
bundle.putString(KEY_COLLECTION_ID, id)
|
||||
bundle.putString(KEY_COLUMNNAME, columnName)
|
||||
bundle.putInt(KEY_POSITION, position)
|
||||
if (exposureEvent != null) {
|
||||
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST ,ArrayList(exposureEvent.source))
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -748,11 +716,12 @@ object DirectUtils {
|
||||
id: String,
|
||||
subjectName: String? = "",
|
||||
entrance: String? = null,
|
||||
exposureEvent: ExposureEvent? = null
|
||||
exposureEvent: ExposureEvent? = null,
|
||||
isQQMiniGame: Boolean = false,
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false)
|
||||
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, isQQMiniGame = isQQMiniGame)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, SubjectActivity::class.java.name)
|
||||
bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData)
|
||||
@ -1864,8 +1833,11 @@ object DirectUtils {
|
||||
* 跳转到游戏动态,请不要随意修改方法名
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToConcernInfo(context: Context) {
|
||||
context.startActivity(ConcernInfoActivity.getIntent(context));
|
||||
fun directToConcernInfo(context: Context, entrance: String) {
|
||||
context.startActivity(
|
||||
(ARouter.getInstance().build(RouteConsts.provider.concernInfo)
|
||||
.navigation() as? IConcernInfoProvider)?.getIntent(context, entrance)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1877,14 +1849,36 @@ object DirectUtils {
|
||||
entrance: String = "",
|
||||
forumName: String = "",
|
||||
gameCollectionTitle: String = "",
|
||||
gameCollectionId: String = ""
|
||||
gameCollectionId: String = "",
|
||||
collectionName: String = "",
|
||||
collectionId: String = "",
|
||||
traceEvent: ExposureEvent? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
val exposureSourceList = traceEvent?.source
|
||||
bundle.putString(KEY_TO, GameCollectionSquareActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_FORUM_NAME, forumName)
|
||||
bundle.putString(KEY_GAME_COLLECTION_TITLE, gameCollectionTitle)
|
||||
bundle.putString(KEY_GAME_COLLECTION_ID, gameCollectionId)
|
||||
bundle.putString(KEY_COLLECTION_ID, collectionId)
|
||||
bundle.putString(KEY_COLLECTION_NAME, collectionName)
|
||||
if (exposureSourceList is ArrayList) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
} else if (exposureSourceList != null) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureSourceList))
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至游戏单热榜
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameCollectionHotList(context: Context, entrance: String = "") {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameCollectionHotListActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1897,15 +1891,20 @@ object DirectUtils {
|
||||
id: String,
|
||||
entrance: String? = null,
|
||||
path: String? = null,
|
||||
exposureEvent: ExposureEvent? = null
|
||||
traceEvent: ExposureEvent? = null,
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
val exposureSourceList = traceEvent?.source
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
bundle.putString(KEY_TO, GameCollectionDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_GAME_COLLECTION_ID, id)
|
||||
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
|
||||
if (exposureSourceList is ArrayList) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
} else if (exposureSourceList != null) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureSourceList))
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -2030,4 +2029,66 @@ object DirectUtils {
|
||||
platform = platform
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToQGameHome(context: Context) {
|
||||
context.startActivity(QGameHomeWrapperActivity.getIntent(context))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToQGameSearch(
|
||||
context: Context,
|
||||
hint: String,
|
||||
sourceEntrance: String
|
||||
) {
|
||||
context.startActivity(QGameSearchActivity.getIntent(context, hint, sourceEntrance))
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun directToQGameById(
|
||||
activity: Activity,
|
||||
qqGameId: String
|
||||
) {
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
ToastUtils.toast("该游戏仅支持安卓5.0及以上设备")
|
||||
return
|
||||
}
|
||||
|
||||
CheckLoginUtils.checkLogin(
|
||||
activity, null, true, "QQ小游戏-秒开"
|
||||
) {
|
||||
val userToken = UserManager.getInstance().token
|
||||
val userId = UserManager.getInstance().userId
|
||||
val userName = UserManager.getInstance().userInfoEntity?.name ?: "unknown"
|
||||
|
||||
val qGameProvider = ARouter
|
||||
.getInstance()
|
||||
.build(RouteConsts.provider.qGame)
|
||||
.navigation() as IQGameProvider<*>
|
||||
qGameProvider.setLoginInfo(activity, userId, userName, userToken)
|
||||
qGameProvider.launchGame(activity, qqGameId) { _, _ ->
|
||||
RetrofitManager
|
||||
.getInstance()
|
||||
.newApi
|
||||
.postQGamePlay(qqGameId, userId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
QGameViewModel.notifyQGameSubjectUpdate() // 通知QQ小游戏首页列表刷新
|
||||
},
|
||||
{}
|
||||
) // 秒玩记录上报
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToMessageCenter(defaultTabIndex: Int) {
|
||||
ARouter.getInstance().build(RouteConsts.activity.messageWrapperActivity)
|
||||
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
|
||||
.navigation()
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
@ -7,6 +8,7 @@ import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.collection.ArrayMap
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.chain.*
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.dialog.DeviceRemindDialog
|
||||
@ -18,9 +20,11 @@ import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.common.xapk.XapkInstaller.cancelUnzipTask
|
||||
import com.gh.common.xapk.XapkInstaller.isInstalling
|
||||
import com.gh.common.xapk.XapkUnzipStatus
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.download.dialog.DownloadDialog
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
@ -28,15 +32,20 @@ import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.callback.CancelListener
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.provider.IQGameProvider
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
|
||||
import com.gh.vspace.VHelper
|
||||
import com.lightgame.download.DownloadConfig
|
||||
@ -163,6 +172,8 @@ object DownloadItemUtils {
|
||||
briefStyle: String? = null,
|
||||
isShowRecommendStar: Boolean = false
|
||||
) {
|
||||
holder.gameDownloadBtn.putObject(gameEntity)
|
||||
|
||||
// 显示预约
|
||||
if (gameEntity.isReservable) {
|
||||
holder.multiVersionDownloadTv?.visibility = View.GONE
|
||||
@ -233,6 +244,24 @@ object DownloadItemUtils {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.isQQMiniGame()) {
|
||||
val isQQMiniGameOffShelve = gameEntity.qqMiniGameAppStatus == 1 // QQ小游戏是否下架
|
||||
if (isQQMiniGameOffShelve) {
|
||||
downloadBtn.apply {
|
||||
isClickable = false
|
||||
text = context.getString(R.string.off_shelve)
|
||||
buttonStyle = DownloadButton.ButtonStyle.NONE
|
||||
}
|
||||
} else {
|
||||
downloadBtn.apply {
|
||||
isClickable = true
|
||||
setBackgroundResource(R.drawable.download_button_normal_style)
|
||||
setTextColor(R.color.white.toColor(context))
|
||||
text = context.getString(R.string.quick_play)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.getApk().isEmpty() || gameEntity.downloadOffStatus != null) {
|
||||
val h5LinkEntity = gameEntity.h5Link
|
||||
val offStatus = gameEntity.downloadOffStatus
|
||||
@ -263,20 +292,14 @@ object DownloadItemUtils {
|
||||
}
|
||||
}
|
||||
} else if (gameEntity.getApk().size == 1) {
|
||||
// 优先从下载管理获取 downloadEntity
|
||||
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
|
||||
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在,代表游戏已下载并成功安装
|
||||
if (downloadEntity == null && gameEntity.isVGame()) {
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
|
||||
}
|
||||
|
||||
if (downloadEntity == null) {
|
||||
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
if (entryMap.isNotEmpty()) {
|
||||
downloadEntity = entryMap[apkEntity.getPlatform()]
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
downloadBtn.apply {
|
||||
when (downloadEntity.status) {
|
||||
@ -297,6 +320,25 @@ object DownloadItemUtils {
|
||||
DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
|
||||
}
|
||||
} else {
|
||||
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {
|
||||
progress = 100
|
||||
setText(R.string.installing)
|
||||
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
return
|
||||
}
|
||||
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
|
||||
val percent = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_PERCENT]
|
||||
progress = (java.lang.Float.valueOf(percent) * 10).toInt()
|
||||
text = "$percent%"
|
||||
buttonStyle = DownloadButton.ButtonStyle.XAPK_UNZIPPING
|
||||
return
|
||||
} else if (XapkUnzipStatus.FAILURE.name == xapkStatus) {
|
||||
setText(R.string.install)
|
||||
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
return
|
||||
}
|
||||
|
||||
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
setText(R.string.install)
|
||||
}
|
||||
@ -307,6 +349,7 @@ object DownloadItemUtils {
|
||||
DownloadButton.ButtonStyle.NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
DownloadStatus.pause,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror,
|
||||
@ -317,9 +360,11 @@ object DownloadItemUtils {
|
||||
buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
setText(R.string.resume)
|
||||
}
|
||||
|
||||
DownloadStatus.cancel -> {
|
||||
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -341,15 +386,7 @@ object DownloadItemUtils {
|
||||
briefStyle: String?,
|
||||
isShowRecommendStar: Boolean = false
|
||||
) {
|
||||
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
var downloadEntity: DownloadEntity? = null
|
||||
if (entryMap.isNotEmpty()) {
|
||||
downloadEntity = entryMap[apkEntity.getPlatform()]
|
||||
}
|
||||
if (downloadEntity == null) {
|
||||
downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
}
|
||||
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
if (downloadEntity != null) {
|
||||
if (downloadEntity.isSimulatorGame()) {
|
||||
if (downloadEntity.status != DownloadStatus.done) {
|
||||
@ -396,7 +433,7 @@ object DownloadItemUtils {
|
||||
}
|
||||
|
||||
// 更改进度条和提示文本的状态
|
||||
fun changeStatus(
|
||||
private fun changeStatus(
|
||||
context: Context,
|
||||
holder: GameViewHolder,
|
||||
downloadEntity: DownloadEntity,
|
||||
@ -421,6 +458,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.text = downloadEntity.percent.toString() + "%"
|
||||
}
|
||||
}
|
||||
|
||||
DownloadStatus.waiting -> {
|
||||
if (isMultiVersion) {
|
||||
holder.gameDownloadTips?.visibility = View.VISIBLE
|
||||
@ -429,6 +467,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.WAITING
|
||||
holder.gameDownloadBtn.text = context.getString(R.string.waiting)
|
||||
}
|
||||
|
||||
DownloadStatus.pause,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror,
|
||||
@ -443,6 +482,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
holder.gameDownloadBtn.text = context.getString(R.string.resume)
|
||||
}
|
||||
|
||||
DownloadStatus.done -> {
|
||||
if (isMultiVersion) {
|
||||
holder.gameDownloadTips?.visibility = View.VISIBLE
|
||||
@ -462,6 +502,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.progress = 1000
|
||||
holder.gameDownloadBtn.setText(R.string.hundred_percent)
|
||||
}
|
||||
|
||||
else -> {
|
||||
holder.gameDownloadTips?.visibility = View.GONE
|
||||
}
|
||||
@ -592,13 +633,15 @@ object DownloadItemUtils {
|
||||
refreshCallback: EmptyCallback?,
|
||||
allStateClickCallback: EmptyCallback?
|
||||
) {
|
||||
// 为 downloadButton 添加游戏实体,供点击的时候上报用
|
||||
downloadBtn.putObject(gameEntity)
|
||||
|
||||
val gamePermissionDialogFragment = (context as AppCompatActivity).supportFragmentManager.findFragmentByTag(
|
||||
GamePermissionDialogFragment::class.java.name
|
||||
) as GamePermissionDialogFragment?
|
||||
gamePermissionDialogFragment?.dismissAllowingStateLoss()
|
||||
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
|
||||
downloadBtn.setOnClickListener {
|
||||
logDownloadButtonClick(gameEntity, downloadBtn)
|
||||
DialogHelper.showDialog(
|
||||
context,
|
||||
"提示",
|
||||
@ -618,7 +661,6 @@ object DownloadItemUtils {
|
||||
if (gameEntity.isSpecialDownload()) {
|
||||
val info = RegionSettingHelper.getGameSpecialDownloadInfo(gameEntity.id) ?: return
|
||||
downloadBtn.setOnClickListener {
|
||||
logDownloadButtonClick(gameEntity, downloadBtn)
|
||||
DialogHelper.showDialog(
|
||||
context,
|
||||
"提示",
|
||||
@ -659,14 +701,12 @@ object DownloadItemUtils {
|
||||
ReservationHelper.reserve(
|
||||
context,
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: "",
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
LogUtils.logReservation(gameEntity, traceEvent)
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
})
|
||||
gameEntity.name ?: ""
|
||||
) {
|
||||
LogUtils.logReservation(gameEntity, traceEvent)
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -708,16 +748,22 @@ object DownloadItemUtils {
|
||||
val gameH5Download = RegionSettingHelper.getGameH5DownloadByGameId(gameEntity.id)
|
||||
if (gameH5Download != null) {
|
||||
downloadBtn.setOnClickListener {
|
||||
logDownloadButtonClick(gameEntity, downloadBtn)
|
||||
DialogUtils.showGameH5DownloadDialog(context, gameEntity, gameH5Download)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.isQQMiniGame()) {
|
||||
downloadBtn.setOnClickListener {
|
||||
NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name)
|
||||
GlobalActivityManager.currentActivity?.let { activity ->
|
||||
DirectUtils.directToQGameById(activity, gameEntity.qqMiniGameAppId)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.getApk().size == 0 && gameEntity.h5Link != null) {
|
||||
downloadBtn.setOnClickListener {
|
||||
logDownloadButtonClick(gameEntity, downloadBtn)
|
||||
allStateClickCallback?.onCallback()
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.name)
|
||||
val linkEntity = gameEntity.h5Link
|
||||
val isPlay = "play" == linkEntity!!.type // 是否为开始玩
|
||||
if (isPlay) {
|
||||
@ -734,7 +780,6 @@ object DownloadItemUtils {
|
||||
}
|
||||
} else if (gameEntity.getApk().size == 1) {
|
||||
downloadBtn.setOnClickListener {
|
||||
logDownloadButtonClick(gameEntity, downloadBtn)
|
||||
val clickRunnable = EmptyCallback {
|
||||
allStateClickCallback?.onCallback()
|
||||
clickCallback?.onCallback()
|
||||
@ -795,6 +840,7 @@ object DownloadItemUtils {
|
||||
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
|
||||
if (str == context.getString(R.string.download)) {
|
||||
ChainBuilder().apply {
|
||||
addHandler(UnsupportedFeatureHandler())
|
||||
addHandler(UpdateNewSimulatorHandler())
|
||||
addHandler(GamePermissionHandler())
|
||||
addHandler(BrowserInstallHandler())
|
||||
@ -802,6 +848,7 @@ object DownloadItemUtils {
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
.setProcessEndCallback {
|
||||
@ -812,6 +859,7 @@ object DownloadItemUtils {
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
|
||||
} else if (str == context.getString(R.string.attempt)) {
|
||||
ChainBuilder().apply {
|
||||
addHandler(UnsupportedFeatureHandler())
|
||||
addHandler(UpdateNewSimulatorHandler())
|
||||
addHandler(GamePermissionHandler())
|
||||
addHandler(BrowserInstallHandler())
|
||||
@ -819,6 +867,7 @@ object DownloadItemUtils {
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(VersionNumberHandler())
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
@ -830,11 +879,13 @@ object DownloadItemUtils {
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
|
||||
} else if (str == context.getString(R.string.smooth)) {
|
||||
ChainBuilder().apply {
|
||||
addHandler(UnsupportedFeatureHandler())
|
||||
addHandler(GamePermissionHandler())
|
||||
addHandler(PackageCheckHandler())
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(VersionNumberHandler())
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(CheckStoragePermissionHandler())
|
||||
addHandler(ValidateVSpaceHandler())
|
||||
@ -846,9 +897,6 @@ object DownloadItemUtils {
|
||||
.buildHandlerChain()
|
||||
?.handleRequest(context, gameEntity)
|
||||
} else if (str.contains("化")) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "插件化", gameEntity.name)
|
||||
}
|
||||
if (gameEntity.pluggableCollection != null) {
|
||||
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
|
||||
} else {
|
||||
@ -913,42 +961,48 @@ object DownloadItemUtils {
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
|
||||
return
|
||||
}
|
||||
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
|
||||
}
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
|
||||
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
|
||||
} else if (str == context.getString(R.string.update)) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.name)
|
||||
}
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.updateOrReDownload(gameEntity)
|
||||
return
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apk.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
|
||||
|
||||
ChainBuilder()
|
||||
.apply {
|
||||
addHandler(LandPageAddressHandler())
|
||||
}.setProcessEndCallback {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apk.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.buildHandlerChain()
|
||||
?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
if (downloadEntity == null && gameEntity.getApk().size == 1) {
|
||||
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
if (entryMap.isNotEmpty()) {
|
||||
downloadEntity = entryMap[apkEntity.getPlatform()]
|
||||
}
|
||||
|
||||
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在,代表游戏已下载并成功安装
|
||||
if (downloadEntity == null && gameEntity.isVGame()) {
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
|
||||
}
|
||||
|
||||
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
|
||||
if (downloadEntity == null) {
|
||||
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {// 安装过程中避免重复点击
|
||||
return
|
||||
}
|
||||
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
|
||||
cancelUnzipTask(downloadEntity)
|
||||
return
|
||||
@ -957,9 +1011,11 @@ object DownloadItemUtils {
|
||||
context.getString(R.string.resume) -> {
|
||||
DownloadManager.getInstance().resume(downloadEntity, true)
|
||||
}
|
||||
|
||||
context.getString(R.string.waiting) -> {
|
||||
Utils.toast(context, "最多只能同时下载三个任务,请稍等")
|
||||
}
|
||||
|
||||
else -> {
|
||||
DownloadManager.getInstance().pause(downloadEntity.url)
|
||||
}
|
||||
@ -980,7 +1036,7 @@ object DownloadItemUtils {
|
||||
) {
|
||||
if (gameEntity.getApk().isEmpty()) return
|
||||
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size)
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
@ -991,7 +1047,13 @@ object DownloadItemUtils {
|
||||
isSubscribe,
|
||||
traceEvent
|
||||
)
|
||||
Utils.toast(context, gameEntity.name + "已加入下载队列")
|
||||
ToastUtils.toast(gameEntity.name + "已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
if (downloadBtn is DownloadButton) {
|
||||
downloadBtn.text = "0%"
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
|
||||
@ -1012,10 +1074,16 @@ object DownloadItemUtils {
|
||||
isSubscribe: Boolean,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size)
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
||||
Utils.toast(context, gameEntity.name + "已加入下载队列")
|
||||
ToastUtils.toast(gameEntity.name + "已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
if (downloadBtn is DownloadButton) {
|
||||
downloadBtn.setText(R.string.downloading)
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN
|
||||
@ -1045,9 +1113,11 @@ object DownloadItemUtils {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
|
||||
PackageUtils.isCanPluggable(apkEntity) -> {
|
||||
DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
|
||||
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
|
||||
}
|
||||
|
||||
else -> {
|
||||
PackageInstaller.install(context, downloadEntity)
|
||||
}
|
||||
@ -1066,23 +1136,4 @@ object DownloadItemUtils {
|
||||
) {
|
||||
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
|
||||
private fun logDownloadButtonClick(gameEntity: GameEntity, downloadBtn: View) {
|
||||
val buttonName = if (downloadBtn is DownloadButton) downloadBtn.text else ""
|
||||
SensorsBridge.trackEvent(
|
||||
"DownLoadbuttonClick",
|
||||
"game_id", gameEntity.id,
|
||||
"game_name", gameEntity.name ?: "",
|
||||
"game_type", gameEntity.categoryChinese,
|
||||
"download_status", gameEntity.downloadStatusChinese,
|
||||
"button_name", buttonName,
|
||||
"game_schema_type", gameEntity.gameBitChinese,
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
|
||||
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
|
||||
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
|
||||
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
|
||||
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,6 @@ import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.entity.SuggestType
|
||||
import com.gh.gamecenter.common.eventbus.EBShowDialog
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
@ -24,18 +23,13 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils
|
||||
import com.gh.gamecenter.help.HelpAndFeedbackBridge
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.pkg.PkgHelper
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.*
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONObject
|
||||
|
||||
object DownloadObserver {
|
||||
|
||||
@ -45,7 +39,10 @@ object DownloadObserver {
|
||||
// TODO 修复因为更改内存对象造成的双重下载完成事件问题,具体触发代码见 DownloadDao.updateSnapshotList
|
||||
private var mDoneDebouncePair: Pair<String, Long>? = null
|
||||
|
||||
private const val TEA_EVENT_DOWNLOAD_COMPLETE = "game_addiction"
|
||||
private const val TAG = "DownloadObserver"
|
||||
private const val CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED = "CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED"
|
||||
|
||||
private val mRetryableHashMap = hashMapOf<String, Boolean>()
|
||||
|
||||
// 如果在WIFI状态下,下载自动暂停,则再重试一遍
|
||||
@JvmStatic
|
||||
@ -76,28 +73,34 @@ object DownloadObserver {
|
||||
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
DialogHelper.showDialog(currentActivity, "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
|
||||
HelpAndFeedbackBridge.startSuggestionActivity(
|
||||
currentActivity,
|
||||
SuggestType.gameQuestion, "notfound",
|
||||
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
|
||||
SimpleGameEntity(gameId, downloadEntity.name, "")
|
||||
)
|
||||
}, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
|
||||
DialogHelper.showDialog(
|
||||
currentActivity,
|
||||
"下载失败",
|
||||
"下载链接已失效,建议提交反馈",
|
||||
"立即反馈",
|
||||
"取消",
|
||||
{
|
||||
HelpAndFeedbackBridge.startSuggestionActivity(
|
||||
currentActivity,
|
||||
SuggestType.gameQuestion, "notfound",
|
||||
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
|
||||
SimpleGameEntity(gameId, downloadEntity.name, "")
|
||||
)
|
||||
},
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
return
|
||||
} else if (DownloadStatus.neterror == downloadEntity.status
|
||||
|| DownloadStatus.timeout == downloadEntity.status
|
||||
|| DownloadStatus.diskioerror == downloadEntity.status
|
||||
|| DownloadStatus.diskisfull == downloadEntity.status) {
|
||||
if (downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD].isNullOrEmpty()
|
||||
|| DownloadStatus.diskisfull == downloadEntity.status
|
||||
) {
|
||||
if (mRetryableHashMap[downloadEntity.url] == true
|
||||
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
) {
|
||||
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = downloadEntity.progress.toString()
|
||||
downloadManager.updateDownloadEntity(downloadEntity)
|
||||
downloadManager.resumeDownload(downloadEntity.url)
|
||||
debugOnly {
|
||||
Utils.log("DownloadObserver", "下载重试->" + downloadEntity.toJson())
|
||||
}
|
||||
mRetryableHashMap[downloadEntity.url] = false
|
||||
Utils.log(TAG, "下载重试->" + downloadEntity.toJson())
|
||||
} else {
|
||||
if (DownloadStatus.diskisfull == downloadEntity.status) {
|
||||
ToastUtils.toast("磁盘已满,请清理空间后重试下载")
|
||||
@ -108,13 +111,10 @@ object DownloadObserver {
|
||||
}
|
||||
|
||||
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
|
||||
|
||||
debugOnly {
|
||||
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
Utils.log(TAG, "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
} else if (DownloadStatus.redirected == downloadEntity.status) {
|
||||
debugOnly { Utils.log("重定向完毕") }
|
||||
Utils.log(TAG, "重定向完毕")
|
||||
DownloadDataHelper.uploadRedirectEvent(downloadEntity)
|
||||
} else if (DownloadStatus.unqualified == downloadEntity.status) {
|
||||
// 未成年
|
||||
@ -159,40 +159,35 @@ object DownloadObserver {
|
||||
if (DownloadStatus.done == downloadEntity.status) {
|
||||
if (mDoneDebouncePair?.first != downloadEntity.url) {
|
||||
mDoneDebouncePair = Pair(downloadEntity.url, System.currentTimeMillis())
|
||||
performDownloadCompleteAction(downloadEntity, gameId, downloadManager)
|
||||
performDownloadCompleteAction(downloadEntity, downloadManager)
|
||||
} else {
|
||||
if (mDoneDebouncePair?.second == 0L
|
||||
|| System.currentTimeMillis() - (mDoneDebouncePair?.second ?: 0) > 500
|
||||
) {
|
||||
performDownloadCompleteAction(downloadEntity, gameId, downloadManager)
|
||||
performDownloadCompleteAction(downloadEntity, downloadManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.done) {
|
||||
mRetryableHashMap.remove(downloadEntity.url)
|
||||
|
||||
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
|
||||
}
|
||||
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
|
||||
if (downloadEntity.status == DownloadStatus.downloading &&
|
||||
downloadEntity.progress.toString() != downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD]
|
||||
) {
|
||||
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = ""
|
||||
downloadManager.updateDownloadEntity(downloadEntity)
|
||||
if (downloadEntity.status == DownloadStatus.downloading) {
|
||||
mRetryableHashMap[downloadEntity.url] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加观察者
|
||||
DownloadManager.getInstance().addObserver(dataWatcher)
|
||||
|
||||
}
|
||||
|
||||
private fun performDownloadCompleteAction(
|
||||
downloadEntity: DownloadEntity,
|
||||
gameId: String,
|
||||
downloadManager: DownloadManager
|
||||
) {
|
||||
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
|
||||
@ -210,10 +205,7 @@ object DownloadObserver {
|
||||
} else {
|
||||
statDoneEvent(downloadEntity)
|
||||
|
||||
if (!SPUtils.getBoolean(TEA_EVENT_DOWNLOAD_COMPLETE)) {
|
||||
HaloApp.getInstance().flavorProvider.logEvent(TEA_EVENT_DOWNLOAD_COMPLETE)
|
||||
SPUtils.setBoolean(TEA_EVENT_DOWNLOAD_COMPLETE, true)
|
||||
}
|
||||
logCoreEventIfNeeded(downloadEntity.getGameCategory())
|
||||
|
||||
GameActivityDownloadHelper.clear()
|
||||
|
||||
@ -226,13 +218,16 @@ object DownloadObserver {
|
||||
EventBus.getDefault().post(
|
||||
EBShowDialog(
|
||||
BaseActivity.PLUGGABLE,
|
||||
downloadEntity.path
|
||||
downloadEntity.path,
|
||||
downloadEntity.pluginDesc
|
||||
)
|
||||
)
|
||||
|
||||
downloadEntity.isPlugin -> Utils.toast(
|
||||
mApplication,
|
||||
downloadEntity.name + " - " + platform + " - 下载完成"
|
||||
)
|
||||
|
||||
else -> {
|
||||
if (!downloadEntity.isVGame()) {
|
||||
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
|
||||
@ -250,15 +245,10 @@ object DownloadObserver {
|
||||
val gameName = downloadEntity.getMetaExtra(Constants.GAME_NAME)
|
||||
if (simulatorJson.isEmpty()) return
|
||||
var simulator = GsonUtils.fromJson(simulatorJson, SimulatorEntity::class.java)
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(
|
||||
HaloApp.getInstance().application,
|
||||
simulator.apk?.packageName
|
||||
)
|
||||
val isInstalledNewSimulator =
|
||||
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
|
||||
val isInstalledOldSimulator =
|
||||
SimulatorGameManager.isOldSimulatorInstalled(HaloApp.getInstance().application)
|
||||
// if (!isInstalled && !isInstalledNewSimulator) {
|
||||
val currentActivity = AppManager.getInstance().currentActivity()
|
||||
?: return
|
||||
val newSimulator = Config.getNewSimulatorEntitySetting()
|
||||
@ -269,7 +259,6 @@ object DownloadObserver {
|
||||
currentActivity, simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, downloadEntity.gameId, gameName, null
|
||||
)
|
||||
// }
|
||||
SimulatorGameManager.recordDownloadSimulatorGame(downloadEntity.gameId, simulator.type)
|
||||
SimulatorGameManager.postPlayedGame(downloadEntity.gameId, downloadEntity.packageName)
|
||||
} else {
|
||||
@ -296,7 +285,8 @@ object DownloadObserver {
|
||||
EventBus.getDefault().post(
|
||||
EBShowDialog(
|
||||
BaseActivity.PLUGGABLE,
|
||||
downloadEntity.path
|
||||
downloadEntity.path,
|
||||
downloadEntity.pluginDesc
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@ -392,7 +382,7 @@ object DownloadObserver {
|
||||
"DownloadProcessFinish",
|
||||
"game_id", downloadEntity.gameId,
|
||||
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
|
||||
"game_type", downloadEntity.meta[Constants.GAME_TYPE] ?: "",
|
||||
"game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
|
||||
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
|
||||
"page_name", getCurrentPageEntity().pageName,
|
||||
"page_id", getCurrentPageEntity().pageId,
|
||||
@ -409,11 +399,6 @@ object DownloadObserver {
|
||||
var elapsedTime = elapsedTimeString.toLong()
|
||||
if (elapsedTime == 0L) {
|
||||
elapsedTime = 1L
|
||||
SentryHelper.onEvent(
|
||||
"DOWNLOAD_ELAPSED_TIME",
|
||||
"elapsedTime is zero",
|
||||
downloadEntity.gameId + ":" + downloadEntity.size
|
||||
)
|
||||
}
|
||||
downloadSpeed = downloadEntity.size / elapsedTime
|
||||
}
|
||||
@ -452,4 +437,21 @@ object DownloadObserver {
|
||||
DataLogUtils.uploadHijack(mApplication, downloadEntity)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据预设的游戏类型上报关键事件(下载完成事件)
|
||||
*/
|
||||
private fun logCoreEventIfNeeded(gameCategory: String) {
|
||||
val category = PkgHelper.getCoreEventGameCategory()
|
||||
val categoryMatched = if (category == "standard" || category.isNullOrEmpty()) {
|
||||
true
|
||||
} else {
|
||||
gameCategory == category
|
||||
}
|
||||
|
||||
if (!SPUtils.getBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED) && categoryMatched) {
|
||||
HaloApp.getInstance().flavorProvider.logCoreEvent()
|
||||
SPUtils.setBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED, true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,6 +15,7 @@ import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.download.dialog.DownloadDialog
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
@ -26,6 +27,7 @@ import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.observableToMain
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
@ -183,6 +185,12 @@ object GameActivityDownloadHelper {
|
||||
str != context.getString(R.string.launch)
|
||||
) {
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
when {
|
||||
str == context.getString(R.string.download) || str == context.getString(R.string.attempt) -> {
|
||||
@ -205,6 +213,12 @@ object GameActivityDownloadHelper {
|
||||
}
|
||||
else -> {
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,7 +362,7 @@ object GameActivityDownloadHelper {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
|
||||
}
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
|
||||
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
|
||||
}
|
||||
|
||||
// 处理更新状态
|
||||
@ -424,6 +438,12 @@ object GameActivityDownloadHelper {
|
||||
), entrance, location, isSubscribe, traceEvent
|
||||
)
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast(msg)
|
||||
}
|
||||
@ -443,6 +463,12 @@ object GameActivityDownloadHelper {
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast(msg)
|
||||
}
|
||||
@ -463,7 +489,7 @@ object GameActivityDownloadHelper {
|
||||
gameEntity.getEntryMap().remove(apkEntity.getPlatform())
|
||||
}
|
||||
PackageUtils.isCanPluggable(apkEntity) -> {
|
||||
DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
|
||||
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
|
||||
}
|
||||
else -> {
|
||||
PackageInstaller.install(context, downloadEntity)
|
||||
@ -483,6 +509,12 @@ object GameActivityDownloadHelper {
|
||||
) {
|
||||
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
|
||||
18
app/src/main/java/com/gh/common/util/GameTrendsHelper.kt
Normal file
18
app/src/main/java/com/gh/common/util/GameTrendsHelper.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.gamecenter.db.GameTrendsDao
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object GameTrendsHelper {
|
||||
private val mGameTrendsDao = GameTrendsDao(HaloApp.getInstance().application)
|
||||
|
||||
fun updateReadPostTime() {
|
||||
mGameTrendsDao.findGameTrendsInfo(UserManager.getInstance().userId)?.let { trendsInfo ->
|
||||
trendsInfo.readPostTime = System.currentTimeMillis()
|
||||
mGameTrendsDao.add(trendsInfo)
|
||||
MessageUnreadRepository.loadMessageUnreadTotal(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.feature.view.DownloadButton;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
@ -180,7 +181,8 @@ public class GameUtils {
|
||||
if (gameEntity.isVGame()) {
|
||||
return context.getString(R.string.smooth);
|
||||
} else {
|
||||
if ("smooth".equals(gameEntity.getDownloadStatus())) {
|
||||
if (Constants.V_GAME.equals(gameEntity.getDownloadStatus())
|
||||
|| Constants.V_GAME_32.equals(gameEntity.getDownloadStatus())) {
|
||||
GameEntity.GameCategory gameCategory = gameEntity.getGameCategory();
|
||||
if (gameCategory.equals(GameEntity.GameCategory.ONLINE_GAME)
|
||||
|| gameCategory.equals(GameEntity.GameCategory.INTERNATIONAL_ONLINE_GAME)) {
|
||||
|
||||
@ -22,8 +22,8 @@ import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
|
||||
@ -46,7 +46,6 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
@ -786,7 +785,7 @@ public class LibaoUtils {
|
||||
, "关闭", "启动游戏"
|
||||
, () -> {
|
||||
if (LibaoUtils.isAppInstalled(context, libaoEntity.getPackageName())) {
|
||||
PackageUtils.launchApplicationByPackageName(context, libaoEntity.getPackageName());
|
||||
PackageLauncher.launchApp(context, null, libaoEntity.getPackageName());
|
||||
} else {
|
||||
Utils.toast(context, "请安装游戏:" + libaoEntity.getGame().getName()
|
||||
+ PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform()) + "版");
|
||||
|
||||
@ -986,7 +986,7 @@ public class LogUtils {
|
||||
LoghubUtils.log(object, LOG_STORE_EVENT, false);
|
||||
}
|
||||
|
||||
public static void logHomeTopTabClick(String tabName, String linkType, String linkTitle, String linkId, int sequence) {
|
||||
public static void logHomeTopTabClick(String tabName, String linkType, String linkTitle, String linkId, int sequence, String entrance) {
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put(KEY_EVENT, "top_tab_click");
|
||||
@ -995,6 +995,7 @@ public class LogUtils {
|
||||
object.put("link_id", linkId);
|
||||
object.put("link_text", linkTitle);
|
||||
object.put("sequence", sequence);
|
||||
object.put("entrance", entrance);
|
||||
object.put(KEY_META, getMetaObject());
|
||||
object.put(KEY_TIMESTAMP, System.currentTimeMillis() / 1000);
|
||||
} catch (JSONException e) {
|
||||
|
||||
@ -23,6 +23,9 @@ object NewFlatLogUtils {
|
||||
private const val KEY_TEXT = "text"
|
||||
private const val KEY_BUTTON_TYPE = "button_type"
|
||||
private const val KEY_BBS_ID = "bbs_id"
|
||||
private const val KEY_GAME_CATEGORY = "game_category"
|
||||
private const val KEY_DOWNLOAD_STATE = "download_state"
|
||||
private const val KEY_LOCATION = "location"
|
||||
|
||||
private const val EVENT_LOGIN_FROM_GHZS_SHOW = "halo_fun_login_from_ghzs_show"
|
||||
private const val EVENT_LOGIN_FROM_GHZS_CLICK = "halo_fun_login_from_ghzs_click"
|
||||
@ -118,7 +121,7 @@ object NewFlatLogUtils {
|
||||
fun logHaloFunGameDetailJumpClick(downloadStatus: String, gameId: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "halo_fun_game_detail_jump_click"
|
||||
"download_state" to downloadStatus
|
||||
KEY_DOWNLOAD_STATE to downloadStatus
|
||||
KEY_GAME_ID to gameId
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -684,7 +687,7 @@ object NewFlatLogUtils {
|
||||
val json = json {
|
||||
KEY_EVENT to "halo_self_publish_content"
|
||||
"tab_name" to tabName
|
||||
"location" to location
|
||||
KEY_LOCATION to location
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
@ -1052,10 +1055,11 @@ object NewFlatLogUtils {
|
||||
}
|
||||
|
||||
//游戏单广场浏览时长
|
||||
fun logGameCollectSquareStayTime(interval: Long) {
|
||||
fun logGameCollectSquareStayTime(interval: Long, source: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_collect_square_stay_time"
|
||||
"interval" to interval
|
||||
"source" to source
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
@ -1479,7 +1483,7 @@ object NewFlatLogUtils {
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_comment_tab_game_comment_click"
|
||||
"location" to location
|
||||
KEY_LOCATION to location
|
||||
"tag" to tag
|
||||
"filter_tag_name" to filter
|
||||
"button" to button
|
||||
@ -1521,7 +1525,7 @@ object NewFlatLogUtils {
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_comment_tab_game_comment_detail_click"
|
||||
"location" to location
|
||||
KEY_LOCATION to location
|
||||
"tag" to tag
|
||||
"filter_tag_name" to filter
|
||||
"button" to button
|
||||
@ -1623,7 +1627,7 @@ object NewFlatLogUtils {
|
||||
val json = json {
|
||||
"event" to "game_test_detail_game_category_click"
|
||||
"tab_name" to tabName
|
||||
"game_category" to gameCategory
|
||||
KEY_GAME_CATEGORY to gameCategory
|
||||
"game_test_start_type" to gameTestStartType
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1658,7 +1662,7 @@ object NewFlatLogUtils {
|
||||
val json = json {
|
||||
"event" to "game_test_home_more_click"
|
||||
"text" to text //右上角文案,包括:全部、更多
|
||||
"location" to location //新游开测所处位置,包括:首页、版块
|
||||
KEY_LOCATION to location //新游开测所处位置,包括:首页、版块
|
||||
"block_id" to blockId //新游开测所处位置为“版块”,上报版块ID
|
||||
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
|
||||
"link_type" to linkType //右上角文案为“更多”时的链接类型
|
||||
@ -1685,7 +1689,7 @@ object NewFlatLogUtils {
|
||||
) {
|
||||
val json = json {
|
||||
"event" to "game_test_home_recommend_tag_click"
|
||||
"location" to location //新游开测所处位置,包括:首页、版块
|
||||
KEY_LOCATION to location //新游开测所处位置,包括:首页、版块
|
||||
"block_id" to blockId //新游开测所处位置为“版块”,上报版块ID
|
||||
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
|
||||
"tag_id" to tagId //点击推荐标签的ID
|
||||
@ -1733,7 +1737,7 @@ object NewFlatLogUtils {
|
||||
) {
|
||||
val json = json {
|
||||
"event" to "game_test_home_view"
|
||||
"location" to location //新游开测所处位置,包括:首页、版块
|
||||
KEY_LOCATION to location //新游开测所处位置,包括:首页、版块
|
||||
"block_id" to blockId //新游开测所处位置为“版块”,上报版块ID
|
||||
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
|
||||
"interval" to interval //内容在屏幕可见范围完整展示的时长
|
||||
@ -1988,7 +1992,7 @@ object NewFlatLogUtils {
|
||||
"type" to homeSubSlide.cardType
|
||||
"text" to homeSubSlide.cardText
|
||||
"count_num" to countNum
|
||||
"location" to location
|
||||
KEY_LOCATION to location
|
||||
"link_type" to homeSubSlide.linkType
|
||||
"link_id" to homeSubSlide.linkId
|
||||
"link_text" to homeSubSlide.linkText
|
||||
@ -2185,4 +2189,225 @@ object NewFlatLogUtils {
|
||||
}
|
||||
log(json, "event", false)
|
||||
}
|
||||
|
||||
// 游戏单广场刷新
|
||||
@JvmStatic
|
||||
fun logGameCollectionSquareFlush(action: String, countNum: Int) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_list_square_flush"
|
||||
"action" to action
|
||||
"count_num" to countNum
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情点击公告文章
|
||||
@JvmStatic
|
||||
fun logGameDetailNoticeClick(gameId: String, gameName: String, linkId: String, linkType: String, linkText: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_notice_click"
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
"link_id" to linkId
|
||||
"link_type" to linkType
|
||||
"link_text" to linkText
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 启动游戏(UI被点击)
|
||||
fun logGameLaunchButtonClicked(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
location: String,
|
||||
gameCategory: String,
|
||||
downloadStatus: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_launch_button_click"
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_LOCATION to location
|
||||
KEY_GAME_CATEGORY to gameCategory
|
||||
KEY_DOWNLOAD_STATE to downloadStatus
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 启动游戏(具体实现逻辑)
|
||||
fun logGameLaunch(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
gameCategory: String,
|
||||
downloadStatus: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_launch"
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_CATEGORY to gameCategory
|
||||
KEY_DOWNLOAD_STATE to downloadStatus
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 进入游戏单热榜
|
||||
@JvmStatic
|
||||
fun logGameCollectionHotListEnter(entrance: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_list_hot_rank_enter"
|
||||
"entrance" to entrance
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 离开游戏单热榜
|
||||
@JvmStatic
|
||||
fun logGameCollectionHotListExit(interval: Long, tabName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_list_hot_rank_exit"
|
||||
"interval" to interval
|
||||
"tab_name" to tabName
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏热榜点击tab
|
||||
@JvmStatic
|
||||
fun logGameCollectionHotListTabClick(tabName: String, collectionId: String, collectionName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_hot_rank_tab_click"
|
||||
"tab_name" to tabName
|
||||
"game_list_collection_id" to collectionId
|
||||
"game_list_collection_name" to collectionName
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏热榜tab浏览
|
||||
@JvmStatic
|
||||
fun logGameCollectionHotListTabView(interval: Int, tabName: String, collectionId: String, collectionName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_hot_rank_tab_view"
|
||||
"interval" to interval
|
||||
"tab_name" to tabName
|
||||
"game_list_collection_id" to collectionId
|
||||
"game_list_collection_name" to collectionName
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏单热榜点击
|
||||
@JvmStatic
|
||||
fun logGameCollectionHotListClick(tabName: String, collectionId: String, collectionName: String, text: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_list_hot_rank_click"
|
||||
"tab_name" to tabName
|
||||
"game_list_collection_id" to collectionId
|
||||
"game_list_collection_name" to collectionName
|
||||
"text" to text
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏单合集点击
|
||||
fun logGameListCollectionClick(
|
||||
source: String,
|
||||
blockName: String,
|
||||
blockId: String,
|
||||
collectionName: String,
|
||||
collectionId: String,
|
||||
text: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_list_collection_click"
|
||||
"source" to source
|
||||
"block_name" to blockName
|
||||
"block_id" to blockId
|
||||
"game_list_collection_id" to collectionId
|
||||
"game_list_collection_name" to collectionName
|
||||
"text" to text
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情-求加速点击事件
|
||||
fun logGameDetailClickForAccelerate(gameId: String, gameName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_click_for_accelerate"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情-求版本投票事件
|
||||
fun logGameDetailClickForVersionVote(gameId: String, gameName: String, button: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_click_for_version_vote"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
"button" to button
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情-求版本取消投票事件
|
||||
fun logGameDetailCancelForVersionVote(gameId: String, gameName: String, button: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_cancel_for_version_vote"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
"button" to button
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 消息中心-插件版本提醒弹窗点击事件
|
||||
@JvmStatic
|
||||
fun logMessageInformClickPluginVersion(gameId: String, gameName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "message_inform_click_plugin_version"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏动态关注列表取消关注事件 / 游戏动态关注列表查看详情事件
|
||||
@JvmStatic
|
||||
fun logGameActivityConcern(event: String, gameId: String, gameName: String?) {
|
||||
val json = json {
|
||||
KEY_EVENT to event
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logQGameClick(qqGameId: String, qqGameName: String?) {
|
||||
val json = json {
|
||||
KEY_EVENT to "qq_game_click"
|
||||
"qq_game_id" to qqGameId
|
||||
"qq_game_name" to qqGameName ?: ""
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
}
|
||||
@ -1657,13 +1657,22 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//进入游戏单广场
|
||||
fun logEnterGameCollectionSquare(entrance: String, forumName: String = "", title: String = "", id: String = "") {
|
||||
fun logEnterGameCollectionSquare(
|
||||
entrance: String,
|
||||
forumName: String = "",
|
||||
gameCollectionTitle: String = "",
|
||||
gameCollectionId: String = "",
|
||||
collectionName: String = "",
|
||||
collectionId: String = ""
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "enter_game_collect_square"
|
||||
KEY_ENTRANCE to entrance
|
||||
"forum_name" to forumName
|
||||
"game_collect_title" to title
|
||||
"game_collect_id" to id
|
||||
"game_collect_title" to gameCollectionTitle
|
||||
"game_collect_id" to gameCollectionId
|
||||
"game_list_collection_name" to collectionName
|
||||
"game_list_collection_id" to collectionId
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1671,9 +1680,10 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//进入选择标签
|
||||
fun logEnterGameCollectionTag() {
|
||||
fun logEnterGameCollectionTag(source: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "enter_game_collect_tag_location"
|
||||
"source" to source
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1681,11 +1691,12 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//筛选游戏单标签
|
||||
fun logFilterGameCollectionTag(tagCategory: String, tagName: String) {
|
||||
fun logFilterGameCollectionTag(tagCategory: String, tagName: String, source: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "filter_game_collect_tag"
|
||||
"filter_tag_category" to tagCategory
|
||||
"filter_tag_name" to tagName
|
||||
"source" to source
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1693,9 +1704,10 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//点击安利墙卡片
|
||||
fun logClickGameCollectionAmway() {
|
||||
fun logClickGameCollectionAmway(tabName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "click_game_collect_recommend_card"
|
||||
"tab_name" to tabName
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@ -9,6 +10,7 @@ import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.FileProvider
|
||||
import com.gh.common.dialog.InstallPermissionDialogFragment
|
||||
import com.gh.common.xapk.XapkInstallReceiver
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
@ -118,7 +120,7 @@ object PackageInstaller {
|
||||
}
|
||||
} else {
|
||||
if (isPluggin) {
|
||||
DialogHelper.showPluginDialog(context) {
|
||||
DialogHelper.showPluginDialog(context, downloadEntity?.pluginDesc) {
|
||||
uninstall(context, pkgPath)
|
||||
}
|
||||
} else {
|
||||
@ -142,6 +144,32 @@ object PackageInstaller {
|
||||
context.startActivity(installIntent)
|
||||
}
|
||||
|
||||
fun installMultiple(
|
||||
context: Context,
|
||||
pkgPath: String,
|
||||
sessionId: Int = -1
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
return
|
||||
}
|
||||
val installer = context.packageManager.packageInstaller
|
||||
val session = installer.openSession(sessionId)
|
||||
// 监听安装回调的组件,可以是Activity、Service或者是BroadcastReceiver
|
||||
val intent = Intent(context, XapkInstallReceiver::class.java)
|
||||
.also {
|
||||
it.putExtra(XapkInstallReceiver.KEY_PACKAGE_PATH, pkgPath)
|
||||
}
|
||||
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
val pendingIntent = PendingIntent.getActivity(context, sessionId, intent, flags)
|
||||
// 提交数据流并执行安装
|
||||
session.commit(pendingIntent.intentSender)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取启动安装意图
|
||||
*
|
||||
@ -216,7 +244,8 @@ object PackageInstaller {
|
||||
}
|
||||
|
||||
private fun getFileSuffixByFormat(format: String?): String {
|
||||
return if (format == XapkInstaller.XAPK_EXTENSION_NAME) {
|
||||
return if (format == Constants.XAPK_FORMAT
|
||||
|| format == Constants.XAPK_APKS_FORMAT) {
|
||||
XapkInstaller.XAPK_EXTENSION_NAME
|
||||
} else {
|
||||
"apk"
|
||||
|
||||
54
app/src/main/java/com/gh/common/util/PackageLauncher.kt
Normal file
54
app/src/main/java/com/gh/common/util/PackageLauncher.kt
Normal file
@ -0,0 +1,54 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
|
||||
object PackageLauncher {
|
||||
|
||||
/*
|
||||
* 启动应用
|
||||
*/
|
||||
@JvmStatic
|
||||
fun launchApp(
|
||||
context: Context,
|
||||
gameEntity: GameEntity? = null,
|
||||
packageName: String?
|
||||
) {
|
||||
|
||||
if (packageName.isNullOrEmpty()) {
|
||||
ToastUtils.toast("启动失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 GameInstall 实体,用于记录启动日志用
|
||||
val gameInstall = if (gameEntity != null) {
|
||||
GameInstall.transformGameInstall(gameEntity, packageName)
|
||||
} else {
|
||||
PackageRepository.gameInstalled.find { it.packageName == packageName }
|
||||
}
|
||||
|
||||
if (gameInstall != null) {
|
||||
NewFlatLogUtils.logGameLaunch(
|
||||
gameId = gameInstall.id ?: "unknown",
|
||||
gameName = gameInstall.name ?: "unknown",
|
||||
gameCategory = gameInstall.category ?: "unknown",
|
||||
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
val intent = context.applicationContext.packageManager.getLaunchIntentForPackage(packageName)
|
||||
if (intent != null) {
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
ToastUtils.toast("启动失败")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.toast( "启动失败")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,12 +7,14 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.content.pm.Signature;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -29,6 +31,7 @@ import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.PackageFlavorHelper;
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper;
|
||||
import com.gh.gamecenter.core.utils.MD5Utils;
|
||||
import com.gh.gamecenter.core.utils.SentryHelper;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
@ -74,6 +77,9 @@ public class PackageUtils {
|
||||
|
||||
private static final String TAG = "PackageUtils";
|
||||
|
||||
// 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知,0 代表不支持, 1 代表支持
|
||||
private static int mIsSupportGetInstalledListPermission = -1;
|
||||
|
||||
public static String getInstallPackageInfoSourceDir(String packageName) {
|
||||
try {
|
||||
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
|
||||
@ -137,6 +143,9 @@ public class PackageUtils {
|
||||
updateEntity.setSignature(apkEntity.getSignature());
|
||||
updateEntity.setCategory(gameEntity.getCategory());
|
||||
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
|
||||
if (gameEntity.isLandPageAddressDialog()) {
|
||||
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
|
||||
}
|
||||
updateList.add(updateEntity);
|
||||
}
|
||||
}
|
||||
@ -211,6 +220,9 @@ public class PackageUtils {
|
||||
updateEntity.setSignature(apkEntity.getSignature());
|
||||
updateEntity.setCategory(gameEntity.getCategory());
|
||||
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
|
||||
if (gameEntity.isLandPageAddressDialog()) {
|
||||
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
|
||||
}
|
||||
updateList.add(updateEntity);
|
||||
}
|
||||
}
|
||||
@ -746,9 +758,11 @@ public class PackageUtils {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 启动应用
|
||||
* 请使用 PackageLauncher.launchApp()
|
||||
*/
|
||||
@Deprecated
|
||||
public static void launchApplicationByPackageName(Context context, String packageName) {
|
||||
try {
|
||||
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
@ -958,18 +972,78 @@ public class PackageUtils {
|
||||
return new ArrayList<>(mInstalledPackageList);
|
||||
}
|
||||
|
||||
Utils.log(TAG, "调用系统 API 获取全新的已安装应用列表");
|
||||
// 是否需要调用系统 API 获取最新的已安装应用列表
|
||||
boolean shouldGetNewInstalledPackagedList = false;
|
||||
|
||||
// 当前设备是否支持限制获取已安装应用列表的功能
|
||||
if (isSupportGetInstalledAppsPermission(context)) {
|
||||
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能");
|
||||
// 当前设备是否支持禁用了获取已安装应用列表
|
||||
if (!PermissionHelper.isGetInstalledListPermissionDisabled(context)) {
|
||||
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能");
|
||||
shouldGetNewInstalledPackagedList = true;
|
||||
} else {
|
||||
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能");
|
||||
}
|
||||
} else {
|
||||
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能");
|
||||
shouldGetNewInstalledPackagedList = true;
|
||||
}
|
||||
|
||||
if (shouldGetNewInstalledPackagedList) {
|
||||
mLastInstalledPackageListTime = System.currentTimeMillis();
|
||||
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
|
||||
}
|
||||
|
||||
if (mInstalledPackageList == null) {
|
||||
mInstalledPackageList = new ArrayList<>();
|
||||
}
|
||||
|
||||
mLastInstalledPackageListTime = System.currentTimeMillis();
|
||||
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
|
||||
return mInstalledPackageList;
|
||||
}
|
||||
|
||||
public static boolean isSupportGetInstalledAppsPermission(Context context) {
|
||||
// 若存在缓存,直接返回缓存结果。为 0 代表不支持,为 1 代表支持
|
||||
if (mIsSupportGetInstalledListPermission != -1) {
|
||||
return mIsSupportGetInstalledListPermission != 0;
|
||||
}
|
||||
|
||||
try {
|
||||
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
|
||||
int flag = Settings.Secure.getInt(context.getContentResolver(), "oem_installed_apps_runtime_permission_enable", 0);
|
||||
if (flag == 1) {
|
||||
mIsSupportGetInstalledListPermission = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PermissionInfo permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
if (permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS) {
|
||||
mIsSupportGetInstalledListPermission = 1;
|
||||
return true;
|
||||
} else {
|
||||
mIsSupportGetInstalledListPermission = 0;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mIsSupportGetInstalledListPermission = 0;
|
||||
return false;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
mIsSupportGetInstalledListPermission = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
|
||||
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632
|
||||
*/
|
||||
private static List<PackageInfo> getInstalledPackagesInternal(Context context, int flags) {
|
||||
Utils.log(TAG, "调用系统 API 获取已安装应用列表");
|
||||
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
return pm.getInstalledPackages(flags);
|
||||
|
||||
@ -7,7 +7,7 @@ import android.text.TextUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.walkud.rom.checker.RomIdentifier;
|
||||
|
||||
@ -66,7 +66,7 @@ object RealNameHelper {
|
||||
"game_name",
|
||||
downloadEntity.name ?: "",
|
||||
"game_type",
|
||||
downloadEntity.meta[Constants.GAME_TYPE] ?: ""
|
||||
downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: ""
|
||||
)
|
||||
|
||||
val contentText = if (downloadEntity.status == DownloadStatus.done) {
|
||||
|
||||
@ -95,21 +95,19 @@ object ReservationHelper {
|
||||
NewLogUtils.logReserveGameSuccess(wechatConfig)
|
||||
if (bind && follow && notice) {
|
||||
NewLogUtils.logReserveWechatSuccessPopShow()
|
||||
DialogUtils.showReserveSuccessDialog(context)
|
||||
DialogUtils.showReserveOrVoteSuccessDialog(context, true)
|
||||
} else {
|
||||
NewLogUtils.logReserveWechatRemindPopShow(wechatConfig)
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogShow")
|
||||
DialogUtils.showReserveSuccess2WechatBindDialog(context, object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
|
||||
context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmenWechatRemindConfigPageShow",
|
||||
"source_entrance",
|
||||
"设置微信提醒弹窗"
|
||||
)
|
||||
}
|
||||
DialogUtils.showReserveOrVoteSuccess2WechatBindDialog(context, true, {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
|
||||
context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmenWechatRemindConfigPageShow",
|
||||
"source_entrance",
|
||||
"设置微信提醒弹窗"
|
||||
)
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "关闭弹窗")
|
||||
|
||||
64
app/src/main/java/com/gh/common/xapk/XapkInstallReceiver.kt
Normal file
64
app/src/main/java/com/gh/common/xapk/XapkInstallReceiver.kt
Normal file
@ -0,0 +1,64 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
class XapkInstallReceiver : Activity() {
|
||||
|
||||
companion object {
|
||||
const val KEY_PACKAGE_PATH = "package_path"
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
overridePendingTransition(0, 0)
|
||||
handleIntent(this, intent)
|
||||
|
||||
}
|
||||
|
||||
private fun handleIntent(context: Context, intent: Intent) {
|
||||
when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val installIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
if (installIntent != null) {
|
||||
try {
|
||||
context.startActivity(installIntent)
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION)
|
||||
} catch (e: Exception) {
|
||||
// OPPO低版本会出现CONFIRM_PERMISSIONS的权限异常,这个问题无解,直接取消安装
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE,
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED,
|
||||
PackageInstaller.STATUS_FAILURE_BLOCKED,
|
||||
PackageInstaller.STATUS_FAILURE_CONFLICT,
|
||||
PackageInstaller.STATUS_FAILURE_INCOMPATIBLE,
|
||||
PackageInstaller.STATUS_FAILURE_INVALID,
|
||||
PackageInstaller.STATUS_FAILURE_STORAGE -> {
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
finish()
|
||||
}
|
||||
else -> {
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePendingSessionInfoStatus(intent: Intent, status: Int) {
|
||||
val installPackagePath = intent.getStringExtra(KEY_PACKAGE_PATH)
|
||||
if (!installPackagePath.isNullOrEmpty()) {
|
||||
val pendingSessionInfo = XapkInstaller.getPendingSessionInfo(installPackagePath)
|
||||
pendingSessionInfo?.updateStatus(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,20 +2,34 @@ package com.gh.common.xapk
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.common.utils.debugOnly
|
||||
import com.gh.gamecenter.common.utils.getExtension
|
||||
import com.gh.gamecenter.common.utils.throwExceptionInDebug
|
||||
import com.gh.gamecenter.common.utils.tryCatchInRelease
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.SentryHelper
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.xapk.XApkUnZipper
|
||||
import com.gh.gamecenter.xapk.core.XApkFile
|
||||
import com.gh.gamecenter.xapk.core.XApkUnZipCallback
|
||||
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
|
||||
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
|
||||
import com.gh.gamecenter.xapk.io.NonSplitApksOutput
|
||||
import com.gh.gamecenter.xapk.io.OBBFileOutput
|
||||
import com.gh.gamecenter.xapk.io.SplitApksOutput
|
||||
import com.gh.gamecenter.xapk.io.XApkFileOutput
|
||||
import com.gh.gamecenter.xapk.pi.IPackageInstaller
|
||||
import com.gh.ndownload.NDataChanger
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import java.text.DecimalFormat
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -28,7 +42,8 @@ import java.util.*
|
||||
* apk文件这解压的gh-files文件夹中
|
||||
*/
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object XapkInstaller : IXapkUnzipListener {
|
||||
object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
|
||||
private const val XAPK_PACKAGE_PATH_TAG = "xapk_package_path"
|
||||
|
||||
const val XAPK_EXTENSION_NAME = "xapk"
|
||||
@ -40,10 +55,19 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
const val XAPK_DATA_EXTENSION_NAME = "obb"
|
||||
const val PACKAGE_EXTENSION_NAME = "apk"
|
||||
|
||||
private const val GUIDE_TYPE_MIUI_OPTIMIZATION = "miui_optimization"
|
||||
private const val MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE = "MIUI优化关闭提示弹窗"
|
||||
|
||||
private var mContext = HaloApp.getInstance().application.applicationContext
|
||||
|
||||
// 是否需要开启特定线程处理
|
||||
private val mXapkUnzipThreadMap = Collections.synchronizedMap(HashMap<String, XapkUnzipThread>())
|
||||
private val mXApkUnZipper = XApkUnZipper(this)
|
||||
.also {
|
||||
it.registerCallback(this)
|
||||
}
|
||||
|
||||
private val mDownloadEntityMap = Collections.synchronizedMap(HashMap<String, DownloadEntity>())
|
||||
|
||||
private val mPendingSessionInfoMap = HashMap<String, XapkPendingSessionInfo>()
|
||||
|
||||
// 按并行解压
|
||||
@JvmStatic
|
||||
@ -52,6 +76,38 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
|
||||
val filePath = downloadEntity.path
|
||||
if (XAPK_EXTENSION_NAME == filePath.getExtension()) {
|
||||
if (MiuiUtils.isMiui() && !MiuiUtils.isMiuiOptimizationDisabled() && downloadEntity.format == Constants.XAPK_APKS_FORMAT) {// 小米手机开启miui以后,需要引导用户关闭miui优化
|
||||
DialogHelper.showMiuiOptimizationWarning(
|
||||
context,
|
||||
onHintClick = {
|
||||
val guides = Config.getNewApiSettingsEntity()?.install
|
||||
val miuiOptimizationGuide = guides?.guides?.findLast {
|
||||
it.type == GUIDE_TYPE_MIUI_OPTIMIZATION
|
||||
}
|
||||
if (miuiOptimizationGuide != null) {
|
||||
DirectUtils.directToLinkPage(
|
||||
context,
|
||||
miuiOptimizationGuide.link,
|
||||
MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE,
|
||||
""
|
||||
)
|
||||
}
|
||||
},
|
||||
onConfirmClick = {
|
||||
if (SystemUtils.isDevelopmentSettingsEnabled(context)) {
|
||||
context.startActivity(
|
||||
Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
)
|
||||
it.dismiss()
|
||||
} else {
|
||||
ToastUtils.showToast(context.getString(R.string.miui_open_adb_hint))
|
||||
}
|
||||
}
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
unzipXapkFile(downloadEntity)
|
||||
if (showUnzipToast) {
|
||||
Utils.toast(mContext, "解压过程请勿退出光环助手!")
|
||||
@ -63,122 +119,234 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
}
|
||||
|
||||
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
|
||||
if (mXapkUnzipThreadMap[downloadEntity.path] == null) {
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压开始")
|
||||
val xapkUnzipThread = XapkUnzipThread(downloadEntity, this)
|
||||
xapkUnzipThread.start()
|
||||
mXapkUnzipThreadMap[downloadEntity.path] = xapkUnzipThread
|
||||
} else {
|
||||
debugOnly {
|
||||
Utils.log("unzip", "重复解压,该文件解压已在队列中")
|
||||
}
|
||||
}
|
||||
mXApkUnZipper.unzip(
|
||||
XApkUnZipEntry(
|
||||
downloadEntity.path,
|
||||
File(downloadEntity.path)
|
||||
)
|
||||
)
|
||||
mDownloadEntityMap[downloadEntity.path] = downloadEntity
|
||||
}
|
||||
|
||||
override fun onProgress(downloadEntity: DownloadEntity, unzipPath: String, unzipSize: Long, unzipProgress: Long) {
|
||||
AppExecutor.uiExecutor.execute {
|
||||
val df = DecimalFormat("#.0")
|
||||
var percent = 0.0
|
||||
tryCatchInRelease {
|
||||
percent = df.format((unzipProgress / unzipSize.toFloat()) * 100).toDouble()
|
||||
}
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = percent.toString()
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
|
||||
@JvmStatic
|
||||
fun cancelUnzipTask(downloadEntity: DownloadEntity) {
|
||||
mXApkUnZipper.cancel(downloadEntity.path)
|
||||
}
|
||||
|
||||
override fun onProgress(apk: XApkFile, progress: Float) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = String.format("%.2f", progress * 100)
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onProgress->" + (unzipProgress / unzipSize.toFloat()))
|
||||
Utils.log("unzip", "onProgress->$progress")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNext(downloadEntity: DownloadEntity, unzipPath: String) {
|
||||
if (PACKAGE_EXTENSION_NAME == unzipPath.getExtension()) {
|
||||
downloadEntity.meta[XAPK_PACKAGE_PATH_TAG] = unzipPath
|
||||
override fun onSuccess(apk: XApkFile, installer: IPackageInstaller) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onNext->$unzipPath")
|
||||
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
|
||||
}
|
||||
|
||||
installer.install(mContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消解压回调
|
||||
*
|
||||
* 取消后的表现与下载完成一致
|
||||
*/
|
||||
override fun onCancel(downloadEntity: DownloadEntity) {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
override fun onError(apk: XApkFile, exception: Throwable) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(downloadEntity: DownloadEntity, exception: Exception) {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
|
||||
AppExecutor.ioExecutor.execute {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
)
|
||||
}
|
||||
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
|
||||
}
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onFailure->$exception")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(downloadEntity: DownloadEntity) {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
val pkgPath = downloadEntity.meta[XAPK_PACKAGE_PATH_TAG]
|
||||
|
||||
if (pkgPath == null) {
|
||||
Utils.toast(mContext, "下载出错,请重新下载!")
|
||||
|
||||
return@execute
|
||||
}
|
||||
|
||||
PackageInstaller.install(mContext, downloadEntity.isPlugin, pkgPath, downloadEntity)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
|
||||
override fun onCancel(apk: XApkFile) {
|
||||
val downloadEntity = mDownloadEntityMap.remove(apk.file.path) ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
|
||||
|
||||
override fun onNext(apk: XApkFile, fileName: String) {
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
|
||||
Utils.log("unzip", "onNext->$fileName")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cancelUnzipTask(downloadEntity: DownloadEntity) {
|
||||
val xapkUnzipThread = mXapkUnzipThreadMap[downloadEntity.path]
|
||||
if (xapkUnzipThread != null) {
|
||||
xapkUnzipThread.canceled = true
|
||||
fun getPendingSessionInfo(packagePath: String): XapkPendingSessionInfo? = mPendingSessionInfoMap[packagePath]
|
||||
|
||||
fun isInstalling(packagePath: String): Boolean = mPendingSessionInfoMap.containsKey(packagePath)
|
||||
|
||||
/**
|
||||
* 通知XAPK安装完成
|
||||
*/
|
||||
fun onInstalled(packagePath: String) {
|
||||
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
|
||||
|
||||
mPendingSessionInfoMap.remove(packagePath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.INSTALLED.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装成功")
|
||||
}
|
||||
}
|
||||
|
||||
fun onInstallCanceled(packagePath: String) {
|
||||
|
||||
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
|
||||
|
||||
mPendingSessionInfoMap.remove(packagePath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装取消")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前XAPK安装状态, 主要针对以下出现安装结果回调异常的情况:
|
||||
* 1. 用户触碰安装弹窗(原生Android系统)区域外导致安装取消
|
||||
*/
|
||||
fun updateCurrentInstallStatus() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || mPendingSessionInfoMap.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val updateList = mutableListOf<XapkPendingSessionInfo>()
|
||||
|
||||
for (pendingSessionInfoEntry in mPendingSessionInfoMap) {
|
||||
|
||||
val pendingSessionInfo = pendingSessionInfoEntry.value
|
||||
|
||||
if (pendingSessionInfo.getStatus() == XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION) {// 用户触摸安装弹窗外部区域取消安装后,更新安装状态
|
||||
val installer = mContext.packageManager.packageInstaller
|
||||
val sessionId = pendingSessionInfo.sessionId
|
||||
if (sessionId != -1) {
|
||||
val sessionInfo = installer.getSessionInfo(sessionId)
|
||||
// 表示用户点击了安装弹窗外部区域
|
||||
if (sessionInfo == null) {
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
} else if (sessionInfo.progress <= 0.8F) {
|
||||
AppExecutor.ioExecutor.execute {
|
||||
try {
|
||||
installer.abandonSession(sessionInfo.sessionId)
|
||||
} catch (_: Exception) {
|
||||
// 有概率抛SecurityException,这里只要直接catch不做处理即可
|
||||
}
|
||||
}
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installStatus = pendingSessionInfo.getStatus()
|
||||
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED
|
||||
|| installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS
|
||||
) {
|
||||
updateList.add(pendingSessionInfo)
|
||||
}
|
||||
}
|
||||
|
||||
for (pendingSessionInfo in updateList) {
|
||||
val downloadEntity = mDownloadEntityMap[pendingSessionInfo.path] ?: continue
|
||||
val installStatus = pendingSessionInfo.getStatus()
|
||||
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS) {
|
||||
onInstalled(downloadEntity.path)
|
||||
} else if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED) {
|
||||
onInstallCanceled(downloadEntity.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOBBOutput(apk: XApkFile): XApkFileOutput<Unit> {
|
||||
return OBBFileOutput()
|
||||
}
|
||||
|
||||
override fun onCreateApkOutput(apk: XApkFile): XApkFileOutput<IPackageInstaller> {
|
||||
val isMultiApks = apk.manifest.isMultiApks
|
||||
return if (isMultiApks) {
|
||||
SplitApksOutput(mContext.applicationContext) {
|
||||
SplitApksInstaller(apk, it)
|
||||
}
|
||||
} else {
|
||||
onCancel(downloadEntity) // 刷新页面
|
||||
NonSplitApksOutput {
|
||||
NonSplitApkInstaller(apk, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SplitApksInstaller(
|
||||
private val xApkFile: XApkFile,
|
||||
private val sessionId: Int,
|
||||
) : IPackageInstaller {
|
||||
|
||||
override fun install(context: Context) {
|
||||
val applicationContext = context.applicationContext
|
||||
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
|
||||
|
||||
mPendingSessionInfoMap[downloadEntity.path] = XapkPendingSessionInfo(downloadEntity.path, sessionId)
|
||||
AppExecutor.ioExecutor.execute {// 有可能卡顿造成anr
|
||||
PackageInstaller.installMultiple(applicationContext, downloadEntity.path, sessionId)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NonSplitApkInstaller(
|
||||
private val xApkFile: XApkFile,
|
||||
private val file: File
|
||||
) : IPackageInstaller {
|
||||
|
||||
override fun install(context: Context) {
|
||||
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
|
||||
PackageInstaller.install(
|
||||
context,
|
||||
downloadEntity.isPlugin,
|
||||
file.absolutePath,
|
||||
downloadEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,5 +355,6 @@ enum class XapkUnzipStatus(status: String) {
|
||||
UNZIPPING("unzipping"),
|
||||
SUCCESS("success"),
|
||||
CANCEL("cancel"),
|
||||
INSTALLED("installed"),
|
||||
FAILURE("failure");
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
class XapkPendingSessionInfo(
|
||||
val path: String,
|
||||
val sessionId: Int = -1
|
||||
) {
|
||||
companion object {
|
||||
const val STATUS_INIT = -1
|
||||
const val STATUS_PENDING_USER_ACTION = 0
|
||||
const val STATUS_INSTALL_SUCCESS = 1
|
||||
const val STATUS_INSTALL_CANCELED = 2
|
||||
}
|
||||
|
||||
private var status = STATUS_INIT
|
||||
|
||||
internal fun updateStatus(status: Int) {
|
||||
this.status = status
|
||||
}
|
||||
|
||||
fun getStatus(): Int = status
|
||||
}
|
||||
@ -23,9 +23,6 @@ import org.json.JSONObject
|
||||
object DownloadDataHelper {
|
||||
private const val TAG = "DownloadDataHelper"
|
||||
|
||||
private const val DOWNLOAD_SPEED_TIME = "download_speed_time"
|
||||
private const val DOWNLOAD_SPEED_SIZE = "download_speed_size"
|
||||
|
||||
const val DOWNLOAD_RESUME_WAY = "download_resume_way"
|
||||
const val DOWNLOAD_RESUME_MANUAL = "manual"
|
||||
const val DOWNLOAD_RESUME_AUTO = "auto"
|
||||
@ -34,8 +31,6 @@ object DownloadDataHelper {
|
||||
const val DOWNLOAD_CANCEL_MANUAL = "manual"
|
||||
const val DOWNLOAD_CANCEL_AUTO = "auto"
|
||||
|
||||
const val DOWNLOAD_FIRST_START = "download_first_start"
|
||||
|
||||
const val DOWNLOAD_THREAD_SIZE = "download_thread_size" // 线程数量,0为传统单线程模式; 1为多线程的单线程; >1为多线程的实际线程数量
|
||||
|
||||
private val mDownloadSpeedMap = HashMap<String, MutableList<Long>>()
|
||||
@ -128,7 +123,7 @@ object DownloadDataHelper {
|
||||
payloadObject.put("package", downloadEntity.packageName)
|
||||
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
|
||||
payloadObject.put("filename", getFileName(downloadEntity))
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@ -140,26 +135,28 @@ object DownloadDataHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun uploadDownloadEvent(downloadEntity: DownloadEntity) {
|
||||
val downloadSimpleEntity = DownloadDataSimpleHelper.getDownloadDataSimpleEntity(downloadEntity.url)
|
||||
|
||||
if (downloadEntity.status != DownloadStatus.downloading) {
|
||||
uploadDownloadStatusEvent(downloadEntity)
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.downloading) {
|
||||
val startupTime = downloadEntity.meta[DownloadEntity.DOWNLOAD_STARTUP_TIME_KEY]
|
||||
val startupTime =
|
||||
downloadSimpleEntity?.downloadStartUpTime
|
||||
if (startupTime != null) {
|
||||
uploadDownloadStartupTimeEvent(downloadEntity, startupTime.toInt())
|
||||
downloadEntity.meta.remove(DownloadEntity.DOWNLOAD_STARTUP_TIME_KEY)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
uploadDownloadStartupTimeEvent(downloadEntity, startupTime)
|
||||
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadStartUpTime = null)
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.downloading || downloadEntity.status == DownloadStatus.done) {
|
||||
val time = downloadEntity.meta[DOWNLOAD_SPEED_TIME]
|
||||
val size = downloadEntity.meta[DOWNLOAD_SPEED_SIZE]
|
||||
val time = downloadSimpleEntity?.downloadSpeedTime
|
||||
val size = downloadSimpleEntity?.downloadSpeedSize
|
||||
if (downloadEntity.speed == 0L || time == null || size == null) {
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_TIME] = System.currentTimeMillis().toString()
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_SIZE] = downloadEntity.progress.toString()
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val currentProgress = downloadEntity.progress
|
||||
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadSpeedTime = currentTime, downloadSpeedSize = currentProgress)
|
||||
} else {
|
||||
val offset = System.currentTimeMillis() - time.toLong()
|
||||
if (offset > 5000) {
|
||||
@ -180,15 +177,15 @@ object DownloadDataHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_TIME] = System.currentTimeMillis().toString()
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_SIZE] = downloadEntity.progress.toString()
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val currentProgress = downloadEntity.progress
|
||||
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadSpeedTime = currentTime, downloadSpeedSize = currentProgress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadDownloadStartupTimeEvent(downloadEntity: DownloadEntity, startupTime: Int) {
|
||||
private fun uploadDownloadStartupTimeEvent(downloadEntity: DownloadEntity, startupTime: Long) {
|
||||
val jsonObject = JSONObject()
|
||||
|
||||
try {
|
||||
@ -214,7 +211,7 @@ object DownloadDataHelper {
|
||||
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
|
||||
payloadObject.put("filename", getFileName(downloadEntity))
|
||||
payloadObject.put("launch_ms", startupTime)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
if (parallel != null) {
|
||||
payloadObject.put("parallel", parallel)
|
||||
}
|
||||
@ -264,23 +261,16 @@ object DownloadDataHelper {
|
||||
// 下载时间统计时间为零时,手动改成 1000ms,如果文件大小大于 50M 时上报 sentry
|
||||
if (elapsedTime == 0L) {
|
||||
elapsedTime = 1000L
|
||||
if (sizeInMB > 50) {
|
||||
SentryHelper.onEvent(
|
||||
"DOWNLOAD_ELAPSED_TIME",
|
||||
"elapsedTime is zero",
|
||||
downloadEntity.gameId + ":" + sizeInMB
|
||||
)
|
||||
}
|
||||
}
|
||||
val speed = downloadEntity.size / elapsedTime
|
||||
payloadObject.put("speed", speed)
|
||||
}
|
||||
} else {
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
}
|
||||
payloadObject.put("completed_size", downloadEntity.progress / 1024 / 1024)
|
||||
if (downloadEntity.status == DownloadStatus.resume) {
|
||||
if (downloadEntity.meta[DOWNLOAD_FIRST_START] == "YES") {
|
||||
if (DownloadDataSimpleHelper.getDownloadDataSimpleEntity(downloadEntity.url)?.isFirstTimeDownload == true) {
|
||||
payloadObject.put("is_first_start", true)
|
||||
} else {
|
||||
payloadObject.put("is_first_start", false)
|
||||
@ -288,8 +278,7 @@ object DownloadDataHelper {
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.resume || downloadEntity.status == DownloadStatus.add) {
|
||||
downloadEntity.meta[DOWNLOAD_FIRST_START] = "NO"
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataSimpleHelper.updateDownloadSimpleEntityFirstTimeDownload(downloadEntity.url, false)
|
||||
}
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
@ -329,7 +318,7 @@ object DownloadDataHelper {
|
||||
if (parallel != null) {
|
||||
payloadObject.put("parallel", parallel)
|
||||
}
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@ -342,7 +331,7 @@ object DownloadDataHelper {
|
||||
/**
|
||||
* 分片检测下载进度,每隔15秒内记录一次,60秒上传一次
|
||||
*
|
||||
* 请见:https://gitlab.ghzs.com/stats/stats-issues/-/issues/188#note_66919
|
||||
* 请见:https://git.shanqu.cc/stats/stats-issues/-/issues/188#note_66919
|
||||
*/
|
||||
fun uploadDownloadHeartbeat(upload: Boolean) {
|
||||
val allDownloadEntity = DownloadManager.getInstance().allDownloadEntity
|
||||
@ -352,7 +341,8 @@ object DownloadDataHelper {
|
||||
* 在后台唤醒的情况下 下载状态可能无法修正
|
||||
* see [DownloadManager.initDownloadService]
|
||||
*/
|
||||
if (downloadEntity.status == DownloadStatus.downloading && NDataChanger.downloadingTasks[downloadEntity.url] != null) {
|
||||
if (downloadEntity.status == DownloadStatus.downloading
|
||||
&& NDataChanger.downloadingTaskUrlSet.contains(downloadEntity.url)) {
|
||||
var sheet = mDownloadHeartbeatSheet[downloadEntity.url]
|
||||
if (sheet == null) {
|
||||
sheet = JSONObject()
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
package com.gh.download
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.gh.gamecenter.common.HaloApp
|
||||
import com.gh.gamecenter.common.utils.toJsonIgnoredNull
|
||||
import com.gh.gamecenter.common.utils.toObject
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
|
||||
/**
|
||||
* 用来简单保存/获取下载时一些额外信息的辅助类,避免下载时反复修改原始下载实体的糟糕操作
|
||||
* 使用 SP 来实现,只适用于相对较为低频的调用
|
||||
*/
|
||||
object DownloadDataSimpleHelper {
|
||||
|
||||
private val mSp: SharedPreferences by lazy {
|
||||
HaloApp.getInstance().getSharedPreferences("DownloadDataSimpleDao", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
fun getDownloadDataSimpleEntity(url: String): DownloadDataSimpleEntity? {
|
||||
return mSp.getString(url, "")?.toObject()
|
||||
}
|
||||
|
||||
fun updateDownloadDataSimpleEntity(
|
||||
url: String,
|
||||
downloadStartUpTime: Long? = null,
|
||||
downloadSpeedTime: Long? = null,
|
||||
downloadSpeedSize: Long? = null,
|
||||
) {
|
||||
val entity = getDownloadDataSimpleEntity(url) ?: DownloadDataSimpleEntity()
|
||||
entity.downloadStartUpTime = downloadStartUpTime
|
||||
|
||||
entity.downloadSpeedTime = downloadSpeedTime
|
||||
entity.downloadSpeedSize = downloadSpeedSize
|
||||
|
||||
SPUtils.setString(mSp, url, entity.toJsonIgnoredNull())
|
||||
}
|
||||
|
||||
fun updateDownloadSimpleEntityFirstTimeDownload(url: String, isFirstTimeDownload: Boolean) {
|
||||
val entity = getDownloadDataSimpleEntity(url) ?: DownloadDataSimpleEntity()
|
||||
|
||||
entity.isFirstTimeDownload = isFirstTimeDownload
|
||||
|
||||
SPUtils.setString(mSp, url, entity.toJsonIgnoredNull())
|
||||
}
|
||||
|
||||
fun removeDownloadSimpleEntity(url: String) {
|
||||
SPUtils.remove(mSp, url)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DownloadDataSimpleEntity(
|
||||
var downloadStartUpTime: Long? = null,
|
||||
|
||||
var downloadSpeedTime: Long? = null,
|
||||
var downloadSpeedSize: Long? = null,
|
||||
|
||||
var isFirstTimeDownload: Boolean? = true
|
||||
)
|
||||
@ -61,7 +61,6 @@ import com.lightgame.download.DownloadDao;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
import com.lightgame.download.DownloadStatusListener;
|
||||
import com.lightgame.download.DownloadTask;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.download.HttpDnsManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -284,6 +283,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
|
||||
String path;
|
||||
String downloadId = PackageInstaller.createDownloadId(gameEntity.getName());
|
||||
String gameCategory = gameEntity.getCategory();
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
path = SimulatorGameManager.getPathByType(gameEntity.getSimulatorType()) + "/" + gameEntity.getName() + "." + apkEntity.getFormat();
|
||||
|
||||
@ -309,6 +309,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
downloadEntity.setUrl(apkEntity.getUrl());
|
||||
downloadEntity.setName(gameEntity.getName());
|
||||
downloadEntity.setPath(path);
|
||||
downloadEntity.setPluginDesc(gameEntity.getPluginDesc());
|
||||
downloadEntity.setETag(apkEntity.getEtag());
|
||||
downloadEntity.setIcon(gameEntity.getIcon());
|
||||
downloadEntity.setPlatform(apkEntity.getPlatform());
|
||||
@ -316,6 +317,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
downloadEntity.setGameId(gameEntity.getId());
|
||||
downloadEntity.setEntrance(entrance);
|
||||
downloadEntity.setLocation(location);
|
||||
downloadEntity.setFormat(apkEntity.getFormat());
|
||||
downloadEntity.setVersionName(apkEntity.getVersion());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, apkEntity.getMd5());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_ID, downloadId);
|
||||
@ -323,9 +325,11 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_PLATFORM_RECOMMEND, apkEntity.getRecommend() != null ? "true" : "false");
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_NAME, gameEntity.getName());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_TYPE, gameEntity.getCategoryChinese());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_CATEGORY_IN_CHINESE, gameEntity.getCategoryChinese());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.AD_ICON_ACTIVE, String.valueOf(gameEntity.getAdIconActive()));
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_AD_DATA, String.valueOf(gameEntity.isAdData()));
|
||||
ExtensionsKt.putGameCategory(downloadEntity, gameCategory != null ? gameCategory : "");
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_SIZE, apkEntity.getSize());
|
||||
if (gameEntity.getIconFloat() != null) {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT, gameEntity.getIconFloat().getUpperLeftText());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR, gameEntity.getIconFloat().getUpperLeftColor());
|
||||
@ -545,7 +549,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 任务是否已经下载中
|
||||
*/
|
||||
public boolean isTaskDownloading(String url) {
|
||||
if (NDataChanger.INSTANCE.getDownloadingTasks().get(url) != null) {
|
||||
if (NDataChanger.INSTANCE.getDownloadingTaskUrlSet().contains(url)) {
|
||||
Utils.log(DownloadManager.class.getSimpleName(), url + "正在下载!");
|
||||
return true;
|
||||
}
|
||||
@ -830,6 +834,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
*/
|
||||
public void cancel(String url, boolean isDeleteFile, boolean automatic, boolean cancelSilently) {
|
||||
DownloadEntity entry = mDownloadDao.getSnapshot(url);
|
||||
DownloadDataSimpleHelper.INSTANCE.removeDownloadSimpleEntity(url);
|
||||
if (entry != null) {
|
||||
AppExecutor.getIoExecutor().execute(() -> {
|
||||
NDownloadBridge.INSTANCE.cancel(url);
|
||||
@ -867,12 +872,8 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
private void cancelAndNotify(DownloadEntity entry, boolean cancelSilently) {
|
||||
mDownloadDao.removeErrorMessage(entry.getUrl());
|
||||
|
||||
DownloadTask task = NDataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl());
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
// 改任务队列的状态
|
||||
NDataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl());
|
||||
}
|
||||
// 改任务队列的状态
|
||||
NDataChanger.INSTANCE.getDownloadingTaskUrlSet().remove(entry.getUrl());
|
||||
NDataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
|
||||
if (!cancelSilently) {
|
||||
NDataChanger.INSTANCE.notifyDataChanged(entry);
|
||||
@ -886,8 +887,10 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 暂停所有正在下载的任务
|
||||
*/
|
||||
public void pauseAll() {
|
||||
for (DownloadEntity entity : NDataChanger.INSTANCE.getDownloadEntries().values()) {
|
||||
pause(entity.getUrl());
|
||||
synchronized (NDataChanger.INSTANCE.getDownloadEntries()) {
|
||||
for (DownloadEntity entity : NDataChanger.INSTANCE.getDownloadEntries().values()) {
|
||||
pause(entity.getUrl());
|
||||
}
|
||||
}
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "pause all");
|
||||
}
|
||||
@ -913,10 +916,10 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 3.检查是否显示下载通知栏
|
||||
*/
|
||||
public void initDownloadService() {
|
||||
final List<String> urlList = new ArrayList<>(NDataChanger.INSTANCE.getDownloadingTasks().keySet());
|
||||
final Set<String> urlSet = NDataChanger.INSTANCE.getDownloadingTaskUrlSet();
|
||||
for (DownloadEntity downloadEntity : getAllDownloadEntity()) {
|
||||
if (!urlList.contains(downloadEntity.getUrl()) &&
|
||||
(downloadEntity.getStatus().equals(DownloadStatus.downloading)
|
||||
if (!urlSet.contains(downloadEntity.getUrl())
|
||||
&& (downloadEntity.getStatus().equals(DownloadStatus.downloading)
|
||||
|| downloadEntity.getStatus().equals(DownloadStatus.waiting))) {
|
||||
downloadEntity.setStatus(DownloadStatus.subscribe);
|
||||
mDownloadDao.newOrUpdate(downloadEntity);
|
||||
@ -994,8 +997,11 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
|
||||
if (status == DownloadStatus.add || status == DownloadStatus.subscribe) {
|
||||
if (downloadEntity.getMeta().get(DownloadDataHelper.DOWNLOAD_FIRST_START) == null) {
|
||||
downloadEntity.getMeta().put(DownloadDataHelper.DOWNLOAD_FIRST_START, "YES");
|
||||
DownloadDataSimpleEntity simpleEntity =
|
||||
DownloadDataSimpleHelper.INSTANCE.getDownloadDataSimpleEntity(downloadEntity.getUrl());
|
||||
|
||||
if (simpleEntity == null || simpleEntity.isFirstTimeDownload() == null) {
|
||||
DownloadDataSimpleHelper.INSTANCE.updateDownloadSimpleEntityFirstTimeDownload(downloadEntity.getUrl(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1235,7 +1241,10 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
|
||||
/**
|
||||
* 更新数据库中的下载实体
|
||||
*
|
||||
* @deprecated 随意更新数据库可能会出现意想不到的情况,建议不要随意调用
|
||||
*/
|
||||
@Deprecated()
|
||||
public void updateDownloadEntity(DownloadEntity downloadEntity) {
|
||||
mDownloadDao.update(downloadEntity, false);
|
||||
}
|
||||
|
||||
@ -2,10 +2,11 @@ package com.gh.download
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.util.ConcernUtils
|
||||
import com.gh.gamecenter.feature.utils.ConcernUtils
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.common.util.PackageInstaller
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.loghub.LoghubUtils
|
||||
@ -110,6 +111,10 @@ object PackageObserver {
|
||||
runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) }
|
||||
}
|
||||
|
||||
if (mDownloadEntity.format == Constants.XAPK_FORMAT) {
|
||||
XapkInstaller.onInstalled(mDownloadEntity.path)
|
||||
}
|
||||
|
||||
DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false)
|
||||
|
||||
if (SPUtils.getBoolean(Constants.SP_CONCERN_GAME, true)) { //设置页面控制是否安装后自动关注
|
||||
|
||||
@ -178,9 +178,18 @@ class DownloadDialog : BaseDraggableDialogFragment() {
|
||||
for (i in 0 until it.itemCount) {
|
||||
val apkEntity = itemList[i].normal ?: continue
|
||||
val apkCollection = apkEntity.apkCollection
|
||||
if (apkCollection != null && apkCollection.name == mPlatformName) {
|
||||
scrollAndDownload(recyclerView, false, i)
|
||||
break
|
||||
if (apkCollection != null) {
|
||||
if (apkCollection.name == mPlatformName) {
|
||||
scrollAndDownload(recyclerView, false, i)
|
||||
break
|
||||
} else {
|
||||
apkCollection.saveApkEntity?.forEach { entity ->
|
||||
if (entity.getPlatformName() == mPlatformName || entity.packageName == mPackageName) {
|
||||
scrollAndDownload(recyclerView, false, i)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (apkEntity.getPlatformName() == mPlatformName || apkEntity.packageName == mPackageName) {
|
||||
scrollAndDownload(recyclerView, true, i)
|
||||
|
||||
@ -10,12 +10,9 @@ import com.gh.common.constant.Config
|
||||
import com.gh.common.dialog.CertificationDialog
|
||||
import com.gh.common.dialog.DeviceRemindDialog
|
||||
import com.gh.common.dialog.PackageCheckDialogFragment
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.DownloadDialogHelper
|
||||
import com.gh.common.util.PackageInstaller
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.DownloadManagerActivity
|
||||
@ -244,7 +241,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_下载"
|
||||
}
|
||||
DownloadDialogItemStatus.LAUNCH -> {
|
||||
PackageUtils.launchApplicationByPackageName(it.context, apkEntity.packageName)
|
||||
PackageLauncher.launchApp(it.context, gameEntity, apkEntity.packageName)
|
||||
|
||||
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_启动"
|
||||
}
|
||||
@ -282,7 +279,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
DownloadManager.getInstance().cancel(apkEntity.url)
|
||||
} else {
|
||||
if (PackageUtils.isCanPluggable(apkEntity)) {
|
||||
DialogHelper.showPluginDialog(it.context) {
|
||||
DialogHelper.showPluginDialog(it.context, gameEntity.pluginDesc) {
|
||||
PackageInstaller.uninstall(it.context, downloadEntity.path)
|
||||
}
|
||||
} else {
|
||||
@ -352,54 +349,46 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
if (msg.isNullOrEmpty()) {
|
||||
BrowserInstallHelper.showBrowserInstallHintDialog(
|
||||
context,
|
||||
gameEntity.isVGame(),
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(
|
||||
gameEntity.isVGame() || gameEntity.isSplitXApk()
|
||||
) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(
|
||||
context,
|
||||
gameEntity,
|
||||
apkEntity
|
||||
) {
|
||||
PackageCheckDialogFragment.show(
|
||||
context as AppCompatActivity,
|
||||
gameEntity
|
||||
) {
|
||||
CertificationDialog.showCertificationDialog(
|
||||
context,
|
||||
gameEntity,
|
||||
apkEntity,
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
PackageCheckDialogFragment.show(
|
||||
context as AppCompatActivity,
|
||||
gameEntity,
|
||||
object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
CertificationDialog.showCertificationDialog(
|
||||
context,
|
||||
gameEntity,
|
||||
object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apkEntity.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe ->
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
downloadMethod,
|
||||
entrance,
|
||||
location,
|
||||
isSubscribe, traceEvent
|
||||
)
|
||||
gameEntity
|
||||
) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apkEntity.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe ->
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
downloadMethod,
|
||||
entrance,
|
||||
location,
|
||||
isSubscribe, traceEvent
|
||||
)
|
||||
|
||||
DeviceRemindDialog.showDeviceRemindDialog(
|
||||
context,
|
||||
gameEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
DeviceRemindDialog.showDeviceRemindDialog(
|
||||
context,
|
||||
gameEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, msg)
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import com.gh.gamecenter.common.utils.tryCatchInRelease
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.google.gson.JsonObject
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
@ -93,6 +94,10 @@ object BrowserInstallHelper {
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun shouldAutoSwitchAssistantInstall(gameEntity: GameEntity): Boolean =
|
||||
isUseBrowserToInstallEnabled() && shouldUseBrowserToInstall() && gameEntity.isSplitXApk()
|
||||
|
||||
/**
|
||||
* 是否显示使用浏览器来安装弹窗
|
||||
*/
|
||||
@ -144,7 +149,8 @@ object BrowserInstallHelper {
|
||||
val manufacturer = Build.MANUFACTURER.toUpperCase(Locale.CHINA)
|
||||
var contentText = "当前安装方式为助手安装,如果出现游戏无法安装的问题,可选择切换安装方式为“浏览器安装”"
|
||||
if (manufacturer == "OPPO" || manufacturer == "VIVO") {
|
||||
contentText = "当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”"
|
||||
contentText =
|
||||
"当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”"
|
||||
}
|
||||
|
||||
DialogHelper.showDialog(
|
||||
|
||||
@ -55,23 +55,21 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
* @param status 下载状态
|
||||
*/
|
||||
override fun onStatusChanged(id: String, status: DownloadStatus) {
|
||||
val entity = findEntity(id)
|
||||
val entity = findEntity(id) ?: return
|
||||
|
||||
if (entity != null) {
|
||||
entity.status = status
|
||||
entity.status = status
|
||||
|
||||
if (status == DownloadStatus.COMPLETED) {
|
||||
SimpleDownloadManager.resumeQueuedTask()
|
||||
}
|
||||
if (status == DownloadStatus.COMPLETED) {
|
||||
SimpleDownloadManager.resumeQueuedTask()
|
||||
}
|
||||
|
||||
ExecutorProvider.getInstance().backgroundExecutor.execute {
|
||||
updateDownloadToDatabase(entity)
|
||||
updateDownloadList()
|
||||
}
|
||||
ExecutorProvider.getInstance().backgroundExecutor.execute {
|
||||
updateDownloadToDatabase(entity)
|
||||
updateDownloadList()
|
||||
}
|
||||
|
||||
for (listener in mGlobalStatusChangedListenerList) {
|
||||
listener.invoke(entity!!, status)
|
||||
listener.invoke(entity, status)
|
||||
}
|
||||
|
||||
val listenerList = mListenerMap[id] ?: return
|
||||
@ -165,7 +163,7 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
* @param error 错误类型
|
||||
* @param exception 包裹错误的 Exception
|
||||
*/
|
||||
override fun onError(id: String, error: DownloadError?, exception: Exception) {
|
||||
override fun onError(id: String, error: DownloadError?, exception: Exception?) {
|
||||
error ?: return
|
||||
|
||||
when (error) {
|
||||
|
||||
@ -7,14 +7,21 @@ import com.gh.base.DownloadToolbarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.game.GameFragment
|
||||
|
||||
class BlockActivity : DownloadToolbarActivity() {
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context, blockData: SubjectRecommendEntity, entrance: String): Intent {
|
||||
fun getIntent(context: Context,
|
||||
blockData: SubjectRecommendEntity,
|
||||
exposureSourceList: ArrayList<ExposureSource>? = null,
|
||||
entrance: String): Intent {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EntranceConsts.KEY_BLOCK_DATA, blockData)
|
||||
if (exposureSourceList != null) {
|
||||
args.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
}
|
||||
args.putString(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
return getTargetIntent(context, BlockActivity::class.java, GameFragment::class.java, args)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.entity.MessageEntity;
|
||||
import com.gh.gamecenter.feature.entity.MessageEntity;
|
||||
import com.gh.gamecenter.qa.comment.CommentActivity;
|
||||
import com.gh.gamecenter.qa.comment.NewCommentConversationFragment;
|
||||
import com.halo.assistant.fragment.comment.CommentDetailFragment;
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.info.ConcernFragment;
|
||||
|
||||
/**
|
||||
* Created by khy on 10/04/18.
|
||||
*/
|
||||
|
||||
public class ConcernInfoActivity extends ToolBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
|
||||
public static Intent getIntent(Context context) {
|
||||
return getTargetIntent(context, ConcernInfoActivity.class, ConcernFragment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDarkModeChanged() {
|
||||
super.onDarkModeChanged();
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,7 @@ import androidx.transition.*
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.core.ImagePipeline
|
||||
@ -41,6 +42,7 @@ import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
@ -71,6 +73,7 @@ import kotlin.math.roundToInt
|
||||
* @author 黄壮华
|
||||
*
|
||||
*/
|
||||
@Route(path = RouteConsts.activity.imageViewerActivity)
|
||||
class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
|
||||
private var mScale = 0F
|
||||
@ -150,8 +153,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
mUrlList = ArrayList()
|
||||
mUrlList?.add(base64Image)
|
||||
} else {
|
||||
mUrlList = it.getStringArrayList(KEY_URL_LIST) ?: arrayListOf()
|
||||
mInitialPosition = it.getInt(KEY_CURRENT, 0)
|
||||
mUrlList = it.getStringArrayList(EntranceConsts.KEY_URL_LIST) ?: arrayListOf()
|
||||
mInitialPosition = it.getInt(EntranceConsts.KEY_CURRENT, 0)
|
||||
}
|
||||
mShowSaveBtn = it.getBoolean(KEY_SHOW_SAVE)
|
||||
mUseEnterAndExitAnimation = it.getBoolean(KEY_USE_ENTER_AND_EXIT_ANIMATION)
|
||||
@ -930,8 +933,6 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
var base64Image: String = ""
|
||||
|
||||
private const val KEY_BASE64 = "base64"
|
||||
private const val KEY_URL_LIST = "urls"
|
||||
private const val KEY_CURRENT = "current"
|
||||
private const val KEY_SHOW_SAVE = "showSave"
|
||||
private const val KEY_USE_ENTER_AND_EXIT_ANIMATION = "use_enter_and_exit_animation"
|
||||
private const val KEY_IS_FROM_IMAGE_CONTAINER_VIEW = "is_from_image_container_view"
|
||||
@ -995,8 +996,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
isFromICV: Boolean = false
|
||||
): Intent {
|
||||
val intent = Intent(context, ImageViewerActivity::class.java)
|
||||
intent.putExtra(KEY_URL_LIST, list)
|
||||
intent.putExtra(KEY_CURRENT, position)
|
||||
intent.putExtra(EntranceConsts.KEY_URL_LIST, list)
|
||||
intent.putExtra(EntranceConsts.KEY_CURRENT, position)
|
||||
intent.putExtra(KEY_SHOW_SAVE, isShowSaveBtn)
|
||||
intent.putExtra(AnswerEntity::class.java.name, answerEntity)
|
||||
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
|
||||
@ -18,9 +18,11 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.ethanhua.skeleton.Skeleton;
|
||||
import com.ethanhua.skeleton.ViewSkeletonScreen;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.gamecenter.common.constant.RouteConsts;
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DetailDownloadUtils;
|
||||
@ -38,8 +40,8 @@ import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.view.VerticalItemDecoration;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus;
|
||||
@ -70,6 +72,7 @@ import retrofit2.HttpException;
|
||||
/**
|
||||
* Created by khy on 2016/12/13.
|
||||
*/
|
||||
@Route(path = RouteConsts.activity.libaoDetailActivity)
|
||||
public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailAdapter.OnCodeScrollListener,
|
||||
OnRequestCallBackListener {
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@ -33,6 +32,7 @@ import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -43,9 +43,8 @@ import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.DefaultUrlHandler;
|
||||
import com.gh.ad.AdDelegateHelper;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.exposure.ExposureManager;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
@ -77,7 +76,6 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
|
||||
import com.gh.gamecenter.common.constant.CommonConsts;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.constant.RouteConsts;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.common.entity.SuggestType;
|
||||
@ -92,7 +90,6 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.NotificationHelper;
|
||||
import com.gh.gamecenter.common.utils.ShareUtils;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.provider.IStartUpAdProvider;
|
||||
import com.gh.gamecenter.core.utils.ClassUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
@ -102,8 +99,6 @@ import com.gh.gamecenter.core.utils.SentryHelper;
|
||||
import com.gh.gamecenter.core.utils.TimeUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.download.DownloadFragment;
|
||||
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
|
||||
import com.gh.gamecenter.entity.StartupAdEntity;
|
||||
import com.gh.gamecenter.eventbus.EBSkip;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
@ -141,22 +136,16 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import io.reactivex.SingleSource;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
@ -174,7 +163,7 @@ public class MainActivity extends BaseActivity {
|
||||
public static final String SWITCH_TO_COMMUNITY = "switch_to_community";
|
||||
public static final String SWITCH_TO_VIDEO = "switch_to_video";
|
||||
public static final String SHOW_AD = "show_ad";
|
||||
private static final int COUNTDOWN_AD = 100;
|
||||
public static final int COUNTDOWN_AD = 100;
|
||||
private static final int COUNTDOWN_MAX_COUNT = 3;
|
||||
private int countdownCount = 0;
|
||||
|
||||
@ -190,15 +179,12 @@ public class MainActivity extends BaseActivity {
|
||||
public static boolean isNewFirstLaunch;
|
||||
|
||||
private final Handler handler = new Handler();
|
||||
public boolean showAd = false; // 是否显示广告
|
||||
|
||||
private IStartUpAdProvider mStartUpAdProvider;
|
||||
private boolean mShouldShowAd = false; // 是否显示广告
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
showAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
|
||||
mShouldShowAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
|
||||
|
||||
HaloApp.getInstance().initFresco();
|
||||
HaloApp.getInstance().isAlreadyUpAndRunning = true;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -231,7 +217,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
}, 2000L);
|
||||
getPluginUpdate();
|
||||
sp.edit().putBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), false).apply();
|
||||
|
||||
// 记录曾安装过的版本 + 渠道
|
||||
@ -285,8 +270,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// checkTinkerPath(); // 看情况是否需要显示补丁弹窗
|
||||
|
||||
// 必须放在这里,否则会导致获取 baseActivity 不是本应用包名
|
||||
DownloadManager.getInstance().initDownloadService();
|
||||
|
||||
@ -303,22 +286,23 @@ public class MainActivity extends BaseActivity {
|
||||
doSkip();
|
||||
}
|
||||
|
||||
// debug 模式下的快速跳转页面
|
||||
if (BuildConfig.DEBUG) {
|
||||
handler.postDelayed(() -> {
|
||||
EntranceUtils.jumpShortcut(this);
|
||||
}, 500);
|
||||
handler.postDelayed(() -> EntranceUtils.jumpShortcut(this), 500);
|
||||
}
|
||||
|
||||
if (showAd) {
|
||||
observeStartUp();
|
||||
if (mShouldShowAd) {
|
||||
showAd();
|
||||
} else {
|
||||
hideStartUp();
|
||||
hideStartUpAd();
|
||||
hideTextAd();
|
||||
hideSplashAd();
|
||||
}
|
||||
|
||||
// 默认配置为空时重试
|
||||
if (Config.getSettings() == null) {
|
||||
Config.getGhzsSettings();
|
||||
} else if (Config.getVSettingEntity() == null) {
|
||||
Config.refreshVSettingEntity();
|
||||
}
|
||||
|
||||
// 耗时操作
|
||||
@ -474,7 +458,7 @@ public class MainActivity extends BaseActivity {
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
|
||||
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
|
||||
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
releaseExoSourceCache();
|
||||
@ -498,87 +482,58 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void observeStartUp() {
|
||||
if (!showAd) {
|
||||
hideStartUp();
|
||||
hideStartUpAd();
|
||||
/**
|
||||
* 显示广告 (包括文本广告和开屏广告)
|
||||
*/
|
||||
private void showAd() {
|
||||
if (!mShouldShowAd) {
|
||||
hideTextAd();
|
||||
hideSplashAd();
|
||||
return;
|
||||
}
|
||||
final StartupAdEntity startUp = AdHelper.getStartUp();
|
||||
if (startUp != null) {
|
||||
showStartUp(startUp);
|
||||
final StartupAdEntity textAd = AdHelper.getStartUp();
|
||||
if (textAd != null) {
|
||||
showTextAd(textAd);
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
hideStartUp();
|
||||
initStartUpAd();
|
||||
hideTextAd();
|
||||
showSplashAd();
|
||||
}, 2000);
|
||||
} else {
|
||||
initStartUpAd();
|
||||
showSplashAd();
|
||||
}
|
||||
}
|
||||
|
||||
private void initStartUpAd() {
|
||||
mStartUpAdProvider = (IStartUpAdProvider) ARouter.getInstance().build(RouteConsts.provider.adSdk).navigation();
|
||||
if (mStartUpAdProvider != null && mStartUpAdProvider.shouldEnableSDK(HaloApp.getInstance().getChannel())) {
|
||||
initSDKStartUpAd();
|
||||
} else {
|
||||
observeStartUpAd();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 显示开屏广告
|
||||
*/
|
||||
private void showSplashAd() {
|
||||
if (AdDelegateHelper.INSTANCE.shouldShowStartUpAd()) {
|
||||
ViewGroup startAdContainer = findViewById(R.id.startAdContainer);
|
||||
ViewGroup sdkStartAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
FrameLayout adsFl = findViewById(R.id.adsFl);
|
||||
|
||||
private void observeStartUpAd() {
|
||||
final StartupAdEntity startUpAd = AdHelper.getStartUpAd();
|
||||
int screenWidthInPx = DisplayUtils.getScreenWidth(this);
|
||||
int screenHeightInPx = DisplayUtils.getScreenHeight(this) + DisplayUtils.getStatusBarHeight(this.getResources());
|
||||
float screenWidthInDp = DisplayUtils.px2dip(this, screenWidthInPx);
|
||||
float screenHeightInDp = DisplayUtils.px2dip(this, screenHeightInPx);
|
||||
|
||||
if (startUpAd != null && !TextUtils.isEmpty(startUpAd.getImg())) {
|
||||
// 根据接口返回的广告时间,判断该图片广告是否还有必要显示
|
||||
boolean isAdValid = false;
|
||||
if (startUpAd.getTime() != null) {
|
||||
long currentTimeInSecond = System.currentTimeMillis() / 1000;
|
||||
if (currentTimeInSecond > startUpAd.getTime().getStart()
|
||||
&& currentTimeInSecond < startUpAd.getTime().getEnd()) {
|
||||
isAdValid = true;
|
||||
}
|
||||
} else {
|
||||
// 接口没有返回开始和结束时间时,默认有效
|
||||
isAdValid = true;
|
||||
}
|
||||
|
||||
// 图片广告无效,跳过
|
||||
if (!isAdValid) {
|
||||
hideStartUpAd();
|
||||
return;
|
||||
}
|
||||
|
||||
final String showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "");
|
||||
final String rule = startUpAd.getRule();
|
||||
switch (rule) {
|
||||
case "each":
|
||||
showStartUpAd(startUpAd);
|
||||
break;
|
||||
case "once":
|
||||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(startUpAd.getId())) {
|
||||
showStartUpAd(startUpAd);
|
||||
} else {
|
||||
hideStartUpAd();
|
||||
AdDelegateHelper.requestSplashAd(
|
||||
this,
|
||||
screenWidthInPx,
|
||||
screenHeightInPx,
|
||||
screenWidthInDp,
|
||||
screenHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
adsFl,
|
||||
(BaseHandler) mBaseHandler,
|
||||
() -> {
|
||||
hideSplashAd();
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "everyday":
|
||||
final String today = TimeUtils.getToday();
|
||||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(today)
|
||||
|| !showedTodayTimestamp.contains(startUpAd.getId())) {
|
||||
showStartUpAd(startUpAd);
|
||||
} else {
|
||||
hideStartUpAd();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
hideStartUpAd();
|
||||
break;
|
||||
}
|
||||
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, startUpAd.getId() + TimeUtils.getToday());
|
||||
);
|
||||
} else {
|
||||
hideStartUpAd();
|
||||
hideSplashAd();
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,14 +545,17 @@ public class MainActivity extends BaseActivity {
|
||||
TextView jumpBtn = findViewById(R.id.jumpBtn);
|
||||
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - countdownCount));
|
||||
if (COUNTDOWN_MAX_COUNT < countdownCount) {
|
||||
hideStartUpAd();
|
||||
hideSplashAd();
|
||||
} else {
|
||||
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hideStartUp() {
|
||||
/**
|
||||
* 隐藏开屏文案
|
||||
*/
|
||||
private void hideTextAd() {
|
||||
View maskContainer = findViewById(R.id.maskContainer);
|
||||
if (maskContainer != null) {
|
||||
maskContainer.setVisibility(View.GONE);
|
||||
@ -605,8 +563,11 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void hideStartUpAd() {
|
||||
showAd = false;
|
||||
/**
|
||||
* 隐藏开屏广告
|
||||
*/
|
||||
private void hideSplashAd() {
|
||||
mShouldShowAd = false;
|
||||
getIntent().putExtra(SHOW_AD, false);
|
||||
View startAdContainer = findViewById(R.id.startAdContainer);
|
||||
if (startAdContainer != null) {
|
||||
@ -617,7 +578,7 @@ public class MainActivity extends BaseActivity {
|
||||
if (startSdkAdContainer != null) {
|
||||
startSdkAdContainer.setVisibility(View.GONE);
|
||||
ExtensionsKt.removeFromParent(startSdkAdContainer);
|
||||
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
|
||||
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
|
||||
}
|
||||
checkDialog();
|
||||
}
|
||||
@ -633,62 +594,10 @@ public class MainActivity extends BaseActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void showStartUpAd(StartupAdEntity ad) {
|
||||
View startAdContainer = findViewById(R.id.startAdContainer);
|
||||
View jumpBtn = findViewById(R.id.jumpBtn);
|
||||
TextView jumpDetailBtn = findViewById(R.id.jumpDetailBtn);
|
||||
SimpleDraweeView adImage = findViewById(R.id.adImage);
|
||||
startAdContainer.setVisibility(View.VISIBLE);
|
||||
jumpDetailBtn.setText(ad.getDesc());
|
||||
ExtensionsKt.setDrawableEnd(jumpDetailBtn, AppCompatResources.getDrawable(this, R.drawable.ic_startup_ad_arrow), null, null);
|
||||
ImageUtils.display(adImage, ad.getImg());
|
||||
startAdContainer.setOnClickListener(v -> {
|
||||
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
|
||||
});
|
||||
jumpBtn.setOnClickListener(v -> {
|
||||
mBaseHandler.removeMessages(COUNTDOWN_AD);
|
||||
hideStartUpAd();
|
||||
LinkEntity linkEntity = ad.getJump();
|
||||
NewFlatLogUtils.logOpenScreenAdSkip(
|
||||
ad.getId(),
|
||||
linkEntity.getText() != null ? linkEntity.getText() : "",
|
||||
linkEntity.getType() != null ? linkEntity.getType() : "",
|
||||
linkEntity.getLink() != null ? linkEntity.getLink() : ""
|
||||
);
|
||||
});
|
||||
List<ExposureSource> sources = new ArrayList<>();
|
||||
sources.add(new ExposureSource("开屏广告", ad.getId()));
|
||||
final ExposureEvent event = ExposureEvent.createEvent(null, sources, null, ExposureType.EXPOSURE);
|
||||
ExposureManager.INSTANCE.log(event);
|
||||
if (ad.getButton()) {
|
||||
jumpDetailBtn.setOnClickListener(v -> {
|
||||
DirectUtils.directToLinkPage(this, ad.getJump(), "(启动广告)", "", event);
|
||||
v.postDelayed(() -> {
|
||||
mBaseHandler.removeMessages(COUNTDOWN_AD);
|
||||
hideStartUpAd();
|
||||
}, 1000);
|
||||
});
|
||||
jumpDetailBtn.setVisibility(View.VISIBLE);
|
||||
LogUtils.logStartAd("watch_start_ads", ad);
|
||||
} else {
|
||||
LogUtils.logStartAd("start_ads", ad);
|
||||
}
|
||||
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
|
||||
}
|
||||
|
||||
private void initSDKStartUpAd() {
|
||||
View startAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
startAdContainer.setVisibility(View.VISIBLE);
|
||||
FrameLayout adsFl = findViewById(R.id.adsFl);
|
||||
if (mStartUpAdProvider != null) {
|
||||
mStartUpAdProvider.initStartUpAd(startAdContainer, adsFl, showAd, () -> {
|
||||
hideStartUpAd();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void showStartUp(StartupAdEntity ad) {
|
||||
/**
|
||||
* 显示文本广告
|
||||
*/
|
||||
private void showTextAd(StartupAdEntity ad) {
|
||||
TextView adContentTv = findViewById(R.id.adContentTv);
|
||||
View containerView = findViewById(R.id.maskContainer);
|
||||
containerView.setVisibility(View.VISIBLE);
|
||||
@ -696,7 +605,7 @@ public class MainActivity extends BaseActivity {
|
||||
containerView.setElevation(500F);
|
||||
}
|
||||
containerView.setOnClickListener(v -> {
|
||||
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
|
||||
// 拦截点击事件,避免传递到下面的页面
|
||||
});
|
||||
adContentTv.setText(ad.getDesc());
|
||||
adContentTv.setVisibility(View.VISIBLE);
|
||||
@ -746,7 +655,6 @@ public class MainActivity extends BaseActivity {
|
||||
} else {
|
||||
Intent skipIntent = new Intent(MainActivity.this, clazz);
|
||||
skipIntent.putExtras(bundle);
|
||||
// startActivity(skipIntent);
|
||||
AvoidOnResultManager.Companion.getInstance(this)
|
||||
.startForResult(skipIntent, (resultCode, data) -> {
|
||||
Bundle nextToBundle = getIntent().getBundleExtra(KEY_NEXT_TO);
|
||||
@ -803,6 +711,15 @@ public class MainActivity extends BaseActivity {
|
||||
ToastUtils.showToast("游戏启动失败,请联系客服反馈相关信息");
|
||||
return;
|
||||
}
|
||||
|
||||
VHelper.INSTANCE.logLaunchButtonClicked(
|
||||
gamePackageName,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"桌面快捷图标"
|
||||
);
|
||||
|
||||
ToastUtils.showToast("游戏启动中,请稍后~");
|
||||
handler.postDelayed(() -> {
|
||||
VHelper.postOnInitialized(() -> {
|
||||
@ -859,7 +776,7 @@ public class MainActivity extends BaseActivity {
|
||||
@Override
|
||||
public Boolean invoke(Integer code) {
|
||||
if (code == 404001) {
|
||||
if (showAd) {
|
||||
if (mShouldShowAd) {
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
toast("抱歉,暂未找到相关内容");
|
||||
}, 1000);
|
||||
@ -970,7 +887,7 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
if (showAd) {
|
||||
if (mShouldShowAd) {
|
||||
return R.layout.activity_main;
|
||||
} else {
|
||||
return R.layout.layout_wrapper_activity;
|
||||
@ -993,77 +910,14 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取META-INF中的plugin_update 文件,判断是否从游戏插件中下载的app,是则获取游戏id,启动游戏更新,下载该游戏
|
||||
private void getPluginUpdate() {
|
||||
AppExecutor.getIoExecutor().execute(() -> {
|
||||
ApplicationInfo appinfo = getApplicationInfo();
|
||||
String sourceDir = appinfo.sourceDir;
|
||||
ZipFile zipfile = null;
|
||||
|
||||
try {
|
||||
zipfile = new ZipFile(sourceDir);
|
||||
Enumeration<?> entries = zipfile.entries();
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = ((ZipEntry) entries.nextElement());
|
||||
String entryName = entry.getName();
|
||||
if (entryName.contains("gh_assist")) {
|
||||
String packageName = entryName.substring(entryName.lastIndexOf("_") + 1);
|
||||
startActivity(DownloadManagerActivity.getDownloadMangerIntent(MainActivity.this,
|
||||
packageName, DownloadFragment.INDEX_UPDATE, "(游戏插件)"));
|
||||
break;
|
||||
} else if (entryName.contains("halo_skip.json")) {
|
||||
InputStream in = zipfile.getInputStream(entry);
|
||||
if (in != null) {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
InnerMetaInfoEntity info = GsonUtils.getGson().fromJson(reader, InnerMetaInfoEntity.class);
|
||||
if (info != null) {
|
||||
if (EntranceConsts.HOST_COMMUNITY.equals(info.getType())) {
|
||||
runOnUiThread(() -> mMainWrapperFragment.setCurrentItem(MainWrapperFragment.INDEX_BBS));
|
||||
} else {
|
||||
DirectUtils.directToSpecificPage(this,
|
||||
info.getType(),
|
||||
info.getLink(),
|
||||
info.getText(),
|
||||
EntranceConsts.KEY_PLUGIN,
|
||||
"特定包启动跳转");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (entryName.contains("halo_skip.dat")) {
|
||||
InputStream in = zipfile.getInputStream(entry);
|
||||
if (in != null) {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
String content = "";
|
||||
for (String line; (line = reader.readLine()) != null; content += line) ;
|
||||
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
DefaultUrlHandler.interceptUrl(this, content, "(特定包启动跳转)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (zipfile != null) {
|
||||
try {
|
||||
zipfile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 连接上网络事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(EBNetworkState busNetworkState) {
|
||||
if (busNetworkState.isNetworkConnected()) {
|
||||
if (Config.getSettings() == null) {
|
||||
Config.getGhzsSettings();
|
||||
} else if (Config.getVSettingEntity() == null) {
|
||||
Config.refreshVSettingEntity();
|
||||
}
|
||||
|
||||
mPackageViewModel.checkData();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user