Compare commits

..

42 Commits

Author SHA1 Message Date
278827ffad feat: 32位组件安装插件 2024-03-01 09:13:26 +08:00
79fb496cea refactor: update version 2024-02-29 11:33:21 +08:00
3187ad4ad5 fix: 插件更新逻辑 2024-02-29 11:31:18 +08:00
eae2ebd109 refactor: update vasdk commit id. 2024-02-28 13:45:25 +08:00
88b4600a41 feat: 添加更新按钮。 2024-02-28 09:24:59 +08:00
5913034e66 fix:修复一体化,畅玩游戏启动判断 2024-02-27 11:35:31 +08:00
c1425ae86f fix: 修复卸载apk不生效 2024-02-26 15:52:30 +08:00
6ab8c5c6bf fix:新旧版本畅玩组件isInstalled语义错误 2024-02-26 14:52:18 +08:00
1e22db52ee fix:新旧版本畅玩组件isInstalled语义错误 2024-02-26 14:31:28 +08:00
0867ec80ec fix:畅玩游戏无法更新的问题 2024-02-23 17:57:42 +08:00
fd2743f7be refactor: update vasdk commit id 2024-01-16 09:49:14 +08:00
25e7a8624b refactor: update vasdk commit id 2024-01-11 16:06:14 +08:00
f3c85f8c90 refactor: update commit id 2024-01-11 14:32:42 +08:00
f53ac827da feat: 32位组件更新下载 2024-01-11 14:29:09 +08:00
c5d2e770f9 refactor!: 添加测试环境的脚本 2024-01-10 17:13:42 +08:00
8d0b95960b refactor!: 添加测试环境的脚本 2024-01-10 16:53:59 +08:00
8de168c642 feat: new/upgrade接口参数修改 2024-01-10 14:30:11 +08:00
9f4c6f8bfd feat: 畅玩32位和插件的更新流程 2024-01-10 14:04:27 +08:00
2910f8492d fix: 修复获取module_version错误 2024-01-09 14:22:15 +08:00
fd4ec8224d refactor!: 临时修改打包测试版本 2024-01-09 14:07:27 +08:00
c837c77215 refactor: 优化畅玩32 debug打包步骤 2024-01-05 10:33:44 +08:00
9a45682c74 feat: 获取32位组件和插件的接口数据 2024-01-04 14:35:50 +08:00
ca1448aeb7 refactor: update commit id 2024-01-03 17:58:25 +08:00
5dadd20382 feat: 修改va配置读取 2024-01-03 17:25:58 +08:00
c6917deaca feat: 修改plugin配置读取 2024-01-03 17:12:04 +08:00
003053b8a3 fix: 修复头条,快手等其他flavor脚本打包出错的问题 2024-01-03 14:20:05 +08:00
d37e50915b refactor: upgrade shadow_version to 1.0.4 2023-12-29 17:20:42 +08:00
9668b7e9e6 refactor: update vasdk commit id. 2023-12-29 15:03:08 +08:00
dfd8b29a11 fix: min sdk version smaller than 21. 2023-12-29 15:02:50 +08:00
cfe1bea4d2 refactor: 更新shadow版本至 1.0.3 2023-12-29 11:31:23 +08:00
4eb20fd14c refactor: 更新maven拉取顺序 2023-12-29 11:31:23 +08:00
9b8fd9d8d8 refactor: 更新apk文件路径 2023-12-29 11:31:23 +08:00
94c02835b9 refactor: 下载插件到assets目录 2023-12-29 11:31:23 +08:00
84f24302f0 refactor: 更新打包脚本 2023-12-29 11:31:23 +08:00
e5fa7f8655 feat: 展示64位va插件版本信息 https://jira.shanqu.cc/browse/GHZS-3885 2023-12-29 11:31:23 +08:00
70797b2e6f fix: 过滤va项目的配置&修复错误的assets添加脚步 2023-12-29 11:31:23 +08:00
8f84cf8d51 feat: 光环助手va组件兼容旧版畅玩助手游戏业务 2023-12-29 11:31:23 +08:00
1bc2ef205b feat: 接入vasdk编译通过 2023-12-29 11:31:23 +08:00
5e83085747 refactor: va模块引用 2023-12-29 11:31:23 +08:00
173b0c32de feat: 加速器模块占用空间太大,给ci/cd集成增加时间成本,考虑到加速器变更频繁度较低,改为maven引用 2023-12-29 11:31:18 +08:00
18b14969ec feat: 同步vasdk的代码 2023-12-29 11:30:35 +08:00
581d7d6b0e feat: 接入va模块 2023-12-29 11:29:27 +08:00
2338 changed files with 26106 additions and 56342 deletions

View File

@ -71,7 +71,7 @@ android_build:
exit_codes: 137
only:
- dev
- feat/GHZSCY-5250
- dev-5.32.0
# 代码检查
sonarqube_analysis:
@ -102,7 +102,7 @@ sonarqube_analysis:
exit_codes: 137
only:
- dev
- release
- dev-5.32.0
## 发送简易检测结果报告
send_sonar_report:
@ -120,7 +120,7 @@ send_sonar_report:
exit_codes: 137
only:
- dev
- release
- dev-5.32.0
oss-upload&send-email:
tags:
@ -152,4 +152,4 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail-jira-comment.py
only:
- dev
- feat/GHZSCY-5250
- dev-5.32.0

6
.gitmodules vendored
View File

@ -5,6 +5,12 @@
[submodule "vspace-bridge"]
path = vspace-bridge
url = ../../../cwzs/android/vspace-bridge.git
[submodule "module_common/src/debug/assets/assistant-android-mock"]
path = module_common/src/debug/assets/assistant-android-mock
url = ../../../halo/android/assistant-android-mock.git
[submodule "ndownload"]
path = ndownload
url = ../../../android/ndownload.git
[submodule "vasdk"]
path = vasdk
url = ../../../sdg/android/vasdk.git

View File

