Compare commits

..

46 Commits

Author SHA1 Message Date
141734e8e6 fix: 安利墙页适配底部tab 2024-01-25 17:48:07 +08:00
d6ae3ee1e9 fix: 论坛详情页适配底部tab 2024-01-25 17:29:45 +08:00
9f94e29193 refactor: 帮助与反馈页面改为懒加载 2024-01-25 17:27:16 +08:00
ac2eda9aee refactor: 视频贴页面改为懒加载 2024-01-25 17:27:16 +08:00
3c4a4eb6e4 fix: 修改通用跳转命名 2024-01-25 17:27:16 +08:00
9722051371 refactor: 游戏详情页改为懒加载 2024-01-25 17:11:49 +08:00
212494ea20 Merge branch 'feat/GHZS-3956' of git.shanqu.cc:halo/android/assistant-android into feat/GHZS-3956 2024-01-25 11:05:09 +08:00
b5b61a69ec fix:长列表式,点击换一批crash 2024-01-25 11:05:02 +08:00
b93a49a9e5 feat: APP内容配置重构-埋点—客户端2(补充曝光数据1) https://jira.shanqu.cc/browse/GHZS-4559 2024-01-25 09:56:54 +08:00
48d59502f2 fix:参数缺失 2024-01-25 09:31:38 +08:00
55437238f6 Merge branch 'chen/202401/fix-GHZS-4653-2' into 'feat/GHZS-3956'
fix:APP内容配置重构-客户端-组件:专题合集-轮播图-01/24测试-客户端...

See merge request halo/android/assistant-android!1521
2024-01-24 18:02:54 +08:00
c436ceb72c fix:APP内容配置重构-客户端-组件:专题合集-轮播图-01/24测试-客户端 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4653?filter=myopenissues 2024-01-24 17:56:58 +08:00
fb28a834a5 fix: APP内容配置重构-刷新轮换—客户端(修复刷新轮换游戏全部被屏蔽时显示错误页数的问题) https://jira.shanqu.cc/browse/GHZS-4257 2024-01-24 17:21:59 +08:00
2639a39de3 feat: APP内容配置重构-埋点—客户端2 https://jira.shanqu.cc/browse/GHZS-4559 2024-01-24 16:11:31 +08:00
228d7ff634 Merge branch 'chen/202401/fix-GHZS-4608' into 'feat/GHZS-3956'
fix:APP内容配置重构-客户端-组件:游戏专题-光环游戏-0120测试—客户端...

See merge request halo/android/assistant-android!1515
2024-01-24 14:38:51 +08:00
c02f4df423 fix:APP内容配置重构-客户端-组件:游戏专题-光环游戏-0120测试—客户端 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4608?filter=myopenissues 2024-01-24 14:36:54 +08:00
b84e1291e7 fix: 修复首页闪退问题 https://jira.shanqu.cc/browse/GHZS-3956 2024-01-24 11:23:58 +08:00
f663a076f8 feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-23 16:36:54 +08:00
da4df9fcf6 feat: APP内容配置重构-附属需求:首次启动跳转 https://jira.shanqu.cc/browse/GHZS-4085 2024-01-23 16:36:54 +08:00
03734c1075 feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-23 16:36:54 +08:00
6588392aa7 fix:APP内容配置重构-客户端-组件:游戏专题-QQ小游戏-0120测试-客户端 https://jira.shanqu.cc/browse/GHZS-4607 2024-01-23 16:36:54 +08:00
016d8a2bd4 fix: APP内容配置重构-换一批—客户端(修复点击换一批后功能失效的问题) https://jira.shanqu.cc/browse/GHZS-4256 2024-01-23 16:36:54 +08:00
ee1a17d221 feat:自定义页面曝光埋点:https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4397?filter=myopenissues 2024-01-23 16:36:54 +08:00
472bef5880 feat: APP内容配置重构-自定义页面下载按钮—客户端 https://jira.shanqu.cc/browse/GHZS-4255 2024-01-23 16:36:54 +08:00
b9b13413d5 fix: 补充自定义页面轮播发现页卡片获取游戏逻辑 https://jira.shanqu.cc/browse/GHZS-4596 2024-01-23 16:36:54 +08:00
11fccb2086 fix: 0119测试-客户端(2) https://jira.shanqu.cc/browse/GHZS-4596 2024-01-23 16:36:54 +08:00
3bbaa93503 feat:APP内容配置重构-客户端-页面:自定义页面-01/19测试-客户端 https://jira.shanqu.cc/browse/GHZS-4601 2024-01-23 16:36:54 +08:00
ae4758e7d1 feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-23 16:36:54 +08:00
7a758e0efa fix: APP内容配置重构-其他组件:搜索栏—客户端(修复点击搜索栏无法跳转的问题) https://jira.shanqu.cc/browse/GHZS-4073 2024-01-23 16:36:53 +08:00
0c8925711a fix: APP内容配置重构-其他组件:下拉推送—客户端 (修复下拉推送UI显示问题) https://jira.shanqu.cc/browse/GHZS-4070 2024-01-23 16:36:53 +08:00
d94dd0329d fix:修复折叠滑动大图,图标矩阵crash https://jira.shanqu.cc/browse/GHZS-4076 2024-01-23 16:36:53 +08:00
cb2ea46eb9 fix:光环APP】APP内容配置重构-客户端-页面:自定义页面:修复crash https://jira.shanqu.cc/browse/GHZS-4076 2024-01-23 16:36:53 +08:00
7c649a80b0 fix: 修复懒加载问题 2024-01-23 16:36:53 +08:00
795a850d12 fix: APP内容配置重构-底部tab—客户端(关闭ViewPager2离屏加载,设置缓存数量) https://jira.shanqu.cc/browse/GHZS-4025 2024-01-23 16:36:53 +08:00
97c69ed5b4 fix: APP内容配置重构-底部tab—客户端(修复视频Tab显示问题) https://jira.shanqu.cc/browse/GHZS-4025 2024-01-23 16:36:53 +08:00
e7785a586d fix: APP内容配置重构-其他组件:下拉推送—客户端(修复首页为自定义页面时下拉推送搜索栏没有更新背景的问题) https://jira.shanqu.cc/browse/GHZS-4070 2024-01-23 16:36:53 +08:00
179e0936be feat:【光环APP】APP内容配置重构-客户端-页面:自定义页面 https://jira.shanqu.cc/browse/GHZS-4076 2024-01-23 16:36:53 +08:00
3ab8514a0d feat:APP内容配置重构-页面:自定义页面—客户端 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4077?filter=myopenissues 2024-01-23 16:36:53 +08:00
4af0abaf83 ci 2024-01-23 16:36:53 +08:00
455b93328b feat: APP内容配置重构-换一批—客户端 https://jira.shanqu.cc/browse/GHZS-4256
feat: APP内容配置重构-刷新轮换—客户端 https://jira.shanqu.cc/browse/GHZS-4257
feat: APP内容配置重构-其他组件:搜索栏—客户端 https://jira.shanqu.cc/browse/GHZS-4073
feat: APP内容配置重构-页面:多tab导航页—客户端 https://jira.shanqu.cc/browse/GHZS-4080
feat: APP内容配置重构-其他组件:下拉推送—客户端 https://jira.shanqu.cc/browse/GHZS-4070
feat: APP内容配置重构-页面:多tab导航页—客户端 https://jira.shanqu.cc/browse/GHZS-4080
feat: APP内容配置重构-底部tab—客户端 https://jira.shanqu.cc/browse/GHZS-4025
2024-01-23 16:36:53 +08:00
76beb0188b 对接通用内容合集数据
处理折叠滑动大图气泡动画
2024-01-23 16:36:53 +08:00
b03f7433f8 feat:APP内容配置重构-页面:自定义页面—客户端... 2024-01-23 16:36:53 +08:00
38dc8d2f86 feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-23 16:36:53 +08:00
a9be547587 fix: 处理代码冲突 2024-01-23 16:36:52 +08:00
1e58bc9064 feat: 移除无用的游戏名后缀字段
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-23 16:36:52 +08:00
6f3018d4aa feat: 移除 GameEntity 无用的字段和方法,移除 Config 的一键修复相关功能 https://jira.shanqu.cc/browse/GHZS-4274 2024-01-23 16:36:52 +08:00
859 changed files with 18957 additions and 22111 deletions

View File

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

3
.gitmodules vendored
View File

@ -5,6 +5,9 @@
[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

View File

@ -23,8 +23,6 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -310,6 +308,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 +320,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 +343,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,14 +357,14 @@ 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')
@ -408,13 +408,6 @@ 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) {
exclude group: 'androidx.swiperefreshlayout'
}
}
File propFile = file('sign.properties')
@ -485,13 +478,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",

View File

@ -80,6 +80,9 @@
### EasyFloat
-keep class com.lzf.easyfloat.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
### 广点通SDK
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}

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

@ -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 {

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卡上写文件 -->
@ -107,9 +99,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 +117,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"
@ -323,6 +312,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 +328,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 +369,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 +411,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 +487,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 +501,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 +610,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" />
@ -770,8 +782,6 @@
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"-->
@ -827,7 +837,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 +856,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 +866,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

@ -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)

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
@ -55,7 +54,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
@ -107,7 +106,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 +129,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 +156,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" -> {
@ -193,8 +190,7 @@ object AdDelegateHelper {
/**
* 热启动是否需要显示开屏广告
*/
private fun shouldShowStartUpAdWhenHotLaunch() =
mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK && mSplashAd?.hotStartThirdPartyAd != null
private fun shouldShowStartUpAdWhenHotLaunch() = mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
/**
* 是否需要显示下载管理广告
@ -361,6 +357,11 @@ object AdDelegateHelper {
isHotLaunch: Boolean,
hideCallback: () -> Unit
) {
val timeout = if (isHotLaunch) {
((mSplashAd!!.displayRule.hotStartSplashAd?.timeout ?: 3.5F) * 1000).toInt()
} else {
(mSplashAd!!.displayRule.timeout * 1000).toInt()
}
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
if (isSuccess) {
@ -388,28 +389,20 @@ object AdDelegateHelper {
}
}
val thirdPartyAd = if (isHotLaunch) mSplashAd?.hotStartThirdPartyAd else mSplashAd?.thirdPartyAd
// 第三方广告的数据为空,按加载失败处理
if (mSplashAd == null || thirdPartyAd == null) {
if (mSplashAd?.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) {
if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
sdkStartAdContainer.visibility = View.VISIBLE
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, timeout.toLong(), sdkSplashCallback)
} else if (thirdPartyAd.sourceName == AD_SDK_CSJ) {
} else if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
sdkStartAdContainer.visibility = View.VISIBLE
requestCsjSplashAd(
activity,
thirdPartyAd.slotId,
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
@ -577,17 +570,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 +577,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()
@ -619,10 +589,7 @@ object AdDelegateHelper {
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

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,7 +4,6 @@ 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
@ -15,16 +14,14 @@ 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.core.utils.CurrentActivityHolder.getCurrentActivity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
private var isFromBackgroundToForeground = false // 是否后台回到前台
private var activityCount = 0
private var mIsFromBackgroundToForeground = false // 是否后台回到前台
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
@ -32,8 +29,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity) {
GlobalActivityManager.currentActivity = activity
activityCount ++
if (activityCount == 1 && isFromBackgroundToForeground) {
if (mIsFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isSkippingThirdParty
&& activity !is SplashScreenActivity
@ -43,7 +40,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
isFromBackgroundToForeground = false
mIsFromBackgroundToForeground = false
}
}
@ -84,10 +81,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 +91,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityStopped(activity: Activity) {
activityCount --
isFromBackgroundToForeground = activityCount <= 0
mIsFromBackgroundToForeground = getCurrentActivity() == null
}
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
@ -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,7 @@ 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.MainActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
@ -31,6 +32,7 @@ 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
@ -41,6 +43,7 @@ import com.gh.gamecenter.qa.BbsType
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
import java.nio.charset.Charset
@ -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.TYPE_GAME_LIBRARY))
}
EntranceConsts.HOST_HOME_GAME_COLLECTION_SQUARE -> {
DirectUtils.directToMainActivity(context)
DirectUtils.directToHomeDefaultTab(context)
EventBus.getDefault()
.post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.TYPE_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

@ -1,6 +1,5 @@
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
@ -12,21 +11,8 @@ 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!!)
}
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
}
} else {

View File

@ -1,6 +1,5 @@
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
@ -11,11 +10,6 @@ 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)

View File

@ -57,7 +57,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";
@ -94,7 +95,8 @@ public class Config {
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
PackageHelper.refreshList();
// 加载完设置后刷新下
PackageHelper.initList();
}
@Nullable

View File

@ -52,8 +52,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 +69,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,23 +95,13 @@ 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);
@ -135,7 +122,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:
@ -221,7 +208,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 +268,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 +446,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,

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()
}
@ -66,6 +64,7 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
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

@ -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
@ -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()
}
}
@ -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

@ -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
@ -104,7 +108,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 +169,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,6 +1,5 @@
package com.gh.common.iinterface
import com.gh.common.prioritychain.PullDownPushHandler
import com.gh.gamecenter.entity.PullDownPush
interface ISmartRefresh {
@ -8,5 +7,5 @@ interface ISmartRefresh {
fun finishTwoLevel(action: String)
fun finishRefresh()
fun popupPullDownPush(finishCallback: () -> Unit)
fun setPullDownPush(pullDownPush: PullDownPush?, pullDownPushHandler: PullDownPushHandler?)
fun setPullDownPush(pullDownPush: PullDownPush?)
}

View File

@ -1,5 +1,7 @@
package com.gh.common.iinterface
import android.view.View
interface ISmartRefreshContent {
/**
* 启用/关闭 页面滑动
@ -14,4 +16,6 @@ interface ISmartRefreshContent {
* @param isSwipeRefreshEnabled 是否启用
*/
fun setSwipeRefreshEnabled(isSwipeRefreshEnabled: Boolean)
fun provideSlideBackgroundView(): View?
}