@ -23,8 +23,6 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -75,7 +73,7 @@ android {
versionName rootProject.ext.versionName
applicationId rootProject.ext.applicationId
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt', rootProject.ext.va_proguard_rules
String CORE_EVENT_GAME_CATEGORY = ""
@ -97,10 +95,8 @@ android {
buildConfigField "int", "ACTIVATE_REPORTING_RATIO", "${ACTIVATE_REPORTING_RATIO}"
// All third-party appid/appkey
buildConfigField "boolean", "IS_GAT_APP", "false"
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT}\""
buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "WECHAT_APPID", "\"${WECHAT_APPID}\""
buildConfigField "String", "WECHAT_SECRET", "\"${WECHAT_SECRET}\""
@ -161,9 +157,12 @@ android {
}
}
flavorDimensions("env", "region")
flavorDimensions("env")
sourceSets {
main {
assets.srcDir("${rootProject.buildDir}/plugin")
}
publish {
java.srcDirs = ['src/main/java', "src/default/java"]
}
@ -179,22 +178,14 @@ android {
gdt {
java.srcDirs = ['src/main/java', 'src/gdt/java']
}
gat {
java.srcDirs = ['src/main/java', 'src/gat/java']
}
cn {
java.srcDirs = ['src/main/java', 'src/cn/java']
}
sm {
java.srcDirs = ['src/main/java', 'src/sm/java']
}
}
productFlavors {
// internal 内部测试包使用的 flavor接口包含包括测试和正式环境
internal {
dimension "env"
versionNameSuffix "-debug"
// blame_yangfei: test script lines
//versionNameSuffix "-debug"
buildConfigField "String", "DEV_API_HOST", "\"${DEV_API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_DEV_API_HOST}\""
@ -255,37 +246,6 @@ android {
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
sm {
dimension "env"
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", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
// 港澳台
gat {
dimension "region"
applicationId rootProject.ext.applicationIdGat
// 支持繁体
resConfigs "zh", "zh-rTW"
buildConfigField "boolean", "IS_GAT_APP", "true"
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT_GAT}\""
buildConfigField "String", "API_HOST", "\"${API_HOST_GAT}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST_GAT}\""
}
cn {
dimension "region"
}
}
}
@ -302,7 +262,6 @@ dependencies {
teaImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/tea/libs')
kuaishouImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/kuaishou/libs')
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
smImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/sm/libs')
testImplementation 'junit:junit:4.12'
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
@ -310,6 +269,7 @@ dependencies {
// debugImplementation "com.gu.android:toolargetool:${toolargetool}" // 需要使用调试时才启用
debugImplementation "com.github.nichbar:WhatTheStack:${whatTheStack}"
// debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
implementation "androidx.multidex:multidex:${multiDex}"
implementation "androidx.fragment:fragment-ktx:${fragment}"
@ -321,8 +281,7 @@ dependencies {
implementation "com.kyleduo.switchbutton:library:${switchButton}"
implementation "com.tencent.vasdolly:helper:${apkChannelPackage}"
implementation "com.tencent.vasdolly:writer:${apkChannelPackage}"
implementation "com.leon.channel:helper:${apkChannelPackage}"
implementation "com.j256.ormlite:ormlite-android:${ormlite}"
implementation "com.j256.ormlite:ormlite-core:${ormlite}"
@ -345,6 +304,8 @@ dependencies {
})
implementation "com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-exo_player2:$gsyVideo"
// implementation "androidx.work:work-runtime:${workManager}"
implementation "com.llew.huawei:verifier:${verifier}"
teaImplementation "com.bytedance.applog:RangersAppLog-Lite-cn:${bytedanceApplog}"
@ -357,20 +318,20 @@ dependencies {
implementation "com.lg:easyfloat:${easyFloat}"
implementation "io.github.florent37:shapeofview:${shapeOfView}"
implementation "com.lg:apksig:${apksig}"
implementation "com.lg:gid:${gid}"
implementation "com.lg:shortcut:${shortcut}"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:${desugarJdkLibs}"
kapt "com.alibaba:arouter-compiler:$arouterVersion"
implementation project(':ndownload')
implementation project(':vspace-bridge:vspace')
implementation project(':vspace-bridge')
implementation (project(':module_common')) {
implementation(project(':module_common')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_login')) {
@ -408,13 +369,13 @@ dependencies {
exclude group: 'androidx.swiperefreshlayout'
}
internalImplementation(project(':module_internal_test'))
// 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用阿里云推送
def pushProject = findProperty('BUILD_PUSH_TYPE') == 'jg'
? project(':feature:jg_push') : project(':feature:acloud_push')
implementation(pushProject) {
implementation(project(':va-main')) {
exclude group: 'androidx.swiperefreshlayout'
}
debugImplementation "com.bytedance.tools.codelocator:codelocator-core:2.0.3"
compileOnly project(":va-core")
compileOnly project(":va-plugin-host-lib")
implementation project(":va-plugin-host")
}
File propFile = file('sign.properties')
@ -485,13 +446,6 @@ andResGuard {
// 打开这个开关会合并所有哈希值相同的资源,但请不要过度依赖这个功能去除去冗余资源
mergeDuplicatedRes = true
whiteList = [
"R.xml.jpush*",
"R.drawable.jpush*",
"R.layout.jpush*",
"R.layout.push*",
"R.string.jg*",
"R.style.MyDialogStyle",
"R.style.JPushTheme",
"R.drawable.icon",
"R.drawable.ic_bar_back",
"R.drawable.toolbar_search_icon",
@ -663,4 +617,14 @@ project.afterEvaluate {
}
}
}
}
def copyArtifacts = tasks.create("copyArtifacts", Copy) {
from new File(rootProject.buildDir, "artifacts.zip")
into new File(rootProject.buildDir, "plugin")
}.dependsOn(":va-plugin-floating:generateDebugArtifacts")
tasks.whenTaskAdded { Task task ->
if (task.name == "preInternalDebugBuild" || task.name == "prePublishDebugBuild") {
task.dependsOn(copyArtifacts)
}
}

View File

@ -80,14 +80,14 @@
### EasyFloat
-keep class com.lzf.easyfloat.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
### 广点通SDK
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}
-keep public class com.tencent.turingfd.sdk.**
### 神马 SDK
-dontwarn com.gism.**
-keepclasseswithmembers class * {
native <methods>;
}

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.tencent.vasdolly.helper.ChannelReaderUtil
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {
override fun getChannelStr(application: Application): String {

View File

@ -5,7 +5,6 @@ import com.lightgame.utils.Utils
import com.qq.gdt.action.ActionParam
import com.qq.gdt.action.ActionType
import com.qq.gdt.action.GDTAction
import com.qq.gdt.action.PrivateController
import org.json.JSONObject
object GdtHelper {
@ -17,12 +16,6 @@ object GdtHelper {
@JvmStatic
fun init(application: Application, channel: String) {
GDTAction.setPrivateController(object : PrivateController() {
override fun isCanUsePhoneState(): Boolean {
return false
}
})
if (channel == "KS_GDT_GHZS_MC01") {
GDTAction.init(application, KS_USER_ACTION_SET_ID, KS_APP_SECRET_ID, channel)
} else {

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.halo.assistant.HaloApp
import com.tencent.vasdolly.helper.ChannelReaderUtil
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

View File

@ -25,6 +25,11 @@ class ExternalGameAdapter(private val games: List<ExternalGameUiState>, private
路径:${item.apkPath}
""".trimIndent()
}
holder.update.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)
}
holder.install.goneIf(item.isInstalled) {
holder.install.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)

View File

@ -8,4 +8,5 @@ class ExternalGameViewHolder(binding: LayoutExternalGameItemBinding) : RecyclerV
val install = binding.btnInstall
val uninstall = binding.btnUninstall
val start = binding.btnStart
val update = binding.btnUpdate
}

View File

@ -16,6 +16,7 @@ import com.gh.gamecenter.databinding.FragmentInstallExternalGamesBinding
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.VirtualAppManager
import com.lightgame.download.DownloadEntity
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@ -67,7 +68,7 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
it.layoutManager = LinearLayoutManager(requireContext())
val itemDecoration = HorizontalDividerItemDecoration.Builder(requireContext())
.size(2F.dip2px())
.color(R.color.ui_divider.toColor(requireContext()))
.color(R.color.divider.toColor(requireContext()))
.build()
if (it.itemDecorationCount != 0) {
it.removeItemDecorationAt(0)
@ -105,6 +106,15 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
private fun install(externalGameUiState: ExternalGameUiState) {
val bit =
externalGameUiState.externalGameEntity.cpuAbi.let { if (it.size == 1 && it.contains("armeabi-v7a")) "32" else "64" }
VHelper.install(requireContext(), DownloadEntity().apply {
externalGameUiState.externalGameEntity.apply {
packageName = apkPackageName
path = apkPath
}
}, true)
if (VHelper.showDialogIfVSpaceIsNeeded(
requireContext(),
"",

View File

@ -24,6 +24,14 @@
android:visibility="gone"
tools:visibility="visible" />
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_update"
android:visibility="visible"
tools:visibility="visible" />
<Button
android:id="@+id/btn_uninstall"
android:layout_width="wrap_content"

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title_install_external_game">從SD卡安裝</string>
<string name="text_install">安裝</string>
<string name="text_uninstall">卸載</string>
<string name="text_start">啟動</string>
</resources>

View File

@ -2,6 +2,7 @@
<resources>
<string name="title_install_external_game">从SD卡安装</string>
<string name="text_install">安装</string>
<string name="text_update">更新</string>
<string name="text_uninstall">卸载</string>
<string name="text_start">启动</string>
</resources>

View File

@ -12,7 +12,7 @@ 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.tencent.vasdolly.helper.ChannelReaderUtil
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

Binary file not shown.

View File

@ -11,14 +11,6 @@
<package android:name="com.lg.vspace" />
</queries>
<!-- 华为/荣耀角标 -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE "/>
<uses-permission android:name="com.hihonor.android.launcher.permission.CHANGE_BADGE" />
<!-- vivo角标 -->
<uses-permission android:name="com.vivo.notification.permission.BADGE_ICON" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- 允许应用程序访问网络连接 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许应用程序写入外部存储如SD卡上写文件 -->
@ -92,7 +84,30 @@
com.tencent.qqmini,
com.tencent.qqmini.minigame.external,
com.tencent.qqmini.minigame.opensdk,
com.tencent.qqmini.union.ad" />
com.tencent.qqmini.union.ad,
com.lg.vspace,
io.lg.va.common,
com.va.floating,
com.lg.cloud,
com.lg.archive,
com.lg.vclient,
com.va.realname,
com.lg.vspace.flavor,
com.lg.update,
com.lg.login,
com.lg.accelerator,
com.lody.virtual,
com.lg.core,
com.lg.ads,
com.lg.common,
com.lg.vspace.network,
com.lody.virtual.lib.res,
com.va.host,
com.lg.vspace.plugin.host,
com.lg.plugin.constant,
com.bytedance.tools.codelocator,
org.chickenhook.restrictionbypass,
com.lody.virtual.sandhook,com.lg.vspace.common" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -107,9 +122,8 @@
android:name="android.permission.GET_TASKS"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
tools:node="remove"/>
<supports-screens
android:anyDensity="true"
@ -126,12 +140,10 @@
android:label="@string/app_name"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
tools:replace="android:name,android:allowBackup"
tools:targetApi="r">
tools:targetApi="n">
<meta-data
android:name="EasyGoClient"
@ -204,7 +216,7 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.newsdetail.NewsDetailActivity"
android:name="com.gh.gamecenter.NewsDetailActivity"
android:screenOrientation="portrait" />
<activity
@ -259,7 +271,7 @@
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.gh.gamecenter.libao.LibaoDetailActivity"
android:name="com.gh.gamecenter.LibaoDetailActivity"
android:screenOrientation="portrait" />
<activity
@ -323,6 +335,14 @@
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.InfoActivity"
android:screenOrientation="portrait" />
@ -331,6 +351,10 @@
android:name=".qa.questions.invite.QuestionsInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.myqa.MyAskActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.questions.edit.QuestionEditActivity"
android:screenOrientation="portrait" />
@ -368,6 +392,10 @@
android:name="com.gh.gamecenter.qa.article.edit.ArticleEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.MyArticleActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.draft.ArticleDraftActivity"
android:screenOrientation="portrait" />
@ -406,6 +434,10 @@
android:name="com.gh.gamecenter.history.HistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.personalhome.rating.RatingActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity"
android:screenOrientation="portrait" />
@ -478,6 +510,9 @@
android:name=".gamedetail.fuli.kaifu.ServersSubscribedGameListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.answer.draft.AnswerDraftActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.rating.RatingFoldActivity"
android:screenOrientation="portrait" />
@ -489,6 +524,10 @@
android:name=".video.poster.PosterEditActivity"
android:screenOrientation="portrait" />
<activity
android:name=".video.poster.PosterClipActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.detail.ForumDetailActivity"
android:screenOrientation="portrait" />
@ -594,10 +633,6 @@
android:name=".game.commoncollection.detail.CommonCollectionDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name=".game.commoncollection.detail.CustomCommonCollectionDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamecollection.detail.GameCollectionDetailActivity"
android:screenOrientation="portrait" />
@ -689,7 +724,7 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.toolbox.ToolBoxActivity"
android:name="com.gh.gamecenter.toolbox.ToolBoxBlockActivity"
android:screenOrientation="portrait" />
<activity
@ -762,16 +797,6 @@
android:name="com.gh.gamecenter.UserAuthActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.SplashAdActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.wrapper.ToolbarWrapperActivity"
android:screenOrientation="portrait" />
<activity android:name=".forum.home.CommunityActivity"
android:screenOrientation="portrait"/>
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
@ -783,7 +808,8 @@
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
@ -827,7 +853,7 @@
<!-- tools:node="remove" />-->
<!-- </provider>-->
<service android:name="com.gh.gamecenter.install.InstallService" />
<service android:name = "com.gh.gamecenter.install.InstallService" />
<receiver
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
@ -846,8 +872,8 @@
<activity
android:name="com.gh.common.xapk.XapkInstallReceiver"
android:exported="false"
android:theme="@style/Theme.Transparent" />
android:theme="@style/Theme.Transparent"
android:exported="false" />
<receiver
android:name="com.gh.gamecenter.receiver.ActivitySkipReceiver"
@ -856,6 +882,7 @@
<action android:name="com.gh.gamecenter.ACTIVITYSKIP" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -6,6 +6,8 @@
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="video-js.min.css">
<!-- <link rel="stylesheet" href="https://static-web.ghzs.com/website-static/lib/video-js.min.css">--> <!--在web页面播放视频-->
<!--<link rel="stylesheet" type="text/css" href="https://resource.ghzs.com/css/halo_app.css">-->
</head>
<body style="overflow-x: hidden; word-break: break-all;">
@ -13,5 +15,8 @@
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="rich_editor.js"></script>
<script type="text/javascript" src="video.min.js"></script>
<!--<script src="https://static-web.ghzs.com/website-static/lib/video.min.js"></script>--> <!--在web页面播放视频-->
<!--<script type="text/javascript" src="content.js"></script>-->
<!--<script type="text/javascript" src="https://resource.ghzs.com/js/halo_app.js"></script>-->
</body>
</html>

View File

@ -1 +0,0 @@
{"v":"5.12.2","fr":60,"ip":0,"op":40,"w":66,"h":66,"nm":"icon_tab_my","ddd":0,"assets":[{"id":"comp_0","nm":"icon","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"highlight","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33.134,34.5,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":1,"k":[{"i":{"x":0.667,"y":0.733},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,-0.004],[0.493,0],[0,0.004],[-0.493,0]],"o":[[0,0.004],[-0.493,0],[0,-0.004],[0.493,0]],"v":[[0.893,1.488],[0,1.496],[-0.893,1.488],[0,1.483]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0.267},"t":10,"s":[{"i":[[0,-1.018],[1.793,0],[0,1.018],[-1.793,0]],"o":[[0,1.018],[-1.793,0],[0,-1.018],[1.793,0]],"v":[[2.914,-0.344],[0,1.5],[-2.914,-0.344],[0,-1.5]],"c":true}]},{"i":{"x":0.333,"y":1},"o":{"x":0.667,"y":0},"t":18,"s":[{"i":[[0,-1.181],[1.407,0],[0,1.181],[-1.407,0]],"o":[[0,1.181],[-1.407,0],[0,-1.181],[1.407,0]],"v":[[2.226,-0.341],[0,1.74],[-2.211,-0.341],[0,-1.74]],"c":true}]},{"i":{"x":0.333,"y":1},"o":{"x":0.667,"y":0},"t":26,"s":[{"i":[[0,-0.905],[1.381,0],[0,0.905],[-1.381,0]],"o":[[0,0.905],[-1.381,0],[0,-0.905],[1.381,0]],"v":[[2.5,-0.306],[0,1.333],[-2.5,-0.306],[0,-1.333]],"c":true}]},{"t":32,"s":[{"i":[[0,-1.018],[1.381,0],[0,1.018],[-1.381,0]],"o":[[0,1.018],[-1.381,0],[0,-1.018],[1.381,0]],"v":[[2.5,-0.344],[0,1.5],[-2.5,-0.344],[0,-1.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"color","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":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"body","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,34.204,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":[[-3.866,0],[0,3.866],[3.866,0],[0,-3.866]],"o":[[3.866,0],[0,-3.866],[-3.866,0],[0,3.866]],"v":[[0,4.599],[7,-2.401],[0,-9.401],[-7,-2.401]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.207,0.359],[2.438,0],[1.189,-2.104],[-0.361,-0.204],[-0.204,0.361],[-1.915,0],[-0.932,-1.613],[-0.359,0.207]],"o":[[-1.198,-2.072],[-2.462,0],[-0.204,0.361],[0.361,0.204],[0.925,-1.638],[1.897,0],[0.207,0.359],[0.359,-0.207]],"v":[[5.848,8.225],[0,4.849],[-5.88,8.282],[-5.596,9.304],[-4.574,9.02],[0,6.349],[4.549,8.976],[5.574,9.25]],"c":true},"ix":2},"nm":"路径 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"合并路径 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.267,0.639,1,0.5,0.241,0.596,1,1,0.216,0.553,1],"ix":9}},"s":{"a":0,"k":[-3.812,-4.384],"ix":5},"e":{"a":0,"k":[6.345,8.129],"ix":6},"t":1,"nm":"color","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":"Union","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"icon","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2,"l":2},"a":{"a":0,"k":[33,33,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":8,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":18,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":26,"s":[90,90,100]},{"t":32,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"w":66,"h":66,"ip":0,"op":60,"st":0,"bm":0}],"markers":[],"props":{}}

View File

@ -34,18 +34,18 @@ try {
var script = document.createElement("script")
document.body.appendChild(script)
if (isDebug) {
script.src = "https://dev-and-static.ghzs66.com/web/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
script.src = "https://resource.ghzs.com/js/halo_app_test.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
script.src = "https://and-static.ghzs66.com/web/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
script.src = "https://resource.ghzs.com/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
var style = document.createElement("link")
style.rel = "stylesheet"
style.type = "text/css"
if (isDebug) {
style.href = "https://dev-and-static.ghzs66.com/web/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
style.href = "https://resource.ghzs.com/css/halo_app_test.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
style.href = "https://and-static.ghzs66.com/web/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
style.href = "https://resource.ghzs.com/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
document.head.appendChild(style)

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.os.Message
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
@ -18,7 +17,6 @@ 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.common.util.PackageUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
@ -55,7 +53,7 @@ object AdDelegateHelper {
private var mCsjAdImpl: ICsjAdProvider? = null
private var mBeiziAdImpl: IBeiziAdProvider? = null
private val mAdConfigList: ArrayList<AdConfig> by lazy { arrayListOf() }
private var mAdConfigList: ArrayList<AdConfig>? = null
private var mSplashAd: AdConfig? = null
private var mDownloadManagerAd: AdConfig? = null
@ -68,7 +66,6 @@ object AdDelegateHelper {
private const val AD_SDK_CSJ = "穿山甲"
private const val AD_SDK_BEIZI = "倍孜"
const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
const val AD_TYPE_OWNER = "owner_ads" // 自有广告
private const val KEY_CACHE_CONFIG = "cache_config" // 放在 SP 里的广告缓存(避免接口加载问题)
@ -76,7 +73,6 @@ object AdDelegateHelper {
HaloApp.getInstance().getSharedPreferences("AdConfig", Context.MODE_PRIVATE)
}
var isShowingSplashAd = false // 是否正在显示开屏广告
var gameSearchKeyword = ""
fun initAdSdk(context: Context) {
@ -107,7 +103,7 @@ object AdDelegateHelper {
@SuppressLint("CheckResult")
fun requestAdConfig(isFromRetry: Boolean, keyword: String = "", callback: (() -> Unit)? = null) {
// mAdConfigList 不为空不需要重试
if (isFromRetry && mAdConfigList.isNotEmpty()) {
if (isFromRetry && mAdConfigList != null) {
return
}
val paramsMap = if (keyword.isNotEmpty()) mapOf("keyword" to keyword) else mapOf()
@ -130,7 +126,7 @@ object AdDelegateHelper {
// 若接口请求失败时,从 SP 里获取上次缓存的数据
val cachedConfig: List<AdConfig>? = SPUtils.getString(mAdConfigSp, KEY_CACHE_CONFIG).toObject()
if (cachedConfig != null && mAdConfigList.isEmpty()) {
if (cachedConfig != null) {
handleAdConfig(cachedConfig)
}
@ -157,13 +153,11 @@ object AdDelegateHelper {
* 处理广告配置
*/
fun handleAdConfig(configList: List<AdConfig>) {
mAdConfigList.clear()
mGameSearchAdList.clear()
mSplashAd = null
mDownloadManagerAd = null
mVGameLaunchAd = null
for (config in configList) {
mAdConfigList.add(config)
// 处理返回的数据
when (config.location) {
"halo_launch" -> {
@ -180,100 +174,9 @@ object AdDelegateHelper {
/**
* 是否需要显示开屏广告
* @param isHotLaunch 是否为热启动
*/
fun shouldShowStartUpAd(isHotLaunch: Boolean): Boolean {
fun shouldShowStartUpAd(): Boolean {
return mSplashAd != null
&& !isShowingSplashAd
&& (!isHotLaunch || shouldShowStartUpAdWhenHotLaunch())
&& !isMatchAdFreeRule(mSplashAd)
&& isMatchStartUpAdDisplayRule()
}
/**
* 热启动是否需要显示开屏广告
*/
private fun shouldShowStartUpAdWhenHotLaunch() =
mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK && mSplashAd?.hotStartThirdPartyAd != null
/**
* 是否需要显示下载管理广告
*/
fun shouldShowDownloadManagerAd(): Boolean {
return mDownloadManagerAd != null && !isMatchAdFreeRule(mDownloadManagerAd) && isMatchDownloadManagerAdDisplayRule()
}
/**
* 是否需要显示游戏搜索广告
*/
fun shouldShowGameSearchAd(adConfig: AdConfig): Boolean {
return !isMatchAdFreeRule(adConfig) && isMatchGameSearchAdDisplayRule(adConfig)
}
/**
* 是否在免广告时长内
*/
private fun isMatchAdFreeRule(adConfig: AdConfig?): Boolean {
adConfig?.displayRule?.run {
if (adFreeDuration > 0) {
val ghInstalledDurationInHours = (System.currentTimeMillis() - PackageUtils.getInstalledTime(
HaloApp.getInstance(),
BuildConfig.APPLICATION_ID
)).toFloat() / 1000 / 3600
return ghInstalledDurationInHours < adFreeDuration
} else {
return false
}
}
return false
}
/**
* 是否大于开屏广告展示间隔时长
*/
private fun isMatchStartUpAdDisplayRule(): Boolean {
mSplashAd?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
* 是否大于广告管理展示间隔时长
*/
private fun isMatchDownloadManagerAdDisplayRule(): Boolean {
mDownloadManagerAd?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
* 是否大于游戏搜索展示间隔时长
*/
private fun isMatchGameSearchAdDisplayRule(adConfig: AdConfig?): Boolean {
adConfig?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
@ -297,128 +200,55 @@ object AdDelegateHelper {
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
hideAction: () -> Unit
) {
val hideCallback = {
isShowingSplashAd = false
hideAction.invoke()
}
if (mSplashAd != null) {
when (if (isHotLaunch) mSplashAd!!.displayRule.hotStartSplashAd?.type else mSplashAd!!.displayRule.adSource) {
AD_TYPE_SDK -> {
isShowingSplashAd = true
requestThirdPartySplashAd(
activity,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
}
AD_TYPE_OWNER -> {
isShowingSplashAd = true
requestStandardSplashAd(
activity,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
}
}
} else {
hideCallback.invoke()
}
}
/**
* 获取第三方开屏广告
*/
private fun requestThirdPartySplashAd(
activity: Activity,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
hideCallback: () -> Unit
) {
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
if (isSuccess) {
hideCallback.invoke()
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
} else {
if (mSplashAd?.displayRule?.adSource == AD_TYPE_SDK && mSplashAd?.displayRule?.onFailedAction == "show" && !isHotLaunch) {
sdkStartAdContainer.visibility = View.GONE
requestStandardSplashAd(
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?.startAd,
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,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
sdkSplashCallback
)
} else {
hideCallback.invoke()
}
} else {
requestStandardSplashAd(mSplashAd!!.ownerAd?.startAd, startAdContainer, handler, hideCallback)
}
}
val thirdPartyAd = if (isHotLaunch) mSplashAd?.hotStartThirdPartyAd else mSplashAd?.thirdPartyAd
// 第三方广告的数据为空,按加载失败处理
if (mSplashAd == null || thirdPartyAd == null) {
sdkSplashCallback.invoke(false)
return
}
val timeout = if (isHotLaunch) {
((mSplashAd?.displayRule?.hotStartSplashAd?.timeout ?: 3.5F) * 1000).toInt()
} else {
((mSplashAd?.displayRule?.timeout ?: 3.5F) * 1000).toInt()
}
if (thirdPartyAd.sourceName == AD_SDK_BEIZI) {
sdkStartAdContainer.visibility = View.VISIBLE
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, timeout.toLong(), sdkSplashCallback)
} else if (thirdPartyAd.sourceName == AD_SDK_CSJ) {
sdkStartAdContainer.visibility = View.VISIBLE
requestCsjSplashAd(
activity,
thirdPartyAd.slotId,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
sdkStartAdContainer,
timeout,
sdkSplashCallback
)
}
}
/**
@ -432,7 +262,6 @@ object AdDelegateHelper {
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
timeout: Int,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mCsjAdImpl == null) {
@ -446,7 +275,6 @@ object AdDelegateHelper {
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
timeout,
callback,
)
}
@ -460,13 +288,12 @@ object AdDelegateHelper {
adsFl: FrameLayout,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
timeout: Long,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mBeiziAdImpl == null) {
callback.invoke(false)
} else {
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, timeout, callback)
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, callback)
}
}
@ -474,41 +301,13 @@ object AdDelegateHelper {
* 显示自有的开屏广告
*/
private fun requestStandardSplashAd(
activity: Activity,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
splashAd: StartupAdEntity?,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
hideCallback: () -> Unit
) {
val splashAd = mSplashAd?.ownerAd?.startAd
val onEmptyCallback = {
if (mSplashAd?.displayRule?.adSource == AD_TYPE_OWNER && mSplashAd?.displayRule?.onFailedAction == "show" && mSplashAd?.thirdPartyAd != null) {
// 自有广告为空时,显示第三方广告
requestThirdPartySplashAd(
activity,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
} else {
hideCallback.invoke()
}
}
if (splashAd == null) {
onEmptyCallback.invoke()
hideCallback.invoke()
return
}
@ -521,7 +320,7 @@ object AdDelegateHelper {
) {
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
} else {
onEmptyCallback.invoke()
hideCallback.invoke()
}
"everyday" -> {
@ -532,7 +331,7 @@ object AdDelegateHelper {
) {
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
} else {
onEmptyCallback.invoke()
hideCallback.invoke()
}
}
@ -577,17 +376,6 @@ object AdDelegateHelper {
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
}
val sources: MutableList<ExposureSource> = ArrayList()
sources.add(ExposureSource("开屏广告", ad.id))
@ -595,19 +383,7 @@ object AdDelegateHelper {
ExposureManager.log(event)
if (ad.button) {
jumpDetailBtn.setOnClickListener { v: View ->
val linkEntity = ad.jump
directToLinkPage(v.context, linkEntity, "(启动广告)", "", event)
SensorsBridge.trackEvent(
"SplashAdOwnClick",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
directToLinkPage(v.context, ad.jump, "(启动广告)", "", event)
v.postDelayed({
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
@ -618,11 +394,7 @@ object AdDelegateHelper {
} else {
LogUtils.logStartAd("start_ads", ad)
}
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
val msg = Message.obtain()
msg.what = MainActivity.COUNTDOWN_AD
msg.obj = ad
handler.sendMessageDelayed(msg, 1000)
handler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
}
/**

View File

@ -44,7 +44,7 @@ import org.json.JSONObject
import java.io.File
// TODO: 移动到module_bbs模块
abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor() : ToolBarActivity(),
abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarActivity(),
KeyboardHeightObserver, UploadVideoListener {
lateinit var mRichEditor: RichEditor
@ -233,7 +233,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
mKeyboardHeightProvider = KeyboardHeightProvider(this)
mRichEditor.post { mKeyboardHeightProvider?.start() }
mRichEditor.enableForceDark(DarkModeUtils.isDarkModeOn(this))
mRichEditor.setEditorBackgroundColor(R.color.ui_surface.toColor(this))
mRichEditor.setEditorBackgroundColor(R.color.background_white.toColor(this))
mRichEditor.setEditorFontColor(if (mIsDarkModeOn) Color.parseColor("#C2C2C2") else Color.parseColor("#4A4A4A"))
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
@ -797,9 +797,9 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
override fun onDarkModeChanged() {
super.onDarkModeChanged()
updateStatusBarColor(R.color.ui_surface, R.color.ui_surface)
updateStatusBarColor(R.color.background_white, R.color.background_white)
mRichEditor.enableForceDark(DarkModeUtils.isDarkModeOn(this))
mRichEditor.setEditorBackgroundColor(R.color.ui_surface.toColor(this))
mRichEditor.setEditorBackgroundColor(R.color.background_white.toColor(this))
mRichEditor.setEditorFontColor(if (mIsDarkModeOn) Color.parseColor("#C2C2C2") else Color.parseColor("#4A4A4A"))
}

View File

@ -12,13 +12,13 @@ import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.entity.QuoteCountEntity
@ -28,6 +28,7 @@ import com.gh.gamecenter.retrofit.service.ApiService
import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.google.gson.JsonObject
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@ -61,6 +62,7 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
val TITLE_MIN_LENGTH = 6
val MIN_TEXT_LENGTH = 6
val MAX_TEXT_LENGTH = 10000
val FILE_HOST = "file:///"
var id = ""//视频标记
var videoId = ""//更改封面视频id
val quoteCountEntity = QuoteCountEntity()//数据上报用
@ -127,13 +129,15 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
}
val map = LinkedHashMap<String, String>()
for (key in imageUrlMap.keys) {
val localFileUri = FILE_HOST + key.decodeURI()
// 文件格式为 HEIC 时,使用经 OSS 转码的图片作为预览图片
if (FileUtils.getFileMimeType(getApplication(), key.decodeURI())?.lowercase(Locale.CHINA)?.contains("heic") == true) {
val transformedImgUrl = ImageUtils.getIdealImageUrl(imageUrlMap[key], 5000) ?: ""
val transformedImgUrl = ImageUtils.getTransformedUrl(imageUrlMap[key], 5000) ?: ""
map[MD5Utils.getUrlMD5(key)] = transformedImgUrl
mapImages[transformedImgUrl.decodeURI()] = imageUrlMap[key] ?: ""
} else {
map[MD5Utils.getUrlMD5(key)] = imageUrlMap[key] ?: ""
map[MD5Utils.getUrlMD5(key)] = localFileUri
mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrlMap[key] ?: ""
}
}

View File

@ -46,7 +46,7 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
override fun inflateMenu(res: Int) {
super.inflateMenu(res)
if (!getBoolean(Constants.SP_TEENAGER_MODE) && showDownloadMenu()) {
if (showDownloadMenu()) {
createDownloadMenu(res)
}
}
@ -60,7 +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, Constants.DIN_FONT_PATH)
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, "fonts/d_din_bold_only_number.ttf")
}
override fun onMenuItemClick(item: MenuItem?): Boolean {

View File

@ -4,27 +4,22 @@ import android.app.Activity
import android.app.Application
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.ad.AdDelegateHelper
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
import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.authorization.AuthorizationActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.ui.launcher.LaunchActivity
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
private var isFromBackgroundToForeground = false // 是否后台回到前台
private var activityCount = 0
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
@ -32,19 +27,6 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity) {
GlobalActivityManager.currentActivity = activity
activityCount ++
if (activityCount == 1 && isFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isSkippingThirdParty
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
&& activity !is SplashAdActivity
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
isFromBackgroundToForeground = false
}
}
override fun onActivityResumed(activity: Activity) {
@ -76,6 +58,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
if (activity is AppCompatActivity
&& activity !is LaunchActivity
&& activity !is LoginActivity
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
@ -84,10 +68,6 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
XapkInstaller.updateCurrentInstallStatus()
// 清除桌面角标
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
override fun onActivityPaused(activity: Activity) {
@ -98,8 +78,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityStopped(activity: Activity) {
activityCount --
isFromBackgroundToForeground = activityCount <= 0
// do nothing
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

View File

@ -45,6 +45,7 @@ import com.gh.gamecenter.login.user.LoginTag
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.gh.gamecenter.login.utils.LoginHelper
import com.gh.gamecenter.login.utils.QuickLoginHelper
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
import com.gh.gamecenter.setting.SettingBridge
@ -129,12 +130,12 @@ class DefaultJsApi(
@JavascriptInterface
fun login(msg: Any) {
// if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
// QuickLoginHelper.startLogin(context, "浏览器")
// } else {
if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
QuickLoginHelper.startLogin(context, "浏览器")
} else {
val intent = LoginActivity.getIntent(context, "浏览器")
context.startActivity(intent)
// }
}
}
@JavascriptInterface
@ -219,7 +220,7 @@ class DefaultJsApi(
runOnUiThread {
// 若畅玩列表中安装了,优先启动畅玩游戏
if (VHelper.isInstalled(packageName)) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "", "", "")) {
VHelper.validateVSpaceBeforeAction(context, packageName, null) {
VHelper.launch(context, packageName)
}
} else {
@ -328,11 +329,6 @@ class DefaultJsApi(
return HaloApp.getInstance().gid
}
@JavascriptInterface
fun getOaid(msg: Any): String {
return HaloApp.getInstance().oaid
}
@JavascriptInterface
fun showIncompatibleVersionDialog(msg: Any) {
DialogHelper.showUpgradeDialog(context)

View File

@ -15,6 +15,9 @@ import com.gh.common.util.DirectUtils.directToLegacyVideoDetail
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.DirectUtils.directToQa
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.LibaoDetailActivity
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
@ -31,12 +34,12 @@ import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.ActivityLabelEntity
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
import com.gh.gamecenter.libao.LibaoDetailActivity
import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.gh.gamecenter.qa.BbsType
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.gh.gamecenter.subject.SubjectActivity
@ -48,8 +51,8 @@ import java.nio.charset.Charset
object DefaultUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String, sourceEntrance: String = ""): Boolean {
return interceptUrl(context, url, null, entrance, false, sourceEntrance)
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
return interceptUrl(context, url, null, entrance, false)
}
/**
@ -63,8 +66,7 @@ object DefaultUrlHandler {
fun interceptUrl(context: Context, url: String,
traceEvent: ExposureEvent? = null,
entrance: String,
bringAppToFront: Boolean = false,
sourceEntrance: String = ""): Boolean {
bringAppToFront: Boolean = false): Boolean {
val uri = Uri.parse(url)
if ("ghzhushou" == uri.scheme) {
Utils.log("url = $url")
@ -133,7 +135,7 @@ object DefaultUrlHandler {
}
}
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接", sourceEntrance)
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
"real_name" -> DirectUtils.directToRealName(context)
@ -176,7 +178,7 @@ object DefaultUrlHandler {
if ("articles" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接", sourceEntrance
entrance, "文章链接"
)
}
}
@ -244,22 +246,24 @@ object DefaultUrlHandler {
act,
paginationType,
fieldId,
sectionName,
sourceEntrance = sourceEntrance
sectionName
)
}
EntranceConsts.HOST_VIDEO_DETAIL -> {
DirectUtils.directToVideoDetail(context, id, entrance, path, sourceEntrance)
DirectUtils.directToVideoDetail(context, id, entrance, path)
}
EntranceConsts.HOST_VIDEO_SINGLE -> {
val referer = uri.getQueryParameter("referer") ?: ""
DirectUtils.directToVideoDetail(
context, id, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.value,
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer, sourceEntrance
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer
)
}
EntranceConsts.HOST_VIDEO_STREAMING_HOME -> {
DirectUtils.directToHomeVideoTab(context)
intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true)
context.startActivity(intent)
}
EntranceConsts.HOST_VIDEO_STREAMING_DESC -> {
directToGameDetailVideoStreaming(context, id, entrance)
@ -321,7 +325,7 @@ object DefaultUrlHandler {
val linkData = Base64.decode(dataString, Base64.DEFAULT)
val linkDataString = String(linkData, Charset.defaultCharset())
val le = gson.fromJson(linkDataString, LinkEntity::class.java)
directToLinkPage(context, le, entrance, sourceEntrance, "")
directToLinkPage(context, le, entrance, "")
}
} catch (e: Exception) {
e.printStackTrace()
@ -360,8 +364,9 @@ object DefaultUrlHandler {
}
EntranceConsts.HOST_FORUM -> {
val position = uri.getQueryParameter(EntranceConsts.KEY_POSITION)?.toInt()
DirectUtils.directToHomeCommunityTab(context)
DirectUtils.directToForum(context, position ?: 0)
}
EntranceConsts.HOST_UPLOAD_VIDEO_NEW -> {
@ -498,11 +503,13 @@ object DefaultUrlHandler {
EntranceConsts.HOST_GAME_LIBRARY -> {
DirectUtils.directToMainActivity(context)
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_GAME))
}
EntranceConsts.HOST_HOME_GAME_COLLECTION_SQUARE -> {
DirectUtils.directToMainActivity(context)
DirectUtils.directToHomeDefaultTab(context)
EventBus.getDefault()
.post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_HOME))
EventBus.getDefault().post(EBReuse(host))
}
@ -557,7 +564,7 @@ object DefaultUrlHandler {
}
// 处理内部页面逻辑
if (transformNormalScheme(context, url, entrance, sourceEntrance)) {
if (transformNormalScheme(context, url, entrance)) {
return true
}
@ -566,14 +573,14 @@ object DefaultUrlHandler {
}
@JvmStatic
fun transformNormalScheme(context: Context, url: String, entrance: String, sourceEntrance: String): Boolean {
val b = transformNewNormalScheme(context, url, entrance, sourceEntrance)
fun transformNormalScheme(context: Context, url: String, entrance: String): Boolean {
val b = transformNewNormalScheme(context, url, entrance)
if (b) return b
return transformOldNormalScheme(context, url, entrance, sourceEntrance)
return transformOldNormalScheme(context, url, entrance)
}
@JvmStatic
fun transformOldNormalScheme(context: Context, url: String, entrance: String, sourceEntrance: String): Boolean {
fun transformOldNormalScheme(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if (uri.host == "www.ghzs666.com"
|| uri.host == "www.ghzs.com"
@ -589,7 +596,6 @@ object DefaultUrlHandler {
DirectUtils.directToGameDetail(
context,
gameId,
"",
entrance,
autoDownload = false,
traceEvent = null
@ -599,7 +605,7 @@ object DefaultUrlHandler {
val questionId = split("/")[2]
val answerId = uri.getQueryParameter("answer")
if (answerId.isNullOrEmpty()) {
DirectUtils.directToQuestionDetail(context, questionId, entrance, "", sourceEntrance)
DirectUtils.directToQuestionDetail(context, questionId, entrance, "")
} else {
DirectUtils.directToAnswerDetail(context, answerId, entrance, "")
}
@ -629,7 +635,7 @@ object DefaultUrlHandler {
if ("articles" == type || "article" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接", sourceEntrance
entrance, "文章链接"
)
}
}
@ -660,7 +666,7 @@ object DefaultUrlHandler {
}
@JvmStatic
fun transformNewNormalScheme(context: Context, url: String, entrance: String, sourceEntrance: String): Boolean {
fun transformNewNormalScheme(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if (uri.host == "www.ghzs666.com"
|| uri.host == "www.ghzs.com"
@ -678,7 +684,7 @@ object DefaultUrlHandler {
val articleId = splits[2].substring(7)
DirectUtils.directToCommunityArticle(
context, articleId, "",
entrance, "文章链接", sourceEntrance
entrance, "文章链接"
)
}
//https://m.ghzs666.com/article/文章ID
@ -698,7 +704,7 @@ object DefaultUrlHandler {
//https://m.ghzs666.com/bbs/video-视频ID
splits.size >= 3 && splits[1] == "bbs" && splits[2].startsWith("video-") -> {
val videoId = splits[2].substring(6)
DirectUtils.directToVideoDetail(context, videoId, entrance, sourceEntrance)
DirectUtils.directToVideoDetail(context, videoId, entrance)
}
else -> return false
}

View File

@ -2,16 +2,17 @@ package com.gh.common
import com.gh.common.exposure.ExposureManager
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.AdHelper
import com.gh.common.videolog.VideoRecordUtils
import com.gh.download.DownloadDataHelper
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.doOnMainProcessOnly
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.entity.TimeEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import kotlin.concurrent.fixedRateTimer
@ -25,6 +26,7 @@ object FixedRateJobHelper {
private const val DOWNLOAD_HEARTBEAT_PERIOD: Long = 60 * 1000L
private const val DOWNLOAD_HEARTBEAT_SHEET_PERIOD: Long = 15 * 1000L
private const val STARTUP_AD: Long = 30 * 60 * 1000L
private var mExecuteCount: Int = 0
@ -32,56 +34,58 @@ object FixedRateJobHelper {
@JvmStatic
fun begin() {
// 时间检查每15秒检查一次
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
val elapsedTime = mExecuteCount * CHECKER_PERIOD
// 时间校对10分钟一次
if (elapsedTime % TIME_PERIOD == 0L) {
RetrofitManager.getInstance().api.time
.subscribeOn(Schedulers.io())
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let {
timeDeltaBetweenServerAndClient = it * 1000 - System.currentTimeMillis()
doOnMainProcessOnly {
// 时间检查每15秒检查一次
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
val elapsedTime = mExecuteCount * CHECKER_PERIOD
// 时间校对10分钟一次
if (elapsedTime % TIME_PERIOD == 0L) {
RetrofitManager.getInstance().api.time
.subscribeOn(Schedulers.io())
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let {
timeDeltaBetweenServerAndClient = it * 1000 - System.currentTimeMillis()
}
}
}
})
}
// 提交曝光数据
if (elapsedTime % EXPOSURE_PERIOD == 0L) {
ExposureManager.commitSavedExposureEvents(true)
}
// 分片检测下载进度
if (elapsedTime % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
tryCatchInRelease {
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
DownloadDataHelper.uploadDownloadHeartbeat(upload)
})
}
}
// 提交普通 loghub 数据
if (elapsedTime % LOGHUB_PERIOD == 0L) {
runOnUiThread {
LoghubUtils.commitSavedLoghubEvents(true)
// 提交曝光数据
if (elapsedTime % EXPOSURE_PERIOD == 0L) {
ExposureManager.commitSavedExposureEvents(true)
}
}
// 更新游戏屏蔽信息
if (elapsedTime % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
// 分片检测下载进度
if (elapsedTime % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
tryCatchInRelease {
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
DownloadDataHelper.uploadDownloadHeartbeat(upload)
}
}
}
// 提交视频浏览记录数据
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
// 提交普通 loghub 数据
if (elapsedTime % LOGHUB_PERIOD == 0L) {
runOnUiThread {
LoghubUtils.commitSavedLoghubEvents(true)
}
}
mExecuteCount++
// 更新游戏屏蔽信息
if (elapsedTime % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
}
}
// 提交视频浏览记录数据
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
mExecuteCount++
}
}
}
}

View File

@ -1,351 +0,0 @@
package com.gh.common.browse
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.lifecycle.*
import androidx.lifecycle.Lifecycle.Event
/**
* 浏览时长计时器核心接口类,用于页面浏览时长相关埋点上报
*/
interface IBrowseTimerCore {
/**
* 开始计时
*/
fun start()
/**
* 结束计时
*/
fun stop()
}
/**
* 浏览时长计时器核心实现类
*/
class BrowseTimerCore internal constructor() : IBrowseTimerCore {
/**
* 延迟执行的时间
*/
var delayInMills: Long = 3000L
/**
* 开始计时函数回调
*/
var onStart: (() -> Unit)? = null
/**
* 结束计时函数回调
*/
var onResult: ((Long) -> Unit)? = null
/**
* 开始计时的时间点
*/
private var startTimeInMills: Long = 0L
/**
* Handler操作类
*/
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
if (msg.what == MESSAGE_START) {
dispatchOnStart()
}
}
}
/**
* 延迟执行开始计时
* @see delayInMills
* @see onStart
*/
override fun start() {
if (delayInMills <= 0) {
dispatchOnStart()
} else {
handler.sendEmptyMessageDelayed(MESSAGE_START, delayInMills)
}
}
/**
* 结束计时,统计浏览时长并回调结束计时函数
* @see onResult
*/
override fun stop() {
handler.removeMessages(MESSAGE_START)
if (startTimeInMills > 0L) {
onResult?.invoke(System.currentTimeMillis() - startTimeInMills)
startTimeInMills = 0L
}
}
/**
* 开始计时,回调开始计时函数
*/
private fun dispatchOnStart() {
startTimeInMills = System.currentTimeMillis()
onStart?.invoke()
}
companion object {
private const val MESSAGE_START = 1
}
}
/**
* 无数据浏览计时器接口类
*/
interface IBrowseTimer : IBrowseTimerCore {
fun withDelayInMills(delayInMills: Long): IBrowseTimer
fun withStart(onStart: () -> Unit): IBrowseTimer
fun withResult(onResult: (Long) -> Unit): IBrowseTimer
}
/**
* 无数据的浏览计时器实现类
*/
class BrowseTimer : IBrowseTimer {
private val core = BrowseTimerCore()
private var isStarted: Boolean = false
override fun withDelayInMills(delayInMills: Long): IBrowseTimer {
core.delayInMills = delayInMills
return this
}
override fun withStart(onStart: () -> Unit): IBrowseTimer {
core.onStart = onStart
return this
}
override fun withResult(onResult: (Long) -> Unit): IBrowseTimer {
core.onResult = onResult
return this
}
override fun start() {
if (isStarted) return
isStarted = true
core.start()
}
override fun stop() {
if (!isStarted) return
core.stop()
isStarted = false
}
}
/**
* 支持Lifecycle的无数据的浏览计时器
*/
class LifecycleBoundBrowseTimer internal constructor(
private val base: IBrowseTimer,
private val onStateChanged: (IBrowseTimer, Event) -> Unit
) : IBrowseTimer, LifecycleEventObserver {
override fun withDelayInMills(delayInMills: Long): IBrowseTimer {
return base.withDelayInMills(delayInMills)
}
override fun withStart(onStart: () -> Unit): IBrowseTimer {
return base.withStart(onStart)
}
override fun withResult(onResult: (Long) -> Unit): IBrowseTimer {
return base.withResult(onResult)
}
override fun start() {
base.start()
}
override fun stop() {
base.stop()
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
onStateChanged.invoke(this, event)
}
}
fun IBrowseTimer.withLifecycle(
owner: LifecycleOwner,
onStateChanged: (IBrowseTimer, Event) -> Unit = { timer, event ->
when(event) {
Event.ON_START -> timer.start()
Event.ON_STOP -> timer.stop()
else -> {}
}
}
): LifecycleBoundBrowseTimer = LifecycleBoundBrowseTimer(this, onStateChanged).apply {
owner.lifecycle.addObserver(this)
}
/**
* 带数据的浏览计时器接口类
*/
interface IValueBrowseTimer<T> : IBrowseTimerCore {
fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T>
fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T>
fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T>
fun dispatchValue(value: T?)
}
/**
* 带数据的浏览计时器实现类
*/
class ValueBrowseTimer<T> : IValueBrowseTimer<T> {
private val core = BrowseTimerCore()
private var isDispatchValue: Boolean = false
private var isStarted: Boolean = false
private var value: T? = null
override fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T> {
core.delayInMills = delayInMills
return this
}
override fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T> {
core.onStart = { onStart.invoke(value) }
return this
}
override fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T> {
core.onResult = { onResult.invoke(value, it) }
return this
}
override fun start() {
if (isStarted) return
isStarted = true
if (isDispatchValue) {
core.start()
}
}
override fun stop() {
if (!isStarted) return
core.stop()
isStarted = false
}
override fun dispatchValue(value: T?) {
this.value = value
if (isStarted && !isDispatchValue) {
core.start()
}
isDispatchValue = true
}
}
/**
* 支持LiveData的带数据的浏览计时器
*/
class ObserverBoundValueBrowseTimer<T> internal constructor(private val base: IValueBrowseTimer<T>) : IValueBrowseTimer<T>, Observer<T> {
override fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T> {
return base.withDelayInMills(delayInMills)
}
override fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T> {
return base.withResult(onResult)
}
override fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T> {
return base.withStart(onStart)
}
override fun start() {
base.start()
}
override fun stop() {
base.stop()
}
override fun dispatchValue(value: T?) {
base.dispatchValue(value)
}
override fun onChanged(t: T) {
dispatchValue(t)
}
}
/**
* 支持Lifecycle的带数据的浏览计时器
*/
class LifecycleBoundValueBrowseTimer<T> internal constructor(
private val base: IValueBrowseTimer<T>,
private val onStateChanged: (IValueBrowseTimer<T>, Event) -> Unit
) : IValueBrowseTimer<T>, LifecycleEventObserver {
override fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T> {
return base.withDelayInMills(delayInMills)
}
override fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T> {
return base.withResult(onResult)
}
override fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T> {
return base.withStart(onStart)
}
override fun start() {
base.start()
}
override fun stop() {
base.stop()
}
override fun dispatchValue(value: T?) {
base.dispatchValue(value)
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
onStateChanged.invoke(this, event)
}
}
fun <T> IValueBrowseTimer<T>.asObserver(): ObserverBoundValueBrowseTimer<T> = ObserverBoundValueBrowseTimer(this)
fun <T> IValueBrowseTimer<T>.withLifecycle(
owner: LifecycleOwner,
onStateChanged: (IValueBrowseTimer<T>, Event) -> Unit = { timer, event ->
when(event) {
Event.ON_START -> timer.start()
Event.ON_STOP -> timer.stop()
else -> {}
}
}
): LifecycleBoundValueBrowseTimer<T> = LifecycleBoundValueBrowseTimer(this, onStateChanged).apply {
owner.lifecycle.addObserver(this)
}

View File

@ -0,0 +1,18 @@
package com.gh.common.chain
import android.content.Context
import com.gh.common.dialog.CertificationDialog
import com.gh.gamecenter.feature.entity.GameEntity
class CertificationHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
}
}
}

View File

@ -1,33 +1,16 @@
package com.gh.common.chain
import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.TempCertificationUtils
import com.gh.gamecenter.feature.entity.GameEntity
class LandPageAddressHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
if (gameEntity.isLandPageAddressDialog()) {
TempCertificationUtils.checkCertificationBeforeAction(gameEntity) {
if (context is Activity && context.isFinishing) {
// 当前 context 已经无效,不需要再传递执行下去了
return@checkCertificationBeforeAction
}
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
if (gameEntity.isLandPageAddressDialogShowOnly()) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
} else {
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
}
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
} else {
if (hasNext()) {

View File

@ -1,27 +1,18 @@
package com.gh.common.chain
import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.TempCertificationUtils
import com.gh.gamecenter.feature.entity.GameEntity
class OverseaDownloadHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
if (gameEntity.isOverseaAddressDialog()) {
TempCertificationUtils.checkCertificationBeforeAction(gameEntity) {
if (context is Activity && context.isFinishing) {
// 当前 context 已经无效,不需要再传递执行下去了
return@checkCertificationBeforeAction
}
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {// 跳转海外下载地址弹窗
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {// 跳转海外下载地址弹窗
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
}
} else {

View File

@ -16,7 +16,7 @@ class ValidateVSpaceHandler : DownloadChainHandler() {
}
if (asVGame) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
closure.invoke()
}
} else {

View File

@ -21,26 +21,35 @@ import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.AppEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
import com.gh.gamecenter.entity.VNewSetting;
import com.gh.gamecenter.entity.VSetting;
import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.utils.ContentBlockedHelper;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.retrofit.service.VApiService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;
import okhttp3.ResponseBody;
public class Config {
@ -57,7 +66,8 @@ public class Config {
public static final String WEIBO_APPKEY = BuildConfig.WEIBO_APPKEY;
public static final String QUICK_LOGIN_APPID = BuildConfig.QUICK_LOGIN_APPID;
public static final String QUICK_LOGIN_APPKEY = BuildConfig.QUICK_LOGIN_APPKEY;
public static final String URL_ARTICLE = "www.ghzs666.com/article/"; // ghzs/ghzs666 统一
// http://www.ghzs666.com/article/${articleId}.html
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
private static final String SETTINGS_KEY = "settingsKey";
@ -68,13 +78,58 @@ public class Config {
private static NewApiSettingsEntity.NightMode mNightModeSetting;
private static SimulatorEntity mNewSimulatorEntity;
private static VSetting mVSetting;
private static VNewSetting mVNewSetting;
private static AppEntity mNew32UpdateEntity;
public static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
private static GameGuidePopupEntity mGameGuidePopupEntity;
private static SharedPreferences mDefaultSharedPreferences;
public static final String FIX_DOWNLOAD_KEY = "isFixDownload";
public static final String FIX_PLUGIN_KEY = "isFixPlugin";
public static final int VIDEO_PAGE_SIZE = 21; // 视频列表大多都是一行3个
public static boolean isShow() {
return !SPUtils.getBoolean(Constants.SP_TEENAGER_MODE);
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) return false;
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (!isExistDownloadFilter()) return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && "normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
}
}
}
return false;
}
public static boolean isShowDownload(String gameId) {
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if (gameId.equals(entity.getGame())) {
if ("normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
} else {
return false;
}
} else if ("all".equals(entity.getGame())) {
if ("normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
}
}
}
return false;
}
/**
@ -90,11 +145,76 @@ public class Config {
return mNewApiSettingsEntity.getInstall().getVpnRequired().getShouldShowVpnOption();
}
public static boolean isShowPlugin(String gameId) {
SharedPreferences preferences = getPreferences();
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
if (isFixPlugin) return true;
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if (gameId.equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
return true;
} else {
return false;
}
}
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
preferences.edit().putBoolean(FIX_PLUGIN_KEY, true).apply();
return true;
}
}
}
return false;
}
public static boolean isShowPlugin() {
SharedPreferences preferences = getPreferences();
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
if (isFixPlugin) return true;
if (!isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
preferences.edit().putBoolean(FIX_PLUGIN_KEY, true).apply();
return true;
}
}
}
return false;
}
private static boolean filterTime(SettingsEntity.Download.TimeEntity timeEntity) {
long end = timeEntity.getEnd();
long start = timeEntity.getStart();
long curTime = Utils.getTime(HaloApp.getInstance().getApplication());
if ((start == 0 || curTime >= start) && (end == 0 || curTime <= end)) {
return true;
}
return false;
}
public static void setSettings(SettingsEntity settingsEntity) {
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
PackageHelper.refreshList();
// 更新设置状态
mSettingsEntity.showArticleEntrance();
mSettingsEntity.showCommunityEntrance();
// 加载完设置后刷新下
PackageHelper.initList();
}
@Nullable
@ -195,6 +315,27 @@ public class Config {
return mVSetting;
}
@Nullable
public static VNewSetting getVNewSettingEntity() {
if (mVNewSetting == null) {
try {
String json = SPUtils.getString(Constants.SP_V_NEW_SETTINGS);
if (!TextUtils.isEmpty(json)) {
mVNewSetting = GsonUtils.fromJson(json, VNewSetting.class);
vNewSettingSubject.onNext(mVNewSetting);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return mVNewSetting;
}
@Nullable
public static AppEntity getNew32UpdateEntity() {
return mNew32UpdateEntity;
}
/**
* 请求网络数据,尝试刷新畅玩相关配置
*/
@ -215,11 +356,62 @@ public class Config {
});
}
@SuppressLint("CheckResult")
public static void getNewSetting() {
VApiService vApi = RetrofitManager.getInstance().getVApi();
vApi.getNewSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT).flatMap(new Function<VNewSetting, SingleSource<AppEntity>>() {
@Override
public SingleSource<AppEntity> apply(VNewSetting data) throws Exception {
mVNewSetting = data;
vNewSettingSubject.onNext(mVNewSetting);
SPUtils.setString(Constants.SP_V_NEW_SETTINGS, GsonUtils.toJson(data));
if (data.getVa() != null && data.getVa().getArch32() != null) {
String versionNameByPackageName = PackageUtils.getVersionNameByPackageName(data.getVa().getArch32().getPackageName());
return vApi.getNewPackageUpdate(
BuildConfig.VERSION_NAME,
versionNameByPackageName != null ? versionNameByPackageName : "",
HaloApp.getInstance().getChannel()
);
}
return Single.error(new IllegalStateException("VNewSetting entity is not expected"));
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<AppEntity>() {
@Override
public void onSuccess(AppEntity data) {
mNew32UpdateEntity = data;
}
});
}
@Nullable
public static GameGuidePopupEntity getGameGuidePopupEntity() {
return mGameGuidePopupEntity;
}
private static boolean isExistDownloadFilter() {
if (getSettings() == null || getSettings().getDownload() == null || getSettings().getDownload().size() == 0) {
return false;
} else {
return true;
}
}
public static void filterPluginArticle(List<NewsEntity> list) {
if (isShowPlugin() || list == null) return;
for (int i = 0; i < list.size(); i++) {
NewsEntity newsEntity = list.get(i);
String title = newsEntity.getTitle();
if (!TextUtils.isEmpty(title) && title.contains("插件")) {
list.remove(i);
i--;
}
}
}
public static SharedPreferences getPreferences() {
if (mDefaultSharedPreferences == null) {
mDefaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
@ -250,6 +442,9 @@ public class Config {
GsonUtils.toJson(response.getSuggestion()));
edit.apply();
if (!getPreferences().getBoolean(Config.FIX_DOWNLOAD_KEY, false) && Config.isShow()) {
getPreferences().edit().putBoolean(Config.FIX_DOWNLOAD_KEY, true).apply();
}
if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
EventBus.getDefault().post(new EBReuse("Refresh"));
}
@ -269,6 +464,7 @@ public class Config {
});
refreshVSettingEntity();
getNewSetting();
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
@ -326,11 +522,6 @@ public class Config {
DarkModeUtils.INSTANCE.initDarkMode();
}
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
// 刷新屏蔽字段
if (mNewApiSettingsEntity.getGameShieldContents() != null) {
ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
}
}
});
}

View File

@ -120,13 +120,13 @@ object AddKaiFuBindingAdapter {
@BindingAdapter("kaiFuTextColor", "kaiFuTextPosition")
fun kaiFuTextColor(view: EditText, dataMark: Int, position: Int) {
if (dataMark == 1 && view.id == R.id.kaifu_add_time || dataMark == 2 && view.id == R.id.kaifu_add_first_name || dataMark == 3 && view.id == R.id.kaifu_add_server_name || dataMark == 4) {
view.setTextColor(ContextCompat.getColor(view.context, R.color.secondary_red))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.secondary_red))
view.setTextColor(ContextCompat.getColor(view.context, R.color.theme_red))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.theme_red))
} else if (position == 0) {
view.setTextColor(ContextCompat.getColor(view.context, R.color.hint))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.hint))
} else {
view.setTextColor(ContextCompat.getColor(view.context, R.color.text_primary))
view.setTextColor(ContextCompat.getColor(view.context, R.color.text_title))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.hint))
}
}

View File

@ -15,6 +15,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.gh.common.chain.BrowserInstallHandler;
import com.gh.common.chain.CertificationHandler;
import com.gh.common.chain.DownloadChainBuilder;
import com.gh.common.chain.DownloadChainHandler;
import com.gh.common.chain.CheckDownloadHandler;
@ -52,8 +53,6 @@ import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.MtaHelper;
@ -71,14 +70,13 @@ import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import kotlin.collections.CollectionsKt;
/**
* Created by khy on 12/02/18.
*/
@ -98,29 +96,20 @@ public class BindingAdapters {
}
}
public static void setDownloadButton(DownloadButton progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
@Nullable View.OnClickListener clickCallBack,
@Nullable String entrance,
@Nullable String location) {
setDownloadButton(progressBar, gameEntity, traceEvent, clickCallBack, entrance, location, "其他");
}
// 大图下的进度条
public static void setDownloadButton(DownloadButton progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
@Nullable View.OnClickListener clickCallBack,
@Nullable String entrance,
@Nullable String location,
String sourceEntrance) {
@Nullable String location) {
// 恢复DialogFragment
restoreDialogFragment(progressBar);
// 判断是否显示按钮
if (gameEntity != null
&& Config.isShowDownload(gameEntity.getId())
&& !"光环助手".equals(gameEntity.getName())) {
progressBar.setVisibility(View.VISIBLE);
} else {
@ -135,7 +124,7 @@ public class BindingAdapters {
case DOWNLOADING_PLUGIN:
case DOWNLOADING_NORMAL:
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl(), entrance);
gameEntity.getApk().get(0).getUrl(), entrance);
v.getContext().startActivity(intent);
break;
case NONE:
@ -167,6 +156,7 @@ public class BindingAdapters {
builder.addHandler(new BrowserInstallHandler());
builder.addHandler(new PackageCheckHandler());
builder.addHandler(new DownloadDialogHelperHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
builder.addHandler(new LandPageAddressHandler());
builder.addHandler(new OverseaDownloadHandler());
@ -195,6 +185,7 @@ public class BindingAdapters {
DownloadChainBuilder builder = new DownloadChainBuilder();
builder.addHandler(new UnsupportedFeatureHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
@ -221,7 +212,7 @@ public class BindingAdapters {
if (gameEntity.getApk().size() == 1) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl());
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
@ -281,7 +272,7 @@ public class BindingAdapters {
case RESERVABLE:
GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> {
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
ReservationHelper.reserve(v.getContext(), gameEntity, sourceEntrance, () -> {
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), gameEntity.getName(), () -> {
LogUtils.logReservation(gameEntity, traceEvent);
updateReservation(progressBar, gameEntity);
});
@ -459,9 +450,9 @@ public class BindingAdapters {
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
}
String buttonText = progressBar.getText();
ApkEntity apkEntity = CollectionsKt.firstOrNull(gameEntity.getApk());
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity == null ? "" : apkEntity.getSize());
if (apkEntity != null && TextUtils.isEmpty(msg)) {
ApkEntity apkEntity = gameEntity.getApk().get(0);
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(progressBar.getContext(),
apkEntity,
gameEntity,
@ -549,10 +540,11 @@ public class BindingAdapters {
}
}
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform) {
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
String gameName;
if (isShowPlatform && game.getApk().size() > 0) {
gameName = String.format("%s - %s", game.getName(),
gameName = String.format("%s - %s", !isShowSuffix ? game.getNameWithoutSuffix() : game.getName(),
PlatformUtils.getInstance(view.getContext()).getPlatformName(
game.getApk().get(0).getPlatform()));
if (!gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
@ -560,7 +552,7 @@ public class BindingAdapters {
view.setTag(R.string.tag_game_name_id, gameName);
}
} else {
gameName = game.getName();
gameName = !isShowSuffix ? game.getNameWithoutSuffix() : game.getName();
if (gameName != null && !gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
view.setText(gameName);
view.setTag(R.string.tag_game_name_id, gameName);

View File

@ -49,7 +49,7 @@ class ApplyModeratorDialogFragment : BaseDialogFragment() {
requireContext(),
startText.length,
startText.length + mGroupNumber.length,
R.color.text_theme,
R.color.theme_font,
true
) {
DirectUtils.directToQqGroup(

View File

@ -0,0 +1,221 @@
package com.gh.common.dialog
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.CheckBox
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
import com.gh.gamecenter.common.avoidcallback.Callback
import com.gh.gamecenter.common.constant.Constants
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.AuthDialogEntity
import com.gh.gamecenter.feature.entity.AuthDialogLevel
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.login.user.UserManager
import com.google.gson.reflect.TypeToken
import com.halo.assistant.fragment.user.UserInfoEditFragment
import com.lightgame.utils.AppManager
class CertificationDialog(
context: Context,
private val authDialogEntity: AuthDialogEntity,
val gameEntity: GameEntity,
val listener: ConfirmListener
) :
Dialog(context, R.style.GhAlertDialog) {
private lateinit var view: View
private lateinit var detailedDesTv: TextView
private lateinit var noRemindAgainCb: CheckBox
private lateinit var actionLeftTv: TextView
private lateinit var actionRightTv: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
view = LayoutInflater.from(context).inflate(R.layout.dialog_sertification, null)
setContentView(view)
detailedDesTv = view.findViewById(R.id.detailedDesTv)
noRemindAgainCb = view.findViewById(R.id.noRemindAgainCb)
actionLeftTv = view.findViewById(R.id.actionLeftTv)
actionRightTv = view.findViewById(R.id.actionRightTv)
detailedDesTv.paint.flags = Paint.UNDERLINE_TEXT_FLAG
detailedDesTv.paint.isAntiAlias = true
detailedDesTv.setOnClickListener {
DirectUtils.directToWebView(context, authDialogEntity.link)
}
when (authDialogEntity.level) {
AuthDialogLevel.MUST_PASS.value -> {
actionLeftTv.text = "暂不下载"
actionRightTv.text = "去实名认证"
noRemindAgainCb.visibility = View.GONE
actionLeftTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
dismiss()
}
actionRightTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
if (UserManager.getInstance().isLoggedIn) {
gotoAuthPage()
} else {
gotoLoginPage()
}
}
}
AuthDialogLevel.ALWAYS_HINT.value -> {
actionLeftTv.text = "去实名认证"
actionRightTv.text = "继续下载"
noRemindAgainCb.visibility = View.GONE
actionLeftTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
if (UserManager.getInstance().isLoggedIn) {
gotoAuthPage()
} else {
gotoLoginPage()
}
}
actionRightTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
listener.onConfirm()
dismiss()
}
}
AuthDialogLevel.OPTIONAL_HINT.value -> {
actionLeftTv.text = "去实名认证"
actionRightTv.text = "继续下载"
noRemindAgainCb.visibility = View.VISIBLE
actionLeftTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
if (noRemindAgainCb.isChecked) {
SPUtils.setBoolean(gameEntity.id, true)
}
if (UserManager.getInstance().isLoggedIn) {
gotoAuthPage()
} else {
gotoLoginPage()
}
}
actionRightTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
if (noRemindAgainCb.isChecked) {
SPUtils.getBoolean(gameEntity.id, true)
}
listener.onConfirm()
dismiss()
}
}
}
SensorsBridge.trackEvent(
"VerificationDialogShow",
"game_id",
gameEntity.id,
"game_name",
gameEntity.name ?: "",
"game_type",
gameEntity.categoryChinese
)
}
//跳转登录页面
private fun gotoLoginPage() {
val currentActivity = AppManager.getInstance().currentActivity() ?: return
CheckLoginUtils.checkLogin(
currentActivity as AppCompatActivity,
null, true, "实名认证弹窗"
) {
if (UserManager.getInstance().isAuth) {
listener.onConfirm()
dismiss()
}
}
}
//跳转实名认证页面
private fun gotoAuthPage() {
val currentActivity = AppManager.getInstance().currentActivity() ?: return
AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity)
.startForResult(
ShellActivity.getIntent(
context,
ShellActivity.Type.REAL_NAME_INFO,
).apply {
putExtra(EntranceConsts.KEY_GAME_ID, gameEntity.id)
}, object : Callback {
override fun onActivityResult(resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && data != null) {
val isAuthSuccess =
data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
if (isAuthSuccess) {
listener.onConfirm()
dismiss()
}
}
}
})
}
companion object {
@JvmStatic
fun showCertificationDialog(context: Context, game: GameEntity, listener: ConfirmListener) {
//1.先判断是否登录 是执行2 否执行3
//2.判断是否实名认证 是终止 否执行3
//3.判断是否需要弹出认证弹窗接口
if (UserManager.getInstance().isLoggedIn) {
if (UserManager.getInstance().isAuth) {//已实名认证
listener.onConfirm()
} else {
authDialog(context, game, listener)
}
} else {
authDialog(context, game, listener)
}
}
@SuppressLint("CheckResult")
private fun authDialog(context: Context, game: GameEntity, listener: ConfirmListener) {
var authDialog: AuthDialogEntity? = null
if (game.authDialog != null) {
authDialog = game.authDialog
}
if (authDialog == null) {
val datas = SPUtils.getString(Constants.SP_AUTH_DIALOG)
val type = object : TypeToken<List<AuthDialogEntity>>() {}.type
val authDialogs = GsonUtils.gson.fromJson<List<AuthDialogEntity>>(datas, type)
if (!authDialogs.isNullOrEmpty()) {
authDialog = authDialogs.find { it.gameCategory == game.category }
}
}
val isCloseAuthDialog = SPUtils.getBoolean(game.id, false)
if (authDialog != null && (authDialog.level != AuthDialogLevel.OPTIONAL_HINT.value || !isCloseAuthDialog)) {
val dialog = CertificationDialog(context, authDialog, game, listener)
dialog.show()
} else {
listener.onConfirm()
}
}
}
}

View File

@ -23,7 +23,6 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
private var mDialog: GameEntity.Dialog? = null
private var mBinding: DialogGameOffServiceBinding? = null
private var mCallback: (() -> Unit)? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -45,7 +44,6 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
titleTv.text = title
contentTv.text = HtmlCompat.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY)
okTv.setOnClickListener {
mCallback?.invoke()
dismissAllowingStateLoss()
}
@ -62,10 +60,11 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
if (index == notEmptySite.size - 1) bottomMargin = 8F.dip2px()
}
siteTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14F)
siteTv.setTextColor(R.color.text_theme.toColor(requireContext()))
siteTv.setTextColor(R.color.theme_font.toColor(requireContext()))
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
dismissAllowingStateLoss()
}
@ -84,13 +83,11 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
const val KEY_DIALOG = "dialog"
@JvmStatic
fun getInstance(dialog: GameEntity.Dialog, callback: (() -> Unit)? = null) =
GameOffServiceDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_DIALOG, dialog)
}
mCallback = callback
fun getInstance(dialog: GameEntity.Dialog) = GameOffServiceDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_DIALOG, dialog)
}
}
}
}

View File

@ -1,68 +0,0 @@
package com.gh.common.dialog
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding
import com.lightgame.dialog.BaseDialogFragment
@RequiresApi(Build.VERSION_CODES.R)
class ManagerAllFilesPermissionDialogFragment : BaseDialogFragment() {
private val mBinding by lazy { DialogAlertDefaultBinding.inflate(layoutInflater) }
private var mCallBack: (() -> Unit)? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mBinding.run {
titleTv.text = "请求权限"
titleTv.gravity = Gravity.CENTER
contentTv.text = "需要所有文件访问权限,请打开权限设置页面"
confirmTv.setOnClickListener {
val intent = Intent().apply {
action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
data = Uri.fromParts("package", requireContext().packageName, null)
}
requireActivity().startActivityForResult(intent, REQUEST_CODE)
}
cancelTv.setOnClickListener {
dismissAllowingStateLoss()
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE && Environment.isExternalStorageManager()) {
mCallBack?.invoke()
dismissAllowingStateLoss()
}
}
companion object {
const val REQUEST_CODE = 1000
@JvmStatic
fun show(activity: AppCompatActivity, callback: () -> Unit) {
ManagerAllFilesPermissionDialogFragment().apply {
mCallBack = callback
}.show(
activity.supportFragmentManager,
ManagerAllFilesPermissionDialogFragment::class.java.name
)
}
}
}

View File

@ -76,7 +76,7 @@ class NewPrivacyPolicyDialogFragment : BaseDialogFragment() {
contentText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}

View File

@ -19,7 +19,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
@ -60,7 +59,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private val mDuration = 3000
private var mDisposable: Disposable? = null
private var mAdapter: PackageCheckAdapter? = null
private var mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
private var mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
@ -126,7 +125,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
requireContext(),
0,
(link.title ?: "").length,
R.color.text_theme,
R.color.theme_font,
true
) {
LogUtils.uploadPackageCheck(
@ -326,7 +325,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onResume() {
super.onResume()
mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
gameEntity?.packageDialog?.let {
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
callBack?.onConfirm()
@ -364,7 +363,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if (busFour.isInstalledOrUninstalled()) {
mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
mAdapter?.notifyDataSetChanged()
}
}
@ -392,10 +391,10 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
if (isAllInstalled) {
holder.binding.statusTv.text = "已安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme))
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font))
} else {
holder.binding.statusTv.text = "未安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.secondary_red))
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.theme_red))
}
holder.binding.statusTv.visibility = View.VISIBLE
} else {
@ -417,7 +416,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
return
}
val allInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
val allInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
callBack.onConfirm()
return

View File

@ -29,15 +29,6 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
private var mCallBack: ((isSuccess: Boolean) -> Unit)? = null
private val mBinding by lazy { DialogPrivacyProtocolBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
dismiss()
return
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -68,7 +59,7 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
@ -110,7 +101,7 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
@ -124,7 +115,7 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}

View File

@ -24,15 +24,6 @@ class ReserveDialog : BaseDialogFragment() {
private lateinit var mReserveList: List<SimpleGameEntity>
private var mDismissListener: (() -> Unit)? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
dismiss()
return
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding: DialogReserveBinding = DialogReserveBinding.inflate(layoutInflater, null, false)

View File

@ -27,7 +27,7 @@ object ExposureUtils {
): ExposureEvent {
val gameEntity = entity.copy()
gameEntity.id = if (entity.id.contains(DownloadEntity.GAME_ID_DIVIDER)) {
entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray().firstOrNull() ?: ""
entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray()[0]
} else {
entity.id
}

View File

@ -19,7 +19,7 @@ import com.halo.assistant.HaloApp
@Database(
entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class],
version = 14,
version = 13,
exportSchema = false
)
@TypeConverters(
@ -41,8 +41,7 @@ import com.halo.assistant.HaloApp
SimpleGameListConverter::class,
TagInfoListConverter::class,
ActivityLabelListConverter::class,
IconFloatConverter::class,
SectionConverter::class
IconFloatConverter::class
)
abstract class HistoryDatabase : RoomDatabase() {
@ -144,14 +143,6 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_13_14: Migration = object : Migration(13, 14) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE ArticleEntity add type TEXT NOT NULL DEFAULT 'community_article'")
database.execSQL("Alter TABLE ArticleEntity add sections TEXT NOT NULL DEFAULT ''")
database.execSQL("Alter TABLE ArticleEntity add tagActivityName TEXT NOT NULL DEFAULT ''")
}
}
val instance by lazy {
Room.databaseBuilder(
HaloApp.getInstance().application,
@ -169,7 +160,6 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_10_11)
.addMigrations(MIGRATION_11_12)
.addMigrations(MIGRATION_12_13)
.addMigrations(MIGRATION_13_14)
.build()
}
}

View File

@ -6,7 +6,11 @@ import com.gh.gamecenter.common.utils.removeVideoContent
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.*
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
@ -71,6 +75,7 @@ object HistoryHelper {
historyGame.iconFloat = gameEntity.iconFloat
historyGame.name = gameEntity.name
historyGame.tagStyle = gameEntity.tagStyle
historyGame.tag = gameEntity.getTag()
historyGame.subtitle = gameEntity.subtitle
historyGame.subtitleStyle = gameEntity.subtitleStyle
return historyGame
@ -104,7 +109,7 @@ object HistoryHelper {
fun deleteArticleEntity(articleId: String) {
runOnIoThread {
tryCatchInRelease {
HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(_id = articleId))
HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(id = articleId))
}
}
}
@ -165,9 +170,6 @@ object HistoryHelper {
articleEntity.images = articleDetailEntity.images
articleEntity.imagesInfo = articleDetailEntity.imagesInfo
articleEntity.videos = articleDetailEntity.videos
articleEntity.tagActivityName = articleDetailEntity.tagActivityName
articleEntity.sections = articleDetailEntity.sections ?: emptyList()
articleEntity.type = "community_article"
return articleEntity
}

View File

@ -1,10 +0,0 @@
package com.gh.common.iinterface
import com.gh.gamecenter.entity.MultiTabNav
interface IMultiTab {
fun provideMultiTabId(): String
fun provideMultiTabName(): String
fun provideCurrentTabEntity(): MultiTabNav.LinkMultiTabNav?
fun provideLastSelectedPosition(): Int
}

View File

@ -1,10 +0,0 @@
package com.gh.common.iinterface
import com.gh.gamecenter.entity.BottomTab
interface ISearchToolbarTab {
fun onScrollChanged(totalHeight: Int, offset: Int, isDarkModeChanged: Boolean)
fun changeAppBarColor(color: Int, pageId: String)
fun setSearchStyle(searchStyle: BottomTab.SearchStyle)
fun getCurrentTabIndex(): Int?
}

View File

@ -1,12 +0,0 @@
package com.gh.common.iinterface
import com.gh.common.prioritychain.PullDownPushHandler
import com.gh.gamecenter.entity.PullDownPush
interface ISmartRefresh {
fun setSmartRefreshEnabled(isEnable: Boolean)
fun finishTwoLevel(action: String)
fun finishRefresh()
fun popupPullDownPush(finishCallback: () -> Unit)
fun setPullDownPush(pullDownPush: PullDownPush?, pullDownPushHandler: PullDownPushHandler?)
}

View File

@ -1,17 +0,0 @@
package com.gh.common.iinterface
interface ISmartRefreshContent {
/**
* 启用/关闭 页面滑动
* @param isScrollEnabled 是否启用
*/
fun setScrollEnabled(isScrollEnabled: Boolean)
fun onRefresh()
/**
* 启用/关闭 SwipeRefreshLayout 的下拉刷新
* @param isSwipeRefreshEnabled 是否启用
*/
fun setSwipeRefreshEnabled(isSwipeRefreshEnabled: Boolean)
}

View File

@ -1,9 +0,0 @@
package com.gh.common.iinterface
import com.gh.common.prioritychain.PriorityChain
interface ISuperiorChain {
fun registerInferiorChain(chain: PriorityChain)
fun unregisterInferiorChain(chain: PriorityChain)
}

View File

@ -14,7 +14,7 @@ import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.PopupAccelerateNotificationBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.wrapper.MainWrapperViewModel
import com.gh.gamecenter.fragment.MainWrapperViewModel
class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priority) {
@ -42,7 +42,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
processNext()
} else {
updateStatus(STATUS_VALID)
process()
onProcess()
}
} else {
if (gameEntityList == null) {
@ -53,7 +53,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
}
}
override fun onProcess() : Boolean {
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val accelerateSet =
@ -64,7 +64,6 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
}
accelerateSet.add(mGameList!![0].messageId)
SPUtils.setStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET, accelerateSet)
return true
} else {
processNext()
}
@ -74,8 +73,6 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
processNext()
}
}
return false
}
companion object {

View File

@ -1,82 +0,0 @@
package com.gh.common.prioritychain
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.floatingwindow.FloatingWindowEntity
import com.gh.gamecenter.livedata.Event
class CustomFloatingWindowHandler(priority: Int) : PriorityChainHandler(priority) {
private val data = arrayListOf<FloatingWindowEntity>()
private val _showFloatingAction = MutableLiveData<Event<ArrayList<FloatingWindowEntity>>>()
val showFloatingAction: LiveData<Event<ArrayList<FloatingWindowEntity>>> = _showFloatingAction
fun setData(newData: List<FloatingWindowEntity>) {
data.clear()
data.addAll(newData)
doPreProcess()
}
private fun doPreProcess() {
// debugOnly {
// data.clear()
// data.add(
// FloatingWindowEntity(
// id = "audire",
// image = "https://jira.shanqu.cc/secure/attachment/57822/57822_image-2023-12-01-17-53-04-492.png",
// link = WelcomeDialogEntity(
// id = null,
// time = null,
// packages = null,
// floatingWindowId = null,
// shouldShowExitAnimation = false
// ),
// pushType = "maiorum",
// expandable = false,
// expandedImage = "fermentum",
// bigPopupNotice = "dignissim"
// )
// )
// }
if (getStatus() == STATUS_PENDING) {
if (data.isNotEmpty()) {
updateStatus(STATUS_VALID)
process()
} else {
processNext()
}
} else {
if (data.isNotEmpty()) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
when (getStatus()) {
STATUS_VALID -> {
_showFloatingAction.value = Event(data)
processNext()
// floatingWindowProvider.showFloatingWindowOnly(
// mFragment!!,
// mRecyclerView!!,
// mWindowList!!,
// ) {
// val welcomeDialog = WelcomeDialogFragment.getInstance(it, true, mFragment)
// welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
// }
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -0,0 +1,87 @@
package com.gh.common.prioritychain
import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IFloatingWindowProvider
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.gh.gamecenter.floatingwindow.FloatingWindowEntity
import com.gh.gamecenter.fragment.WelcomeDialogFragment
import com.lightgame.utils.Utils
class FloatingWindowHandler(priority: Int) : PriorityChainHandler(priority) {
private var mFragment: BaseLazyFragment? = null
private var mRecyclerView: RecyclerView? = null
private var mWindowList: ArrayList<FloatingWindowEntity>? = null
fun setData(windowList: ArrayList<FloatingWindowEntity>?) {
mWindowList = windowList
if (mFragment != null) {
doPreProcess()
}
}
fun setView(
fragment: BaseLazyFragment,
recyclerView: RecyclerView
) {
mFragment = fragment
mRecyclerView = recyclerView
if (mWindowList != null) {
doPreProcess()
}
}
private fun doPreProcess() {
Utils.log(TAG, "FloatingWindowHandler preProcess windowSize is -> ${mWindowList?.size}")
if (getStatus() == STATUS_PENDING) {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
onProcess()
} else {
processNext()
}
} else {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val floatingWindowProvider =
ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
.navigation() as? IFloatingWindowProvider<WelcomeDialogEntity>
// 强校验所有条件均通过才能显示
if (floatingWindowProvider == null || mFragment == null || mFragment?.isAdded == false || mRecyclerView == null) {
processNext()
return
}
floatingWindowProvider.showFloatingWindowOnly(
mFragment!!,
mRecyclerView!!,
mWindowList!!,
) {
val welcomeDialog = WelcomeDialogFragment.getInstance(it, true, mFragment)
welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
}
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -1,244 +0,0 @@
package com.gh.common.prioritychain
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.fragment.app.FragmentActivity
import com.gh.common.iinterface.ISuperiorChain
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.DialogEntity
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
* 全局的 APP 优先级弹窗链管理器
*
* 弹窗的优先级为
* 启动跳转(-101) > 更新弹窗(-100) > 隐私政策弹窗(-99) > 消息通知权限弹窗(0) > 预约弹窗(1) > 启动弹窗(2)
*/
object GlobalPriorityChainHelper : ISuperiorChain {
private val api = RetrofitManager.getInstance().api
private var inferiorChain: PriorityChain? = null
private val mainChain: PriorityChain by lazy { PriorityChain { inferiorChain?.start() } }
/**
* 当前 activity 是否使用于应用全局弹窗的弹出
* 排除启动页和其它非 FragmentActivity
*/
fun isThisActivityValid(activity: Activity?): Boolean {
return activity is FragmentActivity
&& !activity.isFinishing
&& activity !is SplashScreenActivity
}
/**
* 预启动所有的优先级弹窗管理链
*/
fun preStart() {
val launchRedirectHandler = LaunchRedirectHandler(-101)
val updateDialogHandler = UpdateDialogHandler(-100)
val privacyPolicyDialogHandler = PrivacyPolicyDialogHandler(-99)
val notificationPermissionDialogHandler = NotificationPermissionDialogHandler(0)
val reserveDialogHandler = ReserveDialogHandler(1)
val welcomeDialogHandler = WelcomeDialogHandler(2)
mainChain.addHandler(launchRedirectHandler)
mainChain.addHandler(updateDialogHandler)
mainChain.addHandler(privacyPolicyDialogHandler)
mainChain.addHandler(welcomeDialogHandler)
mainChain.addHandler(reserveDialogHandler)
mainChain.addHandler(notificationPermissionDialogHandler)
launchRedirectHandler.doPreProcess()
updateDialogHandler.doPreProcess()
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
}
/**
* 启动优先级弹窗管理链的执行
*/
fun start() {
if (mainChain.isHandlerQueueEmpty()) return
mainChain.start()
observeLifecycle()
}
private fun observeLifecycle() {
HaloApp.getInstance().registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
}
override fun onActivityStarted(activity: Activity) {
// do nothing
}
override fun onActivityResumed(activity: Activity) {
// 优先级弹窗管理链为空时取消注册,避免无用调用
if (mainChain.isHandlerQueueEmpty()) {
HaloApp.getInstance().unregisterActivityLifecycleCallbacks(this)
} else {
resume()
}
}
override fun onActivityPaused(activity: Activity) {
// do nothing
}
override fun onActivityStopped(activity: Activity) {
// do nothing
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
// do nothing
}
override fun onActivityDestroyed(activity: Activity) {
// do nothing
}
})
}
/**
* 恢复链的处理
*/
fun resume() {
mainChain.resume()
}
/**
* 请求首页启动弹窗相关的数据并执行相关 handler 的 preProcess
*/
@SuppressLint("CheckResult")
private fun requestOpeningDialogData(
welcomeDialogHandler: WelcomeDialogHandler,
privacyPolicyDialogHandler: PrivacyPolicyDialogHandler
) {
val sp = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance())
val lastId = SPUtils.getString(sp, Constants.SP_LAST_OPENING_ID, "")
val lastTime = SPUtils.getLong(sp, Constants.SP_LAST_OPENING_TIME, 0)
val openType = if (HaloApp.getInstance().isNewForThisVersion) "first" else "not_first_time"
api.getOpeningDialog(HaloApp.getInstance().channel, lastId, lastTime, openType)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<DialogEntity>() {
override fun onSuccess(data: DialogEntity) {
var welcomeDialogEntity: WelcomeDialogEntity? = null
var privacyPolicyDialogEntity: DialogEntity.PrivacyPolicyEntity? = null
// 全新安装忽略隐私弹窗
if (data.privacyPolicyDialog != null) {
val id = data.privacyPolicyDialog.id
val lastAcceptedId = SPUtils.getString(Constants.SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID, "")
if (HaloApp.getInstance().isBrandNewInstall) {
SPUtils.setString(Constants.SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID, id)
} else {
if (id != lastAcceptedId) {
privacyPolicyDialogEntity = data.privacyPolicyDialog
}
}
}
// debugOnly {
// privacyPolicyDialogEntity = DialogEntity.PrivacyPolicyEntity(
// "5f6f5f3d9d9b4e0001c3b3a5",
// "privacy_policy",
// "ONCE",
// "INFORM",
// "隐私政策",
// 1601116800000)
// }
privacyPolicyDialogHandler.doPreProcess(privacyPolicyDialogEntity)
// 类型为游戏时判断是否本地已安装该游戏,已安装不弹弹窗
if (data.welcomeDialog != null) {
welcomeDialogEntity = data.welcomeDialog
if (data.welcomeDialog.type == "game") {
if (data.welcomeDialog.packages != null) {
for (packageName in data.welcomeDialog.packages!!) {
if (PackageUtils.isInstalled(HaloApp.getInstance(), packageName)) {
welcomeDialogEntity = null
break
}
}
}
}
}
welcomeDialogHandler.doPreProcess(welcomeDialogEntity)
}
override fun onFailure(exception: Exception) {
privacyPolicyDialogHandler.doPreProcess(null)
welcomeDialogHandler.doPreProcess(null)
}
})
}
/**
* 请求预约弹窗相关的数据
*/
@SuppressLint("CheckResult")
private fun requestReserveDialogData(reserveDialogHandler: ReserveDialogHandler) {
// debugOnly {
// reserveDialogHandler.doPreProcess(arrayListOf(SimpleGameEntity(
// "5f6f5f3d9d9b4e0001c3b3a5",
// "5f6f5f3d9d9b4e0001c3b3a5",
// "https://and-static.ghzs.com/image/game/icon/2022/11/18/63772b0d398daaa7c5067298.png",
// "5f6f5f3d9d9b4e0001c3b3a5",
// )))
// return
// }
if (CheckLoginUtils.isLogin()) {
api.getReserveDialog(UserManager.getInstance().userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<SimpleGameEntity>>() {
override fun onSuccess(data: List<SimpleGameEntity>) {
reserveDialogHandler.doPreProcess(data)
}
override fun onFailure(exception: Exception) {
reserveDialogHandler.doPreProcess(null)
}
})
} else {
reserveDialogHandler.doPreProcess(null)
}
}
override fun registerInferiorChain(chain: PriorityChain) {
inferiorChain = chain
if (mainChain.isHandlerQueueEmpty()) {
inferiorChain?.resume()
}
}
override fun unregisterInferiorChain(chain: PriorityChain) {
if (inferiorChain == chain) {
inferiorChain = null
}
}
}

View File

@ -0,0 +1,45 @@
package com.gh.common.prioritychain
import com.gh.gamecenter.fragment.HomeSearchToolWrapperFragment
class HomePushHandler(priority: Int): PriorityChainHandler(priority) {
private var mHomeFragment: HomeSearchToolWrapperFragment? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(homeFragment: HomeSearchToolWrapperFragment?, shouldShow: Boolean) {
mHomeFragment = homeFragment
if (getStatus() == STATUS_PENDING) {
if (shouldShow && homeFragment != null) {
updateStatus(STATUS_VALID)
onProcess()
} else {
processNext()
}
} else {
if (shouldShow && homeFragment != null) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
// 目前首页下拉二楼是首页最后一个弹窗类的东西,还没实现回调,如果有其它要在它后面弹出的,需要自行在它的实现结果后添加回调
mHomeFragment?.popUpHomePushIfNeeded {
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -1,86 +0,0 @@
package com.gh.common.prioritychain
import android.annotation.SuppressLint
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.entity.LaunchRedirect
import com.gh.gamecenter.common.entity.LaunchRedirectWrapper
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.wrapper.MainWrapperRepository
import com.halo.assistant.HaloApp
/**
* 初次启动跳转
*/
class LaunchRedirectHandler(priority: Int) : PriorityChainHandler(priority) {
private var launchData: LaunchRedirect? = null
@SuppressLint("CheckResult")
fun doPreProcess() {
// if (true) {
if (HaloApp.getInstance().isBrandNewInstall) {
RetrofitManager.getInstance().newApi
.getLaunchRedirect(BuildConfig.VERSION_NAME, HaloApp.getInstance().channel)
.compose(singleToMain())
.subscribe(object : BiResponse<LaunchRedirectWrapper>() {
override fun onSuccess(data: LaunchRedirectWrapper) {
launchData = data.launchRedirect
if (launchData == null) {
updateStatus(STATUS_INVALID)
processNext()
return
}
// 尝试提前设置 tab default 避免首页数据加载完成tab 选中会闪烁
if (launchData?.type == "bottom_tab") {
MainWrapperRepository.getInstance().sendSelectTabEvent(launchData!!)
}
if (getStatus() == STATUS_PENDING) {
updateStatus(STATUS_VALID)
process()
} else {
updateStatus(STATUS_VALID)
}
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
updateStatus(STATUS_INVALID)
processNext()
}
})
} else {
updateStatus(STATUS_INVALID)
processNext()
}
}
override fun onProcess(): Boolean {
val currentActivity = CurrentActivityHolder.getCurrentActivity()
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
if (getStatus() == STATUS_VALID) {
// 当 type 为 "bottom_tab" 时上面 doPreProcess 中已经处理过了,但再选中一次好像也没有什么问题,先不特殊处理这个 case 了
DirectUtils.directToLinkPage(currentActivity!!, launchData!!, "首次启动跳转", "")
// 跳转页面不管回调,延迟 500ms 后执行下一个 handler
AppExecutor.uiExecutor.executeWithDelay({
processNext()
}, 500L)
return true
} else if (getStatus() == STATUS_INVALID) {
processNext()
}
}
return false
}
}

View File

@ -6,18 +6,15 @@ import com.gh.gamecenter.login.user.UserManager
class NotificationPermissionDialogHandler(priority: Int) : PriorityChainHandler(priority) {
override fun onProcess(): Boolean {
override fun onProcess() {
// 仅登录后再启动光环时请求一次权限
if (UserManager.getInstance().isLoggedIn) {
NotificationHelper.showNotificationHintDialog(NotificationUgc.LOGIN) {
processNext()
}
return true
} else {
processNext()
}
return false
}
}

View File

@ -1,54 +1,22 @@
package com.gh.common.prioritychain
import com.lightgame.utils.Utils
import java.util.*
import java.util.concurrent.PriorityBlockingQueue
class PriorityChain(private val completeCallback: (() -> Unit)? = null) {
class PriorityChain {
private val handlerQueue: Queue<PriorityChainHandler> = PriorityBlockingQueue()
private val mHandlerQueue: Queue<PriorityChainHandler> = PriorityBlockingQueue()
/**
* 添加 handler 到队列中
*/
fun addHandler(handler: PriorityChainHandler) {
handlerQueue.add(handler.also {
mHandlerQueue.add(handler.also {
it.setPriorityChain(this)
})
}
/**
* 启动队列中的 handler
*/
fun start() {
handlerQueue.peek()?.let {
it.injectQueue(handlerQueue)
it.process()
}
mHandlerQueue.poll()?.process(mHandlerQueue)
}
/**
* 恢复队列中的 handler
*/
fun resume() {
val handler = handlerQueue.peek()
if (handler?.getStatus() == PriorityChainHandler.STATUS_HANDLING) {
Utils.log(PriorityChainHandler.TAG, "${handler.javaClass.simpleName} 处于执行中状态,不用恢复")
} else {
handler?.injectQueue(handlerQueue)
handler?.process()
}
}
/**
* 队列是否为空
*/
fun isHandlerQueueEmpty() = handlerQueue.isEmpty()
fun onHandleComplete() {
completeCallback?.invoke()
}
fun isHandlerQueueEmpty() = mHandlerQueue.isEmpty()
}

View File

@ -5,76 +5,54 @@ import java.util.*
abstract class PriorityChainHandler(private val mPriority: Int) : Comparable<PriorityChainHandler> {
private var status = STATUS_UNKNOWN
private var queue: Queue<PriorityChainHandler>? = null
private var mStatus = STATUS_UNKNOWN
private var mQueue: Queue<PriorityChainHandler>? = null
private var priorityChain: PriorityChain? = null
private var mPriorityChain: PriorityChain? = null
/**
* 获取当前 handler 的状态
* - 等待结果返回 STATUS_PENDING
* - 无需执行 STATUS_INVALID
* - 可执行 STATUS_VALID
* - 执行中 STATUS_HANDLING
* - 未知 STATUS_UNKNOWN
*/
fun getStatus(): Int = status
fun getStatus(): Int = mStatus
fun updateStatus(status: Int) {
Utils.log(TAG, "${javaClass.simpleName} updateStatus ${this.status} $status")
Utils.log(TAG, "${javaClass.simpleName} updateStatus $status")
this.status = status
mStatus = status
}
fun setPriorityChain(priorityChain: PriorityChain) {
this.priorityChain = priorityChain
mPriorityChain = priorityChain
}
fun injectQueue(queue: Queue<PriorityChainHandler>) {
this.queue = queue
}
fun process() {
Utils.log(TAG, "${javaClass.simpleName} process $status")
fun process(queue: Queue<PriorityChainHandler>) {
Utils.log(TAG, "${javaClass.simpleName} process $mStatus")
mQueue = queue
// 若当前 handler 未经处理,将其状态改为 pending
if (status == STATUS_UNKNOWN) {
if (mStatus == STATUS_UNKNOWN) {
updateStatus(STATUS_PENDING)
}
if (status == STATUS_HANDLING) {
Utils.log(TAG, "${javaClass.simpleName} 已经处于执行中状态,不用再次执行")
return
}
val isHandling = onProcess()
if (isHandling) {
updateStatus(STATUS_HANDLING)
}
onProcess()
}
/**
* 执行相关功能的地方
* @return 是否满足执行条件并处于执行中状态
*/
abstract fun onProcess(): Boolean
abstract fun onProcess()
/**
* 分发给下一个 handler 处理
*/
fun processNext() {
Utils.log(TAG, "${javaClass.simpleName} processNext")
Utils.log(TAG, "${javaClass.simpleName} processNext $mStatus")
queue?.remove(this)
if (queue?.isEmpty() == true) {
priorityChain?.onHandleComplete()
} else {
queue?.peek()?.let {
it.injectQueue(queue!!)
it.process()
}
}
mQueue?.poll()?.process(mQueue!!)
}
override fun compareTo(other: PriorityChainHandler): Int {
@ -86,7 +64,6 @@ abstract class PriorityChainHandler(private val mPriority: Int) : Comparable<Pri
internal const val STATUS_INVALID = 1
internal const val STATUS_VALID = 2
internal const val STATUS_UNKNOWN = 3
internal const val STATUS_HANDLING = 4
const val TAG = "PriorityChainHandler"
}

View File

@ -2,17 +2,18 @@ package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.dialog.PrivacyPolicyDialogFragment
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.entity.DialogEntity
class PrivacyPolicyDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mActivity: FragmentActivity? = null
private var mPrivacyPolicyEntity: DialogEntity.PrivacyPolicyEntity? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(privacyPolicyEntity: DialogEntity.PrivacyPolicyEntity?) {
fun doPreProcess(fragmentActivity: FragmentActivity, privacyPolicyEntity: DialogEntity.PrivacyPolicyEntity?) {
mActivity = fragmentActivity
mPrivacyPolicyEntity = privacyPolicyEntity
if (getStatus() == STATUS_PENDING) {
@ -20,7 +21,7 @@ class PrivacyPolicyDialogHandler(priority: Int) : PriorityChainHandler(priority)
processNext()
} else {
updateStatus(STATUS_VALID)
process()
onProcess()
}
} else {
if (privacyPolicyEntity == null) {
@ -31,26 +32,17 @@ class PrivacyPolicyDialogHandler(priority: Int) : PriorityChainHandler(priority)
}
}
override fun onProcess(): Boolean {
val currentActivity = CurrentActivityHolder.getCurrentActivity()
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
when (getStatus()) {
STATUS_VALID -> {
PrivacyPolicyDialogFragment.show(currentActivity as FragmentActivity, mPrivacyPolicyEntity) { _: Boolean? ->
processNext()
}
return true
}
STATUS_INVALID -> {
override fun onProcess() {
when(getStatus()) {
STATUS_VALID -> {
PrivacyPolicyDialogFragment.show(mActivity!!, mPrivacyPolicyEntity) { _: Boolean? ->
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -1,48 +0,0 @@
package com.gh.common.prioritychain
import com.gh.common.iinterface.ISmartRefresh
class PullDownPushHandler(priority: Int): PriorityChainHandler(priority) {
private var mSmartRefreshFragment: ISmartRefresh? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(smartRefreshFragment: ISmartRefresh?, shouldShow: Boolean) {
mSmartRefreshFragment = smartRefreshFragment
if (getStatus() == STATUS_PENDING) {
if (shouldShow && smartRefreshFragment != null) {
updateStatus(STATUS_VALID)
process()
} else {
processNext()
}
} else {
if (shouldShow && smartRefreshFragment != null) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
when (getStatus()) {
STATUS_VALID -> {
mSmartRefreshFragment?.popupPullDownPush {
processNext()
}
return true
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -1,18 +1,20 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.Fragment
import com.gh.common.dialog.ReserveDialog
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.message.MessageUnreadRepository
class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mFragment: Fragment? = null
private var mReserveData: List<SimpleGameEntity>? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(reserveData: List<SimpleGameEntity>?) {
fun doPreProcess(fragment: Fragment, reserveData: List<SimpleGameEntity>?) {
mFragment = fragment
mReserveData = reserveData
if (getStatus() == STATUS_PENDING) {
@ -20,7 +22,7 @@ class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
processNext()
} else {
updateStatus(STATUS_VALID)
process()
onProcess()
}
} else {
if (reserveData.isNullOrEmpty()) {
@ -31,28 +33,21 @@ class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
}
}
override fun onProcess(): Boolean {
val currentActivity = CurrentActivityHolder.getCurrentActivity()
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
when (getStatus()) {
STATUS_VALID -> {
val reserveDialog = ReserveDialog.getInstance(mReserveData!!)
reserveDialog.setOnDismissListener {
processNext()
}
reserveDialog.show((currentActivity as FragmentActivity).supportFragmentManager, "reserveDialog")
return true
}
STATUS_INVALID -> {
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val reserveDialog = ReserveDialog.getInstance(mReserveData!!)
reserveDialog.setOnDismissListener {
MessageUnreadRepository.loadMessageUnreadData()
processNext()
}
reserveDialog.show(mFragment!!.childFragmentManager, "reserveDialog")
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -1,47 +1,17 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.update.UpdateHelper
import android.content.Context
import com.gh.gamecenter.manager.UpdateManager
class UpdateDialogHandler(priority: Int) : PriorityChainHandler(priority) {
class UpdateDialogHandler(context: Context, priority: Int) : PriorityChainHandler(priority) {
fun doPreProcess() {
UpdateHelper.getUpdate(false) {
if (getStatus() == STATUS_PENDING) {
if (UpdateHelper.isUpdateValid(false)) {
updateStatus(STATUS_VALID)
process()
} else {
updateStatus(STATUS_INVALID)
processNext()
}
} else {
if (UpdateHelper.isUpdateValid(false)) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
private val mUpdateManager = UpdateManager.getInstance(context)
override fun onProcess() {
mUpdateManager.checkUpdate(true, null)
mUpdateManager.setDismissCallback {
processNext()
}
}
override fun onProcess(): Boolean {
val currentActivity = CurrentActivityHolder.getCurrentActivity()
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
if (getStatus() == STATUS_VALID) {
UpdateHelper.showUpdateDialog(currentActivity as FragmentActivity) {
processNext()
}
return true
} else if (getStatus() == STATUS_INVALID) {
processNext()
}
}
return false
}
}

View File

@ -1,37 +1,41 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import android.graphics.Bitmap
import androidx.fragment.app.Fragment
import com.gh.gamecenter.common.callback.BiCallback
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.gh.gamecenter.fragment.MainWrapperViewModel
import com.gh.gamecenter.fragment.WelcomeDialogFragment
import com.gh.gamecenter.wrapper.MainWrapperViewModel
import com.halo.assistant.HaloApp
class WelcomeDialogHandler(priority: Int) : PriorityChainHandler(priority) {
class WelcomeDialogHandler(priority: Int): PriorityChainHandler(priority) {
private var welcomeDialogEntity: WelcomeDialogEntity? = null
private var mFragment: Fragment? = null
private var mWelcomeDialogEntity: WelcomeDialogEntity? = null
fun doPreProcess(welcomeDialogEntity: WelcomeDialogEntity?) {
this.welcomeDialogEntity = welcomeDialogEntity
fun doPreProcess(fragment: Fragment, welcomeDialogEntity: WelcomeDialogEntity?) {
mFragment = fragment
mWelcomeDialogEntity = welcomeDialogEntity
val preLoadClosure = {
// 判断启动本次应用是否已经弹窗,不是的话弹启动弹窗
if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false)
val idealUrl = ImageUtils.getIdealImageUrl(this.welcomeDialogEntity!!.icon, 0, true) ?: ""
ImageUtils.prefetchToDiskCache(idealUrl) { isSuccess ->
if (isSuccess) {
ImageUtils.getBitmap(mWelcomeDialogEntity!!.icon, object : BiCallback<Bitmap, Boolean> {
override fun onFirst(first: Bitmap) {
if (getStatus() == STATUS_PENDING) {
updateStatus(STATUS_VALID)
process()
onProcess()
} else {
updateStatus(STATUS_VALID)
}
} else {
}
override fun onSecond(second: Boolean) {
processNext()
}
}
})
} else {
processNext()
}
@ -52,28 +56,24 @@ class WelcomeDialogHandler(priority: Int) : PriorityChainHandler(priority) {
}
}
override fun onProcess(): Boolean {
val currentActivity = CurrentActivityHolder.getCurrentActivity()
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
when (getStatus()) {
STATUS_VALID -> {
val welcomeDialog = WelcomeDialogFragment.getInstance(welcomeDialogEntity)
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
if (mFragment == null || !mFragment!!.isAdded) {
updateStatus(STATUS_INVALID)
processNext()
} else {
val welcomeDialog = WelcomeDialogFragment.getInstance(mWelcomeDialogEntity)
welcomeDialog.setOnDismissListener {
processNext()
}
welcomeDialog.show((currentActivity as FragmentActivity).supportFragmentManager, "WelcomeDialog")
return true
}
STATUS_INVALID -> {
processNext()
welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -8,6 +8,7 @@ import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IFlavorProvider
import com.halo.assistant.HaloApp
import com.va.host.HostUtils
@Route(path = RouteConsts.provider.app, name = "Application暴露服务")
class AppProviderImpl : IAppProvider {
@ -83,7 +84,5 @@ class AppProviderImpl : IAppProvider {
return HaloApp.getInstance().isBrandNewInstall
}
override fun setSkippingThirdParty(isSkippingThirdParty: Boolean) {
HaloApp.getInstance().isSkippingThirdParty = isSkippingThirdParty
}
override fun getPluginVersion(): String = HostUtils.getPluginVersion()
}

View File

@ -16,8 +16,9 @@ class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
view: TextView,
game: GameEntity,
isShowPlatform: Boolean,
isShowSuffix: Boolean
) {
BindingAdapters.setGameName(view, game, isShowPlatform)
BindingAdapters.setGameName(view, game, isShowPlatform, isShowSuffix)
}
override fun setGameTags(layout: LinearLayout, gameEntity: GameEntity) {

View File

@ -19,7 +19,6 @@ class BuildConfigImpl : IBuildConfigProvider {
override fun getExposureVersion(): String = BuildConfig.EXPOSURE_VERSION
override fun isDebug(): Boolean = BuildConfig.DEBUG
override fun isGATApp(): Boolean = BuildConfig.IS_GAT_APP
override fun getApiHost(): String = BuildConfig.API_HOST
@ -32,5 +31,4 @@ class BuildConfigImpl : IBuildConfigProvider {
override fun getVApiHost(): String = BuildConfig.VAPI_HOST
override fun getVDevApiHost(): String = BuildConfig.DEV_VAPI_HOST
override fun getLogProducerProject(): String = BuildConfig.LOG_HUB_PROJECT
}

View File

@ -100,6 +100,10 @@ class ConfigProviderImpl : IConfigProvider {
return Config.getNightModeSetting()?.setting ?: false
}
override fun isShowPlugin(gameId: String): Boolean {
return Config.isShowPlugin(gameId)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -13,10 +13,9 @@ class DefaultUrlHandlerProviderImpl : IDefaultUrlHandlerProvider {
context: Context,
url: String,
entrance: String,
bringAppToFront: Boolean,
sourceEntrance: String
bringAppToFront: Boolean
): Boolean {
return DefaultUrlHandler.interceptUrl(context, url, null, entrance, bringAppToFront, sourceEntrance)
return DefaultUrlHandler.interceptUrl(context, url, null, entrance, bringAppToFront)
}
override fun init(context: Context?) {

View File

@ -22,6 +22,34 @@ class DirectProviderImpl : IDirectProvider {
DirectUtils.directToQqConversation(context, qq)
}
override fun directToCommodityDetail(context: Context, commodityId: String) {
DirectUtils.directToCommodityDetail(context, commodityId)
}
override fun directToEnergyRecord(context: Context) {
DirectUtils.directToEnergyRecord(context)
}
override fun directToEnergyRulePage(context: Context) {
DirectUtils.directToEnergyRulePage(context)
}
override fun directToInviteFriends(context: Context) {
DirectUtils.directToInviteFriends(context)
}
override fun directToExchangeRulePage(context: Context) {
DirectUtils.directToExchangeRulePage(context)
}
override fun directToExchangeCommodityPage(context: Context) {
DirectUtils.directToExchangeCommodityPage(context)
}
override fun directToLotteryParadisePage(context: Context) {
DirectUtils.directToLotteryParadisePage(context)
}
override fun directDouyin(context: Context, userId: String) {
DirectUtils.directDouyin(context, userId)
}
@ -55,20 +83,39 @@ class DirectProviderImpl : IDirectProvider {
articleId: String?,
communityId: String?,
entrance: String?,
path: String?,
sourceEntrance: String
path: String?
) {
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path, sourceEntrance)
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path)
}
override fun directToVideoDetail(context: Context, videoId: String, entrance: String?, path: String?, sourceEntrance: String) {
DirectUtils.directToVideoDetail(context, videoId, entrance, path, sourceEntrance)
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)
}

View File

@ -9,7 +9,6 @@ import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.feature.entity.CustomPageTrackData
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.provider.IDownloadButtonClickedProvider
@ -30,7 +29,6 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
var gameSchemaType = ""
var packageName = ""
var exposureSourceList: List<ExposureSource>? = null
var customPageTrackData: CustomPageTrackData? = null
val boundedObject = downloadButton.getObject()
@ -57,7 +55,6 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
gameSchemaType = boundedObject.gameBitChinese
packageName = boundedObject.getUniquePackageName() ?: ""
exposureSourceList = boundedObject.exposureEvent?.source
customPageTrackData = boundedObject.customPageTrackData
}
is GameUpdateEntity -> {
@ -83,13 +80,11 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
// 上报 UI 状态为启动的点击事件 (样式为启动,或者文案包含启动都算能启动)
if (downloadButton.buttonStyle == DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
|| downloadButton.text.contains("启动")
) {
|| downloadButton.text.contains("启动")) {
// boundedObject 里找不到游戏类型时,尝试从已安装列表中获取
if (gameCategory.isEmpty() && packageName.isNotEmpty()) {
gameCategory =
PackageRepository.gameInstalled.find { it.packageName == packageName }?.category ?: ""
gameCategory = PackageRepository.gameInstalled.find { it.packageName == packageName }?.category ?: ""
}
NewFlatLogUtils.logGameLaunchButtonClicked(
@ -103,8 +98,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
// 预约状态不上报
if (downloadButton.buttonStyle == DownloadButton.ButtonStyle.NORMAL
|| downloadButton.buttonStyle == DownloadButton.ButtonStyle.PLUGIN
) {
|| downloadButton.buttonStyle == DownloadButton.ButtonStyle.PLUGIN) {
val text = downloadButton.text.ifEmpty {
downloadButton.getTag(R.string.download) ?: ""
@ -117,7 +111,6 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
}
// 上报神策点击事件
val customPageKV = customPageTrackData?.toKV() ?: arrayOf()
SensorsBridge.trackEventWithExposureSource(
"DownLoadbuttonClick",
exposureSourceList,
@ -134,7 +127,6 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId,
*customPageKV
)
}
}

View File

@ -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.util.GameSubstituteRepositoryHelper
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IGameSubstituteRepositoryProvider
@Route(path = RouteConsts.provider.gameSubstituteRepository, name = "GameSubstituteRepositoryHelper暴露服务")
class GameSubstituteRepositoryProviderImpl : IGameSubstituteRepositoryProvider {
override fun updateSubstitutableGames() {
GameSubstituteRepositoryHelper.updateSubstitutableGames()
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -2,15 +2,14 @@ package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IMainProvider
@Route(path = RouteConsts.provider.mainActivity, name = "MainActivity暴露服务")
class MainProviderImpl : IMainProvider {
override fun skipToMainActivity(context: Context, type: String) {
DirectUtils.directToHomeDefaultTab(context)
override fun skipToMainActivity(context: Context, position: Int) {
MainActivity.skipToMainActivity(context, position)
}
override fun init(context: Context?) {

View File

@ -3,16 +3,14 @@ package com.gh.common.provider
import android.content.Context
import android.content.pm.PackageInfo
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
import com.gh.gamecenter.core.utils.ProcessUtil
@Route(path = RouteConsts.provider.packageUtils, name = "PackageUtils暴露服务")
class PackageUtilsProviderImpl : IPackageUtilsProvider {
override fun obtainProcessName(): String? {
return ProcessUtil.getCurrentProcessName()
override fun obtainProcessName(context: Context): String? {
return PackageUtils.obtainProcessName(context)
}
override fun getGhVersionName(): String {
@ -24,7 +22,7 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
}
override fun getInstalledPackages(context: Context, flag: Int): List<PackageInfo> {
return PackageHelper.getInstalledPackages(context, flag)
return PackageUtils.getInstalledPackages(context, flag)
}
override fun getApkSignatureByPackageName(context: Context, packageName: String): Array<String> {
@ -39,10 +37,6 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
return PackageUtils.isSignedByGh(context, packageName)
}
override fun isInstalledWithLauncherIcon(context: Context, packageName: String): Boolean {
return PackageUtils.isInstalled(context, packageName)
}
override fun getInstalledTime(context: Context, packageName: String): Long {
return PackageUtils.getInstalledTime(context, packageName)
}

View File

@ -1,30 +1,16 @@
package com.gh.common.provider
import android.content.Context
import androidx.fragment.app.FragmentActivity
import android.os.Handler
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.DialogUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IUpdateManagerProvider
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.update.UpdateHelper
import com.gh.gamecenter.manager.UpdateManager
@Route(path = RouteConsts.provider.updateManager, name = "UpdateManager暴露服务")
class UpdateManagerProviderImpl: IUpdateManagerProvider {
override fun checkUpdate(activity: FragmentActivity, ignoreSuppressOption: Boolean) {
val dialog = DialogUtils.showWaitDialog(activity, "检查更新中...")
UpdateHelper.getUpdate(ignoreSuppressOption) {
dialog.dismiss()
if (UpdateHelper.isUpdateValid(ignoreSuppressOption)) {
UpdateHelper.showUpdateDialog(activity) {
// Do nothing
}
} else {
ToastUtils.toast("您的光环助手已是最新版本")
}
}
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler?) {
UpdateManager.getInstance(context).checkUpdate(isAutoCheck, handler)
}
override fun init(context: Context?) {

View File

@ -3,8 +3,7 @@ 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.entity.InstallGameEntity
import com.gh.gamecenter.feature.provider.IVHelperProvider
import com.gh.gamecenter.core.provider.IVHelperProvider
import com.gh.vspace.VHelper
@Route(path = RouteConsts.provider.vhelper, name = "VHelper暴露服务")
@ -13,14 +12,6 @@ class VHelperProviderImpl: IVHelperProvider {
return VHelper.isVGameOn()
}
override fun getAllInstalledVGameEntity(): ArrayList<InstallGameEntity> {
return VHelper.getAllInstalledVGameEntity()
}
override fun launch(context: Context, packageName: String, ignoreGApps: Boolean, showLoading: Boolean) {
VHelper.launch(context, packageName, ignoreGApps, showLoading)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -91,7 +91,7 @@ object NewSimulatorGameManager {
},
uiModificationCallback = { binding ->
binding.contentTv.gravity = Gravity.START
binding.contentTv.setTextColor(R.color.text_secondary.toColor(context))
binding.contentTv.setTextColor(R.color.text_subtitle.toColor(context))
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)

View File

@ -20,14 +20,15 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor.uiExecutor
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.TrackableEntity
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
import com.gh.gamecenter.entity.TrackableEntity
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.lang.ref.WeakReference
import java.text.DecimalFormat
@ -166,160 +167,170 @@ class SimulatorDownloadManager private constructor() {
this.gameName = gameName
this.gameType = gameCategoryChinese
PermissionHelper.checkGetInstalledAppsListBeforeAction(context) { _ ->
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
//当没有安装新版本模拟器时候 判断是否隐藏
if (simulator?.active == false && !isInstalledNewSimulator) {
showNoneEmulatorDialog(context)
return@checkGetInstalledAppsListBeforeAction
}
var isInstalled = PackageUtils.isInstalledFromAllPackage(
context,
simulator?.apk?.packageName
)
//模拟器管理界面还是用之前的逻辑
if (isInstalledNewSimulator && location != SimulatorLocation.SIMULATOR_MANAGE) {
isInstalled = isInstalledNewSimulator
}
val callback = object : EmptyCallback {
override fun onCallback() {
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
//当没有安装新版本模拟器时候 判断是否隐藏
if (simulator?.active == false && !isInstalledNewSimulator) {
showNoneEmulatorDialog(context)
return
}
var isInstalled = PackageUtils.isInstalledFromAllPackage(
context,
simulator?.apk?.packageName
)
//模拟器管理界面还是用之前的逻辑
if (isInstalledNewSimulator && location != SimulatorLocation.SIMULATOR_MANAGE) {
isInstalled = isInstalledNewSimulator
}
// val versionFromInstalledApp = PackageUtils.getVersionNameByPackageName(simulator?.apk?.packageName)
val shouldShowUpdate =
PackageUtils.isInstalledApkMatchedMd5(simulator?.apk?.packageName, simulator?.apk?.md5)
val showAlertTag = SPUtils.getString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, "") //当天是否弹过
val todayIsShow = showAlertTag == TimeUtils.getToday()
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
if (downloadType == "update" && todayIsShow && location != SimulatorLocation.SIMULATOR_MANAGE) {
return@checkGetInstalledAppsListBeforeAction
}
if (downloadType == "download" && isInstalled) {
return@checkGetInstalledAppsListBeforeAction
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
val trackableEntity = TrackableEntity(
"模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
val shouldShowUpdate =
PackageUtils.isInstalledApkMatchedMd5(simulator?.apk?.packageName, simulator?.apk?.md5)
val showAlertTag = SPUtils.getString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, "") //当天是否弹过
val todayIsShow = showAlertTag == TimeUtils.getToday()
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
if (downloadType == "update" && todayIsShow && location != SimulatorLocation.SIMULATOR_MANAGE) {
return
}
if (downloadType == "download" && isInstalled) {
return
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
val trackableEntity = TrackableEntity(
"模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
message,
positiveText,
negativeText,
trackMtaEvent = true,
cancelClickCallback = {
if (shouldShowUpdate && isInstalled) {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
message,
positiveText,
negativeText,
trackMtaEvent = true,
cancelClickCallback = {
if (shouldShowUpdate && isInstalled) {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
if (downloadType == "update" && location != SimulatorLocation.SIMULATOR_MANAGE) {
SPUtils.setString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, TimeUtils.getToday())
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
if (downloadType == "update" && location != SimulatorLocation.SIMULATOR_MANAGE) {
SPUtils.setString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, TimeUtils.getToday())
}
}
}
if (context is AppCompatActivity
&& PackageUtils.isSupportGetInstalledAppsPermission(context)
&& PermissionHelper.isGetInstalledListPermissionDisabled(context)) {
PermissionHelper.requestGetInstalledAppsListPermission(context, false, callback)
} else {
callback.onCallback()
}
}
fun showDownloadingDialog(
@ -392,7 +403,7 @@ class SimulatorDownloadManager private constructor() {
ToastUtils.showToast("该模拟器暂未提供下载")
},
uiModificationCallback = { binding ->
binding.confirmTv.setTextColor(R.color.text_instance.toColor(context))
binding.confirmTv.setTextColor(R.color.text_body.toColor(context))
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
@ -417,7 +428,7 @@ class SimulatorDownloadManager private constructor() {
DownloadStatus.diskioerror,
DownloadStatus.diskisfull -> {
DownloadManager.getInstance().addObserver(dataWatcher)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, false) }, 200)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, true) }, 200)
SensorsBridge.trackSimulatorDownloadDialogShow(
gameId = gameId,
gameName = gameName,

View File

@ -8,6 +8,7 @@ import android.graphics.Bitmap
import android.net.Uri
import android.text.TextUtils
import com.gh.common.constant.Config
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
@ -23,13 +24,13 @@ import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.SimulatorGameRecordEntity
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadDao
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
@ -38,6 +39,7 @@ import okhttp3.ResponseBody
import org.json.JSONArray
import java.io.ByteArrayOutputStream
import java.io.File
import java.util.*
object SimulatorGameManager {
@ -183,8 +185,8 @@ object SimulatorGameManager {
val intent = Intent()
intent.data = Uri.fromFile(File(downloadEntity.path))
if (gameEntity.simulatorType == "FBA" || gameEntity.simulatorType == "FBN") {
val apkEntity = gameEntity.getApk().firstOrNull()
intent.putExtra("rom_name", apkEntity?.packageName ?: "")
val apkEntity = gameEntity.getApk()[0]
intent.putExtra("rom_name", apkEntity.packageName)
}
intent.putExtra("default_path", downloadEntity.path.substring(0, downloadEntity.path.lastIndexOf('/')))
intent.putExtra("game_type", gameEntity.simulatorType)

View File

@ -9,7 +9,6 @@ import androidx.fragment.app.Fragment
import com.gh.download.simple.AutoUnregisteredSimpleDownloadListener
import com.gh.download.simple.DownloadListener
import com.gh.gamecenter.R
import com.gh.gamecenter.cloudarchive.BaseCloudArchiveViewModel
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
@ -37,7 +36,6 @@ object ArchiveDownloadButtonHelper {
entrance: String,
fragment: Fragment,
packageName: String,
viewModel: BaseCloudArchiveViewModel,
archiveEntity: ArchiveEntity,
downloadBtn: TextView,
gameEntity: GameEntity?,
@ -62,23 +60,19 @@ object ArchiveDownloadButtonHelper {
}
}
// 检查本地是否已下载存档
VArchiveHelper.isArchiveDownloaded(archiveEntity.md5) -> viewModel.getArchiveConfigString {
showApplyArchiveTipDialog(
context,
entrance,
packageName,
it,
archiveEntity,
gameEntity
)
}
VArchiveHelper.isArchiveDownloaded(archiveEntity.md5) -> showApplyArchiveTipDialog(
context,
entrance,
packageName,
archiveEntity,
gameEntity
)
// 检查完毕下载存档
else -> downloadArchive(
context,
entrance,
fragment,
packageName,
viewModel,
archiveEntity,
downloadBtn,
gameEntity,
@ -131,7 +125,6 @@ object ArchiveDownloadButtonHelper {
context: Context,
entrance: String,
packageName: String,
config: String,
archiveEntity: ArchiveEntity,
gameEntity: GameEntity?
) {
@ -142,7 +135,7 @@ object ArchiveDownloadButtonHelper {
.subscribeOn(Schedulers.io())
.subscribe()
VArchiveHelper.applyGameArchive(context, packageName, config, this) { packageName, isSuccess ->
VArchiveHelper.applyGameArchive(context, packageName, this) { packageName, isSuccess ->
runOnUiThread {
if (isSuccess) {
VHelper.launch(context, packageName)
@ -168,7 +161,6 @@ object ArchiveDownloadButtonHelper {
entrance: String,
fragment: Fragment,
packageName: String,
viewModel: BaseCloudArchiveViewModel,
archiveEntity: ArchiveEntity,
downloadBtn: TextView,
gameEntity: GameEntity?,
@ -205,9 +197,7 @@ object ArchiveDownloadButtonHelper {
DownloadStatus.COMPLETED -> {
dismissArchiveLoadingDialog(archiveLoadingDialog)
downloadBtn.text = R.string.archive_apply.toResString()
viewModel.getArchiveConfigString {
showApplyArchiveTipDialog(context, entrance, packageName, it, archiveEntity, gameEntity)
}
showApplyArchiveTipDialog(context, entrance, packageName, archiveEntity, gameEntity)
downloadCompletedListener?.invoke()
}
else -> {
@ -261,46 +251,43 @@ object ArchiveDownloadButtonHelper {
context: Context,
entrance: String,
packageName: String,
config: String,
archiveEntity: ArchiveEntity,
gameEntity: GameEntity?
) {
runOnUiThread {
DialogHelper.showDialog(
context,
R.string.archive_dialog_title.toResString(),
R.string.archive_apply_dialog_content.toResString(),
R.string.archive_apply.toResString(),
R.string.cancel.toResString(),
{
applyArchive(context, entrance, packageName, config, archiveEntity, gameEntity)
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "使用")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogClick",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"button_name", "使用"
)
},
{
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "取消")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogClick",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"button_name", "取消"
)
},
extraConfig = DialogHelper.Config(centerTitle = true)
)
DialogHelper.showDialog(
context,
R.string.archive_dialog_title.toResString(),
R.string.archive_apply_dialog_content.toResString(),
R.string.archive_apply.toResString(),
R.string.cancel.toResString(),
{
applyArchive(context, entrance, packageName, archiveEntity, gameEntity)
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "使用")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogClick",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"button_name", "使用"
)
},
{
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "取消")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogClick",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"button_name", "取消"
)
},
extraConfig = DialogHelper.Config(centerTitle = true)
)
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_show")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogShow",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: ""
)
}
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_show")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogShow",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: ""
)
}
private fun dismissArchiveLoadingDialog(archiveLoadingDialog: Dialog) {

View File

@ -64,7 +64,7 @@ object BbsReportHelper {
this,
1f,
false,
R.color.ui_background
R.color.background
)
)
binding.reasonRv.adapter = reportReasonAdapter
@ -94,7 +94,7 @@ object BbsReportHelper {
binding.otherReasonEt.doOnTextChanged { text, start, before, count ->
val tvCount: Int = text.toString().length
if (tvCount >= 500) {
binding.tvCount.setTextColor(R.color.secondary_red.toColor(binding.tvCount.context))
binding.tvCount.setTextColor(R.color.theme_red.toColor(binding.tvCount.context))
}
binding.tvCount.text = "$tvCount/500"
}

View File

@ -1,11 +1,17 @@
package com.gh.common.util;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.core.utils.CurrentActivityHolder;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
import com.gh.gamecenter.login.view.LoginActivity;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.login.user.UserManager;
import com.lightgame.utils.Utils;
@ -22,15 +28,15 @@ public class CheckLoginUtils {
LogUtils.login("dialog", null, entrance);
LogUtils.login("activity", null, entrance);
// if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
// startQuickLogin(context, entrance);
// } else {
// 有可能App未启动
Bundle bundle = new Bundle();
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
bundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivity(context, bundle);
// }
if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
startQuickLogin(context, entrance);
} else {
// 有可能App未启动
Bundle bundle = new Bundle();
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
bundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivity(context, bundle);
}
} else {
if (listener != null) {
listener.onLogin();
@ -38,16 +44,16 @@ public class CheckLoginUtils {
}
}
// private static void startQuickLogin(Context context, String entrance) {
// // 需要确保传入的 context 不为 application
// if (!(context instanceof Activity)) {
// context = CurrentActivityHolder.getCurrentActivity();
// }
//
// if (context != null) {
// QuickLoginHelper.startLogin(context, entrance);
// }
// }
private static void startQuickLogin(Context context, String entrance) {
// 需要确保传入的 context 不为 application
if (!(context instanceof Activity)) {
context = CurrentActivityHolder.getCurrentActivity();
}
if (context != null) {
QuickLoginHelper.startLogin(context, entrance);
}
}
public static void checkLogin(final Context context, Bundle nextToBundle, boolean isTriggerNextStep, String entrance, OnLoginListener listener) {
if (!isLogin()) {

View File

@ -198,7 +198,7 @@ public class CommentUtils {
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
container.setBackgroundColor(ContextCompat.getColor(context, R.color.ui_surface));
container.setBackgroundColor(ContextCompat.getColor(context, R.color.background_white));
for (final String s : arrReportType) {
TextView reportTypeTv = new TextView(context);
@ -248,12 +248,12 @@ public class CommentUtils {
public static void postVote(final Context context, final CommentEntity commentEntity,
final TextView commentLikeCountTv, final ImageView commentLikeIv,
final OnVoteListener listener) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.text_theme)) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme));
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
@ -318,12 +318,12 @@ public class CommentUtils {
entrance = "视频流-评论-点赞";
}
CheckLoginUtils.checkLogin(context, entrance, () -> {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.text_theme)) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme));
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
@ -444,7 +444,7 @@ public class CommentUtils {
public void onFailure(@Nullable HttpException e) {
super.onFailure(e);
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme));
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
@ -502,7 +502,7 @@ public class CommentUtils {
holder.commentLikeCountTv.setVisibility(View.GONE);
} else { // 检查是否已点赞
if (userDataEntity != null && (userDataEntity.isCommentVoted())) {
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_theme));
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
holder.commentLikeIv.setImageResource(R.drawable.comment_vote_select);
}
holder.commentLikeCountTv.setVisibility(View.VISIBLE);
@ -533,7 +533,7 @@ public class CommentUtils {
} else {
ImageUtils.display(holder.commentUserBadgeIv, "");
}
ImageUtils.display(holder.commentUserIconDv, userInfo.getIcon());
ImageUtils.displayIcon(holder.commentUserIconDv, userInfo.getIcon());
} else {
if (entity.getMe() != null && entity.getMe().isContentOwner()) {
holder.commentAuthorTv.setVisibility(View.VISIBLE);
@ -549,7 +549,7 @@ public class CommentUtils {
if (TextUtils.isEmpty(entity.getUser().getIcon())) {
ImageUtils.display(holder.commentUserIconDv, R.drawable.user_default_icon_comment);
} else {
ImageUtils.display(holder.commentUserIconDv, entity.getUser().getIcon());
ImageUtils.displayIcon(holder.commentUserIconDv, entity.getUser().getIcon());
}
}
}

View File

@ -18,6 +18,7 @@ import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.SPUtils;
@ -124,8 +125,17 @@ public class DataUtils {
HaloApp.getInstance().setGid(gid);
SensorsBridge.setGid(gid);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
ExtensionsKt.doOnMainProcessOnly(HaloApp.getInstance(), () -> {
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
});
// 避免重复调用
if (!TextUtils.isEmpty(gid)) {
GameSubstituteRepositoryHelper.updateSubstitutableGames();
}
getDeviceCertification(gid);
@ -145,8 +155,7 @@ public class DataUtils {
@Override
public void onFailure(String s) {
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
MtaHelper.onEventWithBasicDeviceInfo("开发辅助", "GID 获取异常", s);
}
});
}
@ -171,11 +180,9 @@ public class DataUtils {
if (idCardEntity != null) {
boolean isCertificated = !TextUtils.isEmpty(data.getIdCard().getId());
boolean isAdult = data.getIdCard().getMinor() == null || !data.getIdCard().getMinor();
boolean isCertificating = data.getIdCard().getStatus() == 1;
values.put(GhContentProvider.KEY_IS_CERTIFICATED, isCertificated); // 是否认证
values.put(GhContentProvider.KEY_IS_ADULT, isAdult); // 是否成年
values.put(GhContentProvider.KEY_IS_CERTIFICATING, isCertificating); // 是否认证中
if (!isCertificated) {
RealNameHelper.updateCertificationStatus(0);
@ -189,12 +196,12 @@ public class DataUtils {
} else {
values.put(GhContentProvider.KEY_IS_CERTIFICATED, false);
values.put(GhContentProvider.KEY_IS_ADULT, false);
values.put(GhContentProvider.KEY_IS_CERTIFICATING, false);
RealNameHelper.updateCertificationStatus(0);
}
RealNameHelper.INSTANCE.onRealNameInfoUpdated();
EventBus.getDefault().post(new EBReuse(Constants.EB_REALNAME_RESULT));
// new GhContentProvider().localInsert( HaloApp.getInstance().getApplication(),values);
try {
// Unknown URL content://com.gh.gamecenter.provider/certification
// TODO 将 com.gh.gamecenter 改成 BuildConfig.ApplicationID

View File

@ -1,80 +0,0 @@
package com.gh.common.util
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.TextView
import com.gh.common.constant.Config
/**
* 光环游戏搜索栏默认文案轮换
*/
object DefaultSearchHintHelper {
private val hintList = ArrayList<String>()
init {
loadData()
}
fun loadData() {
hintList.clear()
Config.getSettings()?.search?.defaultData?.also {
if (it.isNotEmpty()) {
for (h in it) {
hintList.add(h.removeSuffix("."))
}
}
}
}
fun setSearchHint(searchTv: TextView) {
var hintIndex = 0
val scaleAnimation = ScaleAnimation(
0.4F, 1.0F, 0.4F, 1.0F,
Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F
)
scaleAnimation.duration = 500
val alphaAnimation = AlphaAnimation(1F, 0.2F)
alphaAnimation.duration = 300
alphaAnimation.startOffset = 5000
scaleAnimation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {}
override fun onAnimationEnd(animation: Animation) {
searchTv.animation = alphaAnimation
alphaAnimation.start()
}
override fun onAnimationRepeat(animation: Animation) {}
})
alphaAnimation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {}
override fun onAnimationEnd(animation: Animation) {
// 切换数据
if (hintList.isNotEmpty()) {
if (hintIndex > hintList.size - 1) {
hintIndex = 0
}
searchTv.hint = hintList[hintIndex]
hintIndex++
searchTv.animation = scaleAnimation
scaleAnimation.start()
}
}
override fun onAnimationRepeat(animation: Animation) {}
})
if (hintList.isEmpty()) {
loadData()
}
if (hintList.isNotEmpty()) {
if (hintList.size > 1) {
searchTv.animation = alphaAnimation
} else {
val hint = hintList[0]
searchTv.hint = hint
}
}
}
}

View File

@ -12,6 +12,9 @@ import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.xapk.XapkInstaller;
import com.gh.common.xapk.XapkUnzipStatus;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
@ -19,9 +22,6 @@ import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
@ -259,7 +259,7 @@ public class DetailDownloadUtils {
if (showDualDownloadButton && viewHolder.getLocalDownloadSizeTv() != null) {
viewHolder.getLocalDownloadSizeTv().setVisibility(View.GONE);
String size = viewHolder.getGameEntity().getApk().isEmpty() ? "" : viewHolder.getGameEntity().getApk().get(0).getSize();
String size = viewHolder.getGameEntity().getApk().get(0).getSize();
if (size != null) {
String sizeWithoutDigit = size.replaceAll("(?<=\\d)\\.[0-9]+(?!\\d)", "");
viewHolder.getLocalDownloadSizeTv().setText(sizeWithoutDigit);
@ -367,7 +367,8 @@ public class DetailDownloadUtils {
String downloadAddWord = gameEntity.getDownloadAddWord();
// 不满足条件的部分游戏隐藏下载按钮
if (!"光环助手".equals(gameEntity.getName())) {
if (Config.isShowDownload(gameEntity.getId())
&& !"光环助手".equals(gameEntity.getName())) {
viewHolder.getDownloadBottom().setVisibility(View.VISIBLE);
} else {
viewHolder.getDownloadBottom().setVisibility(View.GONE);
@ -442,7 +443,7 @@ public class DetailDownloadUtils {
}
private static String getDownloadSizeText(DetailViewHolder viewHolder) {
return String.format("%s", viewHolder.getGameEntity().getApk().isEmpty() ? "" : viewHolder.getGameEntity().getApk().get(0).getSize());
return String.format("%s", viewHolder.getGameEntity().getApk().get(0).getSize());
}
private static void updateVStyleDownloadButton(DetailViewHolder viewHolder,
@ -457,7 +458,8 @@ public class DetailDownloadUtils {
break;
case waiting:
downloadButton.setText(R.string.waiting);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.WAITING);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
downloadButton.setVisibility(View.GONE);
break;
case overflow:
case timeout:

View File

@ -1,17 +1,23 @@
package com.gh.common.util
import android.content.Context
import android.os.Environment
import android.preference.PreferenceManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.entity.TimeEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.io.File
object DeviceTokenUtils {
const val DEVICE_ID = "uuid"
// 同步服务器时间
@JvmStatic
@Synchronized
@ -33,29 +39,99 @@ object DeviceTokenUtils {
}
@JvmStatic
fun getLaunchType(): LunchType {
fun getLaunchType(readOnly: Boolean = false): LunchType {
var lunchType: LunchType? = null
val values = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().application).all
// 版本更新
if (values.isNotEmpty()) {
for (value in values) {
if (value.key.contains(Constants.SP_NEW_FIRST_LAUNCH_VERSION)) {
if (value.key.contains("isNewFirstLaunchV")) {
lunchType = LunchType.UPDATE
break
}
}
}
// 再次重装
if (lunchType == null && !getDeviceId().isNullOrEmpty()) {
lunchType = LunchType.AGAIN
}
// 首次安装
if (lunchType == null) {
lunchType = LunchType.FIRST
}
// 保存deviceId
var deviceId = MetaUtil.getIMEI()
if (deviceId.isNullOrEmpty()) {
deviceId = Utils.getTime(HaloApp.getInstance().application).toString()
}
if (!readOnly) {
setDeviceId(deviceId)
}
return lunchType
}
private fun getDeviceFileList(): List<File> {
val sdCardDir = Environment.getExternalStorageDirectory()
val fileList: MutableList<File> = ArrayList()
fileList.add(File(sdCardDir.path + "/gh-uuid/$DEVICE_ID"))
fileList.add(File(sdCardDir.path + "/system/$DEVICE_ID"))
fileList.add(File(sdCardDir.path + "/data/$DEVICE_ID"))
return fileList
}
@Synchronized
private fun setDeviceId(deviceId: String) {
//将deviceId存到sp
val sp = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().application)
val edit = sp.edit()
edit.putString(DEVICE_ID, deviceId)
edit.apply()
Utils.log("saveDeviceId", "保存成功SP")
//将deviceId存到SD卡
for (file in getDeviceFileList()) {
try {
val parentFile = file.parentFile
if (!parentFile.exists()) parentFile.mkdirs()
file.writeText(deviceId)
Utils.log("saveDeviceId", "保存成功SDCard目录为${file.path}")
} catch (e: Exception) {
Utils.log("保存u${DEVICE_ID}到SDCard异常${file.path} " + e.toString())
e.printStackTrace()
}
}
}
private fun getDeviceId(): String? {
val sp = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().application)
var deviceId = sp.getString(DEVICE_ID, null)
if (deviceId.isNullOrEmpty()) {
val fileList = getDeviceFileList()
for (file in fileList) {
if (file.exists()) {
try {
deviceId = file.readText()
Utils.log("getDeviceId", "获取成功DataFile$DEVICE_ID")
return deviceId
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
if (BuildConfig.DEBUG) {
Utils.log("getDeviceId", "获取成功SP$DEVICE_ID")
}
return deviceId
}
}
enum class LunchType {
FIRST,
UPDATE
UPDATE,
AGAIN
}

View File

@ -82,7 +82,6 @@ import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function0;
public class DialogUtils {
@ -356,8 +355,8 @@ public class DialogUtils {
TextView negativeTv = contentView.findViewById(R.id.negative);
TextView positiveTv = contentView.findViewById(R.id.positive);
TextView content = contentView.findViewById(R.id.content);
positiveTv.setBackground(DrawableView.getOvalDrawable(R.color.ui_background, 999));
negativeTv.setBackground(DrawableView.getOvalDrawable(R.color.primary_theme, 999));
positiveTv.setBackground(DrawableView.getOvalDrawable(R.color.background, 999));
negativeTv.setBackground(DrawableView.getOvalDrawable(R.color.theme, 999));
content.setText(Html.fromHtml(context.getString(R.string.video_upload_draft_dialog_content)));
negativeTv.setOnClickListener(view -> {
@ -579,15 +578,11 @@ public class DialogUtils {
dialog.dismiss();
});
ApkEntity apkEntity = CollectionsKt.firstOrNull(gameEntity.getApk());
String size = apkEntity == null ? "" : apkEntity.getSize();
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
if (apkEntity != null) {
apkEntity.setUrl(gameEntity.getOverseasAddressDialog().getLink());
}
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
}
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.downloadBtn.setText("下载(" + size + "");
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
binding.downloadBtn.setOnClickListener(v -> {
dismissByTouchInside.set(true);
SensorsBridge.trackOverseasAddressDialogClick(
@ -636,12 +631,7 @@ public class DialogUtils {
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
binding.urlTv.setText(gameEntity.getLandPageAddressDialog().getLink());
String downloadText = gameEntity.isLandPageAddressDialogShowOnly()
? "下载(" + gameEntity.getApk().get(0).getSize() + ""
: context.getString(R.string.dialog_land_page_address_confirm);
binding.downloadBtn.setText(downloadText);
binding.downloadBtn.setText(context.getString(R.string.dialog_land_page_address_confirm));
binding.downloadBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
@ -1069,10 +1059,10 @@ public class DialogUtils {
DialogPackageParseErrorBinding binding = DialogPackageParseErrorBinding.inflate(LayoutInflater.from(context), null, false);
Context finalContext = context;
SpannableStringBuilder builder = new SpanBuilder("您也可以点击提交反馈跟我们联系").click(context, 6, 10, R.color.text_theme, true, new Function0<Unit>() {
SpannableStringBuilder builder = new SpanBuilder("您也可以点击提交反馈跟我们联系").click(context, 6, 10, R.color.theme_font, true, new Function0<Unit>() {
@Override
public Unit invoke() {
SimpleGameEntity entity = new SimpleGameEntity(gameId, gameName, "", "");
SimpleGameEntity entity = new SimpleGameEntity(gameId, gameName, "");
HelpAndFeedbackBridge.startSuggestionActivity(finalContext, SuggestType.GAME, "notfound", "模拟器安装包解析错误", entity);
dialog.dismiss();
return null;
@ -1128,7 +1118,7 @@ public class DialogUtils {
return null;
});
binding.reasonRv.setLayoutManager(new LinearLayoutManager(context));
binding.reasonRv.addItemDecoration(new VerticalItemDecoration(context, 1F, false, R.color.ui_background));
binding.reasonRv.addItemDecoration(new VerticalItemDecoration(context, 1F, false, R.color.background));
binding.reasonRv.setAdapter(reportReasonAdapter);
binding.negativeBtn.setOnClickListener(v -> {
@ -1150,7 +1140,7 @@ public class DialogUtils {
ExtensionsKt.setTextChangedListener(binding.otherReasonEt, (s, start, before, count) -> {
int tvCount = s.length();
if (tvCount >= 500) {
binding.tvCount.setTextColor(ContextCompat.getColor(finalContext, R.color.secondary_red));
binding.tvCount.setTextColor(ContextCompat.getColor(finalContext, R.color.theme_red));
}
binding.tvCount.setText(tvCount + "/500");
return null;

View File

@ -33,22 +33,29 @@ import com.gh.gamecenter.common.entity.*
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
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
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.CommunityActivity
import com.gh.gamecenter.forum.home.CommunityHomeFragment
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailActivity
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
@ -61,9 +68,7 @@ import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersSubscribedGameListActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.libao.LibaoDetailActivity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.gh.gamecenter.personalhome.UserHomeActivity
import com.gh.gamecenter.personalhome.background.PersonalityBackgroundActivity
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
@ -83,20 +88,19 @@ import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity
import com.gh.gamecenter.setting.SettingBridge
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.tag.TagsActivity
import com.gh.gamecenter.toolbox.ToolBoxActivity
import com.gh.gamecenter.toolbox.ToolBoxBlockActivity
import com.gh.gamecenter.video.data.VideoDataActivity
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.gh.gamecenter.video.game.GameVideoActivity
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.gh.gamecenter.wrapper.MainWrapperRepository
import com.gh.gamecenter.wrapper.ToolbarWrapperActivity
import com.gh.vspace.VDownloadManagerActivity
import com.halo.assistant.HaloApp
import com.halo.assistant.fragment.WebFragment
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException
import java.net.URLEncoder
import java.util.*
@ -108,8 +112,8 @@ import kotlin.math.roundToInt
object DirectUtils {
@JvmStatic
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String, sourceEntrance: String = "") {
directToLinkPage(context, linkEntity, entrance, path, null, sourceEntrance)
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
directToLinkPage(context, linkEntity, entrance, path, null)
}
@JvmStatic
@ -118,10 +122,9 @@ object DirectUtils {
linkEntity: LinkEntity,
entrance: String,
path: String,
exposureEvent: ExposureEvent? = null,
sourceEntrance: String = ""
exposureEvent: ExposureEvent? = null
) {
directToLinkPage(context, linkEntity, entrance, path, exposureEvent, null, sourceEntrance)
directToLinkPage(context, linkEntity, entrance, path, exposureEvent, null)
}
// 用于判断是否已经对接相关类型
@ -156,21 +159,7 @@ object DirectUtils {
"explore_column",
"game_explore",
"column_test_v2",
"game_list_collection",
"multi_tab_nav",
"custom_page",
"bottom_tab",
"qq_mini_game_column_detail",
"game_hot_list",
"libao_center",
"article_center",
"video_stream",
"libao",
"community_home",
"bbs_section",
"qa",
"feedback",
"toolkit"
"game_list_collection"
)
fun directToLinkPage(
@ -180,7 +169,6 @@ object DirectUtils {
path: String,
exposureEvent: ExposureEvent? = null,
unknownCallback: (() -> Unit)?,
sourceEntrance: String = ""
) {
when (linkEntity.type) {
"article", "news", "文章" -> {
@ -195,7 +183,6 @@ object DirectUtils {
if (exposureEvent != null) {
directToGameDetail(
context, linkEntity.link
?: "", linkEntity.text
?: "", BaseActivity.mergeEntranceAndPath(entrance, path), traceEvent = exposureEvent
)
} else {
@ -216,7 +203,7 @@ object DirectUtils {
"question", "社区问题" -> directToQuestionDetail(
context, linkEntity.link
?: "", entrance, path, sourceEntrance
?: "", entrance, path
)
"answer", "社区回答" -> directToAnswerDetail(context, linkEntity.link ?: "", entrance, path)
@ -231,8 +218,7 @@ object DirectUtils {
linkEntity.community!!,
linkEntity.link!!,
entrance,
path,
sourceEntrance,
path
)
"community_column", "社区专题" -> directToCommunityColumn(
@ -310,7 +296,6 @@ object DirectUtils {
"",
linkEntity.blockId,
linkEntity.blockName,
"",
exposureEvent
)
@ -320,21 +305,12 @@ object DirectUtils {
"wechat_bind" -> context.startActivity(WebActivity.getBindWechatIntent(context))
"video", "bbs_video", "视频" -> directToVideoDetail(
"video", "bbs_video", "video_stream", "视频" -> directToVideoDetail(
context,
videoId = linkEntity.link!!,
fromLocation = VideoDetailContainerViewModel.Location.VIDEO_CHOICENESS.value,
entrance = entrance,
path = path,
sourceEntrance = sourceEntrance
)
"video_stream" -> directToLegacyVideoDetail(
context,
"",
VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value,
referer = "视频流-$entrance",
isHomeVideo = true
path = path
)
"game_video" -> directToGameVideo(context, linkEntity.link ?: "", entrance, path)
@ -345,8 +321,6 @@ object DirectUtils {
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa_list" -> directToHelpAndFeedback(context)
"qa_collection", "Q&A合集" -> directToQaCollection(
context, linkEntity.text
?: "", linkEntity.link
@ -407,17 +381,17 @@ object DirectUtils {
"setting" -> context.startActivity(SettingBridge.getSettingIntent(context, false, entrance))
"index_page" -> directToHomeDefaultTab(context)
"index_page" -> directToHomeTab(context)
"video_upload" -> context.startActivity(VideoManagerActivity.getIntent(context, "", entrance))
"bbs", "community_home" -> directToHomeCommunityTab(context)
"bbs" -> directToForum(context)
"user_page" -> directToHomeActivity(context, UserManager.getInstance().userId, "", entrance)
"video_tab" -> directToHomeVideoTab(context)
"video_tab" -> directToVideoTab(context)
"toolkit" -> context.startActivity(ToolBoxActivity.getIntent(context, entrance))
"toolkit" -> context.startActivity(ToolBoxBlockActivity.getIntent(context, entrance))
"column_test" -> context.startActivity(
GameServerTestActivity.getIntent(
@ -438,7 +412,7 @@ object DirectUtils {
} ?: ""
}
"halo_tab" -> directToHomeMyHaloTab(context)
"halo_tab" -> directToPersonalTab(context)
"common_collection" -> directToCommonCollectionDetail(
context,
@ -477,29 +451,6 @@ object DirectUtils {
"qq_mini_game_column" -> directToQGameHome(context)
// QQ游戏专题详情页
"qq_mini_game_column_detail" -> {
directToSubject(
context = context,
id = linkEntity.link ?: "",
subjectName = linkEntity.text,
entrance = BaseActivity.mergeEntranceAndPath(entrance, path),
exposureEvent = exposureEvent,
isQQMiniGame = true
)
}
// 资讯中心
"article_center" -> {
context.startActivity(InfoActivity.getIntent(context))
}
// 礼包中心
"libao_center" -> {
directToGift(context, entrance)
}
"game_hot_list" -> directToGameCollectionHotList(context, entrance)
"game_list_collection" -> directToGameCollectionListDetail(
context,
linkEntity.link ?: "",
@ -508,34 +459,6 @@ object DirectUtils {
entrance
)
"multi_tab_nav" -> context.startActivity(
ToolbarWrapperActivity.getMultiTabNavIntent(
context,
linkEntity.link ?: "",
linkEntity.text ?: ""
)
)
"custom_page" -> context.startActivity(
ToolbarWrapperActivity.getCustomPageIntent(
context,
linkEntity.link ?: "",
linkEntity.text ?: ""
)
)
// 选中首页底部 tab
"bottom_tab" -> {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
}
context.startActivity(intent)
if (linkEntity is LaunchRedirect) {
MainWrapperRepository.getInstance().sendSelectTabEvent(linkEntity)
}
}
"" -> {
// do nothing
}
@ -590,9 +513,7 @@ object DirectUtils {
columnName: String = "",
blockId: String = "",
blockName: String = "",
style: String = "",
exposureEvent: ExposureEvent? = null,
showSubjectTab: Boolean = false
exposureEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
val bundle = Bundle()
@ -602,9 +523,7 @@ object DirectUtils {
bundle.putString(KEY_COLUMNNAME, columnName)
bundle.putString(KEY_BLOCK_ID, blockId)
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putString(KEY_COLUMN_COLLECTION_STYLE, style)
bundle.putInt(KEY_POSITION, position)
bundle.putBoolean(KEY_SHOW_SUBJECT_TAB, showSubjectTab)
if (exposureEvent != null) {
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source))
}
@ -659,7 +578,7 @@ object DirectUtils {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.name)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
bundle.putString(KEY_NEWSID, id)
if (entrance?.contains("隐私政策") == true) {
bundle.putBoolean(KEY_HIDE_USELESS_INFO, true)
@ -675,7 +594,7 @@ object DirectUtils {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.name)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
bundle.putString(KEY_NEWSID, id)
bundle.putBoolean(KEY_HIDE_USELESS_INFO, hideUselessInfo)
jumpActivity(context, bundle)
@ -754,7 +673,6 @@ object DirectUtils {
fun directToGameDetail(
context: Context,
id: String,
name: String = "",
entrance: String? = null,
autoDownload: Boolean? = null,
tab: String? = "",
@ -774,7 +692,7 @@ object DirectUtils {
}
}
if (traceEvent != null) {
val clickEvent = createEvent(GameEntity(id = id, name = name), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK)
val clickEvent = createEvent(GameEntity(id), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK)
log(clickEvent)
bundle.putParcelable(KEY_TRACE_EVENT, clickEvent)
}
@ -928,31 +846,6 @@ object DirectUtils {
jumpActivity(context, bundle)
}
@JvmStatic
fun directToDownloadManager(
context: Context,
entrance: String = "",
bottomTab: String = "",
gameColumnId: String = "",
gameColumnName: String = "",
customPageId: String = "",
customPageName: String = "",
multiTabId: String = "",
multiTabName: String = ""
) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_TO, DownloadManagerActivity.TAG)
bundle.putString(KEY_BOTTOM_TAB_NAME, bottomTab)
bundle.putString(KEY_GAME_COLUMN_ID, gameColumnId)
bundle.putString(KEY_GAME_COLUMN_NAME, gameColumnName)
bundle.putString(KEY_CUSTOM_PAGE_ID, customPageId)
bundle.putString(KEY_CUSTOM_PAGE_NAME, customPageName)
bundle.putString(KEY_MULTI_TAB_NAV_ID, multiTabId)
bundle.putString(KEY_MULTI_TAB_NAV_NAME, multiTabName)
jumpActivity(context, bundle)
}
@JvmStatic
fun directToDownloadManagerAndStartUpdate(
context: Context,
@ -973,7 +866,7 @@ object DirectUtils {
fun directToToolbox(context: Context, gameId: String, toolboxUrl: String, entrance: String = ENTRANCE_BROWSER) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_TO, ToolBoxActivity::class.java.name)
bundle.putString(KEY_TO, ToolBoxBlockActivity::class.java.name)
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_URL, toolboxUrl)
jumpActivity(context, bundle)
@ -991,14 +884,13 @@ object DirectUtils {
}
@JvmStatic
fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null, sourceEntrance: String = "") {
fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewQuestionDetailActivity::class.java.name)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_QUESTIONS_ID, id)
bundle.putString(KEY_SOURCE_ENTRANCE, sourceEntrance)
jumpActivity(context, bundle)
}
@ -1097,7 +989,12 @@ object DirectUtils {
@JvmStatic
fun directToGiftDetail(context: Context, giftId: String, entrance: String? = null) {
if (giftId.isEmpty()) return
context.startActivity(LibaoDetailActivity.getIntentById(context, giftId, entrance))
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, LibaoDetailActivity::class.java.simpleName)
bundle.putString(EntranceConsts.KEY_ID, giftId)
HaloApp.put(LibaoEntity.TAG, null)
jumpActivity(context, bundle)
}
/**
@ -1114,7 +1011,21 @@ object DirectUtils {
*/
@JvmStatic
fun directToCommunity(context: Context, community: CommunityEntity?) {
// if (MainActivity::class.java.name != RunningUtils.getTopActivity(context)) {
// val intent = Intent(context, MainActivity::class.java)
// intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
// context.startActivity(intent)
//
// UserManager.getInstance().setCommunityData(community)
//
// // 这里换个线程操作是为了做一点延时
// AppExecutor.ioExecutor.execute {
// EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
// EventBus.getDefault().post(EBReuse(CommunityFragment.EB_RETRY_PAGE))
// }
// } else {
directForumDetail(context, community?.id)
// }
}
@JvmStatic
@ -1123,15 +1034,13 @@ object DirectUtils {
articleId: String?,
communityId: String?,
entrance: String?,
path: String?,
sourceEntrance: String = ""
path: String?
) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, ArticleDetailActivity::class.java.name)
bundle.putString(KEY_COMMUNITY_ARTICLE_ID, articleId)
bundle.putString(KEY_SOURCE_ENTRANCE, sourceEntrance)
bundle.putParcelable(KEY_COMMUNITY_DATA, CommunityEntity(id = communityId!!))
jumpActivity(context, bundle)
}
@ -1142,8 +1051,7 @@ object DirectUtils {
community: CommunityEntity?,
articleId: String?,
entrance: String?,
path: String?,
sourceEntrance: String = "",
path: String?
) {
if (articleId.isNullOrEmpty()) return
val bundle = Bundle()
@ -1151,7 +1059,6 @@ object DirectUtils {
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, ArticleDetailActivity::class.java.name)
bundle.putString(KEY_COMMUNITY_ARTICLE_ID, articleId)
bundle.putString(KEY_SOURCE_ENTRANCE, sourceEntrance)
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
jumpActivity(context, bundle)
}
@ -1181,8 +1088,7 @@ object DirectUtils {
fun directToVideoDetail(
context: Context, videoId: String,
entrance: String? = null,
path: String? = "",
sourceEntrance: String = ""
path: String? = ""
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
@ -1190,7 +1096,6 @@ object DirectUtils {
bundle.putString(KEY_TO, ForumVideoDetailActivity::class.java.name)
bundle.putString(KEY_VIDEO_ID, videoId);
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_SOURCE_ENTRANCE, sourceEntrance)
jumpActivity(context, bundle)
} else {
DialogHelper.showVideoUnsupportedDialog(context)
@ -1216,8 +1121,7 @@ object DirectUtils {
paginationType: String = "",
fieldId: String = "",
sectionName: String = "",
isHomeVideo: Boolean = false,
sourceEntrance: String = ""
isHomeVideo: Boolean = false
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
@ -1236,7 +1140,6 @@ object DirectUtils {
bundle.putString(KEY_FIELD_ID, fieldId)
bundle.putString(KEY_SECTION_NAME, sectionName)
bundle.putBoolean(KEY_IS_HOME_VIDEO, isHomeVideo)
SensorsBridge.trackAccessVideoStreaming(sourceEntrance)
jumpActivity(context, bundle)
} else {
DialogHelper.showVideoUnsupportedDialog(context)
@ -1252,10 +1155,9 @@ object DirectUtils {
gameId: String = "",
entrance: String? = null,
path: String? = "",
referer: String = "",
sourceEntrance: String = ""
referer: String = ""
) {
directToVideoDetail(context, videoId, entrance, path, sourceEntrance)
directToVideoDetail(context, videoId, entrance, path)
}
/**
@ -1556,61 +1458,85 @@ object DirectUtils {
}
/**
* 到首页-默认选中的 tab
* 到首页-首页 tab
*/
@JvmStatic
fun directToHomeDefaultTab(context: Context) {
fun directToHomeTab(context: Context) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
MainWrapperRepository.getInstance().sendReSelectDefaultTabEvent()
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_HOME))
}
} else {
jumpActivity(context, Bundle())
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_HOME) })
}
}
/**
* 到首页-社区 tab
* @param position 社区子 tab 位置
* 到首页-论坛 tab
* @param position 论坛的子 tab 位置
*/
@JvmStatic
fun directToHomeCommunityTab(context: Context) {
val bundle = Bundle()
bundle.putString(KEY_TO, CommunityActivity::class.java.name)
jumpActivity(context, bundle)
fun directToForum(context: Context, position: Int = 0) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
EventBus.getDefault().post(EBSkip(CommunityHomeFragment.EB_TAB, position))
}
} else {
jumpActivity(context, Bundle().apply {
putInt(KEY_POSITION, MainWrapperFragment.INDEX_BBS)
putInt(KEY_SUB_POSITION, position)
})
}
}
/**
* 到首页-视频 tab
*/
@JvmStatic
fun directToHomeVideoTab(context: Context) {
fun directToVideoTab(context: Context) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
} else {
jumpActivity(context, Bundle())
}
MainWrapperRepository.getInstance().sendSelectTabEvent(ViewPagerFragmentHelper.TYPE_VIDEO_STREAM)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_VIDEO))
}
} else {
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_VIDEO) })
}
}
/**
* 到首页-我的光环 tab
*/
fun directToHomeMyHaloTab(context: Context) {
@JvmStatic
fun directToPersonalTab(context: Context) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
} else {
jumpActivity(context, Bundle())
}
MainWrapperRepository.getInstance().sendSelectTabEvent(ViewPagerFragmentHelper.TYPE_MY_HALO)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_PERSONAL))
}
} else {
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_PERSONAL) })
}
}
/**
@ -1625,6 +1551,211 @@ object DirectUtils {
jumpActivityCompat(context, newBundle)
}
/**
* 跳转至商品详情
*/
@JvmStatic
fun directToCommodityDetail(context: Context, commodityId: String) {
var url: String = if (EnvHelper.isDevEnv) {
Constants.COMMODITY_DETAIL_ADDRESS_DEV
} else {
Constants.COMMODITY_DETAIL_ADDRESS
}
url = String.format(
Locale.CHINA,
"%s&shopid=%s&timestamp=%d",
url,
commodityId,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至光能记录默认跳到光能记录第一个Tab
*/
@JvmStatic
fun directToEnergyRecord(context: Context) {
directToEnergyRecord(context, 0)
}
@JvmStatic
fun directToEnergyRecord(context: Context, position: Int) {
var url: String = if (EnvHelper.isDevEnv) {
Constants.ENERGY_RECORD_ADDRESS_DEV
} else {
Constants.ENERGY_RECORD_ADDRESS
}
url = String.format(
Locale.CHINA,
"%s&position=%s&timestamp=%d",
url,
position,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至订单中心
*/
@JvmStatic
fun directToOrderCenter(context: Context) {
val url: String = if (EnvHelper.isDevEnv) {
Constants.ORDER_CENTER_ADDRESS_DEV
} else {
Constants.ORDER_CENTER_ADDRESS
}
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至订单详情
*/
@JvmStatic
fun directToOrderDetail(context: Context, orderId: String) {
var url: String = if (EnvHelper.isDevEnv) {
Constants.ORDER_DETAIL_ADDRESS_DEV
} else {
Constants.ORDER_DETAIL_ADDRESS
}
url = String.format(
Locale.CHINA,
"%s&order_id=%s&timestamp=%d",
url,
orderId,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至邀请好友
*/
@JvmStatic
fun directToInviteFriends(context: Context) {
val url: String = if (EnvHelper.isDevEnv) {
Constants.INVITE_FRIENDS_ADDRESS_DEV
} else {
Constants.INVITE_FRIENDS_ADDRESS
}
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至等级页面
*/
@JvmStatic
fun directToLevelPage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.LEVEL_ADDRESS
} else {
Constants.LEVEL_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s?timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至兑换规则
*/
@JvmStatic
fun directToExchangeRulePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.EXCHANGE_RULE_ADDRESS
} else {
Constants.EXCHANGE_RULE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至光能规则
*/
@JvmStatic
fun directToEnergyRulePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.ENERGY_RULE_ADDRESS
} else {
Constants.ENERGY_RULE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至兑换商品
*/
@JvmStatic
fun directToExchangeCommodityPage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.EXCHANGE_COMMODITY_ADDRESS
} else {
Constants.EXCHANGE_COMMODITY_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至抽奖乐园
*/
@JvmStatic
fun directToLotteryParadisePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.LOTTERY_PARADISE_ADDRESS
} else {
Constants.LOTTERY_PARADISE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至我的奖品
*/
@JvmStatic
fun directToMyPrizePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.MY_PRIZE_ADDRESS
} else {
Constants.MY_PRIZE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至中奖订单详情
*/
@JvmStatic
fun directToWinOrderDetail(context: Context, orderId: String, activityId: String) {
var url: String = if (isPublishEnv()) {
Constants.WIN_ORDER_DETAIL_ADDRESS
} else {
Constants.WIN_ORDER_DETAIL_ADDRESS_DEV
}
url = String.format(
Locale.CHINA,
"%s&order_id=%s&activity_id=%s&timestamp=%d",
url,
orderId,
activityId,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至地址信息
@ -1704,7 +1835,7 @@ object DirectUtils {
) {
if (collectionId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, CustomCommonCollectionDetailActivity::class.java.name)
bundle.putString(KEY_TO, CommonCollectionDetailActivity::class.java.name)
bundle.putString(KEY_BLOCK_ID, blockId)
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putString(KEY_ENTRANCE, entrance)
@ -1808,8 +1939,7 @@ object DirectUtils {
fromRatingKey: Boolean = false,
diagnosis: String = "",
forceLogin: Boolean = true,
requestCode: Int? = null,
isSmoothGame: Boolean = false
requestCode: Int? = null
) {
val intent = HelpAndFeedbackBridge.getIntent(
context,
@ -1822,8 +1952,7 @@ object DirectUtils {
qaContentId,
fromRatingKey,
diagnosis,
forceLogin,
isSmoothGame
forceLogin
)
if (requestCode != null) {
(context as Activity).startActivityForResult(intent, requestCode)
@ -1842,35 +1971,15 @@ object DirectUtils {
bbsId: String,
entrance: String,
sourceEntrance: String,
forumName: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
forumName: String
) {
context.startActivity(
ForumOrUserSearchActivity.getIntent(
context,
bbsId,
entrance,
sourceEntrance,
forumName,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
)
context.startActivity(ForumOrUserSearchActivity.getIntent(context, bbsId, entrance, sourceEntrance, forumName))
}
@JvmStatic
fun directToVGameDownload(context: Context, entrance: String, switchToDownloadingTab: Boolean = false) {
fun directToVGameDownload(context: Context, switchToDownloadingTab: Boolean = false) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_ENTRANCE, ENTRANCE_BROWSER)
bundle.putString(KEY_TO, VDownloadManagerActivity::class.java.name)
bundle.putInt(KEY_POSITION, if (switchToDownloadingTab) 1 else 0)
jumpActivity(context, bundle)
@ -1938,27 +2047,9 @@ object DirectUtils {
fun directToQGameSearch(
context: Context,
hint: String,
sourceEntrance: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
sourceEntrance: String
) {
context.startActivity(
QGameSearchActivity.getIntent(
context,
hint,
sourceEntrance,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
)
context.startActivity(QGameSearchActivity.getIntent(context, hint, sourceEntrance))
}
@SuppressLint("CheckResult")
@ -2051,62 +2142,4 @@ object DirectUtils {
context.startActivity(ServersCalendarManagementActivity.getIntent(context))
}
}
fun directToSearch(
context: Context,
searchType: String,
searchHint: String,
entrance: String,
sourceEntrance: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
) {
when (searchType) {
BottomTab.SearchStyle.TYPE_HALO_GAME -> context.startActivity(
SearchActivity.getIntent(
context,
false,
searchHint,
entrance,
sourceEntrance,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
)
BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> directToQGameSearch(
context,
"请输入小游戏关键词",
sourceEntrance,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
BottomTab.SearchStyle.TYPE_BBS -> directToForumOrUserSearch(
context,
"",
entrance,
sourceEntrance,
"",
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
}
}
}

View File

@ -6,7 +6,6 @@ import android.text.TextUtils
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.collection.ArrayMap
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.chain.*
import com.gh.common.constant.Config
@ -46,6 +45,7 @@ import com.gh.vspace.VHelper
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File
import java.util.concurrent.LinkedBlockingQueue
@ -199,7 +199,7 @@ object DownloadItemUtils {
holder.gameDownloadTips?.visibility = View.GONE
updateNormalItem(context, holder, gameEntity, briefStyle, isShowRecommendStar)
} else {
holder.multiVersionDownloadTv?.isVisible = !SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)
holder.multiVersionDownloadTv?.visibility = View.VISIBLE
updatePluginItem(context, holder, gameEntity, briefStyle, isShowRecommendStar)
}
updateDownloadButton(
@ -219,7 +219,7 @@ object DownloadItemUtils {
pluginLocation: PluginLocation? = PluginLocation.only_game
) {
// 控制是否显示下载按钮
downloadBtn.goneIf(context.getString(R.string.app_name) == gameEntity.name)
downloadBtn.goneIf(!Config.isShowDownload(gameEntity.id) || context.getString(R.string.app_name) == gameEntity.name)
// 青少年模式或者需要特殊处理显示查看
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) || gameEntity.isSpecialDownload()) {
downloadBtn.text = "查看"
@ -443,7 +443,6 @@ object DownloadItemUtils {
briefStyle: String?,
isShowRecommendStar: Boolean = false
) {
updateItemViewStatus(holder, briefStyle, gameEntity.columnRecommend, isShowRecommendStar)
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity != null) {
if (downloadEntity.isSimulatorGame()) {
@ -458,6 +457,7 @@ object DownloadItemUtils {
return
}
}
updateItemViewStatus(holder, briefStyle, gameEntity.columnRecommend, isShowRecommendStar)
}
// 更新插件的条目有多个apk包
@ -624,10 +624,9 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
location: String,
sourceEntrance: String = "其他"
location: String
) {
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, sourceEntrance, location, null)
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, location, null)
}
@JvmStatic
@ -638,11 +637,10 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
sourceEntrance: String = "其他",
location: String,
traceEvent: ExposureEvent?,
traceEvent: ExposureEvent?
) {
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, sourceEntrance, location, traceEvent, null)
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent, null)
}
/**
@ -656,10 +654,9 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
sourceEntrance: String = "其他",
location: String,
traceEvent: ExposureEvent?,
clickCallback: EmptyCallback?,
clickCallback: EmptyCallback?
) {
setOnClickListener(
context,
@ -668,7 +665,6 @@ object DownloadItemUtils {
position,
adapter,
entrance,
sourceEntrance,
location,
traceEvent,
clickCallback,
@ -688,7 +684,6 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
sourceEntrance: String = "其他",
location: String,
traceEvent: ExposureEvent?,
clickCallback: EmptyCallback?,
@ -776,33 +771,31 @@ object DownloadItemUtils {
return
}
if (gameEntity.isReservable) {
downloadBtn.setOnClickListener {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
downloadBtn.setOnClickListener {
SensorsBridge.trackEvent(
"AppointmentGame",
"game_name",
gameEntity.name ?: "",
"game_id",
gameEntity.id,
"game_type",
gameEntity.categoryChinese,
"source_entrance",
sourceEntrance
gameEntity.id
)
allStateClickCallback?.onCallback()
CheckLoginUtils.checkLogin(context, entrance) {
clickCallback?.onCallback()
ReservationHelper.reserve(
context,
gameEntity,
sourceEntrance
gameEntity.id,
gameEntity.name ?: ""
) {
LogUtils.logReservation(gameEntity, traceEvent)
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
}
} else {
}
} else {
downloadBtn.setOnClickListener {
allStateClickCallback?.onCallback()
clickCallback?.onCallback()
if ("download" == gameEntity.reserveStatus) {
@ -910,6 +903,7 @@ object DownloadItemUtils {
DownloadChainBuilder().apply {
addHandler(GamePermissionHandler())
addHandler(CheckStoragePermissionHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
}
.setProcessEndCallback { _, _ ->
@ -951,6 +945,7 @@ object DownloadItemUtils {
addHandler(BrowserInstallHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(OverseaDownloadHandler())
addHandler(LandPageAddressHandler())
addHandler(CheckDownloadHandler())
@ -969,6 +964,7 @@ object DownloadItemUtils {
addHandler(BrowserInstallHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
@ -986,6 +982,7 @@ object DownloadItemUtils {
addHandler(GamePermissionHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
@ -1004,6 +1001,7 @@ object DownloadItemUtils {
} else {
DownloadChainBuilder().apply {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback { _, isSubscribe ->
@ -1059,7 +1057,7 @@ object DownloadItemUtils {
NewSimulatorGameManager.showUpdateNewsSimulator(context, gameEntity, null)
return
}
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().firstOrNull()?.url)
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk()[0].url)
if (downloadEntity != null) {
val file = File(downloadEntity.path)
if (!file.exists()) {
@ -1125,7 +1123,7 @@ object DownloadItemUtils {
}
when (str) {
context.getString(R.string.resume) -> {
DownloadManager.getInstance().resume(downloadEntity, false)
DownloadManager.getInstance().resume(downloadEntity, true)
}
context.getString(R.string.waiting) -> {
@ -1153,7 +1151,7 @@ object DownloadItemUtils {
) {
if (gameEntity.getApk().isEmpty()) return
val msg = FileUtils.isCanDownload(context, gameEntity.getApk().firstOrNull()?.size ?: "")
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(
context,
@ -1191,7 +1189,7 @@ object DownloadItemUtils {
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
val msg = FileUtils.isCanDownload(context, gameEntity.getApk().firstOrNull()?.size ?: "")
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, gameEntity, false, entrance, location, isSubscribe, traceEvent)
ToastUtils.toast(gameEntity.name + "已加入下载队列")
@ -1218,7 +1216,7 @@ object DownloadItemUtils {
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
refreshCallback: EmptyCallback?
) {
val apkEntity = gameEntity.getApk().firstOrNull()
val apkEntity = gameEntity.getApk()[0]
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity != null) {
val path = downloadEntity.path
@ -1226,7 +1224,7 @@ object DownloadItemUtils {
FileUtils.isEmptyFile(path) -> {
Utils.toast(context, R.string.install_failure_hint)
DownloadManager.getInstance().cancel(downloadEntity.url)
gameEntity.getEntryMap().remove(apkEntity?.getPlatform())
gameEntity.getEntryMap().remove(apkEntity.getPlatform())
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}

View File

@ -8,7 +8,6 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.base.activity.BaseActivity
@ -18,13 +17,12 @@ 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.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.CustomPageTrackData
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
import com.gh.gamecenter.feature.utils.PlatformUtils
@ -32,10 +30,7 @@ import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.pkg.PkgHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.*
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
@ -176,34 +171,6 @@ object DownloadObserver {
ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载")
}
// 删除任务
downloadEntity.status = DownloadStatus.cancel
downloadManager.cancel(downloadEntity.url)
} else if (DownloadStatus.isCertificating == downloadEntity.status) {
// 未接入防沉迷系统
val currentActivity = AppManager.getInstance().currentActivity()
if (currentActivity != null) {
DialogHelper.showDialog(
context = currentActivity,
title = "实名提示",
content = "您当前的身份信息正在认证中,根据相关政策要求,该游戏需通过认证后才能进行下载",
cancelText = "知道了",
confirmText = "查看实名认证",
cancelClickCallback = null,
confirmClickCallback = {
currentActivity.startActivity(
ShellActivity.getIntent(
currentActivity,
ShellActivity.Type.REAL_NAME_INFO,
)
)
}
)
} else {
ToastUtils.toast("您当前的身份信息正在认证中,根据相关政策要求,该游戏需通过认证后才能进行下载")
}
// 删除任务
downloadEntity.status = DownloadStatus.cancel
downloadManager.cancel(downloadEntity.url)
@ -333,13 +300,8 @@ object DownloadObserver {
simulator = newSimulator ?: simulator
}
SimulatorDownloadManager.getInstance().showDownloadDialog(
currentActivity,
simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH,
downloadEntity.gameId,
gameName,
downloadEntity.categoryChinese,
null
currentActivity, simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, downloadEntity.gameId, gameName, downloadEntity.categoryChinese, null
)
SimulatorGameManager.recordDownloadSimulatorGame(downloadEntity.gameId, simulator.type)
SimulatorGameManager.postPlayedGame(downloadEntity.gameId, downloadEntity.packageName)
@ -354,8 +316,7 @@ object DownloadObserver {
} else {
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)
|| downloadType == Constants.VGAME
|| downloadType == Constants.DUAL_DOWNLOAD_VGAME
) {
|| downloadType == Constants.DUAL_DOWNLOAD_VGAME) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
tryWithDefaultCatch {
NewFlatLogUtils.logGameInstall(
@ -487,20 +448,12 @@ object DownloadObserver {
)
if (downloadEntity.asVGame()) {
val customTrackDataJson = downloadEntity.customPageTrackDataJson
val kvs = if (customTrackDataJson.isNullOrBlank()) {
arrayOf<String>()
} else {
GsonUtils.fromJson(customTrackDataJson, CustomPageTrackData::class.java).toKV()
}
SensorsBridge.trackEventWithExposureSource(
"HaloFunGameDownloadDone",
exposureEvent?.source,
"game_name", downloadEntity.name,
"game_id", downloadEntity.gameId,
"game_type", downloadEntity.categoryChinese,
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
*kvs
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位"
)
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
SensorsBridge.trackEvent(
@ -508,36 +461,33 @@ object DownloadObserver {
"space_schema_type",
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
)
} else if(downloadEntity.gameId == Constants.HALO_FUN_NEW_32_GAME_ID) {
SensorsBridge.trackEvent(
"HaloFunDownloadDone",
"space_schema_type",
"32位(新)"
)
}
if (downloadEntity.gameId != Constants.GHZS_GAME_ID
&& downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD
&& downloadEntity.gameId != Constants.HALO_FUN_GAME_ID
) {
val trackJson = downloadEntity.customPageTrackDataJson
val kvs = if (!trackJson.isNullOrBlank()) {
GsonUtils.fromJson(trackJson, CustomPageTrackData::class.java).toKV()
} else {
arrayOf()
}
SensorsBridge.trackEventWithExposureSource(
"DownloadProcessFinish",
exposureEvent?.source,
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
"game_label", downloadEntity.tags.joinToString(","),
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
"page_name", getCurrentPageEntity().pageName,
"page_id", getCurrentPageEntity().pageId,
"page_business_id", getCurrentPageEntity().pageBusinessId,
"last_page_name", getLastPageEntity().pageName,
"last_page_id", getLastPageEntity().pageId,
"last_page_business_id", getLastPageEntity().pageBusinessId,
"download_status", downloadEntity.meta[Constants.DOWNLOAD_STATUS_IN_CHINESE] ?: "",
"download_type", if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
*kvs
)
&& downloadEntity.gameId != Constants.HALO_FUN_NEW_32_GAME_ID) {
SensorsBridge.trackEventWithExposureSource(
"DownloadProcessFinish",
exposureEvent?.source,
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"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,
"page_business_id", getCurrentPageEntity().pageBusinessId,
"last_page_name", getLastPageEntity().pageName,
"last_page_id", getLastPageEntity().pageId,
"last_page_business_id", getLastPageEntity().pageBusinessId,
"download_type", if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
)
}
DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")

View File

@ -13,14 +13,12 @@ import com.gh.gamecenter.VerifyPhoneActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
import com.gh.gamecenter.common.avoidcallback.Callback
import com.gh.gamecenter.common.callback.CancelListener
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.login.user.LoginTag
import com.halo.assistant.fragment.user.UserInfoEditFragment
import com.halo.assistant.fragment.user.VerifyPhoneFragment
import com.lightgame.utils.AppManager
@ -42,12 +40,8 @@ object ErrorHelper {
context: Context,
errorString: String?,
showHighPriorityHint: Boolean = false,
sourceEntrance: String = "",
articleType: String = "",
verificationType: String = "内容实名",
gameEntity: GameEntity? = null,
realNameConfirmListener: ConfirmListener? = null,
customizedHandler: (code: Int) -> Boolean,
customizedHandler: (code: Int) -> Boolean
) {
val errorEntity = errorString?.toObject<ErrorEntity>()
@ -65,17 +59,7 @@ object ErrorHelper {
return
}
handleError(
context,
showHighPriorityHint,
errorEntity,
"",
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener,
)
handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener)
}
/**
@ -87,12 +71,8 @@ object ErrorHelper {
context: Context,
errorString: String?,
showHighPriorityHint: Boolean = false,
entrance: String = "",
sourceEntrance: String = "",
articleType: String = "",
verificationType: String = "内容实名",
gameEntity: GameEntity? = null,
realNameConfirmListener: ConfirmListener? = null
realNameConfirmListener: ConfirmListener? = null,
entrance: String = ""
) {
val errorEntity = errorString?.toObject<ErrorEntity>()
@ -106,17 +86,7 @@ object ErrorHelper {
return
}
handleError(
context,
showHighPriorityHint,
errorEntity,
entrance,
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener
)
handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener, entrance)
}
/***
@ -140,12 +110,8 @@ object ErrorHelper {
context: Context,
showHighPriorityHint: Boolean = false,
errorEntity: ErrorEntity,
entrance: String = "",
sourceEntrance: String = "",
articleType: String = "",
verificationType: String = "内容实名",
gameEntity: GameEntity? = null,
realNameConfirmListener: ConfirmListener? = null,
entrance: String = ""
) {
when (errorEntity.code) {
403050,
@ -166,7 +132,6 @@ object ErrorHelper {
403057,
403068 -> handleErrorWithCommentBannedDialog(context, errorEntity)
403200,
403201,
403202 -> handleErrorWithGameCollectionBannedDialog(context, errorEntity)
@ -213,17 +178,9 @@ object ErrorHelper {
// 多设备登录同一帐号,不需要这里处理
}
403209 -> handleRealNameError(
context,
errorEntity,
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener,
)
403209 -> handleRealNameError(context, errorEntity, realNameConfirmListener)
403210 -> handleVerifyPhoneError(context, errorEntity, entrance, articleType, realNameConfirmListener)
403210 -> handleVerifyPhoneError(context, errorEntity, realNameConfirmListener, entrance)
// 禁言(发布内容)
403402 -> Utils.toast(context, "您的账号存在违规,不允许发布内容")
@ -251,21 +208,8 @@ object ErrorHelper {
private fun handleRealNameError(
context: Context,
errorEntity: ErrorEntity,
sourceEntrance: String = "",
articleType: String = "",
verificationType: String = "内容实名",
gameEntity: GameEntity? = null,
realNameConfirmListener: ConfirmListener?,
realNameConfirmListener: ConfirmListener?
) {
SensorsBridge.trackVerificationDialogShow(
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?:"",
articleType = articleType,
verificationType = verificationType
)
DialogHelper.showDialog(
context,
"实名提醒",
@ -292,7 +236,7 @@ object ErrorHelper {
)
}
binding.hintTv.text = errorEntity.data?.text
binding.hintTv.setTextColor(R.color.text_theme.toColor(context))
binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
binding.hintTv.setOnClickListener {
errorEntity.data?.toLinkEntity()?.let { entity ->
DirectUtils.directToLinkPage(context, entity, "实名提醒弹窗", "")
@ -300,25 +244,23 @@ object ErrorHelper {
}
},
confirmClickCallback = {
SensorsBridge.trackVerificationPopupClick("前往实名认证")
val currentActivity = AppManager.getInstance().currentActivity() ?: return@showDialog
val intent = ShellActivity.getIntent(context, ShellActivity.Type.REAL_NAME_INFO)
.putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity)
.startForResult(intent, object : Callback {
override fun onActivityResult(resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && data != null) {
val isAuthSuccess =
data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
if (isAuthSuccess) {
realNameConfirmListener?.onConfirm()
.startForResult(
ShellActivity.getIntent(
context,
ShellActivity.Type.REAL_NAME_INFO,
), object : Callback {
override fun onActivityResult(resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && data != null) {
val isAuthSuccess =
data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
if (isAuthSuccess) {
realNameConfirmListener?.onConfirm()
}
}
}
}
})
},
cancelClickCallback = {
SensorsBridge.trackVerificationPopupClick("以后再说")
})
}
)
}
@ -326,15 +268,9 @@ object ErrorHelper {
private fun handleVerifyPhoneError(
context: Context,
errorEntity: ErrorEntity,
entrance: String,
articleType: String,
realNameConfirmListener: ConfirmListener?,
entrance: String
) {
SensorsBridge.trackMobileNumberVerificationDialog(
articleType = articleType
)
DialogHelper.showDialog(
context,
"手机号验证",
@ -361,7 +297,7 @@ object ErrorHelper {
)
}
binding.hintTv.text = errorEntity.data?.text
binding.hintTv.setTextColor(R.color.text_theme.toColor(context))
binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
binding.hintTv.setOnClickListener {
errorEntity.data?.toLinkEntity()?.let { entity ->
DirectUtils.directToLinkPage(context, entity, "手机号验证", "")
@ -384,12 +320,10 @@ object ErrorHelper {
}
}
})
SensorsBridge.trackMobileNumberVerificationPopupClick(buttonName = "前往手机号验证")
NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "前往手机号验证")
NewFlatLogUtils.logPhoneNumberVerifyDialogShow("手机号验证弹窗-前往验证")
},
cancelClickCallback = {
SensorsBridge.trackMobileNumberVerificationPopupClick(buttonName = "以后再说")
NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "以后再说")
}
)

View File

@ -6,6 +6,7 @@ import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.DefaultJsApi
import com.gh.common.constant.Config
import com.gh.common.dialog.CertificationDialog
import com.gh.common.exposure.ExposureManager
import com.gh.common.history.HistoryHelper
import com.gh.common.repository.ReservationRepository
@ -41,6 +42,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File
@ -161,10 +163,12 @@ object GameActivityDownloadHelper {
) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
CheckLoginUtils.checkLogin(context, entrance) {
ReservationHelper.reserve(context, gameEntity) {
LogUtils.logReservation(gameEntity, traceEvent)
clear()
}
ReservationHelper.reserve(context, gameEntity.id, gameEntity.name ?: "", object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
clear()
}
})
}
} else {
ToastUtils.toast("游戏已成功预约")
@ -260,14 +264,10 @@ object GameActivityDownloadHelper {
traceEvent: ExposureEvent
) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
download(context, gameEntity, apk, false, isSubscribe, entrance, location, traceEvent)
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
download(context, gameEntity, apk, false, isSubscribe, entrance, location, traceEvent)
}
}
}
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
@ -282,16 +282,18 @@ object GameActivityDownloadHelper {
location: String,
traceEvent: ExposureEvent
) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
download(context, gameEntity, apk, true, isSubscribe, entrance, location, traceEvent)
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
download(context, gameEntity, apk, true, isSubscribe, entrance, location, traceEvent)
}
}
}
}
@ -309,14 +311,10 @@ object GameActivityDownloadHelper {
if (gameEntity.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
}
}
@ -384,7 +382,7 @@ object GameActivityDownloadHelper {
return
}
val simulatorDownloadEntity =
SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().firstOrNull()?.url)
SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk()[0].url)
if (simulatorDownloadEntity != null) {
val file = File(simulatorDownloadEntity.path)
if (!file.exists()) {
@ -431,7 +429,7 @@ object GameActivityDownloadHelper {
return when {
gameEntity.getApk().isEmpty() -> null
gameEntity.getApk().size == 1 -> gameEntity.getApk().firstOrNull()
gameEntity.getApk().size == 1 -> gameEntity.getApk()[0]
// 找出对应平台版本Apk且移除掉其他平台版本Apk
isRemoveOther -> {

View File

@ -1,30 +1,38 @@
package com.gh.common.util
import android.content.Context
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.common.utils.doOnMainProcessOnly
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
/**
* 补充游戏库管理
* 首页补充游戏库辅助
*/
object GameSubstituteRepositoryHelper {
private const val SP_GAME_SUB = "sp_game_sub"
private const val KEY_GAME_REPOSITORY = "game_substitute_repository"
private var mSubstitutableGameIdSet = hashSetOf<String>()
private var mApi = RetrofitManager.getInstance().api
private var mApplicationContext = HaloApp.getInstance().application
private val mGameSubSp by lazy { mApplicationContext.getSharedPreferences(SP_GAME_SUB, Context.MODE_PRIVATE) }
private var mGameCollectionList: List<SubjectEntity>? = null // 游戏补充库
var gameCollectionList: List<SubjectEntity> = arrayListOf()
init {
loadSavedRepository()
}
/**
* 获取游戏补充库
@ -33,37 +41,68 @@ object GameSubstituteRepositoryHelper {
fun updateGameSubstituteRepository() {
mApi.reserveColumns
.subscribeOn(Schedulers.io())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
.subscribe(object : Response<List<SubjectEntity>>() {
override fun onResponse(response: List<SubjectEntity>?) {
super.onResponse(response)
if (response != null) {
updateGameRepository(response)
}
updateGameRepository(response)
}
})
}
private fun updateGameRepository(response: ResponseBody) {
val responseContent = response.string()
SPUtils.setString(mGameSubSp, KEY_GAME_REPOSITORY, responseContent)
if (mGameCollectionList?.isEmpty() == true) {
mGameCollectionList = responseContent.toObject()
@JvmStatic
@SuppressLint("CheckResult")
fun updateSubstitutableGames() {
mApplicationContext.doOnMainProcessOnly {
val single = if (UserManager.getInstance().isLoggedIn) {
mApi.getIdListOfPlayedGames(UserManager.getInstance().userId, Utils.getTime(mApplicationContext))
} else {
mApi.getIdListOfDownloadedGames(HaloApp.getInstance().gid, Utils.getTime(mApplicationContext))
}
single.subscribeOn(Schedulers.io()).subscribe(object : BiResponse<List<String>>() {
override fun onSuccess(data: List<String>) {
mSubstitutableGameIdSet = data.toHashSet()
}
})
}
}
/**
* 刷新内存中的游戏库(即从 SP 中再读一次)
*/
@JvmStatic
fun refreshRepositoryFromLocal() = loadSavedRepository()
private fun loadSavedRepository() {
gameCollectionList = SPUtils.getString(KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
}
private fun updateGameRepository(subjects: List<SubjectEntity>?) {
if (subjects == null) return
SPUtils.setString(KEY_GAME_REPOSITORY, subjects.toJson())
gameCollectionList = subjects
}
/**
* 从补充游戏库相应的专题中取出一个与其它游戏都不相同的游戏,为空时即为游戏用完或不存在该相应专题
* @param collectionId 补充游戏库相应专题 ID
* @param gameIdList 该专题里已经包含的游戏 ID 列表
*/
private fun getValidGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
private fun getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
collectionId?.let {
val collection = mGameCollectionList?.find { it.id == collectionId }
val collection = gameCollectionList.find { it.id == collectionId }
collection?.let {
val game = collection.data?.find { game -> isThisGameValid(game, gameIdList) }
val game = collection.data?.find { game -> isThisGameUnique(game, gameIdList) }
game?.let {
collection.data?.remove(game)
// collection.data?.size?.let { remainingSize ->
// // 记录被替换游戏的数量10个以上的时候触发
// if (remainingSize % 10 == 0) {
// SentryHelper.onEvent("game_substitute", "substituted_size", "${50 - remainingSize}")
// }
// }
// 产品说要记录补充专题的曝光数,所以这个游戏附带了所在专题的名字
game.subjectName = collection.name
game.subjectId = collection.id
@ -76,19 +115,14 @@ object GameSubstituteRepositoryHelper {
/**
* 替换游戏,包括 已安装,历史下载,历史已安装等类型
* @param gameList 需要被替换数据的游戏列表
* @param displayingGameIdSet 页面正在显示的游戏 ID 列表,避免重复替换
* @param relatedCollectionId 关联的替换合集 ID
*/
fun replaceGames(
gameList: MutableList<GameEntity>?,
displayingGameIdSet: HashSet<String>,
gameList: MutableList<GameEntity>,
alreadyDisplayedGameIdSet: HashSet<String>,
relatedCollectionId: String,
shouldLogReplaceEvent: Boolean
) {
if (gameList == null) return
// 需要被替换的游戏 position 列表
val positionOfGameToBeReplacedList = arrayListOf<Int>()
val positionOfTheGameToReplaceList = arrayListOf<Int>()
// 标记需要替换的已安装游戏
for ((index, game) in gameList.withIndex()) {
@ -98,21 +132,28 @@ object GameSubstituteRepositoryHelper {
continue
}
// 这个 position 的游戏是否需要被替换
var thisPositionNeedToBeReplaced = false
var isThisPositionLabeled = false
// 从 游戏ID 判断当前游戏是否需要被替换
if (mSubstitutableGameIdSet.contains(game.id)) {
positionOfTheGameToReplaceList.add(index)
isThisPositionLabeled = true
}
// 检查是否已安装该游戏里同包名的 APK
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
break
if (!isThisPositionLabeled) {
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfTheGameToReplaceList.add(index)
isThisPositionLabeled = true
break
}
}
}
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
if (!thisPositionNeedToBeReplaced) {
if (!isThisPositionLabeled) {
var relatedPackageList = arrayListOf<String>()
for (entity in PackageHelper.relatedPackageList) {
if (entity.gameId == game.id) {
@ -123,49 +164,39 @@ object GameSubstituteRepositoryHelper {
for (packageName in relatedPackageList) {
if (PackageHelper.validLocalPackageNameSet.contains(packageName)) {
positionOfGameToBeReplacedList.add(index)
positionOfTheGameToReplaceList.add(index)
break
}
}
}
}
// 若待替换的位置列表不为空,尝试执行替换
if (positionOfGameToBeReplacedList.isNotEmpty()) {
if (mGameCollectionList == null) {
mGameCollectionList = SPUtils.getString(mGameSubSp, KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
if (positionOfTheGameToReplaceList.isNotEmpty()) {
if (shouldLogReplaceEvent) {
MtaHelper.onEvent("首页_加载", "启动光环", "替换游戏")
}
if (mGameCollectionList.isNullOrEmpty()) return
for (position in positionOfGameToBeReplacedList) {
val validGame = getValidGame(relatedCollectionId, displayingGameIdSet)
validGame?.let {
gameList[position] = it
displayingGameIdSet.add(it.id)
for (position in positionOfTheGameToReplaceList) {
val replacingGame = getOneUniqueGame(relatedCollectionId, alreadyDisplayedGameIdSet)
replacingGame?.let {
gameList[position] = replacingGame
}
}
}
}
/**
* 判断该游戏是否有效
* @param game 需要判断的游戏
* @param gameIdList 专题里已经包含的游戏 ID 列表
*/
private fun isThisGameValid(
game: GameEntity,
gameIdList: HashSet<String>
): Boolean {
// 该游戏是否与专题里已包含的游戏存在关联关系
private fun isThisGameUnique(game: GameEntity, gameIdList: HashSet<String>): Boolean {
// 判断该游戏是否出现在已安装列表
if (mSubstitutableGameIdSet.contains(game.id)) return false
// 该补充游戏是否已经存在关联关系
for (relatedId in game.relatedGameIds!!) {
if (gameIdList.contains(relatedId)) {
return false
}
}
// 检查本地是否已安装该游戏,已过滤部分框架服务的包名
for (apk in game.getApk()) {
// 检查本地是否已安装该游戏,已过滤那部分框架服务的包名
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
return false
}

View File

@ -2,15 +2,20 @@ package com.gh.common.util;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.R;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
@ -70,6 +75,11 @@ public class GameViewUtils {
// 新的游戏标签样式 version>=4.0.0
private static TextView getNewGameTagView(Context context, TagStyleEntity tagEntity, int rightMargin) {
// 参数不全,用旧样式实现
if (TextUtils.isEmpty(tagEntity.getBackground())) {
return getGameTagView(context, tagEntity.getName(), rightMargin, "type", tagEntity);
}
TextView tag = new TextView(context);
updateTagStyle(context, tag, tagEntity, rightMargin);
return tag;
@ -98,6 +108,57 @@ public class GameViewUtils {
textView.setBackground(DrawableView.getServerDrawable(ExtensionsKt.hexStringToIntColor("#" + tagEntity.getBackground(), Color.WHITE)));
}
private static TextView getGameTagView(Context context, String tagStr, int rightMargin, String tagType, TagStyleEntity tagEntity) {
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lparams.rightMargin = rightMargin;
TextView tag = new TextView(context);
tag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 9);
tag.setSingleLine(true);
tag.setText(tagStr);
if ("官方版".equals(tagStr) || "已关注".equals(tagStr)) {
tag.setBackgroundResource(R.drawable.border_green_bg);
tag.setTextColor(ContextCompat.getColor(context, R.color.tag_green));
} else {
String colorStr;
if (!TextUtils.isEmpty(tagType) && "type".equals(tagType) && tagEntity != null) { // 游戏标签
colorStr = "#" + tagEntity.getColor();
GradientDrawable gradientDrawable = new GradientDrawable();
if ("border".equals(tagEntity.getStyle())) {
gradientDrawable.setColor(Color.TRANSPARENT);
gradientDrawable.setStroke(DisplayUtils.dip2px(context, 1f), ExtensionsKt.hexStringToIntColor(colorStr, Color.WHITE));
tag.setTextColor(ExtensionsKt.hexStringToIntColor(colorStr, Color.WHITE));
} else {
gradientDrawable.setColor(ExtensionsKt.hexStringToIntColor(colorStr, Color.WHITE));
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
tag.setTextColor(Color.WHITE);
}
gradientDrawable.setCornerRadius(DisplayUtils.dip2px(3F));
tag.setBackgroundDrawable(gradientDrawable);
} else {
colorStr = TagUtils.getInstance(context).getColor(tagStr);
if (colorStr == null) {
return null;
}
int color = ExtensionsKt.hexStringToIntColor(colorStr, Color.WHITE);
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.TRANSPARENT);
gradientDrawable.setStroke(DisplayUtils.dip2px(context, 1f), color);
gradientDrawable.setCornerRadius(DisplayUtils.dip2px(3F));
tag.setBackgroundDrawable(gradientDrawable);
tag.setTextColor(color);
}
}
tag.setLayoutParams(lparams);
tag.setPadding(DisplayUtils.dip2px(context, 4),
0,
DisplayUtils.dip2px(context, 4),
DisplayUtils.dip2px(context, 1));
return tag;
}
public static String getGameTestDate(long testTime) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);

View File

@ -1,20 +1,15 @@
package com.gh.common.util
import com.gh.common.util.ViewPagerFragmentHelper.TYPE_MY_HALO
import com.gh.gamecenter.R
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
object HomeBottomBarHelper {
private const val GAME_BAR_KEY = "game_bar_key"
private const val KEY_HOME_BOTTOM_TAB = "home_bottom_tab"
private const val VIDEO_BAR_KEY = "video_bar_key"
@JvmStatic
fun getDefaultGameBarData(): SubjectRecommendEntity {
@ -35,6 +30,8 @@ object HomeBottomBarHelper {
text = "游戏库",
name = "游戏库",
position = 2,
iconSelect = "https://resource.ghzs.com/image/game/library/entrance/5e183202913fbd002c75f247.png",
iconUnselect = "https://resource.ghzs.com/image/game/library/entrance/5e1831fd913fbd003024641e.png",
animationCode = animationCode,
default = false,
display = Display()
@ -42,37 +39,41 @@ object HomeBottomBarHelper {
}
@JvmStatic
fun getDefaultBottomTabHomeEntity(): BottomTab {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_home.json")
.bufferedReader().use { it.readText() }
return BottomTab(name = "首页", jsCode = animationCode, iconSelector = R.drawable.selector_ic_home, default = true)
}
@JvmStatic
fun getDefaultBottomTabMineEntity(): BottomTab {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_mine.json")
.bufferedReader().use { it.readText() }
return BottomTab(name = "我的光环", jsCode = animationCode, iconSelector = R.drawable.selector_ic_user, link = LinkEntity(type = TYPE_MY_HALO))
}
@JvmStatic
fun getDefaultHomeBottomTabData(): List<BottomTab> {
fun getDefaultVideoData(): SubjectRecommendEntity {
try {
val json = SPUtils.getString(KEY_HOME_BOTTOM_TAB)
val json = SPUtils.getString(VIDEO_BAR_KEY)
if (json.isNotEmpty()) {
val type = object : TypeToken<List<BottomTab>>() {}.type
return GsonUtils.gson.fromJson(json, type)
return GsonUtils.fromJson(json, SubjectRecommendEntity::class.java)
}
} catch (ignore: Exception) {
}
return listOf(getDefaultBottomTabHomeEntity(), getDefaultBottomTabMineEntity())
return getDefaultVideoEntity()
}
@JvmStatic
fun updateDefaultHomeBottomTabData(data: List<BottomTab>) {
SPUtils.setString(KEY_HOME_BOTTOM_TAB, data.toJson())
fun getDefaultVideoEntity(): SubjectRecommendEntity {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_video.json")
.bufferedReader().use { it.readText() }
return SubjectRecommendEntity(
type = "video_stream",
text = "视频",
name = "视频",
position = 4,
animationCode = animationCode,
default = false,
display = Display()
)
}
@JvmStatic
fun updateDefaultGameBarData(data: SubjectRecommendEntity) {
SPUtils.setString(GAME_BAR_KEY, data.toJson())
}
@JvmStatic
fun updateDefaultVideoBarData(data: SubjectRecommendEntity) {
SPUtils.setString(VIDEO_BAR_KEY, data.toJson())
}
}

Some files were not shown because too many files have changed in this diff Show More