View File

@ -0,0 +1,89 @@
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)
process()
} else {
processNext()
}
} else {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
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 false
}
floatingWindowProvider.showFloatingWindowOnly(
mFragment!!,
mRecyclerView!!,
mWindowList!!,
) {
val welcomeDialog = WelcomeDialogFragment.getInstance(it, true, mFragment)
welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -13,6 +13,7 @@ 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.common.utils.debugOnly
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.DialogEntity
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
@ -190,7 +191,6 @@ object GlobalPriorityChainHelper : ISuperiorChain {
override fun onFailure(exception: Exception) {
privacyPolicyDialogHandler.doPreProcess(null)
welcomeDialogHandler.doPreProcess(null)
}
})
}

View File

@ -2,7 +2,7 @@ package com.gh.common.prioritychain
import com.gh.common.iinterface.ISmartRefresh
class PullDownPushHandler(priority: Int): PriorityChainHandler(priority) {
class HomePushHandler(priority: Int): PriorityChainHandler(priority) {
private var mSmartRefreshFragment: ISmartRefresh? = null

View File

@ -39,7 +39,7 @@ class LaunchRedirectHandler(priority: Int) : PriorityChainHandler(priority) {
// 尝试提前设置 tab default 避免首页数据加载完成tab 选中会闪烁
if (launchData?.type == "bottom_tab") {
MainWrapperRepository.getInstance().sendSelectTabEvent(launchData!!)
MainWrapperRepository.getInstance().sendMainSelectTabEvent(launchData!!)
}
if (getStatus() == STATUS_PENDING) {

View File

@ -64,7 +64,7 @@ abstract class PriorityChainHandler(private val mPriority: Int) : Comparable<Pri
* 分发给下一个 handler 处理
*/
fun processNext() {
Utils.log(TAG, "${javaClass.simpleName} processNext")
Utils.log(TAG, "${javaClass.simpleName} processNext $status")
queue?.remove(this)
if (queue?.isEmpty() == true) {

View File

@ -1,6 +1,8 @@
package com.gh.common.prioritychain
import android.graphics.Bitmap
import androidx.fragment.app.FragmentActivity
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
@ -19,19 +21,20 @@ class WelcomeDialogHandler(priority: Int) : PriorityChainHandler(priority) {
// 判断启动本次应用是否已经弹窗,不是的话弹启动弹窗
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(this.welcomeDialogEntity!!.icon, object : BiCallback<Bitmap, Boolean> {
override fun onFirst(first: Bitmap) {
if (getStatus() == STATUS_PENDING) {
updateStatus(STATUS_VALID)
process()
} else {
updateStatus(STATUS_VALID)
}
} else {
}
override fun onSecond(second: Boolean) {
processNext()
}
}
})
} else {
processNext()
}

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,7 +2,6 @@ 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
@ -10,7 +9,7 @@ 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)
MainActivity.skipToMainActivity(context, type)
}
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

@ -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,162 @@ 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
}
PermissionHelper.checkGetInstalledAppsListBeforeAction(context, 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())
}
}
}
})
}
fun showDownloadingDialog(

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

@ -265,42 +265,40 @@ object ArchiveDownloadButtonHelper {
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, 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)
)
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

@ -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

@ -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);
@ -442,7 +442,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,

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 {
@ -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();

View File

@ -33,22 +33,25 @@ 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.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.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
@ -89,6 +92,7 @@ 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.MainWrapperFragment
import com.gh.gamecenter.wrapper.MainWrapperRepository
import com.gh.gamecenter.wrapper.ToolbarWrapperActivity
import com.gh.vspace.VDownloadManagerActivity
@ -97,6 +101,7 @@ 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 +113,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 +123,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)
}
// 用于判断是否已经对接相关类型
@ -158,19 +162,7 @@ object DirectUtils {
"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"
"custom_page"
)
fun directToLinkPage(
@ -180,7 +172,6 @@ object DirectUtils {
path: String,
exposureEvent: ExposureEvent? = null,
unknownCallback: (() -> Unit)?,
sourceEntrance: String = ""
) {
when (linkEntity.type) {
"article", "news", "文章" -> {
@ -195,7 +186,6 @@ object DirectUtils {
if (exposureEvent != null) {
directToGameDetail(
context, linkEntity.link
?: "", linkEntity.text
?: "", BaseActivity.mergeEntranceAndPath(entrance, path), traceEvent = exposureEvent
)
} else {
@ -216,7 +206,7 @@ object DirectUtils {
"question", "社区问题" -> directToQuestionDetail(
context, linkEntity.link
?: "", entrance, path, sourceEntrance
?: "", entrance, path
)
"answer", "社区回答" -> directToAnswerDetail(context, linkEntity.link ?: "", entrance, path)
@ -231,8 +221,7 @@ object DirectUtils {
linkEntity.community!!,
linkEntity.link!!,
entrance,
path,
sourceEntrance,
path
)
"community_column", "社区专题" -> directToCommunityColumn(
@ -320,21 +309,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)
@ -407,15 +387,15 @@ 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))
@ -438,7 +418,7 @@ object DirectUtils {
} ?: ""
}
"halo_tab" -> directToHomeMyHaloTab(context)
"halo_tab" -> directToPersonalTab(context)
"common_collection" -> directToCommonCollectionDetail(
context,
@ -477,29 +457,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,21 +465,9 @@ object DirectUtils {
entrance
)
"multi_tab_nav" -> context.startActivity(
ToolbarWrapperActivity.getMultiTabNavIntent(
context,
linkEntity.link ?: "",
linkEntity.text ?: ""
)
)
"multi_tab_nav" -> context.startActivity(ToolbarWrapperActivity.getMultiTabNavIntent(context, linkEntity.link ?: "", linkEntity.text ?: ""))
"custom_page" -> context.startActivity(
ToolbarWrapperActivity.getCustomPageIntent(
context,
linkEntity.link ?: "",
linkEntity.text ?: ""
)
)
"custom_page" -> context.startActivity(ToolbarWrapperActivity.getCustomPageIntent(context, linkEntity.link ?: "", linkEntity.text ?: ""))
// 选中首页底部 tab
"bottom_tab" -> {
@ -532,7 +477,7 @@ object DirectUtils {
context.startActivity(intent)
if (linkEntity is LaunchRedirect) {
MainWrapperRepository.getInstance().sendSelectTabEvent(linkEntity)
MainWrapperRepository.getInstance().sendMainSelectTabEvent(linkEntity)
}
}
@ -659,7 +604,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 +620,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 +699,6 @@ object DirectUtils {
fun directToGameDetail(
context: Context,
id: String,
name: String = "",
entrance: String? = null,
autoDownload: Boolean? = null,
tab: String? = "",
@ -774,7 +718,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)
}
@ -936,9 +880,7 @@ object DirectUtils {
gameColumnId: String = "",
gameColumnName: String = "",
customPageId: String = "",
customPageName: String = "",
multiTabId: String = "",
multiTabName: String = ""
customPageName: String = ""
) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
@ -948,8 +890,6 @@ object DirectUtils {
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)
}
@ -991,14 +931,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 +1036,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)
}
/**
@ -1123,15 +1067,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 +1084,7 @@ object DirectUtils {
community: CommunityEntity?,
articleId: String?,
entrance: String?,
path: String?,
sourceEntrance: String = "",
path: String?
) {
if (articleId.isNullOrEmpty()) return
val bundle = Bundle()
@ -1151,7 +1092,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 +1121,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 +1129,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 +1154,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 +1173,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 +1188,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 +1491,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.TYPE_HOME))
}
} else {
jumpActivity(context, Bundle())
jumpActivity(context, Bundle().apply { putString(KEY_TYPE, MainWrapperFragment.TYPE_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.TYPE_COMMUNITY_HOME))
EventBus.getDefault().post(EBSkip(CommunityHomeFragment.EB_TAB, position))
}
} else {
jumpActivity(context, Bundle().apply {
putString(KEY_TYPE, MainWrapperFragment.TYPE_COMMUNITY_HOME)
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.TYPE_VIDEO_STREAM))
}
} else {
jumpActivity(context, Bundle().apply { putString(KEY_TYPE, MainWrapperFragment.TYPE_VIDEO_STREAM) })
}
}
/**
* 到首页-我的光环 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.TYPE_MY_HALO))
}
} else {
jumpActivity(context, Bundle().apply { putString(KEY_TYPE, MainWrapperFragment.TYPE_MY_HALO) })
}
}
/**
@ -1625,6 +1584,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 +1868,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)
@ -1868,9 +2032,9 @@ object DirectUtils {
}
@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)
@ -2066,7 +2230,7 @@ object DirectUtils {
searchBoxPattern: String = ""
) {
when (searchType) {
BottomTab.SearchStyle.TYPE_HALO_GAME -> context.startActivity(
"halo_game" -> context.startActivity(
SearchActivity.getIntent(
context,
false,
@ -2081,10 +2245,9 @@ object DirectUtils {
searchBoxPattern
)
)
BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> directToQGameSearch(
"qq_mini_game" -> directToQGameSearch(
context,
"请输入小游戏关键词",
searchHint,
sourceEntrance,
bottomTab,
multiTabId,
@ -2093,8 +2256,7 @@ object DirectUtils {
customPageName,
searchBoxPattern
)
BottomTab.SearchStyle.TYPE_BBS -> directToForumOrUserSearch(
"bbs" -> directToForumOrUserSearch(
context,
"",
entrance,

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(
@ -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) {
@ -1059,7 +1052,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()) {
@ -1153,7 +1146,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 +1184,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 +1211,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 +1219,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(
@ -512,32 +465,22 @@ object DownloadObserver {
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_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,11 @@ 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.halo.assistant.fragment.user.UserInfoEditFragment
import com.halo.assistant.fragment.user.VerifyPhoneFragment
import com.lightgame.utils.AppManager
@ -42,12 +39,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 +58,7 @@ object ErrorHelper {
return
}
handleError(
context,
showHighPriorityHint,
errorEntity,
"",
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener,
)
handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener)
}
/**
@ -87,12 +70,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 +85,7 @@ object ErrorHelper {
return
}
handleError(
context,
showHighPriorityHint,
errorEntity,
entrance,
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener
)
handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener, entrance)
}
/***
@ -140,12 +109,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 +131,6 @@ object ErrorHelper {
403057,
403068 -> handleErrorWithCommentBannedDialog(context, errorEntity)
403200,
403201,
403202 -> handleErrorWithGameCollectionBannedDialog(context, errorEntity)
@ -213,17 +177,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 +207,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,
"实名提醒",
@ -300,25 +243,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 +267,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,
"手机号验证",
@ -384,12 +319,10 @@ object ErrorHelper {
}
}
})
SensorsBridge.trackMobileNumberVerificationPopupClick(buttonName = "前往手机号验证")
NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "前往手机号验证")
NewFlatLogUtils.logPhoneNumberVerifyDialogShow("手机号验证弹窗-前往验证")
},
cancelClickCallback = {
SensorsBridge.trackMobileNumberVerificationPopupClick(buttonName = "以后再说")
NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "以后再说")
}
)

View File

@ -41,6 +41,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 +162,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("游戏已成功预约")
@ -384,7 +387,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 +434,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,6 +1,5 @@
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
@ -35,6 +34,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()
@ -54,7 +55,7 @@ object HomeBottomBarHelper {
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))
return BottomTab(name = "我的光环", jsCode = animationCode, iconSelector = R.drawable.selector_ic_user, link = LinkEntity(type = "my_halo"))
}
@JvmStatic

View File

@ -1,18 +1,13 @@
package com.gh.common.util
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.tracker.Tracker
import com.gh.gamecenter.common.utils.toastInInternalRelease
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.HomePluggableFilterEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.home.PluginDisplayStatus
import com.gh.gamecenter.room.AppDatabase
/**
* 插件化区域辅助类
* 首页插件化区域辅助类
*/
object HomePluggableHelper {
@ -23,67 +18,19 @@ object HomePluggableHelper {
val apkList = gameEntity.getApk()
if (apkList.isNotEmpty()) {
val apk = apkList.first()
val apkHash = MD5Utils.getContentMD5(gameEntity.id + apk.version)
val tag = if (isNever) "never" else apkHash
runOnIoThread {
tryCatchInRelease {
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
if (filterData != null && !filterData.tag.contains(tag)) {
filterData.tag = filterData.tag + "," + tag
mHomePluggableFilterDao.addData(filterData)
} else {
mHomePluggableFilterDao.addData(
HomePluggableFilterEntity(
pkgName = apk.packageName,
tag = tag,
active = true
)
)
}
}
val tag = if (isNever) "never" else apk.version ?: ""
tryCatchInRelease {
mHomePluggableFilterDao.addData(
HomePluggableFilterEntity(
pkgName = apk.packageName,
tag = tag,
active = isNever
)
)
}
}
}
/**
* 获取插件化区域显示样式
*/
fun getPluginDisplayedStyle(pluginList: List<Any>?): PluginDisplayStatus {
if (pluginList.isNullOrEmpty()) {
return PluginDisplayStatus.DEFAULT
}
val shouldShowCollapsedStyle = shouldShowCollapsedStyle()
return if (shouldShowCollapsedStyle) {
PluginDisplayStatus.CLOSE
} else {
setPluginAreaShowed()
if (pluginList.size > 2) {
PluginDisplayStatus.OPEN_TWO_AND_BUTTON
} else {
PluginDisplayStatus.OPEN
}
}
}
/**
* 是否需要把插件化区域显示为收起样式
* https://jira.shanqu.cc/browse/GHZS-4725
*/
private fun shouldShowCollapsedStyle(): Boolean {
val launchId = SPUtils.getString(Constants.SP_PLUGIN_AREA_SHOWED_LAUNCH_ID)
return if (launchId.isEmpty()) {
false
} else {
Tracker.launchId != launchId
}
}
private fun setPluginAreaShowed() {
SPUtils.setString(Constants.SP_PLUGIN_AREA_SHOWED_LAUNCH_ID, Tracker.launchId)
}
@JvmStatic
fun showHomePluggable(gameEntity: GameEntity): Boolean {
val apkList = gameEntity.getApk()
@ -91,9 +38,9 @@ object HomePluggableHelper {
val apk = apkList.first()
tryCatchInRelease {
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
if (filterData != null) {
if (filterData?.active == true) {
val filterTag = filterData.tag
return !filterTag.contains("never") && !filterTag.contains(MD5Utils.getContentMD5(gameEntity.id + apk.version))
return filterTag != "never" && apk.version != filterTag
}
}
}
@ -108,4 +55,20 @@ object HomePluggableHelper {
return emptyList()
}
@JvmStatic
fun activationFilterData() {
try {
val filterList = mHomePluggableFilterDao.getDataByActive(false)
if (filterList != null) {
for (entity in filterList) {
entity.active = true
}
mHomePluggableFilterDao.addData(filterList)
}
} catch (e: Exception) {
e.printStackTrace()
toastInInternalRelease("插件化筛选出现异常")
}
}
}

View File

@ -50,7 +50,7 @@ public class InstallUtils {
public void handleMessage(Message msg) {
if (msg.what == INSTALL_WHAT && packageManager != null) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = PackageUtils.getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
list.add(packageInfo.packageName);

View File

@ -768,7 +768,7 @@ public class LibaoUtils {
}
public static boolean isAppInstalled(Context context, String packageName) {
List<PackageInfo> pinfo = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> pinfo = PackageUtils.getInstalledPackages(context, 0);
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;

View File

@ -566,7 +566,7 @@ public class MessageShareUtils {
String path;
// 安卓11无法访问Android/data目录
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/ShareImg/";
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ShareImg/";
} else {
path = context.getExternalCacheDir().getPath() + "/ShareImg/";
}

View File

@ -1273,19 +1273,10 @@ object NewFlatLogUtils {
}
// 存档分享弹窗点击事件
fun logCloudArchiveShareDialogClick(
buttonType: String,
gameId: String,
gameName: String,
cloudSaveId: String,
cloudSaveName: String,
content: String
) {
fun logCloudArchiveShareDialogClick(buttonType: String, gameId: String, gameName: String, cloudSaveId: String) {
val json = json {
KEY_EVENT to "cloud_save_share_dialog_click"
"cloud_save_id" to cloudSaveId
"cloud_save_name" to cloudSaveName
"content" to content
KEY_EVENT to "cloud_save_share_dialog_click"
KEY_BUTTON_TYPE to buttonType
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
@ -1335,14 +1326,12 @@ object NewFlatLogUtils {
}
// 上传存档弹窗点击事件
fun logCloudArchiveUploadDialogClick(gameId: String, gameName: String, cloudSaveId: String, cloudSaveName: String, isSuccess: Boolean) {
fun logCloudArchiveUploadDialogClick(buttonType: String, gameId: String, gameName: String) {
val json = json {
KEY_EVENT to "cloud_save_upload_dialog_click"
KEY_BUTTON_TYPE to buttonType
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"cloud_save_id" to cloudSaveId
"cloud_save_name" to cloudSaveName
"is_success" to isSuccess
parseAndPutMeta().invoke(this)
}
log(json)

View File

@ -2,53 +2,23 @@ package com.gh.common.util
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.os.Build
import android.provider.Settings
import com.gh.common.constant.Config
import com.gh.gamecenter.common.utils.PermissionHelper.isGetInstalledListPermissionDisabled
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
object PackageHelper {
private const val TAG = "PackageHelper"
private const val SP_GET_INSTALLED_API_AGREED = "get_installed_api_agreed"
private const val UNKNOWN = -1
private const val UNSUPPORTED = 0
private const val SUPPORTED = 1
private var lastInstalledPackageListTime = 0L
private var installedPackageList: List<PackageInfo> = arrayListOf()
private var isGetInstalledPackagesApiAgreed = false
private var isGetInstalledListPermissionSupported = UNKNOWN // 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知0 代表不支持, 1 代表支持
// 评论黑名单包名列表,避免用户安装了 Xposed Installer 这样的工具,也能在包含该安装包的游戏详情页评论
private var _commentPackageNameBlackList = arrayListOf<String>()
val commentPackageNameBlackList: ArrayList<String> = _commentPackageNameBlackList
var commentPackageNameBlackList = arrayListOf<String>()
// 关闭下载的包列表
private var _downloadPackageNameBlackList = arrayListOf<String>()
val downloadPackageNameBlackList: ArrayList<String> = _downloadPackageNameBlackList
var downloadPackageNameBlackList = arrayListOf<String>()
// 本地已安装的包去掉关闭下载的包后的列表
private var _validLocalPackageNameSet = hashSetOf<String>()
val validLocalPackageNameSet: HashSet<String> = _validLocalPackageNameSet
var validLocalPackageNameSet = hashSetOf<String>()
// 游戏包名匹配列表
private var _relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
val relatedPackageList: ArrayList<SettingsEntity.GameWithPackages> = _relatedPackageList
var relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
// 本地已安装包的列表
var localPackageNameSet = hashSetOf<String>()
@ -68,26 +38,33 @@ object PackageHelper {
}
@JvmStatic
fun refreshList() {
Config.getSettings()?.gameCommentBlackList?.let { _commentPackageNameBlackList = ArrayList(it) }
Config.getSettings()?.gameDownloadBlackList?.let { _downloadPackageNameBlackList = ArrayList(it) }
Config.getSettings()?.gamePackageMatch?.let { _relatedPackageList = ArrayList(it) }
fun initList() {
Config.getSettings()?.gameCommentBlackList?.let {
commentPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList?.let {
downloadPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gamePackageMatch?.let {
relatedPackageList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList
updateValidPackageNameList()
}
private fun updateValidPackageNameList() {
_validLocalPackageNameSet =
validLocalPackageNameSet =
localPackageNameSet.filterNot { p -> downloadPackageNameBlackList.contains(p) }.toHashSet()
}
/**
/*
* 获取所有已安装的软件的包名、版本(非系统应用)
*/
private fun getAllPackageName(context: Context): HashSet<String> {
val set = HashSet<String>()
return try {
val packageInfos = getInstalledPackages(context, 0)
val packageInfos = PackageUtils.getInstalledPackages(context, 0)
for (packageInfo in packageInfos) {
if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
if (context.packageName != packageInfo.packageName) {
@ -102,154 +79,4 @@ object PackageHelper {
}
}
/**
* 弃用已安装列表缓存
*/
fun dumpInstalledListCache() {
lastInstalledPackageListTime = 0
}
/**
* 用户是否已经允许了调用获取已安装应用列表接口
* 优先用内存的值,没有再从 SP 中获取并更新
*/
fun isGetInstalledPackagesApiAgreed(): Boolean {
return isGetInstalledPackagesApiAgreed
|| (SPUtils.getBoolean(SP_GET_INSTALLED_API_AGREED).also { isGetInstalledPackagesApiAgreed = it })
}
/**
* 同意使用已安装应用列表 API
*/
fun agreeOnGetInstalledPackagesApi() {
isGetInstalledPackagesApiAgreed = true
SPUtils.setBoolean(SP_GET_INSTALLED_API_AGREED, true)
}
/**
* 获取已安装应用列表
*/
fun getInstalledPackages(context: Context?, flags: Int): List<PackageInfo> {
Utils.log(TAG, "即将获取已安装应用列表")
// Utils.log(TAG, "即将获取已安装应用列表" + Thread.currentThread().getStackTrace().contentToString().replace( ',', '\n' ))
// 用户未同意使用已安装应用列表 API返回空列表
if (!isGetInstalledPackagesApiAgreed()) {
Utils.log(TAG, "用户未同意使用已安装应用列表 API返回空列表")
return installedPackageList
}
// 简单 debounce 过于频繁的获取已安装应用列表调用
if (System.currentTimeMillis() - lastInstalledPackageListTime < 3000 && installedPackageList.isNotEmpty()) {
Utils.log(TAG, "使用了缓存的已安装应用列表")
return installedPackageList
}
var shouldGetNewInstalledPackagedList = false
// 当前设备是否支持限制获取已安装应用列表的功能
if (isSupportGetInstalledAppsPermission(context!!)) {
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能")
// 当前设备是否支持禁用了获取已安装应用列表
if (!isGetInstalledListPermissionDisabled(context)) {
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能")
shouldGetNewInstalledPackagedList = true
} else {
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能")
}
} else {
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能")
shouldGetNewInstalledPackagedList = true
}
if (shouldGetNewInstalledPackagedList) {
lastInstalledPackageListTime = System.currentTimeMillis()
installedPackageList = getInstalledPackagesInternal(context, flags)
}
return installedPackageList
}
/**
* 是否支持动态获取已安装应用列表权限
*/
fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
// 若存在缓存,直接返回缓存结果。
if (isGetInstalledListPermissionSupported != UNKNOWN) {
return isGetInstalledListPermissionSupported != UNSUPPORTED
}
try {
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
val flag =
Settings.Secure.getInt(context.contentResolver, "oem_installed_apps_runtime_permission_enable", 0)
if (flag == 1) {
isGetInstalledListPermissionSupported = SUPPORTED
return true
}
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
val packageManager = context.packageManager
val permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (permissionInfo.protection == PermissionInfo.PROTECTION_DANGEROUS) {
isGetInstalledListPermissionSupported = SUPPORTED
return true
} else {
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
} else {
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
} catch (e: PackageManager.NameNotFoundException) {
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
}
/**
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632
*/
private fun getInstalledPackagesInternal(context: Context, flags: Int): List<PackageInfo> {
Utils.log(TAG, "调用系统 API 获取已安装应用列表")
val pm = context.packageManager
try {
return pm.getInstalledPackages(flags)
} catch (ignored: java.lang.Exception) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
val process: Process
val result: MutableList<PackageInfo> = java.util.ArrayList()
var bufferedReader: BufferedReader? = null
try {
process = Runtime.getRuntime().exec("pm list packages")
bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
var line: String
while ((bufferedReader.readLine().also { line = it }) != null) {
val packageName = line.substring(line.indexOf(':') + 1)
val packageInfo = pm.getPackageInfo(packageName, flags)
result.add(packageInfo)
}
process.waitFor()
} catch (e: java.lang.Exception) {
e.printStackTrace()
if (e is InterruptedException) {
Thread.currentThread().interrupt()
}
} finally {
if (bufferedReader != null) try {
bufferedReader.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
return result
}
}

View File

@ -24,6 +24,7 @@ import com.gh.gamecenter.vpn.VpnHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File

View File

@ -25,10 +25,12 @@ import androidx.webkit.WebViewCompat;
import com.android.apksig.ApkVerifier;
import com.android.apksig.internal.apk.ApkSigningBlockUtilsLite;
import com.g00fy2.versioncompare.Version;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.xapk.XapkInstaller;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.PackageFlavorHelper;
import com.gh.gamecenter.common.utils.PermissionHelper;
import com.gh.gamecenter.core.utils.MD5Utils;
import com.gh.gamecenter.core.utils.SentryHelper;
@ -67,8 +69,16 @@ import java.util.zip.ZipFile;
public class PackageUtils {
private static long mLastInstalledPackageListTime = 0L;
private static List<PackageInfo> mInstalledPackageList = null;
public static final String publicKey = "OpenSSLRSAPublicKey{modulus=a8c4bb5748fec8d5c35db1a7a182d41ba4721a91131a417330af79ef4ddb43f9fa0ff4907b0a613bfe152de0ed8fc1b2e6f94a908aa98a5f7adc1ce814ba7ec919d75d9910bdfd8649b4789da6a90ffb61f0d23ac4f828a78fcd0d6f6120c1c43c1f87f7498a89eb40ca8e32dfc2f9d5c10d612b95192870223674e241e53305abf320d7eed76ded398778576e4db7b17b3bc6a792f13de5e43a6a5fae4276c73e6990ce97f68dff0ec16fc9594f175c8d49cd0d7877340d9de60942ca0efc737e50b6c295dfe0713e4532b4e810e1ea11b702b4a27753e41559cbceb247e7f044ec4e3ab2e8bccd8b9fd71286e63307550bcde86deee95adb8133076269135b,publicExponent=10001}";
private static final String TAG = "PackageUtils";
// 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知0 代表不支持, 1 代表支持
private static int mIsSupportGetInstalledListPermission = -1;
public static String getInstallPackageInfoSourceDir(String packageName) {
try {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
@ -283,13 +293,11 @@ public class PackageUtils {
/*
* 判断是否为光环签名
* 判断是否是插件包
*/
public static boolean isSignedByGh(Context context, String packageName) {
String signature = getApkSignatureByPackageName(context, packageName)[0];
// 判断当前已安装应用是否为光环签名。若签名列表为空,直接判断为光环签名
return signature == null || SignatureRepository.isSignEmpty() || SignatureRepository.isSignMatched(signature);
return publicKey.equals(signature);
}
/*
@ -446,7 +454,7 @@ public class PackageUtils {
}
// 判断当前已安装应用是否为光环签名
if (isSignedByGh(context, packageName)) {
if (publicKey.equals(getApkSignatureByPackageName(context, packageName)[0])) {
return true;
}
@ -670,7 +678,7 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageName(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
@ -683,7 +691,7 @@ public class PackageUtils {
public static ArrayList<String> getAllPackageNameIncludeGh(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
list.add(packageInfo.packageName);
@ -697,9 +705,11 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageNameIncludeSystemApps(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
list.add(packageInfo.packageName);
if (!context.getPackageName().equals(packageInfo.packageName)) {
list.add(packageInfo.packageName);
}
}
return list;
}
@ -708,7 +718,7 @@ public class PackageUtils {
JSONArray jsonArray = new JSONArray();
try {
PackageManager pm = context.getPackageManager();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
JSONObject jsonObject = new JSONObject();
@ -749,6 +759,7 @@ public class PackageUtils {
}
}
/**
* 启动应用
* 请使用 PackageLauncher.launchApp()
@ -768,6 +779,22 @@ public class PackageUtils {
}
}
/*
* 根据包名,获取软件名称
*/
public static String getNameByPackageName(Context context, String packageName) {
try {
PackageManager pm = context.getApplicationContext().getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(
packageName, 0);
return applicationInfo.loadLabel(pm).toString();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* todo 统一判断
* <p>
@ -862,6 +889,37 @@ public class PackageUtils {
&& !PackageUtils.isSignedByGh(HaloApp.getInstance().getApplication(), apkEntity.getPackageName());
}
/**
* 获取调用者的进程名
*
* @param context 调用者的上下文
* @return 进程名
*/
public static String obtainProcessName(Context context) {
if (PackageFlavorHelper.IS_TEST_FLAVOR) {
try {
final int pid = android.os.Process.myPid();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> listTaskInfo = am.getRunningAppProcesses();
if (listTaskInfo != null && !listTaskInfo.isEmpty()) {
for (ActivityManager.RunningAppProcessInfo info : listTaskInfo) {
if (info != null && info.pid == pid) {
return info.processName;
}
}
}
} catch (Exception e) {
// 遇到异常了让这次调用正常执行
e.printStackTrace();
return BuildConfig.APPLICATION_ID;
}
} else {
return null;
}
return null;
}
/**
* 应用是否在前台运行
*/
@ -886,8 +944,8 @@ public class PackageUtils {
String packageName = context.getApplicationContext().getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)
&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appProcess.processName.equals(packageName) && appProcess.importance
== ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
@ -898,6 +956,132 @@ public class PackageUtils {
return false;
}
/**
* 弃用已安装列表缓存
*/
public static void dumpInstalledListCache() {
mLastInstalledPackageListTime = 0;
}
public static List<PackageInfo> getInstalledPackages(Context context, int flags) {
Utils.log(TAG, "即将获取已安装应用列表");
// 简单 debounce 掉过于频繁的调用获取已安装列表调用
if (System.currentTimeMillis() - mLastInstalledPackageListTime < 1000
&& mInstalledPackageList != null
&& mInstalledPackageList.size() > 0) {
Utils.log(TAG, "使用了缓存的已安装应用列表");
return new ArrayList<>(mInstalledPackageList);
}
// 是否需要调用系统 API 获取最新的已安装应用列表
boolean shouldGetNewInstalledPackagedList = false;
// 当前设备是否支持限制获取已安装应用列表的功能
if (isSupportGetInstalledAppsPermission(context)) {
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能");
// 当前设备是否支持禁用了获取已安装应用列表
if (!PermissionHelper.isGetInstalledListPermissionDisabled(context)) {
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能");
shouldGetNewInstalledPackagedList = true;
} else {
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能");
}
} else {
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能");
shouldGetNewInstalledPackagedList = true;
}
if (shouldGetNewInstalledPackagedList) {
mLastInstalledPackageListTime = System.currentTimeMillis();
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
}
if (mInstalledPackageList == null) {
mInstalledPackageList = new ArrayList<>();
}
return mInstalledPackageList;
}
public static boolean isSupportGetInstalledAppsPermission(Context context) {
// 若存在缓存,直接返回缓存结果。为 0 代表不支持,为 1 代表支持
if (mIsSupportGetInstalledListPermission != -1) {
return mIsSupportGetInstalledListPermission != 0;
}
try {
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
int flag = Settings.Secure.getInt(context.getContentResolver(), "oem_installed_apps_runtime_permission_enable", 0);
if (flag == 1) {
mIsSupportGetInstalledListPermission = 1;
return true;
}
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
PackageManager packageManager = context.getPackageManager();
PermissionInfo permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS) {
mIsSupportGetInstalledListPermission = 1;
return true;
} else {
mIsSupportGetInstalledListPermission = 0;
return false;
}
} else {
mIsSupportGetInstalledListPermission = 0;
return false;
}
} catch (NameNotFoundException e) {
mIsSupportGetInstalledListPermission = 0;
return false;
}
}
/**
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632
*/
private static List<PackageInfo> getInstalledPackagesInternal(Context context, int flags) {
Utils.log(TAG, "调用系统 API 获取已安装应用列表");
final PackageManager pm = context.getPackageManager();
try {
return pm.getInstalledPackages(flags);
} catch (Exception ignored) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
Process process;
List<PackageInfo> result = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
process = Runtime.getRuntime().exec("pm list packages");
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
final String packageName = line.substring(line.indexOf(':') + 1);
final PackageInfo packageInfo = pm.getPackageInfo(packageName, flags);
result.add(packageInfo);
}
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
} finally {
if (bufferedReader != null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static String getWebviewPath(Context context) {
final PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(context);
return webViewPackageInfo != null ? webViewPackageInfo.applicationInfo.sourceDir : null;

View File

@ -1,7 +1,5 @@
package com.gh.common.util
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.download.DownloadManager
import com.gh.gamecenter.ShellActivity
@ -16,19 +14,10 @@ import com.lightgame.download.DownloadStatus
object RealNameHelper {
private var pendingInstallPkgPath = ""
var pendingInstallPkgPath = ""
// 0表示未实名1表示未成年2表示成年
private var certificationStatus: Int = 0
private val _realNameInfoUpdateLiveData = MutableLiveData<Any>()
val realNameInfoUpdateLiveData = _realNameInfoUpdateLiveData as LiveData<Any>
fun updatePendingInstallPkgPath(path: String) {
pendingInstallPkgPath = path
}
fun getPendingInstallPkgPath() = pendingInstallPkgPath
private var mCertificationStatus: Int = 0
/**
* 弹未成年人不能下载游戏弹窗
@ -71,12 +60,14 @@ object RealNameHelper {
downloadEntity?.let {
NewLogUtils.logCertificationTrigger(downloadEntity.gameId, downloadEntity.name)
SensorsBridge.trackVerificationDialogShow(
gameId = downloadEntity.gameId,
gameName = downloadEntity.name ?: "",
gameType = downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
articleType = "",
verificationType = "游戏实名"
SensorsBridge.trackEvent(
"VerificationDialogShow",
"game_id",
downloadEntity.gameId,
"game_name",
downloadEntity.name ?: "",
"game_type",
downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: ""
)
}
@ -105,7 +96,6 @@ object RealNameHelper {
currentActivity,
ShellActivity.Type.REAL_NAME_INFO
).apply {
putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, "游戏实名")
putExtra(EntranceConsts.KEY_IS_FORCED_TO_CERTIFICATE, true)
putExtra(EntranceConsts.KEY_IS_FORCED_TO_CERTIFICATE_BUT_WITH_BACKDOOR, !isForced)
}
@ -114,11 +104,11 @@ object RealNameHelper {
pendingInstallPkgPath = downloadEntity.path
}
NewLogUtils.logCertificationHintDialogOptionsClicked("前往实名认证")
SensorsBridge.trackVerificationPopupClick("前往实名认证")
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", "前往实名认证")
},
cancelClickCallback = {
NewLogUtils.logCertificationHintDialogOptionsClicked("取消")
SensorsBridge.trackVerificationPopupClick("取消")
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", "取消")
if (!isForced) {
DownloadManager.getInstance()
.resumeAllInvisiblePendingTask()
@ -141,15 +131,11 @@ object RealNameHelper {
}
}
fun onRealNameInfoUpdated() {
_realNameInfoUpdateLiveData.postValue(Any())
}
/**
* 获取实名状态 0表示未实名1表示未成年2表示成年
*/
fun getCertificationStatus(): Int {
return certificationStatus
return mCertificationStatus
}
/**
@ -157,7 +143,7 @@ object RealNameHelper {
*/
@JvmStatic
fun updateCertificationStatus(newCertificationStatus: Int) {
certificationStatus = newCertificationStatus
mCertificationStatus = newCertificationStatus
}
}

View File

@ -1,7 +1,7 @@
package com.gh.common.util
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.gamecenter.common.constant.Constants
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
@ -39,7 +39,7 @@ object RecommendPopupHelper {
//判断是否符合安装包大小限制
val minSize = entity.recommendPackage.minSize
val sizeStr = gameEntity.getApk().firstOrNull()?.size ?: continue
val sizeStr = gameEntity.getApk()[0].size ?: continue
val size = sizeStr.substring(0, sizeStr.length - 2).toFloat()
if (size < minSize) continue

View File

@ -69,9 +69,9 @@ object ReservationHelper {
@JvmStatic
@SuppressLint("CheckResult")
fun reserve(context: Context, game: GameEntity?, sourceEntrance: String = "其他", callback: EmptyCallback) {
fun reserve(context: Context, gameId: String, gameName: String, callback: EmptyCallback) {
val requestMap = hashMapOf<String, String>()
requestMap["game_id"] = game?.id ?: ""
requestMap["game_id"] = gameId
RetrofitManager.getInstance().api
.createNewGameReservation(requestMap.createRequestBody())
.compose(singleToMain())
@ -81,18 +81,14 @@ object ReservationHelper {
SensorsBridge.trackEvent(
"AppointmentGameResult",
"game_name",
game?.name ?: "",
gameName,
"game_id",
game?.id ?: "",
"game_type",
game?.categoryChinese ?: "",
gameId,
"result",
"成功",
"source_entrance",
sourceEntrance
"成功"
)
ReservationRepository.addReservationToMemoryAndRefresh(game?.id ?: "")
ReservationRepository.addReservationToMemoryAndRefresh(gameId)
callback.onCallback()
val wechatConfig = SPUtils.getString(Constants.SP_WECHAT_CONFIG).toObject<WechatConfigEntity>()
wechatConfig?.run {
@ -126,15 +122,11 @@ object ReservationHelper {
SensorsBridge.trackEvent(
"AppointmentGameResult",
"game_name",
game?.name ?: "",
gameName,
"game_id",
game?.id ?: "",
"game_type",
game?.categoryChinese ?: "",
gameId,
"result",
"失败",
"source_entrance",
sourceEntrance
"失败"
)
ToastUtils.showToast(exception.message ?: "")
}

View File

@ -1,65 +0,0 @@
package com.gh.common.util
import android.annotation.SuppressLint
import com.gh.gamecenter.common.entity.SignatureEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.retrofit.RetrofitManager
/**
* 存储光环网游使用的签名
*/
object SignatureRepository {
private const val SP_SIGN_DIGEST_LIST = "sign_digest_list"
private var signDigestList: ArrayList<String>? = null
@SuppressLint("CheckResult")
fun init() {
RetrofitManager.getInstance()
.newApi
.ghSignature
.compose(singleToMain())
.subscribe(object : BiResponse<ArrayList<SignatureEntity>>() {
override fun onSuccess(data: ArrayList<SignatureEntity>) {
signDigestList = ArrayList()
for (i in data) {
signDigestList?.add(i.signMd5)
}
SPUtils.setString(SP_SIGN_DIGEST_LIST, signDigestList?.toJson() ?: "")
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
signDigestList = SPUtils.getString(SP_SIGN_DIGEST_LIST).toObject()
}
})
}
/**
* 签名列表是否为空
*/
@JvmStatic
fun isSignEmpty(): Boolean {
return signDigestList.isNullOrEmpty()
}
/**
* 签名是否匹配已知的签名
*/
@JvmStatic
fun isSignMatched(sign: String): Boolean {
val signDigest = MD5Utils.getContentMD5(sign)
return signDigestList?.contains(signDigest) == true
}
}

View File

@ -0,0 +1,94 @@
package com.gh.common.util;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.collection.ArrayMap;
import com.gh.gamecenter.entity.TagEntity;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
public class TagUtils {
private static TagUtils mInstance;
private Context context;
private ArrayMap<String, String> colorMap;
private boolean isUpdate = false;
private TagUtils(Context con) {
this.context = con.getApplicationContext();
initTag();
}
public static TagUtils getInstance(Context context) {
if (mInstance == null) {
mInstance = new TagUtils(context);
}
return mInstance;
}
private void initTag() {
colorMap = new ArrayMap<>();
SharedPreferences sharedPreferences = context.getSharedPreferences("gh_tag", Context.MODE_PRIVATE);
Set<String> set = sharedPreferences.getStringSet("tag", null);
if (set == null) {
getTag();
} else {
for (String str : set) {
String[] platform = str.split("=");
colorMap.put(platform[0], platform[1]);
}
}
}
public String getColor(String tag) {
String color = colorMap.get(tag);
if (color == null) {
getTag();
}
return color;
}
public void getTag() {
if (isUpdate) {
return;
}
isUpdate = true;
RetrofitManager.getInstance().getApi().getTags()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<TagEntity>>() {
@Override
public void onResponse(List<TagEntity> response) {
Set<String> tagSet = new HashSet<>();
for (TagEntity tagEntity : response) {
tagSet.add(tagEntity.getName() + "=" + tagEntity.getColor());
}
SharedPreferences sp = context.getSharedPreferences("gh_tag", Context.MODE_PRIVATE);
sp.edit().putStringSet("tag", tagSet).apply();
initTag();
isUpdate = false;
}
@Override
public void onFailure(HttpException e) {
isUpdate = false;
}
});
}
}

View File

@ -73,7 +73,7 @@ object TempCertificationUtils {
}
}
} catch (e: Exception) {
ToastUtils.showToast("网络异常,请稍后再试 ${e.message}")
ToastUtils.showToast("网络异常,请稍后再试 ${e.printStackTrace()}")
}
}
}

View File

@ -2,7 +2,6 @@ package com.gh.common.util
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.gh.common.iinterface.ISuperiorChain
import com.gh.gamecenter.amway.AmwayFragment
import com.gh.gamecenter.category2.CategoryV2Fragment
import com.gh.gamecenter.common.constant.EntranceConsts
@ -15,7 +14,7 @@ import com.gh.gamecenter.forum.detail.ForumDetailFragment
import com.gh.gamecenter.forum.home.CommunityHomeFragment
import com.gh.gamecenter.fragment.ReloadFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailFragment
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListWrapperFragment
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.gamedetail.GameDetailFragment
@ -31,7 +30,6 @@ import com.gh.gamecenter.qa.video.detail.ForumVideoDetailFragment
import com.gh.gamecenter.servers.GameServersPublishFragment
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Fragment
import com.gh.gamecenter.subject.SubjectFragment
import com.gh.gamecenter.tag.TagsActivity
import com.gh.gamecenter.tag.TagsListFragment
import com.gh.gamecenter.toolbox.ToolboxFragment
import com.gh.gamecenter.video.detail.HomeVideoFragment
@ -45,98 +43,50 @@ import com.halo.assistant.fragment.WebFragment
object ViewPagerFragmentHelper {
const val WRAPPER_FRAGMENT_NAME = "WrapperFragmentName"
const val TYPE_MULTI_TAB_NAV = "multi_tab_nav"
const val TYPE_CUSTOM_PAGE = "custom_page"
const val TYPE_GAME = "game" // 游戏详情页
const val TYPE_MY_HALO = "my_halo" // 我的光环
const val TYPE_COMMUNITY_HOME = "community_home" // 社区首页
const val TYPE_COMMUNITY = "community" // 论坛
const val TYPE_COMMUNITY_SECTION = "bbs_section" // 论坛子版块
const val TYPE_COMMUNITY_ARTICLE = "community_article" // 帖子
const val TYPE_QUESTION = "question" // 提问
const val TYPE_VIDEO_STREAM = "video_stream" // 视频信息流
const val TYPE_VIDEO = "video" // 视频贴
const val TYPE_AMWAY = "top_game_comment" // 安利墙
const val TYPE_GAME_HOT_LIST = "game_hot_list" // 游戏单热搜榜
const val TYPE_GAME_LIST = "game_list" // 游戏单广场
const val TYPE_FEEDBACK = "feedback" // 帮助与反馈
const val TYPE_COLUMN = "column" // 游戏专题详情页
const val TYPE_QQ_MINI_GAME_COLUMN = "qq_mini_game_column_detail" // QQ游戏专题详情页
const val TYPE_COLUMN_COLLECTION = "column_collection" // 专题合集详情页
const val TYPE_SERVER = "server" // 开服表
const val TYPE_COLUMN_TEST = "column_test_v2" // 新游开测
const val TYPE_CATEGORY_V2 = "category_v2" // 分类2.0
const val TYPE_COMMON_COLLECTION = "common_collection" // 通用内容合集详情页
const val TYPE_WEB = "web" // web链接
const val TYPE_EXPLORE = "game_explore" // 发现页
const val TYPE_LIBAO = "libao" // 礼包详情页
const val TYPE_LIBAO_CENTER = "libao_center" // 礼包中心
const val TYPE_TAG = "tag" // 游戏标签详情
const val TYPE_ARTICLE = "article" // 文章
const val TYPE_COMMUNITY_COLUMN = "community_column" // 社区专题
const val TYPE_ARTICLE_CENTER = "article_center" // 资讯中心
const val TYPE_QA = "qa" // QA
const val TYPE_TOOLKIT = "toolkit" // 工具箱
fun createFragment(parentFragment: Fragment?, bundle: Bundle, linkEntity: LinkEntity, isTabWrapper: Boolean): Fragment {
fun createFragment(bundle: Bundle, linkEntity: LinkEntity, isTabWrapper: Boolean): Fragment {
return when (linkEntity.type) {
// 游戏详情页
TYPE_GAME -> {
"game" -> {
bundle.putString(EntranceConsts.KEY_GAMEID, linkEntity.link)
GameDetailFragment().with(bundle)
}
// 我的光环
TYPE_MY_HALO -> {
val superiorChain = if (parentFragment is ISuperiorChain) parentFragment else null
HaloPersonalFragment().setSuperiorChain(superiorChain).with(bundle)
}
"my_halo" -> HaloPersonalFragment().with(bundle)
// 社区首页
TYPE_COMMUNITY_HOME -> CommunityHomeFragment().with(bundle)
"community_home" -> CommunityHomeFragment().with(bundle)
// 视频信息流
TYPE_VIDEO_STREAM -> {
"video_stream" -> {
bundle.putBoolean(EntranceConsts.KEY_IS_HOME_VIDEO, true)
HomeVideoFragment().with(bundle)
}
// 安利墙
TYPE_AMWAY -> {
"top_game_comment" -> {
AmwayFragment().with(bundle)
}
// 论坛
TYPE_COMMUNITY -> {
"community" -> {
bundle.putString(EntranceConsts.KEY_BBS_ID, linkEntity.link)
ForumDetailFragment().with(bundle)
}
// 论坛子版块
TYPE_COMMUNITY_SECTION -> {
"bbs_section" -> {
bundle.putString(EntranceConsts.KEY_BBS_ID, linkEntity.community?.id)
bundle.putString(EntranceConsts.KEY_BBS_SECTION_ID, linkEntity.link)
ForumDetailFragment().with(bundle)
}
// 游戏单热搜榜
TYPE_GAME_HOT_LIST -> {
"game_hot_list" -> {
GameCollectionHotListWrapperFragment().with(bundle)
}
// 视频贴
TYPE_VIDEO -> {
"video" -> {
bundle.putString(EntranceConsts.KEY_VIDEO_ID, linkEntity.link)
ForumVideoDetailFragment().with(bundle)
}
// 帮助与反馈
TYPE_FEEDBACK -> {
"feedback" -> {
HelpAndFeedbackFragment().with(bundle)
}
// 帖子
TYPE_COMMUNITY_ARTICLE -> {
bundle.putString(EntranceConsts.KEY_COMMUNITY_ARTICLE_ID, linkEntity.link)
bundle.putParcelable(EntranceConsts.KEY_COMMUNITY_DATA, linkEntity.community)
ArticleDetailFragment().with(bundle)
}
// 提问
TYPE_QUESTION -> {
bundle.putString(EntranceConsts.KEY_QUESTIONS_ID, linkEntity.link)
NewQuestionDetailFragment().with(bundle)
}
// 其他原来带Toolbar的Fragment
else -> createToolbarWrapperFragment(bundle, linkEntity, isTabWrapper)
}
@ -147,11 +97,11 @@ object ViewPagerFragmentHelper {
when (entity.type) {
// 游戏单广场
TYPE_GAME_LIST -> {
"game_list" -> {
className = GameCollectionSquareFragment::class.java.name
}
// 游戏专题详情页/QQ游戏专题详情页
TYPE_COLUMN, TYPE_QQ_MINI_GAME_COLUMN -> {
"column", "qq_mini_game_column_detail" -> {
className = SubjectFragment::class.java.name
bundle.putParcelable(
EntranceConsts.KEY_SUBJECT_DATA,
@ -160,7 +110,7 @@ object ViewPagerFragmentHelper {
bundle.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, !isTabWrapper)
}
// 专题合集详情页
TYPE_COLUMN_COLLECTION -> {
"column_collection" -> {
className = ColumnCollectionDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
bundle.putInt(EntranceConsts.KEY_POSITION, 0)
@ -168,29 +118,29 @@ object ViewPagerFragmentHelper {
bundle.putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true)
}
// 开服表
TYPE_SERVER -> {
"server" -> {
className = GameServersPublishFragment::class.java.name
bundle.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, !isTabWrapper)
}
// 新游开测
TYPE_COLUMN_TEST -> {
"column_test_v2" -> {
className = GameServerTestV2Fragment::class.java.name
}
// 分类2.0
TYPE_CATEGORY_V2 -> {
"category_v2" -> {
className = CategoryV2Fragment::class.java.name
bundle.putString(EntranceConsts.KEY_CATEGORY_ID, entity.link)
bundle.putString(EntranceConsts.KEY_CATEGORY_TITLE, entity.text)
bundle.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, !isTabWrapper)
}
// 通用内容合集详情页
TYPE_COMMON_COLLECTION -> {
className = CustomCommonCollectionDetailFragment::class.java.name
"common_collection" -> {
className = CommonCollectionDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
bundle.putString(EntranceConsts.KEY_COLUMNNAME, entity.text)
}
// web链接
TYPE_WEB -> {
"web" -> {
className = WebFragment::class.java.name
bundle.putString(EntranceConsts.KEY_URL, entity.link)
bundle.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false)
@ -200,47 +150,57 @@ object ViewPagerFragmentHelper {
}
}
// 发现页
TYPE_EXPLORE -> {
"game_explore" -> {
className = DiscoveryFragment::class.java.name
}
// 礼包详情页
TYPE_LIBAO -> {
"libao" -> {
className = LibaoDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_ID, entity.link)
}
// 游戏标签详情
TYPE_TAG -> {
"tag" -> {
className = TagsListFragment::class.java.name
bundle.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, !isTabWrapper)
bundle.putString(TagsActivity.TAG, entity.text)
}
// 文章
TYPE_ARTICLE -> {
"article" -> {
className = NewsDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_NEWSID, entity.link)
}
// 提问
"question" -> {
className = NewQuestionDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_QUESTIONS_ID, entity.link)
}
// 帖子
"community_article" -> {
className = ArticleDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_COMMUNITY_ARTICLE_ID, entity.link)
bundle.putParcelable(EntranceConsts.KEY_COMMUNITY_DATA, entity.community)
}
// 社区专题
TYPE_COMMUNITY_COLUMN -> {
"community_column" -> {
className = AskSubjectFragment::class.java.name
bundle.putString(EntranceConsts.KEY_COLUMN_ID, entity.link)
bundle.putParcelable(EntranceConsts.KEY_COMMUNITY_DATA, entity.community)
}
// QA
TYPE_QA -> {
"qa" -> {
className = HelpContainerFragment::class.java.name
bundle.putString(EntranceConsts.KEY_QA_ID, entity.link)
bundle.putString(EntranceConsts.KEY_NAVIGATION_TITLE, entity.text)
}
// 资讯中心
TYPE_ARTICLE_CENTER -> {
"article_center" -> {
className = InfoWrapperFragment::class.java.name
}
// 礼包中心
TYPE_LIBAO_CENTER -> {
"libao_center" -> {
className = LibaoFragment::class.java.name
}
// 工具箱
TYPE_TOOLKIT -> {
"toolkit" -> {
className = ToolboxFragment::class.java.name
}
}

View File

@ -43,7 +43,7 @@ class CustomExoPlayerCacheManager : ICacheManager {
return mExoSourceManager != null && mExoSourceManager?.hadCached() == true
}
override fun cachePreview(context: Context, cacheDir: File?, url: String): Boolean {
override fun cachePreview(context: Context, cacheDir: File, url: String): Boolean {
return ExoSourceManager.cachePreView(context, cacheDir, url)
}

View File

@ -0,0 +1,248 @@
package com.gh.common.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.ProgressBar;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.R;
public class DownloadProgressBar extends ProgressBar {
public static final int MAX_LENGTH = 1000;
public static final int DOWNLOAD_NORMAL_STYLE = 0;
public static final int DOWNLOAD_IMAGE_STYLE = 2;
public enum DownloadType {
NORMAL,
NONE,
NONE_WITH_HINT,
PLUGIN,
LAUNCH_OR_OPEN,
INSTALL_NORMAL,
INSTALL_PLUGIN,
DOWNLOADING_NORMAL,
DOWNLOADING_PLUGIN,
RESERVABLE,
RESERVED,
H5_GAME,
UPDATING,
TEENAGER_MODEL,
SPECIAL_DOWNLOAD,
XAPK_UNZIPPING,
XAPK_SUCCESS,
XAPK_FAILURE,
}
private PorterDuffXfermode mDuffXFerMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 仅用于测量文字是否超出范围,不用于画文字
private TextPaint mFakeTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private DownloadType mDownloadType;
private String mText;
private int mDownloadStyle;
private int mDefaultColor;
private int mTextSize;
private boolean mShowDownloadPercent = false;
private Rect mTextBound = new Rect();
public DownloadProgressBar(Context context) {
super(context);
}
public DownloadProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
if (attrs != null) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DownloadProgressBar);
mDownloadStyle = ta.getInteger(R.styleable.DownloadProgressBar_downloadStyle, DOWNLOAD_NORMAL_STYLE);
mTextSize = ta.getDimensionPixelSize(R.styleable.DownloadProgressBar_textSize, DisplayUtils.sp2px(getContext(), 14));
mShowDownloadPercent = ta.getBoolean(R.styleable.DownloadProgressBar_showDownloadPercent, false);
ta.recycle();
}
setMax(MAX_LENGTH);
setProgressDrawable(getResources().getDrawable(R.drawable.game_item_btn_download_style));
}
Bitmap srcBitmap;
Canvas srcCanvas;
RectF rectF;
private void create() {
srcBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
srcCanvas = new Canvas(srcBitmap);
rectF = new RectF(0, 0, getProgress() * getWidth() / MAX_LENGTH, getMeasuredHeight());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (TextUtils.isEmpty(mText)) return;
mPaint.setColor(mDefaultColor == 0 ? ContextCompat.getColor(getContext(), R.color.text_theme) : mDefaultColor); // 初始化颜色
mPaint.setTextSize(mTextSize);
mFakeTextPaint.setTextSize(mTextSize);
mFakeTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mFakeTextPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setXfermode(null);
create();
Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
int baseline = (getHeight() - fontMetrics.bottom - fontMetrics.top) / 2;
mPaint.setTextAlign(Paint.Align.CENTER);
canvas.getClipBounds(mTextBound); //The dimensions of your canvas
int width = mTextBound.width() - 20; //10 to keep some space on the right for the "..."
String txt = TextUtils.ellipsize(mText, mFakeTextPaint, width, TextUtils.TruncateAt.END).toString();
srcCanvas.drawText(txt, getWidth() / 2, baseline, mPaint);
mPaint.setXfermode(mDuffXFerMode);
if (getProgress() != 0) {
int color = Color.WHITE;
if (DOWNLOAD_IMAGE_STYLE == mDownloadStyle) {
color = Color.BLACK;
}
mPaint.setColor(color); // 反向颜色
}
srcCanvas.drawRect(rectF, mPaint);
canvas.drawBitmap(srcBitmap, 0, 0, null);
}
public void setText(String text) {
mText = text;
invalidate();
}
public String getText() {
if (mText != null && mText.contains("%")) {
return getResources().getString(R.string.downloading);
}
return mText;
}
public void setText(@StringRes int res) {
if (mShowDownloadPercent && res == R.string.downloading) {
setText(getProgressPercent());
} else {
setText(getResources().getString(res));
}
}
public void setDownloadStyle(int downloadStyle) {
this.mDownloadStyle = downloadStyle;
}
@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);
if (getResources().getString(R.string.downloading).equals(mText)) {
setText(getProgressPercent());
}
}
private String getProgressPercent() {
return getProgress() / 10 + "%";
}
public void setDownloadType(DownloadType downloadType) {
switch (downloadType) {
case NORMAL:
case NONE_WITH_HINT:
case INSTALL_NORMAL:
case H5_GAME:
if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) {
setProgressDrawable(getResources().getDrawable(R.drawable.text_white_background));
mDefaultColor = Color.BLACK;
} else {
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style));
mDefaultColor = Color.WHITE;
}
setProgress(0);
break;
case PLUGIN:
case INSTALL_PLUGIN:
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_pluggable_style));
mDefaultColor = Color.WHITE;
setProgress(0);
break;
case NONE:
setProgressDrawable(getResources().getDrawable(R.drawable.button_round_gray_light));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_tertiary);
setProgress(0);
break;
case LAUNCH_OR_OPEN:
if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) {
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_image_style));
mDefaultColor = Color.WHITE;
} else {
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style));
mDefaultColor = Color.WHITE;
}
setProgress(0);
break;
case DOWNLOADING_NORMAL:
if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) {
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_image_style));
mDefaultColor = Color.WHITE;
} else {
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_theme);
}
break;
case DOWNLOADING_PLUGIN:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_theme);
break;
case RESERVABLE:
setProgressDrawable(getResources().getDrawable(R.drawable.button_reserve));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
case UPDATING:
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_updating_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
case RESERVED:
setProgressDrawable(getResources().getDrawable(R.drawable.button_round_gray_light));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_tertiary);
break;
case XAPK_FAILURE:
case XAPK_SUCCESS:
case XAPK_UNZIPPING:
setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_xapk_detail_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
case TEENAGER_MODEL:
case SPECIAL_DOWNLOAD:
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
}
mDownloadType = downloadType;
}
public DownloadType getDownloadType() {
return mDownloadType;
}
}

View File

@ -8,19 +8,19 @@ import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.util.DirectUtils
import com.gh.common.util.*
import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.core.utils.TopCutProcess
import com.gh.gamecenter.databinding.ItemCommunityImageBinding
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.CommunityVideoEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
class ImageContainerView : LinearLayout {
@ -159,10 +159,10 @@ class ImageContainerView : LinearLayout {
binding.root.setOnClickListener {
debounceActionWithInterval(it.id, 1000) {
if (mAnswerEntity == null) return@debounceActionWithInterval
val videoEntity = mAnswerEntity!!.getPassVideos().firstOrNull()
val videoEntity = mAnswerEntity!!.getPassVideos()[0]
DirectUtils.directToVideoDetail(
context,
videoEntity?.id ?: "",
videoEntity.id,
VideoDetailContainerViewModel.Location.VIDEO_HOT.value,
showComment = false,
entrance = mEntrance,

View File

@ -4,22 +4,15 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Environment
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.constant.Config
import com.gh.common.dialog.ManagerAllFilesPermissionDialogFragment
import com.gh.common.util.*
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadNotificationHelper
import com.gh.common.util.PackageInstaller
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.xapk.XApkUnZipper
@ -27,7 +20,10 @@ import com.gh.gamecenter.xapk.core.XApkFile
import com.gh.gamecenter.xapk.core.XApkUnZipCallback
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
import com.gh.gamecenter.xapk.io.*
import com.gh.gamecenter.xapk.io.NonSplitApksOutput
import com.gh.gamecenter.xapk.io.OBBFileOutput
import com.gh.gamecenter.xapk.io.SplitApksOutput
import com.gh.gamecenter.xapk.io.XApkFileOutput
import com.gh.gamecenter.xapk.pi.IPackageInstaller
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
@ -114,14 +110,9 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
return
}
if (checkPermission(downloadEntity, showUnzipToast)) {
DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
?.let {
unzipXapkFile(it)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
}
unzipXapkFile(downloadEntity)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
} else {
throwExceptionInDebug("如果是Apk包请使用PackageInstaller进行安装")
@ -129,23 +120,6 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
}
}
private fun checkPermission(downloadEntity: DownloadEntity, showUnzipToast: Boolean = false): Boolean {
// 安卓11以上系统需要开启所有文件访问权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
&& !Environment.isExternalStorageManager()) {
CurrentActivityHolder.getCurrentActivity()?.let {
ManagerAllFilesPermissionDialogFragment.show(it as AppCompatActivity) {
unzipXapkFile(downloadEntity)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
}
}
return false
}
return true
}
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
mXApkUnZipper.unzip(
XApkUnZipEntry(

View File

@ -2,11 +2,15 @@ package com.gh.common.xapk
import android.os.Build
import android.os.Environment
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.throwException
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.MD5Utils
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import net.lingala.zip4j.progress.ProgressMonitor
import java.io.File

View File

@ -20,49 +20,38 @@ import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.entity.CustomPageTrackData;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.common.history.HistoryHelper;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.DataCollectionUtils;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LunchType;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.AppDebugConfig;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.download.DownloadedGameIdAndPackageNameDao;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.HomePluggableFilterEntity;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.HomePluggableFilterEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.vspace.VHelper;
import com.gh.ndownload.NDataChanger;
import com.gh.ndownload.NDownloadBridge;
import com.gh.ndownload.NDownloadService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.download.ConnectionUtils;
import com.lightgame.download.DataWatcher;
@ -71,6 +60,7 @@ import com.lightgame.download.DownloadDao;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.DownloadStatusListener;
import com.lightgame.download.FileUtils;
import com.lightgame.download.HttpDnsManager;
import com.lightgame.utils.Utils;
@ -78,7 +68,6 @@ import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -256,9 +245,7 @@ public class DownloadManager implements DownloadStatusListener {
String location,
boolean isSubscribe,
@Nullable ExposureEvent traceEvent) {
if (!gameEntity.getApk().isEmpty()) {
createDownload(context, gameEntity.getApk().get(0), gameEntity, asVGame, gameEntity.isDualBtnModeEnabled(), entrance, location, isSubscribe, traceEvent);
}
createDownload(context, gameEntity.getApk().get(0), gameEntity, asVGame, gameEntity.isDualBtnModeEnabled(), entrance, location, isSubscribe, traceEvent);
}
/**
@ -342,7 +329,6 @@ public class DownloadManager implements DownloadStatusListener {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_CATEGORY_IN_CHINESE, gameEntity.getCategoryChinese());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.AD_ICON_ACTIVE, String.valueOf(gameEntity.getAdIconActive()));
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_AD_DATA, String.valueOf(gameEntity.isAdData()));
ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_STATUS_IN_CHINESE, gameEntity.getDownloadStatusChinese());
ExtensionsKt.putGameCategory(downloadEntity, gameCategory != null ? gameCategory : "");
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_SIZE, apkEntity.getSize());
if (gameEntity.getIconFloat() != null) {
@ -350,9 +336,6 @@ public class DownloadManager implements DownloadStatusListener {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR, gameEntity.getIconFloat().getUpperLeftColor());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_BOTTOM_TEXT, gameEntity.getIconFloat().getBottomText());
}
if (gameEntity.isModdedGame()) {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_IS_MODDED_GAME, "true");
}
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR_GAME, apkEntity.getFormat());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator()));
@ -404,20 +387,6 @@ public class DownloadManager implements DownloadStatusListener {
// 将下载事件放入 downloadEntity 中供下载完成时取出使用
downloadEntity.setExposureTrace(GsonUtils.toJson(downloadExposureEvent));
// 保存所有游戏标签
List<String> tags = new ArrayList<>();
for (TagStyleEntity tag : gameEntity.getTagStyle()) {
tags.add(tag.getName());
}
downloadEntity.setTags(tags);
// 将自定义页面相关埋点数据放入 downloadEntity 中供下载完成时取出使用
CustomPageTrackData customPageTrackData = gameEntity.getCustomPageTrackData();
if (customPageTrackData != null) {
String trackJson = GsonUtils.toJson(customPageTrackData);
downloadEntity.setCustomPageTrackData(trackJson);
}
if (isSubscribe) {
DownloadManager.getInstance().subscribe(downloadEntity);
} else {
@ -426,19 +395,11 @@ public class DownloadManager implements DownloadStatusListener {
}
if (asVGame) {
String[] vaKvs = {
"game_name", gameEntity.getName(),
"game_id", gameEntity.getId(),
"game_type", gameEntity.getCategoryChinese(),
"game_schema_type", gameEntity.getGameBitChinese()
};
List<String> vaList = new ArrayList<>(Arrays.asList(vaKvs));
if (customPageTrackData != null) {
vaList.addAll(Arrays.asList(customPageTrackData.toKV()));
}
SensorsBridge.trackEventWithExposureSource("HaloFunGameDownloadClick",
downloadExposureEvent.getSource(),
vaList.toArray(new String[0]));
"game_name", gameEntity.getName(),
"game_id", gameEntity.getId(),
"game_schema_type", gameEntity.getGameBitChinese());
}
String trackDownloadType = "";
@ -448,12 +409,11 @@ public class DownloadManager implements DownloadStatusListener {
trackDownloadType = "本地下载";
}
String[] arrayKv = {
SensorsBridge.trackEventWithExposureSource("DownloadProcessBegin",
downloadExposureEvent.getSource(),
"game_id", gameEntity.getId(),
"game_name", gameEntity.getName(),
"game_type", gameEntity.getCategoryChinese(),
"game_label", String.join(",", tags),
"game_schema_type", gameEntity.getGameBitChinese(),
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
"page_id", GlobalActivityManager.getCurrentPageEntity().getPageId(),
@ -461,17 +421,7 @@ public class DownloadManager implements DownloadStatusListener {
"last_page_name", GlobalActivityManager.getLastPageEntity().getPageName(),
"last_page_id", GlobalActivityManager.getLastPageEntity().getPageId(),
"last_page_business_id", GlobalActivityManager.getLastPageEntity().getPageBusinessId(),
"download_status", gameEntity.getDownloadStatusChinese(),
"download_type", trackDownloadType
};
List<String> kvs = new ArrayList<>(Arrays.asList(arrayKv));
if (customPageTrackData != null) {
kvs.addAll(Arrays.asList(customPageTrackData.toKV()));
}
SensorsBridge.trackEventWithExposureSource("DownloadProcessBegin",
downloadExposureEvent.getSource(), kvs.toArray(new String[0])
);
//TODO remove
@ -498,7 +448,6 @@ public class DownloadManager implements DownloadStatusListener {
SentryHelper.INSTANCE.onEvent("CLEAR_DELETED_TASK_ERROR", "exception_digest", e.getLocalizedMessage());
}
}
/**
* 添加一个下载任务
* <p>

View File

@ -3,9 +3,7 @@ package com.gh.download
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.common.util.*
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.constant.Constants
@ -20,7 +18,6 @@ import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.GameDigestEntity
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository

View File

@ -27,13 +27,21 @@ object ExoCacheManager {
if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
10 * 1024 * 1024L
} else {
10 * 1024 * 1024L
when (NetworkUtils.getMobileNetworkType(HaloApp.getInstance().application)) {
"5G", "4G" -> 10 * 1024 * 1024L
"3G" -> 5 * 1024 * 1024L
else -> 0L
}
}
} else {
if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
50 * 1024 * 1024L
} else {
20 * 1024 * 1024L
when (NetworkUtils.getMobileNetworkType(HaloApp.getInstance().application)) {
"5G", "4G" -> 20 * 1024 * 1024L
"3G" -> 5 * 1024 * 1024L
else -> 0L
}
}
}
}

View File

@ -113,16 +113,16 @@ class DownloadDialogAdapter(
holder.binding.run {
links?.let {
leftLink.setOnClickListener { view ->
it.firstOrNull()?.let { link -> clickListener.onClick(view, link) }
clickListener.onClick(view, links[0])
}
rightLink.setOnClickListener { view ->
it.getOrNull(1)?.let { link -> clickListener.onClick(view, link) }
clickListener.onClick(view, links[1])
}
}
leftLink.visibleIf(!links.isNullOrEmpty())
rightLink.visibleIf((links?.size ?: 0) > 1)
leftLink.text = links?.firstOrNull()?.title ?: ""
rightLink.text = links?.getOrNull(1)?.title ?: ""
rightLink.visibleIf(links?.size ?: 0 > 1)
leftLink.text = if (links.isNullOrEmpty()) "" else links[0].title
rightLink.text = if (links?.size ?: 0 > 1) links?.get(1)?.title else ""
leftLink.background = GradientDrawable().apply {
cornerRadius = 8F.dip2px().toFloat()
setStroke(0.5F.dip2px(), R.color.ui_divider.toColor(mContext))

View File

@ -28,6 +28,7 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.manager.PackagesManager
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils

View File

@ -28,10 +28,10 @@ import org.json.JSONObject
import java.io.File
import java.net.URLEncoder
import java.util.*
import kotlin.collections.ArrayList
object BrowserInstallHelper {
// 随便选的 32321 居然在部分 vivo 手机上被占用,喷了
private const val PORT = 40705
private const val RESERVE_PORT = 40706
@ -40,12 +40,15 @@ object BrowserInstallHelper {
private val mContext by lazy { HaloApp.getInstance().application }
private var mUseReservePort = false
private var mValidInstalledPackageList: ArrayList<String> = arrayListOf()
private var mValidConditionMatchedCache: Boolean? = null
private val mAllInstalledPackageList: ArrayList<String> by lazy {
PackageUtils.getAllPackageNameIncludeSystemApps(HaloApp.getInstance().applicationContext).apply {
add(HaloApp.getInstance().applicationContext.packageName)
}
}
private fun getServer(port: Int): DownloadServer {
val server = DownloadServer(port)
for (packageName in getAllInstalledPackageList()) {
for (packageName in mAllInstalledPackageList) {
if (packageName.contains("com.freeme") || packageName.contains("com.zhuoyi")) {
server.isBuggyDevice = true
break
@ -54,23 +57,6 @@ object BrowserInstallHelper {
return server
}
private fun getAllInstalledPackageList(): ArrayList<String> {
when {
mValidInstalledPackageList.isNotEmpty() -> {
return mValidInstalledPackageList
}
else -> {
val allInstalledPackageList = PackageUtils.getAllPackageNameIncludeSystemApps(mContext)
if (allInstalledPackageList.isNotEmpty()) {
mValidInstalledPackageList = allInstalledPackageList
}
return mValidInstalledPackageList
}
}
}
fun downloadFile(filePath: String) {
if (!::mServer.isInitialized) mServer = if (mUseReservePort) getServer(RESERVE_PORT) else getServer(PORT)
if (!mServer.isAlive && !startServer()) {
@ -94,7 +80,7 @@ object BrowserInstallHelper {
Base64.encodeToString(URLEncoder.encode(downloadUrl).trim().toByteArray(), Base64.NO_WRAP)
DirectUtils.directToExternalBrowser(
mContext,
"https://down-and.ghzs6.com/redirect?location=base64($encodedString)"
"https://down-and.ghzs.com/redirect?location=base64($encodedString)"
)
} else {
DirectUtils.directToExternalBrowser(mContext, downloadUrl)
@ -251,43 +237,32 @@ object BrowserInstallHelper {
* 是否满足开启浏览器安装的条件
*/
private fun isConditionMatched(settingsEntity: NewSettingsEntity): Boolean {
if (mValidConditionMatchedCache != null) {
return mValidConditionMatchedCache!!
}
val packageList = getAllInstalledPackageList()
if (packageList.isEmpty()) return false
settingsEntity.installModel?.whiteList?.let {
for (packageName in it) {
if (packageList.contains(packageName)) {
mValidConditionMatchedCache = false
break
if (mAllInstalledPackageList.contains(packageName)) {
return false
}
}
}
settingsEntity.installModel?.packages?.let {
for (packageName in it) {
if (packageList.contains(packageName)) {
mValidConditionMatchedCache = true
break
if (mAllInstalledPackageList.contains(packageName)) {
return true
}
}
}
// 匹配部分字符串即可
settingsEntity.installModel?.regexPackages?.let {
for (packageNamePieces in it) {
for (installedPackageName in packageList) {
for (installedPackageName in mAllInstalledPackageList) {
if (installedPackageName.contains(packageNamePieces)) {
mValidConditionMatchedCache = true
break
return true
}
}
}
}
return mValidConditionMatchedCache ?: false
return false
}
fun onApkInstalled(path: String?) {

View File

@ -1,12 +1,12 @@
package com.gh.download.server
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.FileUtils
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.download.DownloadManager
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import fi.iki.elonen.NanoHTTPD
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers

View File

@ -1,18 +1,30 @@
package com.gh.download.simple
import com.halo.assistant.HaloApp
import com.lg.download.*
import com.lg.ndownload.DownloadConfig
import com.lg.ndownload.DownloadDbManager
import com.lg.ndownload.DownloadQueue
import com.gh.gamecenter.common.utils.FileUtils
import com.lightgame.download.FileUtils
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
object SimpleDownloadManager {
private const val MAX_DOWNLOADING_TASK = 2
private val mDownloadQueue by lazy { DownloadQueue.getInstance() }
private val mExecutor by lazy { Executors.newCachedThreadPool() }
fun init() {
ExecutorProvider.getInstance().backgroundExecutor.execute {
DownloadDbManager.init(HaloApp.getInstance())
}
// 设置最大同时下载任务数 (可选)
DownloadQueue.getInstance().setMaxDownloadingTask(MAX_DOWNLOADING_TASK)
}
/**
* 继续任务
*/

View File

@ -70,7 +70,7 @@ public class DownloadManagerActivity extends ToolBarActivity {
@Override
public boolean onMenuItemClick(MenuItem item) {
NewFlatLogUtils.logHaloFunManageShow("下载管理");
DirectUtils.directToVGameDownload(this, "下载管理", false);
DirectUtils.directToVGameDownload(this, false);
return true;
}

View File

@ -8,13 +8,11 @@ import android.view.View
import com.gh.base.DownloadToolbarActivity
import com.gh.common.exposure.ExposureManager.log
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.toArrayList
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.entity.GamePlatform
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.exposure.ExposureEvent.Companion.createEvent
@ -172,12 +170,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
@JvmStatic
fun startGameDetailActivity(
context: Context,
gameId: String,
entrance: String?,
traceEvent: ExposureEvent?
) {
fun startGameDetailActivity(context: Context, gameId: String, entrance: String?, traceEvent: ExposureEvent?) {
startGameDetailActivity(context, gameId, entrance, -1, traceEvent = traceEvent)
}
@ -233,8 +226,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
platformName: String? = null,
packageName: String? = null,
platforms: List<GamePlatform>? = null,
traceEvent: ExposureEvent? = null,
customPageTrackData: CustomPageTrackData? = null
traceEvent: ExposureEvent? = null
) {
val bundle = Bundle()
@ -288,13 +280,6 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
bundle.putString(EntranceConsts.KEY_GAMEID, gameId)
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
bundle.putParcelable(EntranceConsts.KEY_CUSTOM_PAGE_TRACK_DATA, customPageTrackData)
bundle.putString(EntranceConsts.KEY_LAST_PAGE_ID, GlobalActivityManager.getLastPageEntity().pageId)
bundle.putString(EntranceConsts.KEY_LAST_PAGE_NAME, GlobalActivityManager.getLastPageEntity().pageName)
bundle.putString(
EntranceConsts.KEY_LAST_PAGE_BUSINESS_ID,
GlobalActivityManager.getLastPageEntity().pageBusinessId
)
context.startActivity(
getTargetIntent(
context,

View File

@ -46,7 +46,7 @@ import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.ImageUtils.getIdealImageUrl
import com.gh.gamecenter.common.utils.ImageUtils.getTransformedUrl
import com.gh.gamecenter.common.view.DraggableBigImageView
import com.gh.gamecenter.common.view.Gh_RelativeLayout
import com.gh.gamecenter.core.runOnIoThread
@ -831,7 +831,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
&& !NetworkUtils.isWifiOr4GConnected(this@ImageViewerActivity)
&& !thumbnailImageUrl.contains(".gif")
) {
compressedStandardImageUrl = getIdealImageUrl(thumbnailImageUrl, mLimitWidth)
compressedStandardImageUrl = getTransformedUrl(thumbnailImageUrl, mLimitWidth)
thumbnailImageUrl = compressedStandardImageUrl ?: ""
}
val finalUrl = compressedStandardImageUrl

View File

@ -17,6 +17,7 @@ import static com.gh.gamecenter.common.utils.ExtensionsKt.observableToMain;
import static com.gh.gamecenter.login.utils.LoginHelper.WEIBO_SCOPE;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -50,12 +51,15 @@ import com.gh.common.history.HistoryHelper;
import com.gh.common.prioritychain.GlobalPriorityChainHelper;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.ActivationHelper;
import com.gh.common.util.AdHelper;
import com.gh.common.util.CertificationSwitchHelper;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DeviceTokenUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ErrorHelper;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
import com.gh.common.util.PackageInstaller;
@ -70,7 +74,6 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.constant.CommonConsts;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.entity.SuggestType;
import com.gh.gamecenter.common.eventbus.EBNetworkState;
import com.gh.gamecenter.common.eventbus.EBReuse;
@ -79,7 +82,6 @@ import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.common.utils.ShareUtils;
@ -93,18 +95,19 @@ import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.StartupAdEntity;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.home.custom.model.CustomPageShareRepository;
import com.gh.gamecenter.home.skip.PackageSkipActivity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.room.AppDatabase;
import com.gh.gamecenter.room.dao.SimulatorGameDao;
import com.gh.gamecenter.wrapper.MainWrapperFragment;
import com.gh.gamecenter.wrapper.MainWrapperRepository;
import com.gh.gamecenter.wrapper.MainWrapperViewModel;
import com.gh.vspace.VHelper;
import com.google.android.exoplayer2.upstream.cache.Cache;
@ -113,11 +116,14 @@ import com.google.gson.reflect.TypeToken;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.openapi.IWBAPI;
import com.sina.weibo.sdk.openapi.WBAPIFactory;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;
@ -131,11 +137,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import kotlin.jvm.functions.Function1;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
@ -143,6 +152,9 @@ import tv.danmaku.ijk.media.exo2.ExoSourceManager;
public class MainActivity extends BaseActivity {
public static final String EB_SKIP_MAIN = "MainActivity";
public static final String SWITCH_TO_COMMUNITY = "switch_to_community";
public static final String SWITCH_TO_VIDEO = "switch_to_video";
public static final String SHOW_AD = "show_ad";
public static final int COUNTDOWN_AD = 100;
public static final int COUNTDOWN_MAX_COUNT = 3;
@ -159,6 +171,8 @@ public class MainActivity extends BaseActivity {
// 黄壮华 按连续按返回键两次才退出应用
private final long[] mHits = new long[2];
public static boolean isNewFirstLaunch;
private final Handler handler = new Handler();
private boolean mShouldShowAd = false; // 是否显示广告
@ -171,8 +185,6 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel = new ViewModelProvider(this, new MainWrapperViewModel.Factory(HaloApp.getInstance()))
.get(MainWrapperViewModel.class);
DisplayUtils.updateGlobalScreen(this);
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);
@ -187,10 +199,15 @@ public class MainActivity extends BaseActivity {
replaceFragment(mMainWrapperFragment);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (HaloApp.getInstance().isNewForThisVersion) {
LunchType lunchType = HaloApp.getInstance().getLaunchType();
isNewFirstLaunch = sp.getBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), true);
if (isNewFirstLaunch) {
final LunchType lunchType = DeviceTokenUtils.getLaunchType(false);
// 延时两秒提交,避免提交时还没获取到 GID/OAID
AppExecutor.getUiExecutor().executeWithDelay(() -> {
if (!this.isFinishing()) {
LogUtils.uploadDevice(lunchType);
ActivationHelper.sendActivationInfo();
// 第一次打开App删除模拟器游戏记录不包括更新版本
if (HaloApp.getInstance().isBrandNewInstall) {
getTeenagerMode();
@ -198,7 +215,7 @@ public class MainActivity extends BaseActivity {
}
}
}, 2000L);
sp.edit().putBoolean(Constants.SP_NEW_FIRST_LAUNCH_VERSION + PackageUtils.getGhVersionName(), false).apply();
sp.edit().putBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), false).apply();
// 记录曾安装过的版本 + 渠道
SPUtils.setString("installedVersionV" + PackageUtils.getGhVersionName(), HaloApp.getInstance().getChannel());
@ -223,7 +240,7 @@ public class MainActivity extends BaseActivity {
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手发生了闪退,建议安装到最新版本修复异常"
, "马上反馈", "马上安装修复",
() -> {
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "", "crash", true, "desc", null);
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "crash", true, "desc", null);
return null;
},
() -> {
@ -257,6 +274,10 @@ public class MainActivity extends BaseActivity {
ReservationRepository.refreshReservations();
if (getIntent().getBooleanExtra(SWITCH_TO_VIDEO, false)) {
handler.postDelayed(() -> mMainWrapperFragment.setCurrentItem(MainWrapperFragment.TYPE_VIDEO_STREAM), 800);
}
// 跳转至其它页面
if (getIntent() != null
&& getIntent().getExtras() != null
@ -290,6 +311,7 @@ public class MainActivity extends BaseActivity {
// 初始化PlatformUtils
PlatformUtils.getInstance(getApplicationContext());
HomePluggableHelper.activationFilterData();
// 启动app删除视频缓存文件
try {
@ -318,7 +340,8 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel.requestAllDialogData();
// QuickLoginHelper.getPhoneInfo();
// TODO 去掉一键登录?
QuickLoginHelper.getPhoneInfo();
// TODO 搞清楚为什么这里要获取微信相关配置
WechatBindHelper.getWechatConfig(null);
@ -402,12 +425,12 @@ public class MainActivity extends BaseActivity {
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
int bottomTabPosition = savedInstanceState.getInt(CURRENT_PAGE, -1);
if (bottomTabPosition != -1) {
MainWrapperRepository.Companion.getInstance().sendSelectTabEvent(bottomTabPosition, -1);
int currentPageIndex = savedInstanceState.getInt(CURRENT_PAGE, -1);
if (currentPageIndex >= 0) {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, currentPageIndex));
}
}
}
@ -492,12 +515,7 @@ public class MainActivity extends BaseActivity {
ViewGroup startAdContainer = findViewById(R.id.startAdContainer);
ViewGroup sdkStartAdContainer = findViewById(R.id.sdkStartAdContainer);
FrameLayout adsFl = findViewById(R.id.adsFl);
View icpContainer = findViewById(R.id.sdkStartAdIcpContainer);
if (icpContainer != null) {
icpContainer.setOnClickListener((view) -> {
// consume click event
});
}
int screenWidthInPx = DisplayUtils.getScreenWidth(this);
int screenHeightInPx = DisplayUtils.getScreenHeight(this)
+ DisplayUtils.getStatusBarHeight(this.getResources())
@ -538,21 +556,6 @@ public class MainActivity extends BaseActivity {
if (COUNTDOWN_MAX_COUNT < mCountdownCount) {
AdDelegateHelper.INSTANCE.setShowingSplashAd(false);
hideSplashAd();
if (msg.obj instanceof StartupAdEntity) {
StartupAdEntity ad = (StartupAdEntity) msg.obj;
LinkEntity linkEntity = ad.getJump();
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.getId(),
"link_type",
linkEntity.getType(),
"link_id",
linkEntity.getLink(),
"link_text",
linkEntity.getText());
}
} else {
TextView jumpBtn = findViewById(R.id.jumpBtn);
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - mCountdownCount));
@ -622,7 +625,7 @@ public class MainActivity extends BaseActivity {
if (ad.getButton()) {
View adBtn = findViewById(R.id.adBtn);
adBtn.setOnClickListener(v -> {
DirectUtils.directToLinkPage(this, ad.getJump(), "(启动广告)", "", "开屏文案");
DirectUtils.directToLinkPage(this, ad.getJump(), "(启动广告)", "");
LogUtils.logStartAd("click_watch_start_ads", ad);
});
adBtn.setVisibility(View.VISIBLE);
@ -695,18 +698,15 @@ public class MainActivity extends BaseActivity {
try {
GameEntity gameEntity = GsonUtils.getGson().fromJson(json, new TypeToken<GameEntity>() {
}.getType());
if (gameEntity != null) {
String apkUrl = gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl();
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apkUrl);
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
ToastUtils.showToast("文件已被删除,无法启动");
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
ToastUtils.showToast("文件已被删除,无法启动");
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
}
} catch (JsonSyntaxException exception) {
exception.printStackTrace();
@ -754,7 +754,7 @@ public class MainActivity extends BaseActivity {
Utils.log(bundle);
if (!TextUtils.isEmpty(bundle.getString(EntranceConsts.KEY_TYPE, ""))) {
MainWrapperRepository.Companion.getInstance().sendSelectTabEvent(bundle.getString(EntranceConsts.KEY_TYPE));
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, bundle.getString(EntranceConsts.KEY_TYPE)));
}
}
}, 500);
@ -785,18 +785,23 @@ public class MainActivity extends BaseActivity {
public void onFailure(@Nullable HttpException e) {
super.onFailure(e);
try {
ErrorHelper.handleErrorWithCustomizedHandler(MainActivity.this, e.response().errorBody().string(), false, "", "", "内容实名", null, null, code -> {
if (code == 404001) {
if (mShouldShowAd) {
AppExecutor.getUiExecutor().executeWithDelay(() -> {
ErrorHelper.handleErrorWithCustomizedHandler(MainActivity.this, e.response().errorBody().string(), false, null, new Function1<Integer, Boolean>() {
@Override
public Boolean invoke(Integer code) {
if (code == 404001) {
if (mShouldShowAd) {
AppExecutor.getUiExecutor().executeWithDelay(() -> {
toast("抱歉,暂未找到相关内容");
}, 1000);
} else {
toast("抱歉,暂未找到相关内容");
}, 1000);
} else {
toast("抱歉,暂未找到相关内容");
}
LogUtils.uploadPackageSkip("external_jump", "进入游戏库", "", "");
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.TYPE_GAME_LIBRARY));
return true;
}
return true;
return false;
}
return false;
});
} catch (IOException ex) {
ex.printStackTrace();
@ -888,8 +893,9 @@ public class MainActivity extends BaseActivity {
protected void onSaveInstanceState(@NotNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.clear();
outState.putInt(CURRENT_PAGE, mMainWrapperFragment.getCurrentItem());
if (mMainWrapperFragment != null) {
outState.putInt(CURRENT_PAGE, mMainWrapperFragment.getCurrentItem());
outState.putInt(BaseFragment_ViewPager.ARGS_INDEX, mMainWrapperFragment.getCurrentItem());
}
}
@ -917,6 +923,10 @@ public class MainActivity extends BaseActivity {
&& getIntent().getBooleanExtra(EntranceConsts.KEY_REQUIRE_REDIRECT, false)) {
doSkip();
}
if (getIntent().getBooleanExtra(SWITCH_TO_VIDEO, false)) {
mMainWrapperFragment.setCurrentItem(MainWrapperFragment.TYPE_VIDEO_STREAM);
}
}
// 连接上网络事件
@ -947,6 +957,25 @@ public class MainActivity extends BaseActivity {
return "游戏首页";
}
public static void skipToMainActivity(Context context, String type) {
Activity activity = AppManager.getInstance().findActivity(MainActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
&& activity != null && !activity.isDestroyed()) {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, type));
} else {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, type));
}
}, 300);
}
Intent intent = MainActivity.getMainIntent(context);
context.startActivity(intent);
}
//需要提前初始化微博sdk否则第一次分享或授权登录会失败
private void initWBSDK() {
IWBAPI mWBAPI = WBAPIFactory.createWBAPI(this);

View File

@ -46,8 +46,6 @@ open class SearchActivity : BaseActivity() {
private var mPublishSubject: PublishSubject<String>? = null
private var mSourceEntrance: String = ""
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt(KEY_DISPLAY_TYPE, mDisplayType.value)
@ -70,7 +68,6 @@ open class SearchActivity : BaseActivity() {
deleteIv = findViewById(R.id.deleteIv)
backBtn = findViewById(R.id.backBtn)
mSourceEntrance = intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
val hint = intent.getStringExtra(EntranceConsts.KEY_HINT)
val searchImmediately = intent.getBooleanExtra(KEY_SEARCH_IMMEDIATELY, false)
var ignoreTextChanges = savedInstanceState != null
@ -199,14 +196,7 @@ open class SearchActivity : BaseActivity() {
mSearchKey = key
updateDisplayType(GAME_DIGEST)
LogUtils.uploadSearchGame("searching", "搜索页", key, "自动搜索")
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
TRACK_SEARCH_TYPE_INPUT,
mSourceEntrance
)
trackSearchButtonClick(key, TRACK_SEARCH_TYPE_INPUT)
}
}
@ -217,13 +207,7 @@ open class SearchActivity : BaseActivity() {
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "默认搜索")
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
TRACK_SEARCH_TYPE_DEFAULT,
mSourceEntrance
)
trackSearchButtonClick(key, TRACK_SEARCH_TYPE_DEFAULT)
// MtaHelper.onEvent("游戏搜索", "默认搜索", key)
}
@ -240,14 +224,7 @@ open class SearchActivity : BaseActivity() {
searchEt.setSelection(searchEt.text.length)
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "历史搜索")
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
TRACK_SEARCH_TYPE_HISTORY,
mSourceEntrance
)
trackSearchButtonClick(key, TRACK_SEARCH_TYPE_HISTORY)
// MtaHelper.onEvent("游戏搜索", "历史搜索", key)
}
@ -262,13 +239,7 @@ open class SearchActivity : BaseActivity() {
} else if (newSearchKey != mSearchKey || mDisplayType != GAME_DETAIL) {
mSearchKey = newSearchKey
if (!TextUtils.isEmpty(mSearchKey)) {
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
newSearchKey,
TRACK_SEARCH_TYPE_INPUT,
mSourceEntrance
)
trackSearchButtonClick(newSearchKey, TRACK_SEARCH_TYPE_INPUT)
mDao?.add(mSearchKey)
updateDisplayType(GAME_DETAIL)
@ -368,6 +339,37 @@ open class SearchActivity : BaseActivity() {
else -> TRACK_SEARCH_TYPE_DEFAULT
}
@JvmStatic
fun trackSearchResultClick(key: String, type: String) {
SensorsBridge.trackSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key,
toTrackSearchType(type)
)
}
@JvmStatic
fun trackSearchButtonClick(key: String?, type: String) {
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
type
)
}
@JvmStatic
fun trackSearchResultReturn(key: String?, type: String, hasResult: Boolean) {
SensorsBridge.trackSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
toTrackSearchType(type),
hasResult
)
}
@JvmStatic
fun getIntent(
context: Context,
@ -375,7 +377,7 @@ open class SearchActivity : BaseActivity() {
hint: String,
entrance: String,
sourceEntrance: String
): Intent = getIntent(context, searchImmediately, hint, entrance, sourceEntrance, "", "", "", "", "", "")
): Intent = getIntent(context, searchImmediately, hint, entrance, sourceEntrance)
@JvmStatic
fun getIntent(

View File

@ -111,7 +111,7 @@ public class ShareCardActivity extends ToolBarActivity {
String qrBody;
if (!TextUtils.isEmpty(newsId)) {
qrBody = "https://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
qrBody = "http://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
} else {
qrBody = "https://www.ghzs.com/?source=appshare200";
}

View File

@ -166,7 +166,7 @@ public class ShareCardPicActivity extends ToolBarActivity {
String qrBody;
if (!TextUtils.isEmpty(newsId)) {
qrBody = "https://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
qrBody = "http://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
} else {
qrBody = "https://www.ghzs.com/?source=appshare200";
}

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