Compare commits

...

391 Commits

Author SHA1 Message Date
a0c25a7c56 feat: 使用ASM插件检查隐私政策授权时的隐私问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-28 10:44:41 +08:00
a2bd5e01e0 Merge branch 'hotfix/v5.35.0-1050/jpush_clear_badge' into 'release'
fix: 修复极光推送清除角标提前获取信息的问题

See merge request halo/android/assistant-android!1649
2024-04-28 10:43:11 +08:00
844d227f19 fix: 修复极光推送清除角标提前获取信息的问题 2024-04-28 10:26:20 +08:00
f982bf6478 Merge branch 'hotfix/v5.35.0-1050/disable_jpush_auto_init' into 'release'
fix: 移除极光推送通过 ContentProvider 自动初始化的问题

See merge request halo/android/assistant-android!1647
2024-04-26 14:01:09 +08:00
33d7afec71 fix: 移除极光推送通过 ContentProvider 自动初始化相关代码 2024-04-26 13:40:16 +08:00
37ef50f323 Merge branch 'feat/GHZSCY-5243' into 'dev'
feat: 穿山甲广告SDK更换新版本与信息流广告优化 https://jira.shanqu.cc/browse/GHZSCY-5243

See merge request halo/android/assistant-android!1641
2024-04-26 10:10:33 +08:00
4c6acdee3a Merge branch 'fix/GHZSCY-5261' into 'dev'
fix: 【光环助手】开屏广告神策埋点数据上报问题 https://jira.shanqu.cc/browse/GHZSCY-5261

See merge request halo/android/assistant-android!1646
2024-04-25 10:36:50 +08:00
6beb060e63 fix: 【光环助手】开屏广告神策埋点数据上报问题 https://jira.shanqu.cc/browse/GHZSCY-5261 2024-04-25 10:31:22 +08:00
a552677e41 Merge branch 'chen/202404/GHZSCY-5187-2' into 'dev'
style:匹配按钮设计规范...

See merge request halo/android/assistant-android!1645
2024-04-24 16:12:37 +08:00
bb148f42b8 style:匹配按钮设计规范 https://jira.shanqu.cc/browse/GHZSCY-5187?focusedCommentId=61918&page=com.atlassian.jira.plugin.system.issuetabpanels%253Acomment-tabpanel#comment-61918 2024-04-24 16:09:44 +08:00
065aa96e18 Merge branch 'fix/GHZSCY-5236' into 'dev'
fix: 多渠道多版本-首次启动跳转问题 https://jira.shanqu.cc/browse/GHZSCY-5236

See merge request halo/android/assistant-android!1640
2024-04-24 11:43:36 +08:00
d9a90ca80b fix: 多渠道多版本-首次启动跳转问题 https://jira.shanqu.cc/browse/GHZSCY-5236 2024-04-24 11:10:39 +08:00
2aeffb1cc4 Merge branch 'chen/202404/GHZSCY-5187' into 'dev'
style:匹配按钮设计规范...

See merge request halo/android/assistant-android!1644
2024-04-23 17:47:19 +08:00
d3188cc3cd style:匹配按钮设计规范 https://jira.shanqu.cc/browse/GHZSCY-5187?focusedCommentId=61918&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-61918 2024-04-23 17:42:52 +08:00
1d7f902a81 feat: 移除一键登录 SDK 依赖 (移除相关无用的资源)
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-23 16:19:59 +08:00
13a40806e4 Merge branch 'fix/GHZS-5009' into 'dev'
fix: 插件问题反馈内容默认文案出错 https://jira.shanqu.cc/browse/GHZS-5009

See merge request halo/android/assistant-android!1637
2024-04-23 15:04:29 +08:00
b56e5c4022 Merge branch 'feat/GHZS-5188' into 'dev'
feat: 调整客户端用到的部分域名(同时移除已经从未上线的光能部分相关代码) https://jira.shanqu.cc/browse/GHZS-5188

See merge request halo/android/assistant-android!1638
2024-04-23 15:04:21 +08:00
acca1537da Merge branch 'feat/optimise_package_privacy' into 'dev'
feat: 移除一键登录 SDK 依赖

See merge request halo/android/assistant-android!1642
2024-04-23 15:04:12 +08:00
6e5b639d58 feat: 调整客户端用到的部分域名(同时移除已经从未上线的光能部分相关代码) https://jira.shanqu.cc/browse/GHZS-5188 2024-04-23 14:43:10 +08:00
24000f55af feat: 移除一键登录 SDK 依赖 2024-04-22 17:56:04 +08:00
d11ccba0b7 feat: 穿山甲广告SDK更换新版本与信息流广告优化 https://jira.shanqu.cc/browse/GHZSCY-5243
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-22 16:29:42 +08:00
3540c4626d Merge branch 'fix/update_crash' into 'dev'
fix: 修复软更时更新弹窗回到桌面由于下载监听移除不及时导致的闪退问题

See merge request halo/android/assistant-android!1636
2024-04-22 15:34:30 +08:00
e6a2758fdb fix: 修复软更时更新弹窗回到桌面由于下载监听移除不及时导致的闪退问题 2024-04-22 15:08:02 +08:00
a56e2bd16e Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-04-22 14:01:25 +08:00
e038c565ff Merge branch 'hotfix/v5.34.8-1038/authorization_crash' into 'release'
fix: 修复通用授权登陆界面出现的闪退问题...

See merge request halo/android/assistant-android!1635
2024-04-22 13:57:42 +08:00
ec5905bb11 fix: 修复通用授权登陆界面出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/373879/events/b72b2eb3c7ef4426ba8d42ff5a476bbe/?project=22 2024-04-22 13:49:47 +08:00
21f50c4eed Merge branch 'hotfix/v5.34.8-1038/optional_update_crash' into 'release'
fix: 修复软更时取消弹窗切换页面后有机率触发闪退的问题 https://sentry.shanqu.cc/organizations/lightgame/issues/380566

See merge request halo/android/assistant-android!1634
2024-04-22 11:42:21 +08:00
5a93f3671b fix: 修复软更时取消弹窗切换页面后有机率触发闪退的问题 https://sentry.shanqu.cc/organizations/lightgame/issues/380566 2024-04-22 11:04:57 +08:00
6dcb8b6efe Merge branch 'fix/GHZSCY-5244' into 'dev'
fix:【光环助手】5.35验收问题:极光推送触发了APP角标提示,但不能消除 https://jira.shanqu.cc/browse/GHZSCY-5244

See merge request halo/android/assistant-android!1633
2024-04-19 18:06:48 +08:00
d60916b3bc fix:【光环助手】5.35验收问题:极光推送触发了APP角标提示,但不能消除 https://jira.shanqu.cc/browse/GHZSCY-5244 2024-04-19 18:06:48 +08:00
798b19d9d7 Merge branch 'feat/remove_useless_activity' into 'dev'
feat: 移除已被弃用的 activity 及其相关的代码 (没有依赖、非通用跳转、已无入口等)

See merge request halo/android/assistant-android!1632
2024-04-19 16:14:12 +08:00
5c47d3cda8 feat: 移除已被弃用的 activity 及其相关的代码 (没有依赖、非通用跳转、已无入口等) 2024-04-19 16:14:12 +08:00
aea64c0602 Merge branch 'fix/GHZSCY-5231' into 'dev'
fix:【光环助手】轮播banner刷新时蒙层消失 https://jira.shanqu.cc/browse/GHZSCY-5231

See merge request halo/android/assistant-android!1631
2024-04-18 17:48:51 +08:00
4abc0a3edb fix:【光环助手】轮播banner刷新时蒙层消失 https://jira.shanqu.cc/browse/GHZSCY-5231 2024-04-18 17:48:50 +08:00
ded940412e Merge branch 'feat/remove_useless_dependencies' into 'dev'
feat: 移除无用依赖

See merge request halo/android/assistant-android!1630
2024-04-18 13:59:24 +08:00
9971651fe1 feat: 移除无用依赖
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-18 13:53:25 +08:00
4e00b5db19 chore: 版本更新至 5.34.8 2024-04-17 15:59:16 +08:00
e6a6bbcf97 Merge branch 'feat/GHZS-5229' into 'release'
chore: 神策 SDK 更新至 6.8.0

See merge request halo/android/assistant-android!1629
2024-04-17 15:58:35 +08:00
0eecc4699f chore: 神策 SDK 更新至 6.8.0 2024-04-17 15:56:04 +08:00
c771bad1ea Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-04-16 17:01:37 +08:00
e5dbdb154f Merge branch 'fix/GHZS-5218' into 'release'
fix: 游戏提示解析包错误问题 https://jira.shanqu.cc/browse/GHZS-5218

See merge request halo/android/assistant-android!1628
2024-04-16 15:05:02 +08:00
2b91545d34 fix: 游戏提示解析包错误问题 https://jira.shanqu.cc/browse/GHZS-5218
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-16 15:03:12 +08:00
f8703b9fe1 chore: 版本更新至 5.34.7 2024-04-16 14:34:40 +08:00
58cc8c7f3c Merge branch 'fix/GHZS-5218' into 'release'
fix: 游戏提示解析包错误问题 https://jira.shanqu.cc/browse/GHZS-5218

See merge request halo/android/assistant-android!1625
2024-04-16 14:33:44 +08:00
79cf1566b2 fix: 游戏提示解析包错误问题 https://jira.shanqu.cc/browse/GHZS-5218 2024-04-16 14:32:19 +08:00
47a98f22b5 Merge branch 'feature-fix-sentry-379733' into 'release'
fix: 修复文章分享埋点上报造成的空指针问题

See merge request halo/android/assistant-android!1627
2024-04-16 11:35:29 +08:00
71453054d9 fix: 修复文章分享埋点上报造成的空指针问题 2024-04-16 11:35:29 +08:00
61ae86e40a Merge branch 'hotfix/v5.34.6-1036/null_pointer_crash' into 'release'
fix: 修复空指针闪退问题...

See merge request halo/android/assistant-android!1626
2024-04-16 11:34:47 +08:00
89de5f24bf fix: 修复空指针闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/380027/events/ee8c112a97a940beb59a2d733d228dd9/?project=22 2024-04-16 11:19:40 +08:00
5c8a275b3e Merge branch 'fix/build_scripts' into 'dev'
build: 默认使用极光推送

See merge request halo/android/assistant-android!1624
2024-04-16 09:26:45 +08:00
405fd6c698 build: 默认使用极光推送 2024-04-16 09:22:59 +08:00
d70c8f2b78 Merge branch 'fix/build_gradle' into 'dev'
build: 默认使用极光推送

See merge request halo/android/assistant-android!1623
2024-04-15 18:09:19 +08:00
2700b309dd build: 默认使用极光推送 2024-04-15 18:08:09 +08:00
832509a124 fix: 修复下载模块回调两次 downloadComplete 的问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-15 17:50:38 +08:00
36e69ece10 Merge branch 'feature-GHZS-4991' into 'dev'
feat: 闪指H5落地页新增获取光环游戏数据及相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-4991

See merge request halo/android/assistant-android!1585
2024-04-15 16:15:53 +08:00
7d56f92535 feat: 闪指H5落地页新增获取光环游戏数据及相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-4991 2024-04-15 15:46:28 +08:00
9fe58a72c7 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-04-15 15:13:09 +08:00
4c79c49506 Merge branch 'feat/GHZS-3758' into 'release'
feat: targetSDK 调整至 30

See merge request halo/android/assistant-android!1514
2024-04-15 15:08:25 +08:00
c4a622a55c fix: 合并冲突
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-15 15:06:53 +08:00
3a02823ea9 Merge branch 'feat/GHZS-4988' into 'dev'
feat: 重构图片加载相关代码 https://jira.shanqu.cc/browse/GHZS-4988

See merge request halo/android/assistant-android!1622
2024-04-15 13:49:46 +08:00
7d816c00c4 feat: 重构图片加载相关代码 https://jira.shanqu.cc/browse/GHZS-4988 2024-04-15 10:02:15 +08:00
1214a6fb13 Merge branch 'feature-fix-sentry-376330' into 'release'
fix: 修复开服日历反馈在低版本Android系统中,SimpleDateFormat的日期格式兼容问题

See merge request halo/android/assistant-android!1621
2024-04-12 16:32:52 +08:00
e90053bdc9 fix: 修复开服日历反馈在低版本Android系统中,SimpleDateFormat的日期格式兼容问题 2024-04-12 16:29:48 +08:00
de9980af6a Merge branch 'feat/refactor_do_on_main_process_implementation' into 'dev'
feat: 重构限制主进程执行的相关代码

See merge request halo/android/assistant-android!1620
2024-04-12 15:29:54 +08:00
ec6ad35ade feat: 重构限制主进程执行的相关代码 2024-04-12 14:52:46 +08:00
c199487c51 Merge branch 'chen/202404/fix-common-content-reuse' into 'release'
fix:修复通用内容合集显示错乱问题(考虑极端情况:数据完全相同,样式不同)

See merge request halo/android/assistant-android!1619
2024-04-12 13:48:25 +08:00
a1ac427540 fix:修复通用内容合集显示错乱问题(考虑极端情况:数据完全相同,样式不同) 2024-04-12 13:45:51 +08:00
1e2755c82c Merge branch 'hotfix/v5.34.5-1035/game_detail_crash' into 'release'
fix: 修复游戏详情页闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/376726/?project=22

See merge request halo/android/assistant-android!1618
2024-04-12 10:58:14 +08:00
a05e31705f fix: 修复游戏详情页闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/376726/?project=22 2024-04-12 10:37:38 +08:00
62f2bb40df Merge branch 'hotfix/v5.34.5-1035/forum_article_ask_list_crash' into 'release'
fix: 修复论坛详情页闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/378960/?project=22

See merge request halo/android/assistant-android!1617
2024-04-12 09:52:06 +08:00
eabb277c7b fix: 修复论坛详情页闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/378960/?project=22 2024-04-12 09:45:36 +08:00
fb7cdd5ce7 Merge branch 'feature-GHZS-4956' into 'dev'
feat: 内容卡片新增提示弹窗—客户端 https://jira.shanqu.cc/browse/GHZS-4956

See merge request halo/android/assistant-android!1595
2024-04-11 17:31:58 +08:00
3bbfd676fb feat: 内容卡片新增提示弹窗—客户端 https://jira.shanqu.cc/browse/GHZS-4956 2024-04-11 17:31:58 +08:00
7be6af5f08 Merge branch 'chen/202404/GHZS-5197' into 'release'
fix:【光环助手】同一页面使用相同样式组件的图片复用 https://jira.shanqu.cc/browse/GHZS-5197

See merge request halo/android/assistant-android!1616
2024-04-11 15:50:29 +08:00
982f5faf97 fix:【光环助手】同一页面使用相同样式组件的图片复用 https://jira.shanqu.cc/browse/GHZS-5197 2024-04-11 15:47:58 +08:00
81c8469e7b Merge branch 'feat/GHZS-5075' into 'dev'
feat: 搜索页面专区文案修改—客户端 https://jira.shanqu.cc/browse/GHZS-5075

See merge request halo/android/assistant-android!1615
2024-04-10 15:50:54 +08:00
2e03e9f4f5 feat: 搜索页面专区文案修改—客户端 https://jira.shanqu.cc/browse/GHZS-5075 2024-04-10 15:50:54 +08:00
6ab10a0eee Merge branch 'feat/GHZS-5050' into 'dev'
feat: 消息推送:接入极光消息推送系统—客户端 https://jira.shanqu.cc/browse/GHZS-5050

See merge request halo/android/assistant-android!1613
2024-04-10 14:46:35 +08:00
23f7d1f32c feat: 消息推送:接入极光消息推送系统—客户端 https://jira.shanqu.cc/browse/GHZS-5050 2024-04-10 14:46:35 +08:00
93f5343106 Merge branch 'feat/GHZS-5150' into 'dev'
feat: 下拉推送弹窗规则优化—客户端 https://jira.shanqu.cc/browse/GHZS-5150

See merge request halo/android/assistant-android!1614
2024-04-10 14:41:45 +08:00
6846a61dd5 feat: 下拉推送弹窗规则优化—客户端 https://jira.shanqu.cc/browse/GHZS-5150 2024-04-10 14:41:45 +08:00
1a99fec286 chore: 版本更新至 5.34.6 2024-04-10 11:44:34 +08:00
3d77c1ed3a fix: 处理合并冲突 2024-04-10 11:39:07 +08:00
c312d616da feat: 更改下载地址 https://jira.shanqu.cc/browse/GHZS-3737 2024-04-10 11:27:05 +08:00
8f1affeb74 fix: targetSDK版本升级—1019测试-客户端(修复xapk无法安装的问题) https://jira.shanqu.cc/browse/GHZS-3737 2024-04-10 11:25:43 +08:00
fdbfdecb2d fix: 处理代码冲突 2024-04-10 11:24:36 +08:00
e84b814d2c fix: 修复使用非可见 context 获取屏幕高度时的 IllegalAccessException 2024-04-10 11:24:36 +08:00
14c8591a99 fix: 修复调用 telephonyManager.getNetworkType() 造成的闪退问题 2024-04-10 11:24:36 +08:00
95d073a50d feat: 修改DeviceId文件保存路径,升级版本后迁移文件至新路径 2024-04-10 11:24:36 +08:00
edec43aea2 fix: 修改分享图片保存路径 2024-04-10 11:24:36 +08:00
188b5bdd7f fix: 修改阿里云OSS断点记录文件夹路径 2024-04-10 11:24:36 +08:00
c454b092b2 feat: FileUtils移至module_common 2024-04-10 11:23:37 +08:00
c70b1c962b fix: 修复编辑帖子无法预览上传图片的问题 2024-04-10 11:07:57 +08:00
e71b2b0a56 feat: 游戏下载目录修改为Download文件夹内 2024-04-10 11:07:57 +08:00
c010b7aba4 fix: matisse适配 targetSdk 30 2024-04-10 11:07:57 +08:00
2c23c4f0eb build: 修复特殊包的编译问题 2024-04-10 10:46:53 +08:00
2c2031f623 chore: 版本更新至 5.34.5 2024-04-08 15:42:29 +08:00
41ddf53e23 Merge branch 'feature-fix-comment-like' into 'release'
fix: 修复评论详情点赞异常的问题

See merge request halo/android/assistant-android!1612
2024-04-08 14:21:32 +08:00
b911edb83c fix: 修复评论详情点赞异常的问题 2024-04-08 14:16:00 +08:00
7524144c3d Merge branch 'chen/202404/fxi-refresh-icon-matrix' into 'release'
fix:修复图标矩阵点击换一批ui不刷新的问题

See merge request halo/android/assistant-android!1611
2024-04-08 11:11:46 +08:00
aef5bb0021 fix:修复图标矩阵点击换一批ui不刷新的问题 2024-04-08 11:09:39 +08:00
1e45790280 chore: 版本更新至 5.34.4 2024-04-07 15:11:54 +08:00
6ebae66fc7 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-04-07 13:44:54 +08:00
907f840537 Merge branch 'feature=fix-sentry-bug-2' into 'release'
feat: 修复Sentry上报的BUG

See merge request halo/android/assistant-android!1610
2024-04-07 10:56:04 +08:00
07dfd58538 feat: 修复Sentry上报的BUG 2024-04-07 10:56:04 +08:00
4491865aef Merge branch 'chen/202404/GHZS-5117' into 'release'
fix:【光环助手】视频横屏滑动专题的显示问题 https://jira.shanqu.cc/browse/GHZS-5117

See merge request halo/android/assistant-android!1609
2024-04-03 17:24:22 +08:00
9dabe9fa03 fix:【光环助手】视频横屏滑动专题的显示问题 https://jira.shanqu.cc/browse/GHZS-5117 2024-04-03 17:01:47 +08:00
79349d51ee Merge branch 'hotfix/v5.34.3-1033/custom_common_collection_layout' into 'release'
fix: 修复通用链接跳转通用合集详情样式不正确的问题

See merge request halo/android/assistant-android!1608
2024-04-03 10:19:58 +08:00
a3319b71d2 fix: 修复通用链接跳转通用合集详情样式不正确的问题 2024-04-02 22:42:14 +08:00
b06341959d chore: 版本更新至 5.34.3 2024-04-02 18:20:43 +08:00
089e552e0f Merge branch 'feat/GHZS-5114' into 'release'
feat: 神策SDK版本升级 https://jira.shanqu.cc/browse/GHZS-5114

See merge request halo/android/assistant-android!1607
2024-04-02 18:20:25 +08:00
16e0da0c7c feat: 神策SDK版本升级 https://jira.shanqu.cc/browse/GHZS-5114 2024-04-02 17:58:48 +08:00
e1a9879ea4 chore: 版本更新至 5.34.2 2024-04-02 16:50:34 +08:00
b610e1619d Merge branch 'hotfix/v5.34.1-1031/fix_vgame_display_issue' into 'release'
fix: 修复自定义页面的最近在玩(畅玩)item 隐藏时高度没有变化的问题 https://jira.shanqu.cc/browse/GHZS-5112

See merge request halo/android/assistant-android!1606
2024-04-02 16:47:44 +08:00
6977e99269 fix: 畅玩-最近在玩的显示问题 https://jira.shanqu.cc/browse/GHZS-5112 2024-04-02 16:42:11 +08:00
18246edd46 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-04-02 11:23:44 +08:00
b7cadbce50 chore: 版本更新至 5.34.1 2024-04-01 16:13:50 +08:00
44569233e9 Merge branch 'hotfix/v5.34.0-1030/write_oaid_error' into 'release'
fix: 修复部分游戏没有 V2 签名导致写入 OAID 失败的问题

See merge request halo/android/assistant-android!1600
2024-04-01 11:33:51 +08:00
d1962cf363 Merge branch 'feat/GHZS-5068' into 'release'
feat: 备案号查询跳转 https://jira.shanqu.cc/browse/GHZS-5068

See merge request halo/android/assistant-android!1604
2024-04-01 11:33:48 +08:00
dbf35afa3f Merge branch 'hotfix/v5.34.0-1030/fix_crashes' into 'release'
fix: 修复下载模块初始化闪退问题,修复下载数据库升级闪退问题

See merge request halo/android/assistant-android!1605
2024-04-01 11:33:46 +08:00
1dcdb81529 feat: 备案号查询跳转 https://jira.shanqu.cc/browse/GHZS-5068
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-01 11:18:42 +08:00
fb9d0d01d8 Merge branch 'feature-fix-sentry-bug' into 'release'
feat: 修复Sentry上报的BUG

See merge request halo/android/assistant-android!1603
2024-04-01 11:15:57 +08:00
f449a41257 feat: 修复Sentry上报的BUG 2024-04-01 11:15:57 +08:00
ef41245a1a fix: 修复下载模块初始化闪退问题,修复下载数据库升级闪退问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-01 11:05:45 +08:00
c2aae6d5f9 ci: 添加 release 至 ci 触发分支 2024-04-01 10:51:10 +08:00
700a56c6f9 Merge branch 'chen/202404/GHZS-5069' into 'release'
fix:【光环助手】游戏专题问题修复 https://jira.shanqu.cc/browse/GHZS-5069

See merge request halo/android/assistant-android!1602
2024-04-01 10:32:50 +08:00
6673805ba1 Merge branch 'hotfix/v5.34.0-1030/simulator_game_shortcuts_crash' into 'release'
fix: 修复快捷方式启动模拟器游戏出现的闪退问题...

See merge request halo/android/assistant-android!1601
2024-04-01 10:32:35 +08:00
6130fa345b fix: 修复快捷方式启动模拟器游戏出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/376360/events/7240c5329d03408dba143ffb3fc8213a/?project=22 2024-04-01 10:31:13 +08:00
38a9bf0bfa fix:【光环助手】游戏专题问题修复 https://jira.shanqu.cc/browse/GHZS-5069 2024-04-01 10:30:45 +08:00
bdb2180af6 fix: 修复部分游戏没有 V2 签名导致写入 OAID 失败的问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-29 19:02:10 +08:00
a4b8feb7ef Merge branch 'fix/privacy_issue' into 'release'
fix: 移除应用启动时获取光环包名及是否安装自应用商店的敏感代码

See merge request halo/android/assistant-android!1599
2024-03-29 17:29:12 +08:00
6c58b3b102 Merge branch 'hotfix/v5.34.0-1030/vgame_sinature_check_crash' into 'release'
fix: 修复检查畅玩游戏签名时导致的闪退问题

See merge request halo/android/assistant-android!1598
2024-03-29 17:27:17 +08:00
28014190f3 Merge branch 'chen/202403/optimize-sliding-experience2' into 'release'
优化首页滑动体验

See merge request halo/android/assistant-android!1597
2024-03-29 16:23:39 +08:00
76843829aa 优化首页滑动体验 2024-03-29 16:05:40 +08:00
ef3a243bc5 fix: 修复检查畅玩游戏签名时导致的闪退问题 2024-03-29 15:27:00 +08:00
796848a23c chore: 版本更新至 5.35.0 2024-03-29 11:01:32 +08:00
fc8766f2e7 fix: 移除应用启动时获取光环包名及是否安装自应用商店的敏感代码 2024-03-29 10:35:15 +08:00
278423cfad Merge branch 'feature-delay-notification-channel-create' into 'dev'
feat: 延迟推送NotificationChannel的创建

See merge request halo/android/assistant-android!1596
2024-03-29 10:08:39 +08:00
8e2f06c19b feat: 延迟推送NotificationChannel的创建 2024-03-29 10:05:32 +08:00
bf4f270c37 Merge branch 'feature-GHZS-4941' into 'dev'
feat: 消息推送:接入阿里云消息推送系统—客户端 https://jira.shanqu.cc/browse/GHZS-4941

See merge request halo/android/assistant-android!1593
2024-03-28 17:58:50 +08:00
d406cba6c2 feat: 消息推送:接入阿里云消息推送系统—客户端 https://jira.shanqu.cc/browse/GHZS-4941 2024-03-28 17:58:49 +08:00
6c4d17ab9e feat: 调整判定 refresh 渠道的依据 https://jira.shanqu.cc/browse/GHZS-5043 2024-03-28 14:44:46 +08:00
8fc9134402 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/common/databind/BindingAdapters.java
#	app/src/main/java/com/gh/download/DownloadManager.java
2024-03-27 17:14:09 +08:00
babb7d3f7b Merge branch 'feat/GHZS-4887' into 'dev'
feat: 网游插件签名管理 https://jira.shanqu.cc/browse/GHZS-4887

See merge request halo/android/assistant-android!1591
2024-03-27 10:08:37 +08:00
0972e90049 feat: 网游插件签名管理 https://jira.shanqu.cc/browse/GHZS-4887 2024-03-27 09:58:00 +08:00
df2382609a Merge branch 'hotfix/v5.33.2-1012/index_out_of_bounds_exception' into 'release'
fix: 修复数组越界闪退问题...

See merge request halo/android/assistant-android!1589
2024-03-26 16:19:00 +08:00
b61fdd0a0e fix: 修复数组越界闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/372151/?query=is%3Aunresolved+assigned%3Ame&referrer=issue-stream&statsPeriod=14d 2024-03-26 15:11:52 +08:00
0662ecd86b Merge branch 'feat/remove_legacy_tag_code' into 'dev'
feat: 移除已经失效的插件标签相关代码

See merge request halo/android/assistant-android!1588
2024-03-26 10:51:03 +08:00
3c6920520e feat: 移除已经失效的插件标签相关代码
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-26 10:34:13 +08:00
03bbcc2af3 Merge branch 'feat/GHZS-4955' into 'dev'
feat: 开屏广告神策埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-4955

See merge request halo/android/assistant-android!1587
2024-03-25 15:36:04 +08:00
5efd61d5f6 feat: 开屏广告神策埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-4955 2024-03-25 15:36:04 +08:00
737e14a6ce Merge branch 'feat/GHZS-4959' into 'dev'
feat: 广告位管理第三方广告相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-4959

See merge request halo/android/assistant-android!1586
2024-03-25 15:35:40 +08:00
68931b5d9c feat: 广告位管理第三方广告相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-4959 2024-03-25 15:35:40 +08:00
dac1f207f2 Merge branch 'feat/GHZS-3956' into 'dev'
feat: APP内容配置重构

See merge request halo/android/assistant-android!1584
2024-03-22 16:56:21 +08:00
dd48585bca feat: APP内容配置重构 https://jira.shanqu.cc/browse/GHZS-3956 2024-03-22 16:56:21 +08:00
b4a8c07d8a fix: 修复深色模式下载管理第三方 banner 广告显示透明的问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-22 16:54:28 +08:00
7a417bc655 feat: 为内嵌网页添加 JS 获取 OAID 的方法
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-22 15:51:43 +08:00
920e7a8038 fix: 插件问题反馈内容默认文案出错 https://jira.shanqu.cc/browse/GHZS-5009
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-21 10:07:14 +08:00
6efb8ee700 Merge branch 'feat/GHZS-4844' into 'dev'
feat: 已下载安装包提取及清理需求—客户端 https://jira.shanqu.cc/browse/GHZS-4844

See merge request halo/android/assistant-android!1555
2024-03-20 16:05:10 +08:00
1d58dcc998 feat: 已下载安装包提取及清理需求—客户端 https://jira.shanqu.cc/browse/GHZS-4844 2024-03-20 16:05:10 +08:00
5647b9c0b0 Merge branch 'fix/GHZS-5004' into 'dev'
fix: 开屏广告点击问题 https://jira.shanqu.cc/browse/GHZS-5004

See merge request halo/android/assistant-android!1580
2024-03-20 14:37:51 +08:00
ba0eb38ee8 Merge branch 'feat/clean_up_legacy_code' into 'dev'
feat: 移除已经无用/不维护的代码(dokit, 畅玩数据库备份)

See merge request halo/android/assistant-android!1578
2024-03-20 14:20:39 +08:00
3406addd87 Merge branch 'fix/catch_add_channel_exception' into 'dev'
feat: 包裹为 APK 写入渠道内容时的错误

See merge request halo/android/assistant-android!1579
2024-03-20 14:20:35 +08:00
52f7120157 feat: 包裹为 APK 写入渠道内容时的错误
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-20 14:13:46 +08:00
ee742213e6 feat: 移除已经无用/不维护的代码(dokit, 畅玩数据库备份)
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-20 14:05:47 +08:00
3816ce44a5 fix: 开屏广告点击问题 https://jira.shanqu.cc/browse/GHZS-5004 2024-03-20 11:37:49 +08:00
37c6c7bb26 Merge branch 'feature-GHZS-4982' into 'dev'
fix: 【光环助手】部分页面文字显示颜色没有适配深色模式 https://jira.shanqu.cc/browse/GHZS-4982

See merge request halo/android/assistant-android!1577
2024-03-19 13:39:16 +08:00
a0bc96fa2b fix: 【光环助手】部分页面文字显示颜色没有适配深色模式 https://jira.shanqu.cc/browse/GHZS-4982 2024-03-19 13:39:16 +08:00
5375901813 Merge branch 'feat/GHZS-4992' into 'dev'
feat: 关于XAPK/APKS自动解压的优化—客户端 https://jira.shanqu.cc/browse/GHZS-4993

See merge request halo/android/assistant-android!1576
2024-03-19 11:48:35 +08:00
816c37ed6f feat: 关于XAPK/APKS自动解压的优化—客户端 https://jira.shanqu.cc/browse/GHZS-4993 2024-03-19 10:05:12 +08:00
a3c603490d Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/ndownload/NDownloadBridge.kt
#	libraries/LGLibrary
2024-03-18 16:53:54 +08:00
2e18460f22 Merge branch 'hotfix/v5.33.2-1012/download_dir_crash' into 'release'
fix: 修复部分 Android 6.0 及以下设备获取下载地址时出现的空指针闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/364171

See merge request halo/android/assistant-android!1575
2024-03-18 16:50:02 +08:00
6482bb31e9 fix: 修复部分 Android 6.0 以下设备获取下载地址时出现的空指针闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/364171 2024-03-18 16:49:15 +08:00
1822177e2c Merge branch 'hotfix/v5.33.2-1012/splash_ad_crash' into 'release'
fix: 修复开屏广告空指针闪退问题...

See merge request halo/android/assistant-android!1568
2024-03-15 10:22:30 +08:00
3af3d4255f fix: 修复开屏广告空指针闪退问题... 2024-03-15 10:22:29 +08:00
a58498741b Merge branch 'feature-GHZS-4867' into 'dev'
feat: 新增联网APP字段—客户端 https://jira.shanqu.cc/browse/GHZS-4867

See merge request halo/android/assistant-android!1564
2024-03-15 09:51:54 +08:00
c01c9af191 feat: 新增联网APP字段—客户端 https://jira.shanqu.cc/browse/GHZS-4867 2024-03-15 09:51:54 +08:00
463ac5fc77 Merge branch 'feature-GHZS-3927' into 'dev'
feat: 内容社区神策埋点-第一期—客户端 https://jira.shanqu.cc/browse/GHZS-3927

See merge request halo/android/assistant-android!1496
2024-03-11 09:49:48 +08:00
3bd4823463 feat: 内容社区神策埋点-第一期—客户端 https://jira.shanqu.cc/browse/GHZS-3927 2024-03-11 09:49:47 +08:00
240666aa5f Merge branch 'feature-GHZS-3763' into 'dev'
feat: 替换文件上传 SDK https://jira.shanqu.cc/browse/GHZS-3763

See merge request halo/android/assistant-android!1561
2024-03-08 10:32:42 +08:00
77bbf5c647 feat: 替换文件上传 SDK https://jira.shanqu.cc/browse/GHZS-3763 2024-03-08 10:32:42 +08:00
873178c10d Merge branch 'feature-GHZS-4489' into 'dev'
feat: 游戏分发相关神策埋点-补充-第一期 —客户端 https://jira.shanqu.cc/browse/GHZS-4489

See merge request halo/android/assistant-android!1526
2024-03-07 16:56:34 +08:00
478385a5e0 feat: 游戏分发相关神策埋点-补充-第一期 —客户端 https://jira.shanqu.cc/browse/GHZS-4489 2024-03-07 16:56:33 +08:00
d5b2f586fa Merge branch 'feat/GHZS-4801' into 'dev'
feat: 下载游戏时写入备注文件,附带oaid信息 https://jira.shanqu.cc/browse/GHZS-4801

See merge request halo/android/assistant-android!1550
2024-03-06 11:38:18 +08:00
3e91968c7d feat: 下载游戏时写入备注文件,附带oaid信息 https://jira.shanqu.cc/browse/GHZS-4801 2024-03-06 11:14:57 +08:00
868adca99a Merge branch 'feat/remove_legacy_mock_framework' into 'dev'
feat: 移除过时的 OKHTTP mock 框架

See merge request halo/android/assistant-android!1559
2024-03-05 13:58:06 +08:00
4703c94f4b feat: 移除过时的 OKHTTP mock 框架
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-03-05 13:56:38 +08:00
9246f46d82 Merge branch 'hotfix/v5.33.1-1011/GHZS-4698' into 'dev'
fix: 数据上报问题 https://jira.shanqu.cc/browse/GHZS-4698

See merge request halo/android/assistant-android!1557
2024-03-05 11:11:13 +08:00
8209c97b6c fix: 数据上报问题 https://jira.shanqu.cc/browse/GHZS-4698 2024-03-05 10:22:22 +08:00
fabd160a72 Merge branch 'fix/game_detail_vgame_update' into 'dev'
feat: 修复游戏详情页仅显示一个按钮时,畅玩游戏更新无法正常执行的问题

See merge request halo/android/assistant-android!1551
2024-02-28 13:51:46 +08:00
685102c0da feat: 修复游戏详情页仅显示一个按钮时,畅玩游戏更新无法正常执行的问题 2024-02-28 13:44:52 +08:00
e999fd33f7 Merge branch 'feature-GHZS-4773' into 'dev'
fix:【光环助手】畅玩问题自动回复问题 https://jira.shanqu.cc/browse/GHZS-4773

See merge request halo/android/assistant-android!1548
2024-02-27 13:49:12 +08:00
f8f77b1f4d fix:【光环助手】畅玩问题自动回复问题 https://jira.shanqu.cc/browse/GHZS-4773 2024-02-27 13:49:11 +08:00
0ca5211caf Merge branch 'feature-CWZS-147' into 'dev'
fix: 【畅玩助手】未登录光环账号时下载的存档在我的下载列表不显示 https://jira.shanqu.cc/browse/CWZS-147

See merge request halo/android/assistant-android!1546
2024-02-27 09:31:30 +08:00
2e2fe556cd fix: 【畅玩助手】未登录光环账号时下载的存档在我的下载列表不显示 https://jira.shanqu.cc/browse/CWZS-147 2024-02-27 09:31:30 +08:00
4734bad08a Merge branch 'feat/enhance-update' into 'dev'
feat: 为光环应用更新接口添加安卓版本字段,为接口区分系统版本推送更新提供前置支持

See merge request halo/android/assistant-android!1544
2024-02-23 10:42:39 +08:00
bd4eb76ad1 feat: 为光环应用更新接口添加安卓版本字段,为接口区分系统版本推送更新提供前置支持 2024-02-23 10:35:31 +08:00
c8883bd1cc Merge branch 'fix/GHZS-4790' into 'dev'
fix: 修复浅色/深色模式切换的一些问题

See merge request halo/android/assistant-android!1543
2024-02-22 18:01:33 +08:00
c658df314f fix: 深色模式相关问题 https://jira.shanqu.cc/browse/GHZS-4790 2024-02-22 17:46:38 +08:00
97a93dfa36 fix: 修复客户端切换深色模式导致助手界面显示错乱问题 https://jira.shanqu.cc/browse/GHZS-4573
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-02-22 09:35:07 +08:00
b8fced4237 fix: 修复重启应用后无法删除下载文件的问题;修复全部下载线程处于错误状态时没有正确更新下载速度的问题;修复任务支持多线程下载的任务下载线程数为 1 时,无法正确下载的问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-02-19 17:47:26 +08:00
b5d76cafe1 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-02-05 15:29:08 +08:00
98fb4b381a Merge branch 'hotfix/v5.33.1-1011/GHZS-4743' into 'release'
还原 vivo 设备获取应用列表权限的代码

See merge request halo/android/assistant-android!1541
2024-02-04 17:03:10 +08:00
1afed0d6db fix: VIVO 手机已安装列表权限获取问题 https://jira.shanqu.cc/browse/GHZS-4743 2024-02-04 15:35:11 +08:00
5c872b282c Merge branch 'hotfix/v5.33.1-1011-crashes' into 'release'
修复 5.33.1-1011 线上闪退问题

See merge request halo/android/assistant-android!1539
2024-02-04 14:22:26 +08:00
12be13d267 Merge branch 'hotfix/v5.33.1-1011/home_push_crash' into 'release'
fix: 修复首页下拉推送闪退问题...

See merge request halo/android/assistant-android!1538
2024-02-04 11:54:48 +08:00
83f50bb42c fix: 修复礼包详情页空指针闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/359262/?project=22 2024-02-04 11:50:39 +08:00
61e73ad932 feat: 修复因为延迟引起的海外弹窗弹出闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/360465/?project=22 2024-02-04 11:46:50 +08:00
e811538bbd fix: 修复首页下拉推送闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/352280/events/fa8235ae31344d539a3651d8b9189015/?project=22&statsPeriod=14d 2024-02-04 11:46:04 +08:00
818dec8428 chore: 版本更新至 5.33.2-1012 2024-02-02 17:47:35 +08:00
b79ada682f Merge branch 'hotfix/v5.33.1-1011-crashes' into 'release'
fix: 修复登录后快速关闭绑定手机号页面造成的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/363814

See merge request halo/android/assistant-android!1536
2024-02-02 17:46:45 +08:00
78330c1d12 Merge branch 'hotfix/v5.33.1-1011/runtime_exception' into 'release'
fix: 修复子线程弹出Dialog导致闪退的问题...

See merge request halo/android/assistant-android!1537
2024-02-02 17:45:40 +08:00
ff6e73cdb1 fix: 修复子线程弹出Dialog导致闪退的问题 https://sentry.shanqu.cc/organizations/lightgame/issues/364053/events/20753e6a2e6e4136b9edc2d1c0dcd95e/?project=22&statsPeriod=14d 2024-02-02 17:41:08 +08:00
4be928b015 fix: 修复登录后快速关闭绑定手机号页面造成的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/363814
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-02-02 17:12:58 +08:00
3124082175 chore: 版本更新至 5.34.0 2024-02-02 16:53:42 +08:00
a28451a976 build: 更改 gradle 源地址 2024-01-31 17:59:25 +08:00
ec70e2c47e Merge branch 'hotfix/meta_build_error' into 'release'
fix: 修复推广打包脚本的编译问题

See merge request halo/android/assistant-android!1533
2024-01-31 17:33:30 +08:00
68d546c7ca fix: 修复推广打包脚本的编译问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-31 17:05:15 +08:00
365aa5d8da chore: 版本更新至 5.33.1-1011 2024-01-31 14:39:02 +08:00
c842a9a184 Merge branch 'hotfix/v5.33.0-1010-crashes' into 'release'
修复 5.33.0-1010 的线上问题

See merge request halo/android/assistant-android!1532
2024-01-31 14:38:33 +08:00
6093b662a1 fix: 临时修复微博登录时偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/314704
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-31 14:24:13 +08:00
85d8638178 fix: 修复浏览播放论坛视频时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/363309
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-31 14:23:09 +08:00
ff434a0e51 fix: 修复海外地址弹窗弹出闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/360465/
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-31 11:24:10 +08:00
93ec29884b Merge branch 'hotfix/v5.33.0-1010-crashes' into 'release'
fix: 修复多线程初始化下载数据库可能的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/320027

See merge request halo/android/assistant-android!1531
2024-01-30 18:01:34 +08:00
f7bb617edb fix: 移除 EasyPermission 库
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-30 17:39:38 +08:00
1b5567f470 fix: 尝试修复卸载应用时可能的数组越界问题 https://sentry.shanqu.cc/organizations/lightgame/issues/242447/
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-30 17:17:55 +08:00
d1628b3377 fix: 修复重复设置 LayoutFactoryInflater factory 导致的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/350192
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-30 17:17:55 +08:00
509d6f4ac6 fix: 修复更换用户头像时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/354267
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-30 17:17:54 +08:00
5f9257a103 fix: 修复权限获取后的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/355494 https://sentry.shanqu.cc/organizations/lightgame/issues/355612 2024-01-30 17:17:54 +08:00
d50bea5f62 fix: 修复多线程初始化下载数据库可能的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/320027
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-30 15:52:44 +08:00
e138890f4d Merge branch 'hotfix/v5.33.0-1010-crashes' into 'release'
fix: 修复首页替换游戏导致的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/352562/?project=22

See merge request halo/android/assistant-android!1530
2024-01-30 15:32:49 +08:00
96734e3ead fix: 修复首页替换游戏导致的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/352562 2024-01-30 14:51:02 +08:00
7a596f49ca Merge branch 'fix/GHZS-4681' into 'dev'
fix:【光环助手】同步正式环境问题-反馈内容提交到后台显示乱码 https://jira.shanqu.cc/browse/GHZS-4681

See merge request halo/android/assistant-android!1528
2024-01-29 13:40:28 +08:00
564e5cbb8c fix:【光环助手】同步正式环境问题-反馈内容提交到后台显示乱码 https://jira.shanqu.cc/browse/GHZS-4681 2024-01-29 13:38:51 +08:00
25d7f2731a Merge branch 'fix/download_crash' into 'dev'
fix: 修复下载完成状态同步异常导致的闪退问题

See merge request halo/android/assistant-android!1527
2024-01-29 11:11:01 +08:00
36c164da26 fix: 修复下载完成状态同步异常导致的闪退问题 2024-01-29 11:09:21 +08:00
4996d62252 Merge branch 'fix/GHZS-4678' into 'dev'
fix:【光环助手】同步正式环境问题-畅玩问题内容未带前缀 https://jira.shanqu.cc/browse/GHZS-4678

See merge request halo/android/assistant-android!1525
2024-01-26 17:10:59 +08:00
20bab0fc84 fix:【光环助手】同步正式环境问题-畅玩问题内容未带前缀 https://jira.shanqu.cc/browse/GHZS-4678 2024-01-26 16:32:21 +08:00
74f6f3467b Merge branch 'chen/202401/GHZS-4673' into 'dev'
feat:搜索结果页面新增游戏首位设置:5.33.0客户端交互验收小优化—客户端 https://jira.shanqu.cc/browse/GHZS-4673

See merge request halo/android/assistant-android!1524
2024-01-26 14:11:22 +08:00
af4647dc37 feat:搜索结果页面新增游戏首位设置:5.33.0客户端交互验收小优化—客户端 https://jira.shanqu.cc/browse/GHZS-4673 2024-01-26 14:04:57 +08:00
e2306124b2 Merge branch 'feat/GHZS-4461' into 'dev'
feat: 神策统计口径切换 https://jira.shanqu.cc/browse/GHZS-4461

See merge request halo/android/assistant-android!1510
2024-01-25 13:43:24 +08:00
00cd4c1f1f feat: 神策统计口径切换 https://jira.shanqu.cc/browse/GHZS-4461 2024-01-25 13:34:54 +08:00
4ace4b8056 Merge branch 'feat/GHZS-4434' into 'dev'
feat: 版本更新弹窗神策埋点补充 https://jira.shanqu.cc/browse/GHZS-4434

See merge request halo/android/assistant-android!1519
2024-01-25 09:18:08 +08:00
bffdc42eac feat: 版本更新弹窗神策埋点补充 https://jira.shanqu.cc/browse/GHZS-4434 2024-01-24 17:11:30 +08:00
0d6aa9f11d Merge branch 'feature-GHZS-4529' into 'dev'
feat: 云存档埋点优化—客户端 https://jira.shanqu.cc/browse/GHZS-4529

See merge request halo/android/assistant-android!1518
2024-01-24 16:52:16 +08:00
357c48ab08 feat: 云存档埋点优化—客户端 https://jira.shanqu.cc/browse/GHZS-4529 2024-01-24 16:52:16 +08:00
f1d3705f80 Merge branch 'feature-GHZS-4530' into 'dev'
feat: 兼职包特殊渠道处理—客户端 https://jira.shanqu.cc/browse/GHZS-4530

See merge request halo/android/assistant-android!1517
2024-01-24 16:14:37 +08:00
699679289b feat: 兼职包特殊渠道处理—客户端 https://jira.shanqu.cc/browse/GHZS-4530 2024-01-24 16:14:37 +08:00
f8dc122c41 Merge branch 'feat/GHZS-4501' into 'dev'
feat: 实名接口调整 https://jira.shanqu.cc/browse/GHZS-4501

See merge request halo/android/assistant-android!1511
2024-01-24 15:44:53 +08:00
0a56189ae8 feat: 实名接口调整 https://jira.shanqu.cc/browse/GHZS-4501 2024-01-24 14:41:52 +08:00
e079116d80 Merge branch 'fix/GHZS-4627' into 'dev'
fix: 广告管理相关优化—0122测试-客户端 https://jira.shanqu.cc/browse/GHZS-4627

See merge request halo/android/assistant-android!1513
2024-01-24 10:28:10 +08:00
d661a91c2f Merge branch 'feat/GHZS-4639' into 'dev'
feat: 推广包升级广点通SDK https://jira.shanqu.cc/browse/GHZS-4639

See merge request halo/android/assistant-android!1512
2024-01-24 10:11:16 +08:00
3ff5b04893 feat: 推广包升级广点通SDK https://jira.shanqu.cc/browse/GHZS-4639
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-24 10:01:09 +08:00
9c8bc7742c Revert "fix: 广告管理相关优化—0122测试-客户端(ci) https://jira.shanqu.cc/browse/GHZS-4627"
This reverts commit 9778cf439b.
2024-01-24 09:56:23 +08:00
4c01859683 Merge branch 'feat/GHZS-4542' into 'dev'
feat: 游戏内容屏蔽后台 https://jira.shanqu.cc/browse/GHZS-4542

See merge request halo/android/assistant-android!1509
2024-01-23 11:09:25 +08:00
794a681f07 feat: 游戏内容屏蔽后台 https://jira.shanqu.cc/browse/GHZS-4542 2024-01-23 11:01:15 +08:00
9778cf439b fix: 广告管理相关优化—0122测试-客户端(ci) https://jira.shanqu.cc/browse/GHZS-4627 2024-01-23 10:09:41 +08:00
a66f62bcb7 fix: 广告管理相关优化—0122测试-客户端 https://jira.shanqu.cc/browse/GHZS-4627 2024-01-23 10:07:45 +08:00
0935a75ec0 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/build.gradle
#	dependencies.gradle
2024-01-19 17:34:31 +08:00
0a221c07bf Merge branch 'fix/GHZS-4600' into 'dev'
fix:【光环助手】意见反馈的默认文案出错 https://jira.shanqu.cc/browse/GHZS-4600

See merge request halo/android/assistant-android!1505
2024-01-19 11:31:43 +08:00
011ff1e24a fix:【光环助手】意见反馈的默认文案出错 https://jira.shanqu.cc/browse/GHZS-4600 2024-01-19 11:28:49 +08:00
9cd8b5d8d5 chore: 版本更新至 5.32.9-1001 2024-01-16 15:52:27 +08:00
1eb77e8bd2 Merge branch 'fix/GHZS-4567' into 'release'
fix: V5.32.8实名认证问题 https://jira.shanqu.cc/browse/GHZS-4567

See merge request halo/android/assistant-android!1502
2024-01-16 15:41:18 +08:00
650dd2e2ad fix: V5.32.8实名认证问题 https://jira.shanqu.cc/browse/GHZS-4567
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-16 14:43:04 +08:00
563955940d chore: 版本更新至 5.32.9-1000 2024-01-15 17:59:36 +08:00
376996540d Merge branch 'fix/GHZS-4553' into 'release'
fix: V5.32.9群测问题汇总 https://jira.shanqu.cc/browse/GHZS-4553

See merge request halo/android/assistant-android!1500
2024-01-15 17:58:51 +08:00
1292446bd0 fix: V5.32.9群测问题汇总 https://jira.shanqu.cc/browse/GHZS-4553 2024-01-15 17:58:15 +08:00
427ce5bc38 Merge branch 'feature-GHZS-3815-dev' into 'dev'
feat: 港澳APP—客户端 https://jira.shanqu.cc/browse/GHZS-3815

See merge request halo/android/assistant-android!1499
2024-01-15 17:48:25 +08:00
e7897f9b18 feat: 港澳APP—客户端 https://jira.shanqu.cc/browse/GHZS-3815 2024-01-15 17:48:25 +08:00
55ece981b5 chore: 版本更新至 5.32.9 2024-01-12 16:23:11 +08:00
7f68b165cb Merge branch 'feat/GHZS-4498' into 'release'
feat: 神马SDK接入 https://jira.shanqu.cc/browse/GHZS-4498

See merge request halo/android/assistant-android!1495
2024-01-12 16:22:01 +08:00
bf46229bcd feat: 神马SDK接入 https://jira.shanqu.cc/browse/GHZS-4498 2024-01-12 15:43:18 +08:00
ce80f133a0 feat: 更新 LGLibrary 的依赖 2024-01-12 15:41:34 +08:00
e5ea731946 Merge branch 'feat/GHZS-4541' into 'release'
feat: 更新信通院最新版本SDK https://jira.shanqu.cc/browse/GHZS-4541

See merge request halo/android/assistant-android!1494
2024-01-12 15:36:46 +08:00
24d7f60426 Merge branch 'feat/GHZS-4522' into 'release'
feat: 第三方下载地址-实名流程补充 https://jira.shanqu.cc/browse/GHZS-4522

See merge request halo/android/assistant-android!1493
2024-01-12 15:34:30 +08:00
3a0205789a feat: 第三方下载地址-实名流程补充 https://jira.shanqu.cc/browse/GHZS-4522 2024-01-12 15:18:12 +08:00
f86edd196f Merge branch 'feat/GHZS-4537' into 'release'
feat: 推广包升级快手SDK https://jira.shanqu.cc/browse/GHZS-4536

See merge request halo/android/assistant-android!1492
2024-01-12 14:48:21 +08:00
898278b3d9 feat: 推广包升级快手SDK https://jira.shanqu.cc/browse/GHZS-4536 2024-01-12 14:42:48 +08:00
fd757a346c feat: 更新信通院最新版本SDK https://jira.shanqu.cc/browse/GHZS-4541 2024-01-12 14:17:21 +08:00
ed32da8882 Merge branch 'fix/GHZS-4487' into 'dev'
fix: V5.32.8华为鸿蒙系统-模拟器下载问题 https://jira.shanqu.cc/browse/GHZS-4487

See merge request halo/android/assistant-android!1488
2024-01-08 10:06:21 +08:00
d7e88ba38a fix: V5.32.8华为鸿蒙系统-模拟器下载问题 https://jira.shanqu.cc/browse/GHZS-4487 2024-01-08 09:57:28 +08:00
af0ba215dd Merge branch 'feat/GHZS-4476' into 'dev'
feat: 补充权限使用说明 https://jira.shanqu.cc/browse/GHZS-4476

See merge request halo/android/assistant-android!1487
2024-01-05 10:15:40 +08:00
8e7a168495 feat: 补充权限使用说明 https://jira.shanqu.cc/browse/GHZS-4476 2024-01-05 09:47:42 +08:00
913bf7ad2f Merge branch 'fix/hot_launch_splash_ad' into 'dev'
fix: 修复使用第三方登录或分享回到光环时显示开屏广告的问题

See merge request halo/android/assistant-android!1486
2024-01-04 11:21:15 +08:00
4d84af6ff9 fix: 修复使用第三方登录或分享回到光环时显示开屏广告的问题 2024-01-04 11:21:15 +08:00
1acfe4227f Merge branch 'fix/GHZS-4442' into 'dev'
fix: 客户端添加多个下载任务,操作全部开始和暂停时会有任务卡住无法下载  https://jira.shanqu.cc/browse/GHZS-4442

See merge request halo/android/assistant-android!1483
2024-01-03 12:02:33 +08:00
847def3d30 Merge branch 'fix/GHZS-4467' into 'dev'
fix: 同时下载多个畅玩游戏时,游戏详情页的进度条会消失 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4467

See merge request halo/android/assistant-android!1485
2024-01-03 12:02:28 +08:00
f523e984c8 fix: 客户端添加多个下载任务,操作全部开始和暂停时会有任务卡住无法下载 https://jira.shanqu.cc/browse/GHZS-4442 2024-01-03 11:47:15 +08:00
5fe39d69de Merge branch 'fix/wrong_entity_usage' into 'dev'
fix: 修复 下载管理-游戏更新 页面上报数据时使用了错误实体的问题

See merge request halo/android/assistant-android!1484
2023-12-29 10:38:41 +08:00
0c76783397 fix: 修复 下载管理-游戏更新 页面上报数据时使用了错误实体的问题 2023-12-29 10:20:32 +08:00
e4b5a6ef5a fix: 同时下载多个畅玩游戏时,游戏详情页的进度条会消失 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4467 2023-12-28 15:22:27 +08:00
f03a9677cc fix: 处理合并冲突 2023-12-28 13:52:22 +08:00
c4b519204b Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/common/util/DialogUtils.java
#	app/src/main/java/com/gh/gamecenter/MainActivity.java
#	app/src/main/res/layout/dialog_privacy_policy.xml
#	dependencies.gradle
#	module_common/src/main/java/com/gh/gamecenter/common/utils/PermissionHelper.kt
2023-12-28 11:53:03 +08:00
423bcda7ff Merge branch 'feat/GHZS-4446' into 'release'
feat:【光环助手】隐私合规问题-12/22 https://jira.shanqu.cc/browse/GHZS-4444

See merge request halo/android/assistant-android!1482
2023-12-28 11:44:29 +08:00
2bb61e8e4b feat: 隐私合规问题-12/22 https://jira.shanqu.cc/browse/GHZS-4446 2023-12-28 11:43:56 +08:00
84d8de881e Merge branch 'fix/GHZS-4421' into 'dev'
fix: 神策埋点上报问题 https://jira.shanqu.cc/browse/GHZS-4421

See merge request halo/android/assistant-android!1478
2023-12-27 17:26:07 +08:00
3809d6d887 Merge branch 'fix/CWZS-145' into 'dev'
fix: 偶现下载任务无法删除 https://jira.shanqu.cc/browse/CWZS-145

See merge request halo/android/assistant-android!1480
2023-12-27 17:26:04 +08:00
96c18ec7a6 Merge branch 'fix/GHZS-4393' into 'dev'
fix: 开测表时间问题 https://jira.shanqu.cc/browse/GHZS-4393

See merge request halo/android/assistant-android!1481
2023-12-27 17:25:59 +08:00
d052ef5923 fix: 开测表时间问题 https://jira.shanqu.cc/browse/GHZS-4393 2023-12-27 11:51:06 +08:00
993631c853 fix: 偶现下载任务无法删除 https://jira.shanqu.cc/browse/CWZS-145 2023-12-22 17:12:40 +08:00
3a9958fa7d Merge branch 'fix/GHZS-4439' into 'dev'
fix: 【光环助手】版块下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-4439

See merge request halo/android/assistant-android!1479
2023-12-22 11:31:50 +08:00
bb51391b61 fix: 【光环助手】版块下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-4439 2023-12-22 11:31:50 +08:00
57f1cb7e59 Merge branch 'fix/GHZS-3923' into 'dev'
fix: 内容触发敏感词点击还原后未正常展示 https://jira.shanqu.cc/browse/GHZS-3923

See merge request halo/android/assistant-android!1476
2023-12-18 16:44:50 +08:00
b4cd90a7e9 Merge branch 'fix/sensor-privacy-issue' into 'dev'
fix: 修复神策 SDK 可能反复获取运营商信息的问题...

See merge request halo/android/assistant-android!1477
2023-12-18 16:44:45 +08:00
6ec9d2076f fix: 修复神策 SDK 可能反复获取运营商信息的问题 https://manual.sensorsdata.cn/sa/latest/zh_cn/tech_sdk_client_android_high-128974940.html#id-.%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD%EF%BC%88Android%EF%BC%89v2.5-%E9%99%90%E5%88%B6SDK%E8%AF%BB%E5%8F%96%E6%95%8F%E6%84%9F%E5%B1%9E%E6%80%A7 2023-12-18 16:36:45 +08:00
22c727cd2f Merge branch 'hotfix/v5.32.7-997/crashes' into 'release'
修复sentry闪退问题

See merge request halo/android/assistant-android!1475
2023-12-18 14:20:19 +08:00
5e5aee539e fix: 修复首页下拉刷新偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/352463/?project=22&query=is%3Aunresolved+assigned%3Ame&sort=date&statsPeriod=14d 2023-12-18 14:11:21 +08:00
c158225472 fix: 修复开屏广告偶发的空指针闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/349408/events/ca7a12772e484958a5a9d4113fcba161/?project=22&statsPeriod=14d 2023-12-18 14:10:30 +08:00
ac5b7837db Merge branch 'fix/hot_launch_splash_ad' into 'dev'
fix: 修复重复展示热启动和冷启动开屏广告的问题

See merge request halo/android/assistant-android!1474
2023-12-15 17:45:15 +08:00
05a113de40 fix: 修复重复展示热启动和冷启动开屏广告的问题 2023-12-15 17:29:25 +08:00
d45d02bfd2 fix: 神策埋点上报问题 https://jira.shanqu.cc/browse/GHZS-4421
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-12-15 17:19:25 +08:00
395433f21f Merge branch 'feature-GHZS-3788' into 'dev'
feat: 新增草稿箱入口—客户端 https://jira.shanqu.cc/browse/GHZS-3788

See merge request halo/android/assistant-android!1473
2023-12-14 18:07:18 +08:00
ccbd70666a feat: 新增草稿箱入口—客户端 https://jira.shanqu.cc/browse/GHZS-3788 2023-12-14 18:07:18 +08:00
aaa8eda004 Merge branch 'feature-GHZS-4259' into 'dev'
fix: 【光环助手】“横屏滑动视频”专题滑动导致APP卡顿 https://jira.shanqu.cc/browse/GHZS-4259

See merge request halo/android/assistant-android!1459
2023-12-14 18:06:45 +08:00
748497e5b1 fix: 【光环助手】“横屏滑动视频”专题滑动导致APP卡顿 https://jira.shanqu.cc/browse/GHZS-4259 2023-12-14 18:06:45 +08:00
1cf49b931e Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-12-14 17:03:14 +08:00
e4a9d533d4 Merge branch 'feat/GHZS-3698' into 'dev'
feat: 通用链接模块新增帮助与反馈类型 https://jira.shanqu.cc/browse/GHZS-3785

See merge request halo/android/assistant-android!1425
2023-12-14 16:53:55 +08:00
36e9bd20ac fix: V5.32.5群测问题汇总1204 https://jira.shanqu.cc/browse/GHZS-4375 2023-12-13 15:36:34 +08:00
cc4ef16e10 chore: 版本更新至 5.32.7 2023-12-13 14:20:28 +08:00
6a446a6f3a Merge branch 'fix/GHZS-4375' into 'dev'
fix: V5.32.5群测问题汇总1204 https://jira.shanqu.cc/browse/GHZS-4375

See merge request halo/android/assistant-android!1472
2023-12-13 10:44:01 +08:00
233e0ec71d fix: V5.32.5群测问题汇总1204 https://jira.shanqu.cc/browse/GHZS-4375 2023-12-13 10:27:10 +08:00
d6e1a90472 Merge branch 'feat/GHZS-4384' into 'dev'
feat: 适龄提示等级补充 https://jira.shanqu.cc/browse/GHZS-4384

See merge request halo/android/assistant-android!1471
2023-12-13 10:06:52 +08:00
0911cd146b Merge branch 'hotfix/v5.32.5-995/CWZS-138' into 'release'
fix:【畅玩助手】畅玩-最近在玩模块、双开按钮异常 https://jira.shanqu.cc/browse/CWZS-138

See merge request halo/android/assistant-android!1468
2023-12-13 09:34:04 +08:00
8e255b1803 fix:【畅玩助手】畅玩-最近在玩模块、双开按钮异常 https://jira.shanqu.cc/browse/CWZS-138 2023-12-13 09:34:04 +08:00
14939625dd Merge branch 'feat/GHZS-3791' into 'dev'
feat: 广告管理相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3791

See merge request halo/android/assistant-android!1430
2023-12-13 09:31:58 +08:00
19afb7221d feat: 广告管理相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3791 2023-12-13 09:31:58 +08:00
ae0f4c948b chore: 版本更新至 5.32.5 2023-12-12 15:04:32 +08:00
d650739632 Merge branch 'feature-GHZS-sentry-20231211' into 'release'
fix: Sentry异常修复

See merge request halo/android/assistant-android!1470
2023-12-11 18:00:01 +08:00
6f6a734cb5 fix: Sentry异常修复 2023-12-11 18:00:01 +08:00
e510146775 Merge branch 'hotfix/v5.32.5-995/search_crash' into 'release'
fix: 修复点击搜索栏闪退的问题...

See merge request halo/android/assistant-android!1469
2023-12-11 10:09:01 +08:00
8b863955a3 fix: 修复点击搜索栏闪退的问题 https://sentry.shanqu.cc/organizations/lightgame/issues/350701/events/e5db556244ac4ecb93d37e7997103bf3/?environment=kuaishou&project=22 2023-12-11 10:03:02 +08:00
37155b96dd Merge branch 'hotfix/v5.32.5-995/crashes' into 'release'
修复sentry闪退问题

See merge request halo/android/assistant-android!1467
2023-12-08 14:07:02 +08:00
e55d4d3332 fix: 捕获替换Fragment关联的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/348952/events/d6c0400d0edb4ee8b302faab4707960d/?project=22&statsPeriod=14d 2023-12-08 13:50:00 +08:00
3e38830480 Merge branch 'feat/GHZS-4377' into 'dev'
feat: 游戏详情当前版本展示规则变更 https://jira.shanqu.cc/browse/GHZS-4377

See merge request halo/android/assistant-android!1466
2023-12-06 16:04:10 +08:00
dabf532ae7 feat: 游戏详情当前版本展示规则变更 https://jira.shanqu.cc/browse/GHZS-4377
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-12-06 15:59:10 +08:00
7aa2b20224 feat: 适龄提示等级补充 https://jira.shanqu.cc/browse/GHZS-4384
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-12-06 11:53:25 +08:00
10572e7b0b fix: 修复线上闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/349079/events/06d299cb0e6549a49f80cd248a91e614/?project=22 2023-12-05 14:53:00 +08:00
3912729fff Merge branch 'fix/GHZS-4364' into 'dev'
fix: 游戏下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-4364

See merge request halo/android/assistant-android!1465
2023-12-05 10:27:39 +08:00
78ff8dcb0a fix: 游戏下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-4364
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-12-01 16:54:40 +08:00
80e7ad9401 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-12-01 10:08:09 +08:00
a9ba7d056b Merge branch 'feat/GHZS-3983' into 'dev'
feat: 游戏下载判断逻辑优化 https://jira.shanqu.cc/browse/GHZS-3982

See merge request halo/android/assistant-android!1444
2023-11-23 16:36:23 +08:00
da4e83d29d feat: 游戏下载判断逻辑优化 https://jira.shanqu.cc/browse/GHZS-3983 2023-11-23 16:17:40 +08:00
cc9c390bbb fix: 内容触发敏感词点击还原后未正常展示 https://jira.shanqu.cc/browse/GHZS-3923
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-11-23 14:56:52 +08:00
d96ae0cdbb Merge branch 'chen/202311/GHZS-3800' into 'dev'
feat:搜索结果页面新增游戏首位设置—客户端 https://jira.shanqu.cc/browse/GHZS-3800

See merge request halo/android/assistant-android!1457
2023-11-23 13:37:10 +08:00
c8a1bd5278 feat:搜索结果页面新增游戏首位设置—客户端 https://jira.shanqu.cc/browse/GHZS-3800 2023-11-23 13:37:10 +08:00
aa0d36a3ba Merge branch 'feat/GHZS-3783' into 'dev'
feat: 畅玩游戏问题反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3783

See merge request halo/android/assistant-android!1423
2023-11-23 11:47:33 +08:00
ffe1c0606a feat: 畅玩游戏问题反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3783 2023-11-23 11:47:33 +08:00
7f73b728a5 feat: 通用链接模块新增帮助与反馈类型 https://jira.shanqu.cc/browse/GHZS-3785 2023-11-22 17:54:41 +08:00
5cfb7f5036 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-11-22 17:54:06 +08:00
399e513174 Merge branch 'feat/GHZS-3760' into 'dev'
feat: 帮助与反馈第二期迭代 https://jira.shanqu.cc/browse/GHZS-3760

See merge request halo/android/assistant-android!1424
2023-11-22 17:16:10 +08:00
1eeb34c93a Merge branch 'feature/GHZS-4272-patch' into 'dev'
fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端...

See merge request halo/android/assistant-android!1450
2023-11-20 15:24:05 +08:00
d18f3909ea fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端... 2023-11-20 15:24:05 +08:00
c23118e535 Merge remote-tracking branch 'origin/dev' into dev-5.33.0
# Conflicts:
#	dependencies.gradle
2023-11-20 14:41:30 +08:00
4d4498cdee Merge branch 'release' into 'dev'
chore: 版本更新至 5.32.1

See merge request halo/android/assistant-android!1448
2023-11-20 14:36:25 +08:00
a348b80eaf Merge branch 'dev' into 'dev-5.33.0'
merge dev into dev-5.33.0

See merge request halo/android/assistant-android!1447
2023-11-20 14:34:22 +08:00
64bdbbf409 Merge branch 'feature-GHZS-4272' into 'dev-5.33.0'
fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端 https://jira.shanqu.cc/browse/GHZS-4272

See merge request halo/android/assistant-android!1446
2023-11-20 10:51:36 +08:00
984bb60e6a fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端 https://jira.shanqu.cc/browse/GHZS-4272 2023-11-20 10:51:36 +08:00
1461af16b9 feat: 帮助与反馈第二期迭代 https://jira.shanqu.cc/browse/GHZS-3760 2023-11-15 14:14:28 +08:00
14fca95ed6 Merge branch 'feature-GHZS-3949' into 'dev-5.33.0'
fix: 内容搜索新增搜索配置(客-户-端)—1110测试-后端 https://jira.shanqu.cc/browse/GHZS-3949

See merge request halo/android/assistant-android!1442
2023-11-15 11:21:50 +08:00
c3926c85d8 fix: 内容搜索新增搜索配置(客-户-端)—1110测试-后端 https://jira.shanqu.cc/browse/GHZS-3949 2023-11-15 11:21:50 +08:00
9b73272019 Merge branch 'dev' into 'dev-5.33.0'
合并 dev 到 dev-5.33.0

See merge request halo/android/assistant-android!1443
2023-11-15 11:16:14 +08:00
5757df01e7 Merge branch 'dev-5.33.0-merged-dev' into 'dev-5.33.0'
Dev 5.33.0 merged dev

See merge request halo/android/assistant-android!1436
2023-11-10 14:12:42 +08:00
3f60f85992 Merge branch 'dev' into dev-5.33.0-merged-dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/forum/search/CommunitySearchEventListener.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListFragment.kt
2023-11-10 14:05:20 +08:00
52980189ed Merge branch 'chen/202310/GHZS-3730' into 'dev-5.33.0' 2023-11-09 14:01:17 +08:00
852f7734ef feat:论坛搜索排序逻辑优化—客户端 https://jira.shanqu.cc/browse/GHZS-3730 2023-11-09 14:01:17 +08:00
a25503113b Merge branch 'docs/GHZS-3866' into 'dev-5.33.0'
docs: 为首页所有现有的 ViewHolder 备注后台对应的样式名称 https://jira.shanqu.cc/browse/GHZS-3866

See merge request halo/android/assistant-android!1426
2023-11-08 18:03:38 +08:00
0d6b62b361 docs: 为首页所有现有的 ViewHolder 备注后台对应的样式名称 https://jira.shanqu.cc/browse/GHZS-3866 2023-11-08 14:34:29 +08:00
e3b8ea74c1 fix: 处理与 5.32.0 的代码冲突 2023-11-08 11:44:15 +08:00
bf10d5aa42 Merge remote-tracking branch 'origin/dev' into dev-5.33.0
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryFragment.kt
#	app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListFragment.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/UserSearchListFragment.kt
#	app/src/main/res/layout/fragment_list_article_detail_comment.xml
2023-11-08 11:30:16 +08:00
3efcd71046 Merge branch 'fix/GHZS-3853' into 'dev-5.33.0'
fix: 畅玩游戏反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3853

See merge request halo/android/assistant-android!1417
2023-11-03 16:24:53 +08:00
ce99eef958 fix: 畅玩游戏反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3853 2023-11-03 16:17:49 +08:00
4f1ccac6fc Merge branch 'fix/GHZS-3754' into 'dev-5.33.0'
fix:【光环助手】跳转链接问题 https://jira.shanqu.cc/browse/GHZS-3754

See merge request halo/android/assistant-android!1409
2023-11-01 17:54:58 +08:00
41c8d4950f Merge branch 'merge_dev_to_dev-5.33.0' into 'dev-5.33.0'
合并 dev 变更

See merge request halo/android/assistant-android!1408
2023-11-01 17:54:46 +08:00
d633d9b37b fix:【光环助手】跳转链接问题 https://jira.shanqu.cc/browse/GHZS-3754 2023-11-01 16:36:42 +08:00
23ec072ac5 fix: 处理合并冲突 2023-11-01 15:54:12 +08:00
3f3fd1ad5f Merge branch 'dev' into merge_dev_to_dev-5.33.0
# Conflicts:
#	app/src/main/java/com/gh/common/databind/BindingAdapters.java
#	app/src/main/java/com/gh/gamecenter/cloudarchive/CloudArchiveManagerActivity.kt
#	app/src/main/java/com/gh/gamecenter/cloudarchive/CloudArchiveManagerViewModel.kt
#	app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt
#	app/src/main/java/com/gh/gamecenter/gamedetail/fuli/kaifu/ServersDetailReportViewHolder.kt
#	app/src/main/java/com/gh/gamecenter/gamedetail/fuli/kaifu/ServersDetailViewHolder.kt
#	app/src/main/java/com/gh/vspace/VHelper.kt
#	app/src/main/res/layout/dialog_servers_calendear_detail.xml
#	app/src/main/res/layout/dialog_servers_calendear_detail_item.xml
#	app/src/main/res/layout/dialog_servers_calendear_detail_report.xml
#	module_common/src/main/res/drawable/download_button_normal_style.xml
2023-11-01 14:47:48 +08:00
3022118445 Merge branch 'feature-GHZS-3769' into 'dev-5.33.0'
feat:更新光环编译SDK版本至 34 https://jira.shanqu.cc/browse/GHZS-3769

See merge request halo/android/assistant-android!1407
2023-10-30 18:04:17 +08:00
edf56c92d5 feat:更新光环编译SDK版本至 34 https://jira.shanqu.cc/browse/GHZS-3769 2023-10-30 18:04:17 +08:00
ad6bf59297 Merge branch 'chen/202310/GHZS-3757' into 'dev-5.33.0'
feat:统一设计规范与客户端内代码的命名 https://jira.shanqu.cc/browse/GHZS-3757

See merge request halo/android/assistant-android!1404
2023-10-25 18:01:45 +08:00
42e009b91d feat:统一设计规范与客户端内代码的命名 https://jira.shanqu.cc/browse/GHZS-3757 2023-10-25 17:37:23 +08:00
fe2d0e6a34 Merge branch 'fix/CWZS-127' into 'dev-5.33.0'
fix: 云存档使用存档流程优化—客户端(修复云存档管理页面获取存档配置失败的问题) https://jira.shanqu.cc/browse/CWZS-127

See merge request halo/android/assistant-android!1396
2023-10-23 10:04:14 +08:00
1cbfbeb118 Merge branch 'fix/CWZS-129' into 'dev-5.33.0'
fix: 游戏详情中从云存档启动游戏,缺少谷歌框架流程导致无法进入游戏—客户端 https://jira.shanqu.cc/browse/CWZS-129

See merge request halo/android/assistant-android!1395
2023-10-23 10:04:01 +08:00
d845ceb31a fix: 云存档使用存档流程优化—客户端(修复云存档管理页面获取存档配置失败的问题) https://jira.shanqu.cc/browse/CWZS-127 2023-10-23 09:48:38 +08:00
c080049322 fix: 游戏详情中从云存档启动游戏,缺少谷歌框架流程导致无法进入游戏—客户端 https://jira.shanqu.cc/browse/CWZS-129 2023-10-20 17:31:56 +08:00
820e29db23 Merge remote-tracking branch 'origin/dev' into dev-5.33.0 2023-10-20 14:28:21 +08:00
be4d464bc0 Merge branch 'dev' into 'dev-5.33.0'
Dev

See merge request halo/android/assistant-android!1392
2023-10-19 15:50:39 +08:00
e3c56fa800 Merge branch 'feat/CWZS-127' into 'dev-5.33.0'
feat: 云存档使用存档流程优化—客户端 https://jira.shanqu.cc/browse/CWZS-127

See merge request halo/android/assistant-android!1391
2023-10-19 15:30:35 +08:00
7e982e30a3 feat: 云存档使用存档流程优化—客户端 https://jira.shanqu.cc/browse/CWZS-127 2023-10-19 14:19:20 +08:00
0eae5262af Merge branch 'feat/GHZS-3622' into 'dev-5.33.0'
feat: 反馈管理新增包名屏蔽—客户端 https://jira.shanqu.cc/browse/GHZS-3622

See merge request halo/android/assistant-android!1389
2023-10-19 09:55:51 +08:00
6656cbc635 feat: 反馈管理新增包名屏蔽—客户端 https://jira.shanqu.cc/browse/GHZS-3622 2023-10-19 09:55:51 +08:00
0a6b93a8f8 chore: 版本更新至 5.33.0 2023-10-10 14:47:26 +08:00
2330 changed files with 56008 additions and 24869 deletions

View File

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

3
.gitmodules vendored
View File

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

@ -4,6 +4,7 @@ apply plugin: 'kotlin-android' // kotlin
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'AndResGuard'
apply plugin: 'privacy-sentry-plugin'
import groovy.xml.XmlUtil
@ -23,6 +24,8 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -95,8 +98,10 @@ android {
buildConfigField "int", "ACTIVATE_REPORTING_RATIO", "${ACTIVATE_REPORTING_RATIO}"
// All third-party appid/appkey
buildConfigField "boolean", "IS_GAT_APP", "false"
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT}\""
buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "WECHAT_APPID", "\"${WECHAT_APPID}\""
buildConfigField "String", "WECHAT_SECRET", "\"${WECHAT_SECRET}\""
@ -157,7 +162,7 @@ android {
}
}
flavorDimensions("env")
flavorDimensions("env", "region")
sourceSets {
publish {
@ -175,6 +180,15 @@ android {
gdt {
java.srcDirs = ['src/main/java', 'src/gdt/java']
}
gat {
java.srcDirs = ['src/main/java', 'src/gat/java']
}
cn {
java.srcDirs = ['src/main/java', 'src/cn/java']
}
sm {
java.srcDirs = ['src/main/java', 'src/sm/java']
}
}
productFlavors {
@ -242,6 +256,37 @@ android {
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
sm {
dimension "env"
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
// 港澳台
gat {
dimension "region"
applicationId rootProject.ext.applicationIdGat
// 支持繁体
resConfigs "zh", "zh-rTW"
buildConfigField "boolean", "IS_GAT_APP", "true"
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT_GAT}\""
buildConfigField "String", "API_HOST", "\"${API_HOST_GAT}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST_GAT}\""
}
cn {
dimension "region"
}
}
}
@ -258,6 +303,7 @@ dependencies {
teaImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/tea/libs')
kuaishouImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/kuaishou/libs')
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
smImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/sm/libs')
testImplementation 'junit:junit:4.12'
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
@ -265,7 +311,6 @@ 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}"
@ -277,7 +322,8 @@ dependencies {
implementation "com.kyleduo.switchbutton:library:${switchButton}"
implementation "com.leon.channel:helper:${apkChannelPackage}"
implementation "com.tencent.vasdolly:helper:${apkChannelPackage}"
implementation "com.tencent.vasdolly:writer:${apkChannelPackage}"
implementation "com.j256.ormlite:ormlite-android:${ormlite}"
implementation "com.j256.ormlite:ormlite-core:${ormlite}"
@ -300,8 +346,6 @@ 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}"
@ -314,14 +358,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')
@ -365,6 +409,51 @@ dependencies {
exclude group: 'androidx.swiperefreshlayout'
}
internalImplementation(project(':module_internal_test'))
def pushProperty = findProperty('BUILD_PUSH_TYPE')
// 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用极光推送
def pushProject = (pushProperty == null || pushProperty == 'jg')
? project(':feature:jg_push') : project(':feature:acloud_push')
implementation(pushProject) {
exclude group: 'androidx.swiperefreshlayout'
}
def privacyVersion = "1.3.4.2"
implementation "com.github.allenymt.PrivacySentry:hook-sentry:$privacyVersion"
implementation "com.github.allenymt.PrivacySentry:privacy-annotation:$privacyVersion"
// 代理类的库如果自己没有代理类那么必须引用这个aar
// 如果不想使用库中本身的代理方法可以不引入这个aar但是自己必须实现代理类
// 引入privacy-proxy也可以自定义类代理方法优先以业务方定义的为准
implementation "com.github.allenymt.PrivacySentry:privacy-proxy:$privacyVersion"
// 1.2.3 新增类替换主要是为了hook构造函数的参数按业务方需求自己决定
implementation "com.github.allenymt.PrivacySentry:privacy-replace:$privacyVersion"
}
privacy {
// 设置免hook的名单
blackList = []
// 开关PrivacySentry插件功能
enablePrivacy = true
// 开启hook反射的方法
hookReflex = true
// 开启hook 替换类目前支持file
hookConstructor = true
// 是否开启hook变量默认为false建议弃用
hookField = true
// 以下是为了解决小米照明弹自启动问题的尝试, 如果没有自启动的需求,这里关闭即可
// hook Service的部分代码修复在MIUI上的自启动问题
// 部分Service把自己的Priority设置为1000这里开启代理功能可以代理成0
enableReplacePriority = true
replacePriority = 1
// 支持关闭Service的Export功能默认为false注意部分厂商通道之类的push(xiaomi、vivo、huawei等厂商的pushService),不能关闭
enableCloseServiceExport = true
// Export白名单Service, 这里根据厂商的名称设置了白名单
serviceExportPkgWhiteList = ["xiaomi","vivo","honor","meizu","oppo","Oppo","Hms","huawei","stp","Honor"]
// 修改Service的onStartCommand 返回值修改为START_NOT_STICKY
enableHookServiceStartCommand = true
}
File propFile = file('sign.properties')
@ -435,6 +524,13 @@ 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,14 +80,14 @@
### EasyFloat
-keep class com.lzf.easyfloat.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
### 广点通SDK
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}
-keep public class com.tencent.turingfd.sdk.**
### 神马 SDK
-dontwarn com.gism.**
-keepclasseswithmembers class * {
native <methods>;
}

View File

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

View File

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

View File

@ -67,7 +67,7 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
it.layoutManager = LinearLayoutManager(requireContext())
val itemDecoration = HorizontalDividerItemDecoration.Builder(requireContext())
.size(2F.dip2px())
.color(R.color.divider.toColor(requireContext()))
.color(R.color.ui_divider.toColor(requireContext()))
.build()
if (it.itemDecorationCount != 0) {
it.removeItemDecorationAt(0)

View File

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

View File

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

Binary file not shown.

View File

@ -11,6 +11,14 @@
<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卡上写文件 -->
@ -99,6 +107,10 @@
android:name="android.permission.GET_TASKS"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
tools:node="remove" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
@ -114,10 +126,12 @@
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="n">
tools:targetApi="r">
<meta-data
android:name="EasyGoClient"
@ -190,7 +204,7 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.NewsDetailActivity"
android:name="com.gh.gamecenter.newsdetail.NewsDetailActivity"
android:screenOrientation="portrait" />
<activity
@ -245,7 +259,7 @@
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.gh.gamecenter.LibaoDetailActivity"
android:name="com.gh.gamecenter.libao.LibaoDetailActivity"
android:screenOrientation="portrait" />
<activity
@ -309,14 +323,6 @@
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" />
@ -325,10 +331,6 @@
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" />
@ -366,10 +368,6 @@
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" />
@ -408,10 +406,6 @@
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" />
@ -484,9 +478,6 @@
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" />
@ -498,10 +489,6 @@
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" />
@ -607,6 +594,10 @@
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" />
@ -698,7 +689,7 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.toolbox.ToolBoxBlockActivity"
android:name="com.gh.gamecenter.toolbox.ToolBoxActivity"
android:screenOrientation="portrait" />
<activity
@ -771,6 +762,16 @@
android:name="com.gh.gamecenter.UserAuthActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.SplashAdActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.wrapper.ToolbarWrapperActivity"
android:screenOrientation="portrait" />
<activity android:name=".forum.home.CommunityActivity"
android:screenOrientation="portrait"/>
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
@ -826,6 +827,8 @@
<!-- tools:node="remove" />-->
<!-- </provider>-->
<service android:name="com.gh.gamecenter.install.InstallService" />
<receiver
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
android:exported="false">
@ -843,8 +846,8 @@
<activity
android:name="com.gh.common.xapk.XapkInstallReceiver"
android:theme="@style/Theme.Transparent"
android:exported="false" />
android:exported="false"
android:theme="@style/Theme.Transparent" />
<receiver
android:name="com.gh.gamecenter.receiver.ActivitySkipReceiver"
@ -853,7 +856,6 @@
<action android:name="com.gh.gamecenter.ACTIVITYSKIP" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -6,8 +6,6 @@
<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;">
@ -15,8 +13,5 @@
<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

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

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

View File

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

View File

@ -12,13 +12,13 @@ import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.entity.QuoteCountEntity
@ -28,7 +28,6 @@ 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
@ -62,7 +61,6 @@ 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()//数据上报用
@ -129,15 +127,13 @@ 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.getTransformedUrl(imageUrlMap[key], 5000) ?: ""
val transformedImgUrl = ImageUtils.getIdealImageUrl(imageUrlMap[key], 5000) ?: ""
map[MD5Utils.getUrlMD5(key)] = transformedImgUrl
mapImages[transformedImgUrl.decodeURI()] = imageUrlMap[key] ?: ""
} else {
map[MD5Utils.getUrlMD5(key)] = localFileUri
map[MD5Utils.getUrlMD5(key)] = imageUrlMap[key] ?: ""
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 (showDownloadMenu()) {
if (!getBoolean(Constants.SP_TEENAGER_MODE) && 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, "fonts/d_din_bold_only_number.ttf")
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, Constants.DIN_FONT_PATH)
}
override fun onMenuItemClick(item: MenuItem?): Boolean {

View File

@ -4,20 +4,27 @@ import android.app.Activity
import android.app.Application
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.FloatingBackViewManager
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.SingletonWebActivity
import com.gh.gamecenter.SkipActivity
import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.authorization.AuthorizationActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
private var isFromBackgroundToForeground = false // 是否后台回到前台
private var activityCount = 0
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
@ -25,6 +32,27 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity) {
GlobalActivityManager.currentActivity = activity
activityCount ++
if (activityCount == 1 && isFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isSkippingThirdParty
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
&& activity !is SplashAdActivity
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
isFromBackgroundToForeground = false
}
if (activityCount == 1) {
// 清除桌面角标
if (activity !is SplashScreenActivity && activity !is AuthorizationActivity) {
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
}
}
override fun onActivityResumed(activity: Activity) {
@ -74,7 +102,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityStopped(activity: Activity) {
// do nothing
activityCount --
isFromBackgroundToForeground = activityCount <= 0
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

View File

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

View File

@ -2,17 +2,16 @@ 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
@ -26,7 +25,6 @@ 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
@ -34,58 +32,56 @@ object FixedRateJobHelper {
@JvmStatic
fun begin() {
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()
}
// 时间检查每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 % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
}
}
// 提交视频浏览记录数据
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
mExecuteCount++
}
})
}
// 提交曝光数据
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 % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
}
}
// 提交视频浏览记录数据
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
mExecuteCount++
}
}
}

View File

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

View File

@ -11,7 +11,8 @@ class CheckStoragePermissionHandler : DownloadChainHandler() {
context,
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese
gameEntity.categoryChinese,
gameEntity.getApk().firstOrNull()?.format,
) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)

View File

@ -1,16 +1,33 @@
package com.gh.common.chain
import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.TempCertificationUtils
import com.gh.gamecenter.feature.entity.GameEntity
class LandPageAddressHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
if (gameEntity.isLandPageAddressDialog()) {
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
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!!)
}
}
}
} else {
if (hasNext()) {

View File

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

View File

@ -8,7 +8,6 @@ import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.util.AdHelper;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
@ -26,20 +25,18 @@ import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
import com.gh.gamecenter.entity.VSetting;
import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.utils.ContentBlockedHelper;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -60,8 +57,7 @@ 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;
// http://www.ghzs666.com/article/${articleId}.html
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
public static final String URL_ARTICLE = "www.ghzs666.com/article/"; // ghzs/ghzs666 统一
private static final String SETTINGS_KEY = "settingsKey";
@ -75,51 +71,10 @@ public class Config {
private static GameGuidePopupEntity mGameGuidePopupEntity;
private static SharedPreferences mDefaultSharedPreferences;
public static final String FIX_DOWNLOAD_KEY = "isFixDownload";
public static final String FIX_PLUGIN_KEY = "isFixPlugin";
public static final int VIDEO_PAGE_SIZE = 21; // 视频列表大多都是一行3个
public static boolean isShow() {
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) return false;
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (!isExistDownloadFilter()) return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && "normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
}
}
}
return false;
}
public static boolean isShowDownload(String gameId) {
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if (gameId.equals(entity.getGame())) {
if ("normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
} else {
return false;
}
} else if ("all".equals(entity.getGame())) {
if ("normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
}
}
}
return false;
return !SPUtils.getBoolean(Constants.SP_TEENAGER_MODE);
}
/**
@ -135,74 +90,10 @@ public class Config {
return mNewApiSettingsEntity.getInstall().getVpnRequired().getShouldShowVpnOption();
}
public static boolean isShowPlugin(String gameId) {
SharedPreferences preferences = getPreferences();
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
if (isFixPlugin) return true;
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if (gameId.equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
return true;
} else {
return false;
}
}
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
preferences.edit().putBoolean(FIX_PLUGIN_KEY, true).apply();
return true;
}
}
}
return false;
}
public static boolean isShowPlugin() {
SharedPreferences preferences = getPreferences();
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
if (isFixPlugin) return true;
if (!isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
preferences.edit().putBoolean(FIX_PLUGIN_KEY, true).apply();
return true;
}
}
}
return false;
}
private static boolean filterTime(SettingsEntity.Download.TimeEntity timeEntity) {
long end = timeEntity.getEnd();
long start = timeEntity.getStart();
long curTime = Utils.getTime(HaloApp.getInstance().getApplication());
if ((start == 0 || curTime >= start) && (end == 0 || curTime <= end)) {
return true;
}
return false;
}
public static void setSettings(SettingsEntity settingsEntity) {
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
// 更新设置状态
mSettingsEntity.showArticleEntrance();
mSettingsEntity.showCommunityEntrance();
// 加载完设置后刷新下
PackageHelper.initList();
}
@ -330,27 +221,6 @@ public class Config {
return mGameGuidePopupEntity;
}
private static boolean isExistDownloadFilter() {
if (getSettings() == null || getSettings().getDownload() == null || getSettings().getDownload().size() == 0) {
return false;
} else {
return true;
}
}
public static void filterPluginArticle(List<NewsEntity> list) {
if (isShowPlugin() || list == null) return;
for (int i = 0; i < list.size(); i++) {
NewsEntity newsEntity = list.get(i);
String title = newsEntity.getTitle();
if (!TextUtils.isEmpty(title) && title.contains("插件")) {
list.remove(i);
i--;
}
}
}
public static SharedPreferences getPreferences() {
if (mDefaultSharedPreferences == null) {
mDefaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
@ -381,9 +251,6 @@ public class Config {
GsonUtils.toJson(response.getSuggestion()));
edit.apply();
if (!getPreferences().getBoolean(Config.FIX_DOWNLOAD_KEY, false) && Config.isShow()) {
getPreferences().edit().putBoolean(Config.FIX_DOWNLOAD_KEY, true).apply();
}
if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
EventBus.getDefault().post(new EBReuse("Refresh"));
}
@ -460,6 +327,11 @@ public class Config {
DarkModeUtils.INSTANCE.initDarkMode();
}
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
// 刷新屏蔽字段
if (mNewApiSettingsEntity.getGameShieldContents() != null) {
ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
}
}
});
}

View File

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

View File

@ -15,7 +15,6 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.gh.common.chain.BrowserInstallHandler;
import com.gh.common.chain.CertificationHandler;
import com.gh.common.chain.DownloadChainBuilder;
import com.gh.common.chain.DownloadChainHandler;
import com.gh.common.chain.CheckDownloadHandler;
@ -53,6 +52,8 @@ 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;
@ -70,13 +71,14 @@ 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.
*/
@ -96,20 +98,29 @@ 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) {
// 恢复DialogFragment
restoreDialogFragment(progressBar);
// 判断是否显示按钮
if (gameEntity != null
&& Config.isShowDownload(gameEntity.getId())
&& !"光环助手".equals(gameEntity.getName())) {
progressBar.setVisibility(View.VISIBLE);
} else {
@ -124,7 +135,7 @@ public class BindingAdapters {
case DOWNLOADING_PLUGIN:
case DOWNLOADING_NORMAL:
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().get(0).getUrl(), entrance);
gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl(), entrance);
v.getContext().startActivity(intent);
break;
case NONE:
@ -156,7 +167,6 @@ public class BindingAdapters {
builder.addHandler(new BrowserInstallHandler());
builder.addHandler(new PackageCheckHandler());
builder.addHandler(new DownloadDialogHelperHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
builder.addHandler(new LandPageAddressHandler());
builder.addHandler(new OverseaDownloadHandler());
@ -185,7 +195,6 @@ public class BindingAdapters {
DownloadChainBuilder builder = new DownloadChainBuilder();
builder.addHandler(new UnsupportedFeatureHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
@ -212,7 +221,7 @@ public class BindingAdapters {
if (gameEntity.getApk().size() == 1) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
@ -272,7 +281,7 @@ public class BindingAdapters {
case RESERVABLE:
GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> {
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), gameEntity.getName(), () -> {
ReservationHelper.reserve(v.getContext(), gameEntity, sourceEntrance, () -> {
LogUtils.logReservation(gameEntity, traceEvent);
updateReservation(progressBar, gameEntity);
});
@ -450,9 +459,9 @@ public class BindingAdapters {
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
}
String buttonText = progressBar.getText();
ApkEntity apkEntity = gameEntity.getApk().get(0);
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
if (TextUtils.isEmpty(msg)) {
ApkEntity apkEntity = CollectionsKt.firstOrNull(gameEntity.getApk());
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity == null ? "" : apkEntity.getSize());
if (apkEntity != null && TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(progressBar.getContext(),
apkEntity,
gameEntity,
@ -540,11 +549,10 @@ public class BindingAdapters {
}
}
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform) {
String gameName;
if (isShowPlatform && game.getApk().size() > 0) {
gameName = String.format("%s - %s", !isShowSuffix ? game.getNameWithoutSuffix() : game.getName(),
gameName = String.format("%s - %s", game.getName(),
PlatformUtils.getInstance(view.getContext()).getPlatformName(
game.getApk().get(0).getPlatform()));
if (!gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
@ -552,7 +560,7 @@ public class BindingAdapters {
view.setTag(R.string.tag_game_name_id, gameName);
}
} else {
gameName = !isShowSuffix ? game.getNameWithoutSuffix() : game.getName();
gameName = game.getName();
if (gameName != null && !gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
view.setText(gameName);
view.setTag(R.string.tag_game_name_id, gameName);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -125,7 +125,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
requireContext(),
0,
(link.title ?: "").length,
R.color.theme_font,
R.color.text_theme,
true
) {
LogUtils.uploadPackageCheck(
@ -391,10 +391,10 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
if (isAllInstalled) {
holder.binding.statusTv.text = "已安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font))
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme))
} else {
holder.binding.statusTv.text = "未安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.theme_red))
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.secondary_red))
}
holder.binding.statusTv.visibility = View.VISIBLE
} else {

View File

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

View File

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

View File

@ -27,7 +27,7 @@ object ExposureUtils {
): ExposureEvent {
val gameEntity = entity.copy()
gameEntity.id = if (entity.id.contains(DownloadEntity.GAME_ID_DIVIDER)) {
entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray()[0]
entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray().firstOrNull() ?: ""
} 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 = 13,
version = 14,
exportSchema = false
)
@TypeConverters(
@ -41,7 +41,8 @@ import com.halo.assistant.HaloApp
SimpleGameListConverter::class,
TagInfoListConverter::class,
ActivityLabelListConverter::class,
IconFloatConverter::class
IconFloatConverter::class,
SectionConverter::class
)
abstract class HistoryDatabase : RoomDatabase() {
@ -143,6 +144,14 @@ 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,
@ -160,6 +169,7 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_10_11)
.addMigrations(MIGRATION_11_12)
.addMigrations(MIGRATION_12_13)
.addMigrations(MIGRATION_13_14)
.build()
}
}

View File

@ -6,11 +6,7 @@ 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.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.feature.entity.*
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
@ -75,7 +71,6 @@ object HistoryHelper {
historyGame.iconFloat = gameEntity.iconFloat
historyGame.name = gameEntity.name
historyGame.tagStyle = gameEntity.tagStyle
historyGame.tag = gameEntity.getTag()
historyGame.subtitle = gameEntity.subtitle
historyGame.subtitleStyle = gameEntity.subtitleStyle
return historyGame
@ -109,7 +104,7 @@ object HistoryHelper {
fun deleteArticleEntity(articleId: String) {
runOnIoThread {
tryCatchInRelease {
HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(id = articleId))
HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(_id = articleId))
}
}
}
@ -170,6 +165,9 @@ 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

@ -0,0 +1,10 @@
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

@ -0,0 +1,10 @@
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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -82,4 +82,8 @@ class AppProviderImpl : IAppProvider {
override fun getIsBrandNewInstall(): Boolean {
return HaloApp.getInstance().isBrandNewInstall
}
override fun setSkippingThirdParty(isSkippingThirdParty: Boolean) {
HaloApp.getInstance().isSkippingThirdParty = isSkippingThirdParty
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -22,34 +22,6 @@ 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)
}
@ -83,39 +55,20 @@ class DirectProviderImpl : IDirectProvider {
articleId: String?,
communityId: String?,
entrance: String?,
path: String?
path: String?,
sourceEntrance: String
) {
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path)
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path, sourceEntrance)
}
override fun directToVideoDetail(context: Context, videoId: String, entrance: String?, path: String?) {
DirectUtils.directToVideoDetail(context, videoId, entrance, path)
override fun directToVideoDetail(context: Context, videoId: String, entrance: String?, path: String?, sourceEntrance: String) {
DirectUtils.directToVideoDetail(context, videoId, entrance, path, sourceEntrance)
}
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,6 +9,7 @@ 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
@ -29,6 +30,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
var gameSchemaType = ""
var packageName = ""
var exposureSourceList: List<ExposureSource>? = null
var customPageTrackData: CustomPageTrackData? = null
val boundedObject = downloadButton.getObject()
@ -55,6 +57,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
gameSchemaType = boundedObject.gameBitChinese
packageName = boundedObject.getUniquePackageName() ?: ""
exposureSourceList = boundedObject.exposureEvent?.source
customPageTrackData = boundedObject.customPageTrackData
}
is GameUpdateEntity -> {
@ -80,11 +83,13 @@ 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(
@ -98,7 +103,8 @@ 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) ?: ""
@ -111,6 +117,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
}
// 上报神策点击事件
val customPageKV = customPageTrackData?.toKV() ?: arrayOf()
SensorsBridge.trackEventWithExposureSource(
"DownLoadbuttonClick",
exposureSourceList,
@ -127,6 +134,7 @@ 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

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

View File

@ -6,11 +6,12 @@ import com.alibaba.android.arouter.facade.annotation.Route
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(context: Context): String? {
return PackageUtils.obtainProcessName(context)
override fun obtainProcessName(): String? {
return ProcessUtil.getCurrentProcessName()
}
override fun getGhVersionName(): String {

View File

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

View File

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

View File

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

View File

@ -20,15 +20,14 @@ 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
@ -395,7 +394,7 @@ class SimulatorDownloadManager private constructor() {
ToastUtils.showToast("该模拟器暂未提供下载")
},
uiModificationCallback = { binding ->
binding.confirmTv.setTextColor(R.color.text_body.toColor(context))
binding.confirmTv.setTextColor(R.color.text_instance.toColor(context))
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
@ -420,7 +419,7 @@ class SimulatorDownloadManager private constructor() {
DownloadStatus.diskioerror,
DownloadStatus.diskisfull -> {
DownloadManager.getInstance().addObserver(dataWatcher)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, true) }, 200)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, false) }, 200)
SensorsBridge.trackSimulatorDownloadDialogShow(
gameId = gameId,
gameName = gameName,

View File

@ -8,7 +8,6 @@ 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
@ -24,13 +23,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
@ -39,7 +38,6 @@ import okhttp3.ResponseBody
import org.json.JSONArray
import java.io.ByteArrayOutputStream
import java.io.File
import java.util.*
object SimulatorGameManager {
@ -185,8 +183,8 @@ object SimulatorGameManager {
val intent = Intent()
intent.data = Uri.fromFile(File(downloadEntity.path))
if (gameEntity.simulatorType == "FBA" || gameEntity.simulatorType == "FBN") {
val apkEntity = gameEntity.getApk()[0]
intent.putExtra("rom_name", apkEntity.packageName)
val apkEntity = gameEntity.getApk().firstOrNull()
intent.putExtra("rom_name", apkEntity?.packageName ?: "")
}
intent.putExtra("default_path", downloadEntity.path.substring(0, downloadEntity.path.lastIndexOf('/')))
intent.putExtra("game_type", gameEntity.simulatorType)

View File

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

View File

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

View File

@ -1,17 +1,11 @@
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;
@ -28,15 +22,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();
@ -44,16 +38,16 @@ public class CheckLoginUtils {
}
}
private static void startQuickLogin(Context context, String entrance) {
// 需要确保传入的 context 不为 application
if (!(context instanceof Activity)) {
context = CurrentActivityHolder.getCurrentActivity();
}
if (context != null) {
QuickLoginHelper.startLogin(context, entrance);
}
}
// private static void startQuickLogin(Context context, String entrance) {
// // 需要确保传入的 context 不为 application
// if (!(context instanceof Activity)) {
// context = CurrentActivityHolder.getCurrentActivity();
// }
//
// if (context != null) {
// QuickLoginHelper.startLogin(context, entrance);
// }
// }
public static void checkLogin(final Context context, Bundle nextToBundle, boolean isTriggerNextStep, String entrance, OnLoginListener listener) {
if (!isLogin()) {

View File

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

View File

@ -18,7 +18,6 @@ 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;
@ -125,17 +124,8 @@ public class DataUtils {
HaloApp.getInstance().setGid(gid);
SensorsBridge.setGid(gid);
// 更新广告配置
ExtensionsKt.doOnMainProcessOnly(HaloApp.getInstance(), () -> {
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
});
// 避免重复调用
if (!TextUtils.isEmpty(gid)) {
GameSubstituteRepositoryHelper.updateSubstitutableGames();
}
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
getDeviceCertification(gid);
@ -155,7 +145,8 @@ public class DataUtils {
@Override
public void onFailure(String s) {
MtaHelper.onEventWithBasicDeviceInfo("开发辅助", "GID 获取异常", s);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
}
});
}
@ -180,9 +171,11 @@ 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);
@ -196,12 +189,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);
}
EventBus.getDefault().post(new EBReuse(Constants.EB_REALNAME_RESULT));
RealNameHelper.INSTANCE.onRealNameInfoUpdated();
// new GhContentProvider().localInsert( HaloApp.getInstance().getApplication(),values);
try {
// Unknown URL content://com.gh.gamecenter.provider/certification
// TODO 将 com.gh.gamecenter 改成 BuildConfig.ApplicationID

View File

@ -0,0 +1,80 @@
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,9 +12,6 @@ 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;
@ -22,6 +19,9 @@ 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().get(0).getSize();
String size = viewHolder.getGameEntity().getApk().isEmpty() ? "" : viewHolder.getGameEntity().getApk().get(0).getSize();
if (size != null) {
String sizeWithoutDigit = size.replaceAll("(?<=\\d)\\.[0-9]+(?!\\d)", "");
viewHolder.getLocalDownloadSizeTv().setText(sizeWithoutDigit);
@ -367,8 +367,7 @@ public class DetailDownloadUtils {
String downloadAddWord = gameEntity.getDownloadAddWord();
// 不满足条件的部分游戏隐藏下载按钮
if (Config.isShowDownload(gameEntity.getId())
&& !"光环助手".equals(gameEntity.getName())) {
if (!"光环助手".equals(gameEntity.getName())) {
viewHolder.getDownloadBottom().setVisibility(View.VISIBLE);
} else {
viewHolder.getDownloadBottom().setVisibility(View.GONE);
@ -443,7 +442,7 @@ public class DetailDownloadUtils {
}
private static String getDownloadSizeText(DetailViewHolder viewHolder) {
return String.format("%s", viewHolder.getGameEntity().getApk().get(0).getSize());
return String.format("%s", viewHolder.getGameEntity().getApk().isEmpty() ? "" : viewHolder.getGameEntity().getApk().get(0).getSize());
}
private static void updateVStyleDownloadButton(DetailViewHolder viewHolder,
@ -458,8 +457,7 @@ public class DetailDownloadUtils {
break;
case waiting:
downloadButton.setText(R.string.waiting);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
downloadButton.setVisibility(View.GONE);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.WAITING);
break;
case overflow:
case timeout:

View File

@ -1,23 +1,17 @@
package com.gh.common.util
import android.content.Context
import android.os.Environment
import android.preference.PreferenceManager
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.constant.Constants
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
@ -39,99 +33,29 @@ object DeviceTokenUtils {
}
@JvmStatic
fun getLaunchType(readOnly: Boolean = false): LunchType {
fun getLaunchType(): LunchType {
var lunchType: LunchType? = null
val values = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().application).all
// 版本更新
if (values.isNotEmpty()) {
for (value in values) {
if (value.key.contains("isNewFirstLaunchV")) {
if (value.key.contains(Constants.SP_NEW_FIRST_LAUNCH_VERSION)) {
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,
AGAIN
UPDATE
}

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
@ -12,16 +11,9 @@ import android.net.Uri;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -34,12 +26,9 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.constant.Config;
import com.gh.common.filter.RegionSetting;
@ -47,11 +36,9 @@ import com.gh.common.xapk.XapkDialogHelper;
import com.gh.gamecenter.R;
import com.gh.gamecenter.ShellActivity;
import com.gh.gamecenter.adapter.ReportReasonAdapter;
import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder;
import com.gh.gamecenter.common.base.TrackableDialog;
import com.gh.gamecenter.common.callback.CancelListener;
import com.gh.gamecenter.common.callback.ConfirmListener;
import com.gh.gamecenter.common.callback.SimpleCallback;
import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding;
import com.gh.gamecenter.common.entity.SimpleGameEntity;
import com.gh.gamecenter.common.entity.SuggestType;
@ -60,9 +47,7 @@ import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.common.view.CustomLinkMovementMethod;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.common.view.FixLinearLayoutManager;
import com.gh.gamecenter.common.view.MaxHeightLinearLayout;
import com.gh.gamecenter.common.view.MaxHeightNestedScrollView;
import com.gh.gamecenter.common.view.VerticalItemDecoration;
@ -80,10 +65,7 @@ import com.gh.gamecenter.databinding.DialogRelievePhoneBinding;
import com.gh.gamecenter.databinding.DialogReportReasonBinding;
import com.gh.gamecenter.databinding.DialogWechatReserveSuccessBinding;
import com.gh.gamecenter.databinding.ImprintContentItemBinding;
import com.gh.gamecenter.databinding.PrivacyItemBinding;
import com.gh.gamecenter.entity.BadgeEntity;
import com.gh.gamecenter.entity.PermissionsEntity;
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
import com.gh.gamecenter.entity.TrackableEntity;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.Badge;
@ -91,7 +73,6 @@ import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.help.HelpAndFeedbackBridge;
import com.gh.gamecenter.setting.SettingBridge;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Util_System_Keyboard;
@ -101,6 +82,7 @@ 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 {
@ -328,180 +310,7 @@ public class DialogUtils {
return dialog;
}
public static void showPrivacyPolicyDialog(Context context,
@NonNull PrivacyPolicyEntity entity,
SimpleCallback<Boolean> callback) {
final Context activityContext = checkDialogContext(context);
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
AtomicBoolean isCanceledByClickOutsideOfDialog = new AtomicBoolean(true);
final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_privacy_policy, null);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawableResource(android.R.color.transparent);
WindowManager.LayoutParams params = window.getAttributes();
params.horizontalMargin = 0;
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
// int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
// int maxHeight = DisplayUtils.dip2px(446);
// if (height > maxHeight) {
// params.height = maxHeight;
// } else {
// params.height = height;
// }
window.setAttributes(params);
}
TextView title = contentView.findViewById(R.id.title);
TextView bottomContent = contentView.findViewById(R.id.bottom_content);
TextView topContent = contentView.findViewById(R.id.top_content);
TextView allowButton = contentView.findViewById(R.id.allow_button);
TextView disallowButton = contentView.findViewById(R.id.disallow_button);
TextView linkContent = contentView.findViewById(R.id.link_content);
RecyclerView permissions = contentView.findViewById(R.id.permissions_content);
permissions.setLayoutManager(new FixLinearLayoutManager(context));
permissions.setAdapter(new BaseRecyclerAdapter(context) {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.privacy_item, parent, false);
return new PrivacyPolicyItemViewHolder(PrivacyItemBinding.bind(view));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof PrivacyPolicyItemViewHolder) {
PrivacyPolicyItemViewHolder viewHolder = (PrivacyPolicyItemViewHolder) holder;
PrivacyItemBinding binding = viewHolder.getBinding();
final PermissionsEntity permissionsEntity = entity.getPermissions().get(position);
ImageUtils.display(binding.icon, permissionsEntity.getIcon());
binding.name.setText(permissionsEntity.getName());
binding.intro.setText(permissionsEntity.getIntro());
GenericDraweeHierarchy hierarchy = binding.icon.getHierarchy();
if (hierarchy != null) {
if (position == 0) {
hierarchy.setPlaceholderImage(R.drawable.permission_storage);
} else if (position == 1) {
hierarchy.setPlaceholderImage(R.drawable.permission_phone_state);
}
}
}
}
@Override
public int getItemCount() {
return entity.getPermissions().size();
}
});
SpannableStringBuilder skipText = new SpannableStringBuilder("查看完整版的隐私政策和用户协议");
skipText.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
ds.setUnderlineText(false);
}
@Override
public void onClick(@NonNull View widget) {
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击隐私政策");
DirectUtils.directToExternalBrowser(context, context.getString(R.string.privacy_policy_url));
}
}, skipText.length() - 9, skipText.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
skipText.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
ds.setUnderlineText(false);
}
@Override
public void onClick(@NonNull View widget) {
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击用户协议");
DirectUtils.directToExternalBrowser(context, context.getString(R.string.disclaimer_url));
}
}, skipText.length() - 4, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
/*skipText.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
ds.setUnderlineText(false);
}
@Override
public void onClick(@NonNull View widget) {
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击第三方SDK接入说明");
activityContext.startActivity(WebActivity.getThirdPartySdkStatementIntent(activityContext));
}
}, skipText.length() - 10, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);*/
title.setText(entity.getTitle());
linkContent.setText(skipText);
linkContent.setMovementMethod(LinkMovementMethod.getInstance());
topContent.setText(entity.getTopContent());
bottomContent.setText(ExtensionsKt.fromHtml(entity.getBottomContent()));
bottomContent.setMovementMethod(CustomLinkMovementMethod.getInstance());
// Remove underline
Spannable sa = (Spannable) bottomContent.getText();
for (URLSpan u : sa.getSpans(0, sa.length(), URLSpan.class)) {
sa.setSpan(new UnderlineSpan() {
public void updateDrawState(TextPaint tp) {
tp.setUnderlineText(false);
}
}, sa.getSpanStart(u), sa.getSpanEnd(u), 0);
}
allowButton.setOnClickListener(view -> {
dialog.dismiss();
callback.onCallback(true);
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
});
disallowButton.setOnClickListener(v -> {
dialog.dismiss();
callback.onCallback(false);
// showPrivacyPolicyDisallowDialog(activityContext, entity, callback);
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
});
dialog.setOnCancelListener(cd -> {
if (isCanceledByClickOutsideOfDialog.get()) {
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
}
});
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
isCanceledByClickOutsideOfDialog.set(false);
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
}
return false;
});
// 用户未同意隐私策略不应该触发 MTA 事件
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
try {
dialog.setCancelable(false);
dialog.show();
} catch (Exception ignored) {
}
}
public static void showPrivacyPolicyDisallowDialog(Context context,
@NonNull PrivacyPolicyEntity entity,
EmptyCallback callback) {
final Context activityContext = checkDialogContext(context);
@ -547,8 +356,8 @@ public class DialogUtils {
TextView negativeTv = contentView.findViewById(R.id.negative);
TextView positiveTv = contentView.findViewById(R.id.positive);
TextView content = contentView.findViewById(R.id.content);
positiveTv.setBackground(DrawableView.getOvalDrawable(R.color.background, 999));
negativeTv.setBackground(DrawableView.getOvalDrawable(R.color.theme, 999));
positiveTv.setBackground(DrawableView.getOvalDrawable(R.color.ui_background, 999));
negativeTv.setBackground(DrawableView.getOvalDrawable(R.color.primary_theme, 999));
content.setText(Html.fromHtml(context.getString(R.string.video_upload_draft_dialog_content)));
negativeTv.setOnClickListener(view -> {
@ -770,11 +579,15 @@ public class DialogUtils {
dialog.dismiss();
});
ApkEntity apkEntity = CollectionsKt.firstOrNull(gameEntity.getApk());
String size = apkEntity == null ? "" : apkEntity.getSize();
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
if (apkEntity != null) {
apkEntity.setUrl(gameEntity.getOverseasAddressDialog().getLink());
}
}
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
binding.downloadBtn.setText("下载(" + size + "");
binding.downloadBtn.setOnClickListener(v -> {
dismissByTouchInside.set(true);
SensorsBridge.trackOverseasAddressDialogClick(
@ -823,7 +636,12 @@ public class DialogUtils {
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
binding.urlTv.setText(gameEntity.getLandPageAddressDialog().getLink());
binding.downloadBtn.setText(context.getString(R.string.dialog_land_page_address_confirm));
String downloadText = gameEntity.isLandPageAddressDialogShowOnly()
? "下载(" + gameEntity.getApk().get(0).getSize() + ""
: context.getString(R.string.dialog_land_page_address_confirm);
binding.downloadBtn.setText(downloadText);
binding.downloadBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
@ -1251,10 +1069,10 @@ public class DialogUtils {
DialogPackageParseErrorBinding binding = DialogPackageParseErrorBinding.inflate(LayoutInflater.from(context), null, false);
Context finalContext = context;
SpannableStringBuilder builder = new SpanBuilder("您也可以点击提交反馈跟我们联系").click(context, 6, 10, R.color.theme_font, true, new Function0<Unit>() {
SpannableStringBuilder builder = new SpanBuilder("您也可以点击提交反馈跟我们联系").click(context, 6, 10, R.color.text_theme, true, new Function0<Unit>() {
@Override
public Unit invoke() {
SimpleGameEntity entity = new SimpleGameEntity(gameId, gameName, "");
SimpleGameEntity entity = new SimpleGameEntity(gameId, gameName, "", "");
HelpAndFeedbackBridge.startSuggestionActivity(finalContext, SuggestType.GAME, "notfound", "模拟器安装包解析错误", entity);
dialog.dismiss();
return null;
@ -1310,7 +1128,7 @@ public class DialogUtils {
return null;
});
binding.reasonRv.setLayoutManager(new LinearLayoutManager(context));
binding.reasonRv.addItemDecoration(new VerticalItemDecoration(context, 1F, false, R.color.background));
binding.reasonRv.addItemDecoration(new VerticalItemDecoration(context, 1F, false, R.color.ui_background));
binding.reasonRv.setAdapter(reportReasonAdapter);
binding.negativeBtn.setOnClickListener(v -> {
@ -1332,7 +1150,7 @@ public class DialogUtils {
ExtensionsKt.setTextChangedListener(binding.otherReasonEt, (s, start, before, count) -> {
int tvCount = s.length();
if (tvCount >= 500) {
binding.tvCount.setTextColor(ContextCompat.getColor(finalContext, R.color.theme_red));
binding.tvCount.setTextColor(ContextCompat.getColor(finalContext, R.color.secondary_red));
}
binding.tvCount.setText(tvCount + "/500");
return null;

View File

@ -33,29 +33,22 @@ 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.GameCollectionListEntity
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.GameDetailServer
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.LibaoEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.provider.IConcernInfoProvider
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.forum.home.CommunityHomeFragment
import com.gh.gamecenter.forum.home.CommunityActivity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailActivity
import com.gh.gamecenter.game.upload.GameSubmissionActivity
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
@ -68,7 +61,9 @@ import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersSubscribedGameListActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.libao.LibaoDetailActivity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.gh.gamecenter.personalhome.UserHomeActivity
import com.gh.gamecenter.personalhome.background.PersonalityBackgroundActivity
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
@ -88,19 +83,20 @@ import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity
import com.gh.gamecenter.setting.SettingBridge
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.tag.TagsActivity
import com.gh.gamecenter.toolbox.ToolBoxBlockActivity
import com.gh.gamecenter.toolbox.ToolBoxActivity
import com.gh.gamecenter.video.data.VideoDataActivity
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.gh.gamecenter.video.game.GameVideoActivity
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.gh.gamecenter.wrapper.MainWrapperRepository
import com.gh.gamecenter.wrapper.ToolbarWrapperActivity
import com.gh.vspace.VDownloadManagerActivity
import com.halo.assistant.HaloApp
import com.halo.assistant.fragment.WebFragment
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException
import java.net.URLEncoder
import java.util.*
@ -112,8 +108,8 @@ import kotlin.math.roundToInt
object DirectUtils {
@JvmStatic
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
directToLinkPage(context, linkEntity, entrance, path, null)
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String, sourceEntrance: String = "") {
directToLinkPage(context, linkEntity, entrance, path, null, sourceEntrance)
}
@JvmStatic
@ -122,9 +118,10 @@ object DirectUtils {
linkEntity: LinkEntity,
entrance: String,
path: String,
exposureEvent: ExposureEvent? = null
exposureEvent: ExposureEvent? = null,
sourceEntrance: String = ""
) {
directToLinkPage(context, linkEntity, entrance, path, exposureEvent, null)
directToLinkPage(context, linkEntity, entrance, path, exposureEvent, null, sourceEntrance)
}
// 用于判断是否已经对接相关类型
@ -159,7 +156,21 @@ object DirectUtils {
"explore_column",
"game_explore",
"column_test_v2",
"game_list_collection"
"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"
)
fun directToLinkPage(
@ -169,6 +180,7 @@ object DirectUtils {
path: String,
exposureEvent: ExposureEvent? = null,
unknownCallback: (() -> Unit)?,
sourceEntrance: String = ""
) {
when (linkEntity.type) {
"article", "news", "文章" -> {
@ -183,6 +195,7 @@ object DirectUtils {
if (exposureEvent != null) {
directToGameDetail(
context, linkEntity.link
?: "", linkEntity.text
?: "", BaseActivity.mergeEntranceAndPath(entrance, path), traceEvent = exposureEvent
)
} else {
@ -203,7 +216,7 @@ object DirectUtils {
"question", "社区问题" -> directToQuestionDetail(
context, linkEntity.link
?: "", entrance, path
?: "", entrance, path, sourceEntrance
)
"answer", "社区回答" -> directToAnswerDetail(context, linkEntity.link ?: "", entrance, path)
@ -218,7 +231,8 @@ object DirectUtils {
linkEntity.community!!,
linkEntity.link!!,
entrance,
path
path,
sourceEntrance,
)
"community_column", "社区专题" -> directToCommunityColumn(
@ -296,6 +310,7 @@ object DirectUtils {
"",
linkEntity.blockId,
linkEntity.blockName,
"",
exposureEvent
)
@ -305,12 +320,21 @@ object DirectUtils {
"wechat_bind" -> context.startActivity(WebActivity.getBindWechatIntent(context))
"video", "bbs_video", "video_stream", "视频" -> directToVideoDetail(
"video", "bbs_video", "视频" -> directToVideoDetail(
context,
videoId = linkEntity.link!!,
fromLocation = VideoDetailContainerViewModel.Location.VIDEO_CHOICENESS.value,
entrance = entrance,
path = path
path = path,
sourceEntrance = sourceEntrance
)
"video_stream" -> directToLegacyVideoDetail(
context,
"",
VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value,
referer = "视频流-$entrance",
isHomeVideo = true
)
"game_video" -> directToGameVideo(context, linkEntity.link ?: "", entrance, path)
@ -321,6 +345,8 @@ object DirectUtils {
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa_list" -> directToHelpAndFeedback(context)
"qa_collection", "Q&A合集" -> directToQaCollection(
context, linkEntity.text
?: "", linkEntity.link
@ -381,17 +407,17 @@ object DirectUtils {
"setting" -> context.startActivity(SettingBridge.getSettingIntent(context, false, entrance))
"index_page" -> directToHomeTab(context)
"index_page" -> directToHomeDefaultTab(context)
"video_upload" -> context.startActivity(VideoManagerActivity.getIntent(context, "", entrance))
"bbs" -> directToForum(context)
"bbs", "community_home" -> directToHomeCommunityTab(context)
"user_page" -> directToHomeActivity(context, UserManager.getInstance().userId, "", entrance)
"video_tab" -> directToVideoTab(context)
"video_tab" -> directToHomeVideoTab(context)
"toolkit" -> context.startActivity(ToolBoxBlockActivity.getIntent(context, entrance))
"toolkit" -> context.startActivity(ToolBoxActivity.getIntent(context, entrance))
"column_test" -> context.startActivity(
GameServerTestActivity.getIntent(
@ -412,7 +438,7 @@ object DirectUtils {
} ?: ""
}
"halo_tab" -> directToPersonalTab(context)
"halo_tab" -> directToHomeMyHaloTab(context)
"common_collection" -> directToCommonCollectionDetail(
context,
@ -451,6 +477,29 @@ 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 ?: "",
@ -459,6 +508,34 @@ object DirectUtils {
entrance
)
"multi_tab_nav" -> context.startActivity(
ToolbarWrapperActivity.getMultiTabNavIntent(
context,
linkEntity.link ?: "",
linkEntity.text ?: ""
)
)
"custom_page" -> context.startActivity(
ToolbarWrapperActivity.getCustomPageIntent(
context,
linkEntity.link ?: "",
linkEntity.text ?: ""
)
)
// 选中首页底部 tab
"bottom_tab" -> {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
}
context.startActivity(intent)
if (linkEntity is LaunchRedirect) {
MainWrapperRepository.getInstance().sendSelectTabEvent(linkEntity)
}
}
"" -> {
// do nothing
}
@ -513,7 +590,9 @@ object DirectUtils {
columnName: String = "",
blockId: String = "",
blockName: String = "",
exposureEvent: ExposureEvent? = null
style: String = "",
exposureEvent: ExposureEvent? = null,
showSubjectTab: Boolean = false
) {
if (id.isEmpty()) return
val bundle = Bundle()
@ -523,7 +602,9 @@ object DirectUtils {
bundle.putString(KEY_COLUMNNAME, columnName)
bundle.putString(KEY_BLOCK_ID, blockId)
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putString(KEY_COLUMN_COLLECTION_STYLE, style)
bundle.putInt(KEY_POSITION, position)
bundle.putBoolean(KEY_SHOW_SUBJECT_TAB, showSubjectTab)
if (exposureEvent != null) {
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source))
}
@ -578,7 +659,7 @@ object DirectUtils {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.name)
bundle.putString(KEY_NEWSID, id)
if (entrance?.contains("隐私政策") == true) {
bundle.putBoolean(KEY_HIDE_USELESS_INFO, true)
@ -594,7 +675,7 @@ object DirectUtils {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.name)
bundle.putString(KEY_NEWSID, id)
bundle.putBoolean(KEY_HIDE_USELESS_INFO, hideUselessInfo)
jumpActivity(context, bundle)
@ -673,6 +754,7 @@ object DirectUtils {
fun directToGameDetail(
context: Context,
id: String,
name: String = "",
entrance: String? = null,
autoDownload: Boolean? = null,
tab: String? = "",
@ -692,7 +774,7 @@ object DirectUtils {
}
}
if (traceEvent != null) {
val clickEvent = createEvent(GameEntity(id), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK)
val clickEvent = createEvent(GameEntity(id = id, name = name), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK)
log(clickEvent)
bundle.putParcelable(KEY_TRACE_EVENT, clickEvent)
}
@ -846,6 +928,31 @@ object DirectUtils {
jumpActivity(context, bundle)
}
@JvmStatic
fun directToDownloadManager(
context: Context,
entrance: String = "",
bottomTab: String = "",
gameColumnId: String = "",
gameColumnName: String = "",
customPageId: String = "",
customPageName: String = "",
multiTabId: String = "",
multiTabName: String = ""
) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_TO, DownloadManagerActivity.TAG)
bundle.putString(KEY_BOTTOM_TAB_NAME, bottomTab)
bundle.putString(KEY_GAME_COLUMN_ID, gameColumnId)
bundle.putString(KEY_GAME_COLUMN_NAME, gameColumnName)
bundle.putString(KEY_CUSTOM_PAGE_ID, customPageId)
bundle.putString(KEY_CUSTOM_PAGE_NAME, customPageName)
bundle.putString(KEY_MULTI_TAB_NAV_ID, multiTabId)
bundle.putString(KEY_MULTI_TAB_NAV_NAME, multiTabName)
jumpActivity(context, bundle)
}
@JvmStatic
fun directToDownloadManagerAndStartUpdate(
context: Context,
@ -866,7 +973,7 @@ object DirectUtils {
fun directToToolbox(context: Context, gameId: String, toolboxUrl: String, entrance: String = ENTRANCE_BROWSER) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_TO, ToolBoxBlockActivity::class.java.name)
bundle.putString(KEY_TO, ToolBoxActivity::class.java.name)
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_URL, toolboxUrl)
jumpActivity(context, bundle)
@ -884,13 +991,14 @@ object DirectUtils {
}
@JvmStatic
fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null, sourceEntrance: String = "") {
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)
}
@ -920,9 +1028,9 @@ object DirectUtils {
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(browserIntent)
} catch (e: ActivityNotFoundException) {
} catch (e: Exception) {
e.printStackTrace()
Utils.toast(context, "跳转地址无效")
url.copyTextAndToast(context.getString(R.string.direct_to_external_browser_failed_toast))
}
}
@ -989,12 +1097,7 @@ object DirectUtils {
@JvmStatic
fun directToGiftDetail(context: Context, giftId: String, entrance: String? = null) {
if (giftId.isEmpty()) return
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)
context.startActivity(LibaoDetailActivity.getIntentById(context, giftId, entrance))
}
/**
@ -1011,21 +1114,7 @@ object DirectUtils {
*/
@JvmStatic
fun directToCommunity(context: Context, community: CommunityEntity?) {
// if (MainActivity::class.java.name != RunningUtils.getTopActivity(context)) {
// val intent = Intent(context, MainActivity::class.java)
// intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
// context.startActivity(intent)
//
// UserManager.getInstance().setCommunityData(community)
//
// // 这里换个线程操作是为了做一点延时
// AppExecutor.ioExecutor.execute {
// EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
// EventBus.getDefault().post(EBReuse(CommunityFragment.EB_RETRY_PAGE))
// }
// } else {
directForumDetail(context, community?.id)
// }
}
@JvmStatic
@ -1034,13 +1123,15 @@ object DirectUtils {
articleId: String?,
communityId: String?,
entrance: String?,
path: String?
path: String?,
sourceEntrance: 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)
}
@ -1051,7 +1142,8 @@ object DirectUtils {
community: CommunityEntity?,
articleId: String?,
entrance: String?,
path: String?
path: String?,
sourceEntrance: String = "",
) {
if (articleId.isNullOrEmpty()) return
val bundle = Bundle()
@ -1059,6 +1151,7 @@ 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)
}
@ -1088,7 +1181,8 @@ object DirectUtils {
fun directToVideoDetail(
context: Context, videoId: String,
entrance: String? = null,
path: String? = ""
path: String? = "",
sourceEntrance: String = ""
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
@ -1096,6 +1190,7 @@ 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)
@ -1121,7 +1216,8 @@ object DirectUtils {
paginationType: String = "",
fieldId: String = "",
sectionName: String = "",
isHomeVideo: Boolean = false
isHomeVideo: Boolean = false,
sourceEntrance: String = ""
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
@ -1140,6 +1236,7 @@ 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)
@ -1155,9 +1252,10 @@ object DirectUtils {
gameId: String = "",
entrance: String? = null,
path: String? = "",
referer: String = ""
referer: String = "",
sourceEntrance: String = ""
) {
directToVideoDetail(context, videoId, entrance, path)
directToVideoDetail(context, videoId, entrance, path, sourceEntrance)
}
/**
@ -1458,85 +1556,61 @@ object DirectUtils {
}
/**
* 到首页-首页 tab
* 到首页-默认选中的 tab
*/
@JvmStatic
fun directToHomeTab(context: Context) {
fun directToHomeDefaultTab(context: Context) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_HOME))
}
MainWrapperRepository.getInstance().sendReSelectDefaultTabEvent()
} else {
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_HOME) })
jumpActivity(context, Bundle())
}
}
/**
* 到首页-论坛 tab
* @param position 论坛的子 tab 位置
* 到首页-社区 tab
* @param position 社区子 tab 位置
*/
@JvmStatic
fun directToForum(context: Context, position: Int = 0) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
EventBus.getDefault().post(EBSkip(CommunityHomeFragment.EB_TAB, position))
}
} else {
jumpActivity(context, Bundle().apply {
putInt(KEY_POSITION, MainWrapperFragment.INDEX_BBS)
putInt(KEY_SUB_POSITION, position)
})
}
fun directToHomeCommunityTab(context: Context) {
val bundle = Bundle()
bundle.putString(KEY_TO, CommunityActivity::class.java.name)
jumpActivity(context, bundle)
}
/**
* 到首页-视频 tab
*/
@JvmStatic
fun directToVideoTab(context: Context) {
fun directToHomeVideoTab(context: Context) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_VIDEO))
}
} else {
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_VIDEO) })
jumpActivity(context, Bundle())
}
MainWrapperRepository.getInstance().sendSelectTabEvent(ViewPagerFragmentHelper.TYPE_VIDEO_STREAM)
}
/**
* 到首页-我的光环 tab
*/
@JvmStatic
fun directToPersonalTab(context: Context) {
fun directToHomeMyHaloTab(context: Context) {
if (HaloApp.getInstance().isRunningForeground) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
// 这里换个线程操作是为了做一点延时
runOnIoThread {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_PERSONAL))
}
} else {
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_PERSONAL) })
jumpActivity(context, Bundle())
}
MainWrapperRepository.getInstance().sendSelectTabEvent(ViewPagerFragmentHelper.TYPE_MY_HALO)
}
/**
@ -1551,211 +1625,6 @@ 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)
}
/**
* 跳转至地址信息
@ -1835,7 +1704,7 @@ object DirectUtils {
) {
if (collectionId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, CommonCollectionDetailActivity::class.java.name)
bundle.putString(KEY_TO, CustomCommonCollectionDetailActivity::class.java.name)
bundle.putString(KEY_BLOCK_ID, blockId)
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putString(KEY_ENTRANCE, entrance)
@ -1939,7 +1808,8 @@ object DirectUtils {
fromRatingKey: Boolean = false,
diagnosis: String = "",
forceLogin: Boolean = true,
requestCode: Int? = null
requestCode: Int? = null,
isSmoothGame: Boolean = false
) {
val intent = HelpAndFeedbackBridge.getIntent(
context,
@ -1952,7 +1822,8 @@ object DirectUtils {
qaContentId,
fromRatingKey,
diagnosis,
forceLogin
forceLogin,
isSmoothGame
)
if (requestCode != null) {
(context as Activity).startActivityForResult(intent, requestCode)
@ -1971,15 +1842,35 @@ object DirectUtils {
bbsId: String,
entrance: String,
sourceEntrance: String,
forumName: String
forumName: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
) {
context.startActivity(ForumOrUserSearchActivity.getIntent(context, bbsId, entrance, sourceEntrance, forumName))
context.startActivity(
ForumOrUserSearchActivity.getIntent(
context,
bbsId,
entrance,
sourceEntrance,
forumName,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
)
}
@JvmStatic
fun directToVGameDownload(context: Context, switchToDownloadingTab: Boolean = false) {
fun directToVGameDownload(context: Context, entrance: String, switchToDownloadingTab: Boolean = false) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, ENTRANCE_BROWSER)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_TO, VDownloadManagerActivity::class.java.name)
bundle.putInt(KEY_POSITION, if (switchToDownloadingTab) 1 else 0)
jumpActivity(context, bundle)
@ -2047,9 +1938,27 @@ object DirectUtils {
fun directToQGameSearch(
context: Context,
hint: String,
sourceEntrance: String
sourceEntrance: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
) {
context.startActivity(QGameSearchActivity.getIntent(context, hint, sourceEntrance))
context.startActivity(
QGameSearchActivity.getIntent(
context,
hint,
sourceEntrance,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
)
}
@SuppressLint("CheckResult")
@ -2142,4 +2051,62 @@ object DirectUtils {
context.startActivity(ServersCalendarManagementActivity.getIntent(context))
}
}
fun directToSearch(
context: Context,
searchType: String,
searchHint: String,
entrance: String,
sourceEntrance: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
) {
when (searchType) {
BottomTab.SearchStyle.TYPE_HALO_GAME -> context.startActivity(
SearchActivity.getIntent(
context,
false,
searchHint,
entrance,
sourceEntrance,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
)
BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> directToQGameSearch(
context,
"请输入小游戏关键词",
sourceEntrance,
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
BottomTab.SearchStyle.TYPE_BBS -> directToForumOrUserSearch(
context,
"",
entrance,
sourceEntrance,
"",
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
)
}
}
}

View File

@ -6,6 +6,7 @@ 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
@ -45,7 +46,6 @@ 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?.visibility = View.VISIBLE
holder.multiVersionDownloadTv?.isVisible = !SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)
updatePluginItem(context, holder, gameEntity, briefStyle, isShowRecommendStar)
}
updateDownloadButton(
@ -219,7 +219,7 @@ object DownloadItemUtils {
pluginLocation: PluginLocation? = PluginLocation.only_game
) {
// 控制是否显示下载按钮
downloadBtn.goneIf(!Config.isShowDownload(gameEntity.id) || context.getString(R.string.app_name) == gameEntity.name)
downloadBtn.goneIf(context.getString(R.string.app_name) == gameEntity.name)
// 青少年模式或者需要特殊处理显示查看
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) || gameEntity.isSpecialDownload()) {
downloadBtn.text = "查看"
@ -443,6 +443,7 @@ 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()) {
@ -457,7 +458,6 @@ object DownloadItemUtils {
return
}
}
updateItemViewStatus(holder, briefStyle, gameEntity.columnRecommend, isShowRecommendStar)
}
// 更新插件的条目有多个apk包
@ -624,9 +624,10 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
location: String
location: String,
sourceEntrance: String = "其他"
) {
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, location, null)
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, sourceEntrance, location, null)
}
@JvmStatic
@ -637,10 +638,11 @@ 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, location, traceEvent, null)
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, sourceEntrance, location, traceEvent, null)
}
/**
@ -654,9 +656,10 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
sourceEntrance: String = "其他",
location: String,
traceEvent: ExposureEvent?,
clickCallback: EmptyCallback?
clickCallback: EmptyCallback?,
) {
setOnClickListener(
context,
@ -665,6 +668,7 @@ object DownloadItemUtils {
position,
adapter,
entrance,
sourceEntrance,
location,
traceEvent,
clickCallback,
@ -684,6 +688,7 @@ object DownloadItemUtils {
position: Int,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
entrance: String,
sourceEntrance: String = "其他",
location: String,
traceEvent: ExposureEvent?,
clickCallback: EmptyCallback?,
@ -771,31 +776,33 @@ object DownloadItemUtils {
return
}
if (gameEntity.isReservable) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
downloadBtn.setOnClickListener {
downloadBtn.setOnClickListener {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
SensorsBridge.trackEvent(
"AppointmentGame",
"game_name",
gameEntity.name ?: "",
"game_id",
gameEntity.id
gameEntity.id,
"game_type",
gameEntity.categoryChinese,
"source_entrance",
sourceEntrance
)
allStateClickCallback?.onCallback()
CheckLoginUtils.checkLogin(context, entrance) {
clickCallback?.onCallback()
ReservationHelper.reserve(
context,
gameEntity.id,
gameEntity.name ?: ""
gameEntity,
sourceEntrance
) {
LogUtils.logReservation(gameEntity, traceEvent)
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
}
}
} else {
downloadBtn.setOnClickListener {
} else {
allStateClickCallback?.onCallback()
clickCallback?.onCallback()
if ("download" == gameEntity.reserveStatus) {
@ -890,6 +897,7 @@ object DownloadItemUtils {
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese,
gameEntity.getApk().firstOrNull()?.format,
clickRunnable
)
}
@ -902,7 +910,6 @@ object DownloadItemUtils {
DownloadChainBuilder().apply {
addHandler(GamePermissionHandler())
addHandler(CheckStoragePermissionHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
}
.setProcessEndCallback { _, _ ->
@ -944,7 +951,6 @@ object DownloadItemUtils {
addHandler(BrowserInstallHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(OverseaDownloadHandler())
addHandler(LandPageAddressHandler())
addHandler(CheckDownloadHandler())
@ -963,7 +969,6 @@ object DownloadItemUtils {
addHandler(BrowserInstallHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
@ -981,7 +986,6 @@ object DownloadItemUtils {
addHandler(GamePermissionHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
@ -1000,7 +1004,6 @@ object DownloadItemUtils {
} else {
DownloadChainBuilder().apply {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback { _, isSubscribe ->
@ -1056,7 +1059,7 @@ object DownloadItemUtils {
NewSimulatorGameManager.showUpdateNewsSimulator(context, gameEntity, null)
return
}
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk()[0].url)
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().firstOrNull()?.url)
if (downloadEntity != null) {
val file = File(downloadEntity.path)
if (!file.exists()) {
@ -1122,7 +1125,7 @@ object DownloadItemUtils {
}
when (str) {
context.getString(R.string.resume) -> {
DownloadManager.getInstance().resume(downloadEntity, true)
DownloadManager.getInstance().resume(downloadEntity, false)
}
context.getString(R.string.waiting) -> {
@ -1150,7 +1153,7 @@ object DownloadItemUtils {
) {
if (gameEntity.getApk().isEmpty()) return
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
val msg = FileUtils.isCanDownload(context, gameEntity.getApk().firstOrNull()?.size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(
context,
@ -1188,7 +1191,7 @@ object DownloadItemUtils {
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
val msg = FileUtils.isCanDownload(context, gameEntity.getApk().firstOrNull()?.size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, gameEntity, false, entrance, location, isSubscribe, traceEvent)
ToastUtils.toast(gameEntity.name + "已加入下载队列")
@ -1215,7 +1218,7 @@ object DownloadItemUtils {
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder?>?,
refreshCallback: EmptyCallback?
) {
val apkEntity = gameEntity.getApk()[0]
val apkEntity = gameEntity.getApk().firstOrNull()
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity != null) {
val path = downloadEntity.path
@ -1223,7 +1226,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,6 +8,7 @@ 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
@ -17,12 +18,13 @@ 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
@ -30,7 +32,10 @@ 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.*
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
@ -171,6 +176,34 @@ 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)
@ -300,8 +333,13 @@ 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)
@ -316,7 +354,8 @@ 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(
@ -448,12 +487,20 @@ 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_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位"
"game_type", downloadEntity.categoryChinese,
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
*kvs
)
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
SensorsBridge.trackEvent(
@ -465,22 +512,32 @@ 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) {
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 "本地下载",
)
&& 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
)
}
DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")

View File

@ -13,12 +13,14 @@ 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.login.user.LoginTag
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
@ -40,8 +42,12 @@ 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>()
@ -59,7 +65,17 @@ object ErrorHelper {
return
}
handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener)
handleError(
context,
showHighPriorityHint,
errorEntity,
"",
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener,
)
}
/**
@ -71,8 +87,12 @@ object ErrorHelper {
context: Context,
errorString: String?,
showHighPriorityHint: Boolean = false,
realNameConfirmListener: ConfirmListener? = null,
entrance: String = ""
entrance: String = "",
sourceEntrance: String = "",
articleType: String = "",
verificationType: String = "内容实名",
gameEntity: GameEntity? = null,
realNameConfirmListener: ConfirmListener? = null
) {
val errorEntity = errorString?.toObject<ErrorEntity>()
@ -86,7 +106,17 @@ object ErrorHelper {
return
}
handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener, entrance)
handleError(
context,
showHighPriorityHint,
errorEntity,
entrance,
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener
)
}
/***
@ -110,8 +140,12 @@ 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,
@ -132,6 +166,7 @@ object ErrorHelper {
403057,
403068 -> handleErrorWithCommentBannedDialog(context, errorEntity)
403200,
403201,
403202 -> handleErrorWithGameCollectionBannedDialog(context, errorEntity)
@ -178,9 +213,17 @@ object ErrorHelper {
// 多设备登录同一帐号,不需要这里处理
}
403209 -> handleRealNameError(context, errorEntity, realNameConfirmListener)
403209 -> handleRealNameError(
context,
errorEntity,
sourceEntrance,
articleType,
verificationType,
gameEntity,
realNameConfirmListener,
)
403210 -> handleVerifyPhoneError(context, errorEntity, realNameConfirmListener, entrance)
403210 -> handleVerifyPhoneError(context, errorEntity, entrance, articleType, realNameConfirmListener)
// 禁言(发布内容)
403402 -> Utils.toast(context, "您的账号存在违规,不允许发布内容")
@ -208,8 +251,21 @@ object ErrorHelper {
private fun handleRealNameError(
context: Context,
errorEntity: ErrorEntity,
realNameConfirmListener: ConfirmListener?
sourceEntrance: String = "",
articleType: String = "",
verificationType: String = "内容实名",
gameEntity: GameEntity? = null,
realNameConfirmListener: ConfirmListener?,
) {
SensorsBridge.trackVerificationDialogShow(
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?:"",
articleType = articleType,
verificationType = verificationType
)
DialogHelper.showDialog(
context,
"实名提醒",
@ -236,7 +292,7 @@ object ErrorHelper {
)
}
binding.hintTv.text = errorEntity.data?.text
binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
binding.hintTv.setTextColor(R.color.text_theme.toColor(context))
binding.hintTv.setOnClickListener {
errorEntity.data?.toLinkEntity()?.let { entity ->
DirectUtils.directToLinkPage(context, entity, "实名提醒弹窗", "")
@ -244,23 +300,25 @@ 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(
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()
}
.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()
}
}
})
}
})
},
cancelClickCallback = {
SensorsBridge.trackVerificationPopupClick("以后再说")
}
)
}
@ -268,9 +326,15 @@ object ErrorHelper {
private fun handleVerifyPhoneError(
context: Context,
errorEntity: ErrorEntity,
entrance: String,
articleType: String,
realNameConfirmListener: ConfirmListener?,
entrance: String
) {
SensorsBridge.trackMobileNumberVerificationDialog(
articleType = articleType
)
DialogHelper.showDialog(
context,
"手机号验证",
@ -297,7 +361,7 @@ object ErrorHelper {
)
}
binding.hintTv.text = errorEntity.data?.text
binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
binding.hintTv.setTextColor(R.color.text_theme.toColor(context))
binding.hintTv.setOnClickListener {
errorEntity.data?.toLinkEntity()?.let { entity ->
DirectUtils.directToLinkPage(context, entity, "手机号验证", "")
@ -320,10 +384,12 @@ object ErrorHelper {
}
}
})
SensorsBridge.trackMobileNumberVerificationPopupClick(buttonName = "前往手机号验证")
NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "前往手机号验证")
NewFlatLogUtils.logPhoneNumberVerifyDialogShow("手机号验证弹窗-前往验证")
},
cancelClickCallback = {
SensorsBridge.trackMobileNumberVerificationPopupClick(buttonName = "以后再说")
NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "以后再说")
}
)

View File

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

View File

@ -1,38 +1,30 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
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) }
var gameCollectionList: List<SubjectEntity> = arrayListOf()
init {
loadSavedRepository()
}
private var mGameCollectionList: List<SubjectEntity>? = null // 游戏补充库
/**
* 获取游戏补充库
@ -41,68 +33,37 @@ object GameSubstituteRepositoryHelper {
fun updateGameSubstituteRepository() {
mApi.reserveColumns
.subscribeOn(Schedulers.io())
.subscribe(object : Response<List<SubjectEntity>>() {
override fun onResponse(response: List<SubjectEntity>?) {
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
super.onResponse(response)
updateGameRepository(response)
if (response != null) {
updateGameRepository(response)
}
}
})
}
@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()
}
})
private fun updateGameRepository(response: ResponseBody) {
val responseContent = response.string()
SPUtils.setString(mGameSubSp, KEY_GAME_REPOSITORY, responseContent)
if (mGameCollectionList?.isEmpty() == true) {
mGameCollectionList = responseContent.toObject()
}
}
/**
* 刷新内存中的游戏库(即从 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 getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
private fun getValidGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
collectionId?.let {
val collection = gameCollectionList.find { it.id == collectionId }
val collection = mGameCollectionList?.find { it.id == collectionId }
collection?.let {
val game = collection.data?.find { game -> isThisGameUnique(game, gameIdList) }
val game = collection.data?.find { game -> isThisGameValid(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
@ -115,14 +76,19 @@ object GameSubstituteRepositoryHelper {
/**
* 替换游戏,包括 已安装,历史下载,历史已安装等类型
* @param gameList 需要被替换数据的游戏列表
* @param displayingGameIdSet 页面正在显示的游戏 ID 列表,避免重复替换
* @param relatedCollectionId 关联的替换合集 ID
*/
fun replaceGames(
gameList: MutableList<GameEntity>,
alreadyDisplayedGameIdSet: HashSet<String>,
gameList: MutableList<GameEntity>?,
displayingGameIdSet: HashSet<String>,
relatedCollectionId: String,
shouldLogReplaceEvent: Boolean
) {
val positionOfTheGameToReplaceList = arrayListOf<Int>()
if (gameList == null) return
// 需要被替换的游戏 position 列表
val positionOfGameToBeReplacedList = arrayListOf<Int>()
// 标记需要替换的已安装游戏
for ((index, game) in gameList.withIndex()) {
@ -132,28 +98,21 @@ object GameSubstituteRepositoryHelper {
continue
}
var isThisPositionLabeled = false
// 从 游戏ID 判断当前游戏是否需要被替换
if (mSubstitutableGameIdSet.contains(game.id)) {
positionOfTheGameToReplaceList.add(index)
isThisPositionLabeled = true
}
// 这个 position 的游戏是否需要被替换
var thisPositionNeedToBeReplaced = false
// 检查是否已安装该游戏里同包名的 APK
if (!isThisPositionLabeled) {
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfTheGameToReplaceList.add(index)
isThisPositionLabeled = true
break
}
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
break
}
}
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
if (!isThisPositionLabeled) {
if (!thisPositionNeedToBeReplaced) {
var relatedPackageList = arrayListOf<String>()
for (entity in PackageHelper.relatedPackageList) {
if (entity.gameId == game.id) {
@ -164,39 +123,49 @@ object GameSubstituteRepositoryHelper {
for (packageName in relatedPackageList) {
if (PackageHelper.validLocalPackageNameSet.contains(packageName)) {
positionOfTheGameToReplaceList.add(index)
positionOfGameToBeReplacedList.add(index)
break
}
}
}
}
if (positionOfTheGameToReplaceList.isNotEmpty()) {
if (shouldLogReplaceEvent) {
MtaHelper.onEvent("首页_加载", "启动光环", "替换游戏")
// 若待替换的位置列表不为空,尝试执行替换
if (positionOfGameToBeReplacedList.isNotEmpty()) {
if (mGameCollectionList == null) {
mGameCollectionList = SPUtils.getString(mGameSubSp, KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
}
for (position in positionOfTheGameToReplaceList) {
val replacingGame = getOneUniqueGame(relatedCollectionId, alreadyDisplayedGameIdSet)
replacingGame?.let {
gameList[position] = replacingGame
if (mGameCollectionList.isNullOrEmpty()) return
for (position in positionOfGameToBeReplacedList) {
val validGame = getValidGame(relatedCollectionId, displayingGameIdSet)
validGame?.let {
gameList[position] = it
displayingGameIdSet.add(it.id)
}
}
}
}
private fun isThisGameUnique(game: GameEntity, gameIdList: HashSet<String>): Boolean {
// 判断该游戏是否出现在已安装列表
if (mSubstitutableGameIdSet.contains(game.id)) return false
// 该补充游戏是否已经存在关联关系
/**
* 判断该游戏是否有效
* @param game 需要判断的游戏
* @param gameIdList 专题里已经包含的游戏 ID 列表
*/
private fun isThisGameValid(
game: GameEntity,
gameIdList: HashSet<String>
): Boolean {
// 该游戏是否与专题里已包含的游戏存在关联关系
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,20 +2,15 @@ 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;
@ -75,11 +70,6 @@ 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;
@ -108,57 +98,6 @@ 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,15 +1,20 @@
package com.gh.common.util
import com.gh.common.util.ViewPagerFragmentHelper.TYPE_MY_HALO
import com.gh.gamecenter.R
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
object HomeBottomBarHelper {
private const val GAME_BAR_KEY = "game_bar_key"
private const val VIDEO_BAR_KEY = "video_bar_key"
private const val KEY_HOME_BOTTOM_TAB = "home_bottom_tab"
@JvmStatic
fun getDefaultGameBarData(): SubjectRecommendEntity {
@ -30,8 +35,6 @@ 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()
@ -39,41 +42,37 @@ object HomeBottomBarHelper {
}
@JvmStatic
fun getDefaultVideoData(): SubjectRecommendEntity {
fun getDefaultBottomTabHomeEntity(): BottomTab {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_home.json")
.bufferedReader().use { it.readText() }
return BottomTab(name = "首页", jsCode = animationCode, iconSelector = R.drawable.selector_ic_home, default = true)
}
@JvmStatic
fun getDefaultBottomTabMineEntity(): BottomTab {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_mine.json")
.bufferedReader().use { it.readText() }
return BottomTab(name = "我的光环", jsCode = animationCode, iconSelector = R.drawable.selector_ic_user, link = LinkEntity(type = TYPE_MY_HALO))
}
@JvmStatic
fun getDefaultHomeBottomTabData(): List<BottomTab> {
try {
val json = SPUtils.getString(VIDEO_BAR_KEY)
val json = SPUtils.getString(KEY_HOME_BOTTOM_TAB)
if (json.isNotEmpty()) {
return GsonUtils.fromJson(json, SubjectRecommendEntity::class.java)
val type = object : TypeToken<List<BottomTab>>() {}.type
return GsonUtils.gson.fromJson(json, type)
}
} catch (ignore: Exception) {
}
return getDefaultVideoEntity()
return listOf(getDefaultBottomTabHomeEntity(), getDefaultBottomTabMineEntity())
}
@JvmStatic
fun getDefaultVideoEntity(): SubjectRecommendEntity {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_video.json")
.bufferedReader().use { it.readText() }
return SubjectRecommendEntity(
type = "video_stream",
text = "视频",
name = "视频",
position = 4,
animationCode = animationCode,
default = false,
display = Display()
)
}
@JvmStatic
fun updateDefaultGameBarData(data: SubjectRecommendEntity) {
SPUtils.setString(GAME_BAR_KEY, data.toJson())
}
@JvmStatic
fun updateDefaultVideoBarData(data: SubjectRecommendEntity) {
SPUtils.setString(VIDEO_BAR_KEY, data.toJson())
fun updateDefaultHomeBottomTabData(data: List<BottomTab>) {
SPUtils.setString(KEY_HOME_BOTTOM_TAB, data.toJson())
}
}

View File

@ -1,13 +1,18 @@
package com.gh.common.util
import com.gh.gamecenter.common.utils.toastInInternalRelease
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.tracker.Tracker
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 {
@ -18,19 +23,67 @@ object HomePluggableHelper {
val apkList = gameEntity.getApk()
if (apkList.isNotEmpty()) {
val apk = apkList.first()
val tag = if (isNever) "never" else apk.version ?: ""
tryCatchInRelease {
mHomePluggableFilterDao.addData(
HomePluggableFilterEntity(
pkgName = apk.packageName,
tag = tag,
active = isNever
)
)
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
)
)
}
}
}
}
}
/**
* 获取插件化区域显示样式
*/
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()
@ -38,9 +91,9 @@ object HomePluggableHelper {
val apk = apkList.first()
tryCatchInRelease {
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
if (filterData?.active == true) {
if (filterData != null) {
val filterTag = filterData.tag
return filterTag != "never" && apk.version != filterTag
return !filterTag.contains("never") && !filterTag.contains(MD5Utils.getContentMD5(gameEntity.id + apk.version))
}
}
}
@ -55,20 +108,4 @@ 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

@ -183,12 +183,12 @@ public class LibaoUtils {
case "coming":
libaoBtn.setText(R.string.libao_coming);
libaoBtn.setBackgroundResource(R.drawable.button_round_gray_light);
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_subtitleDesc));
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_tertiary));
break;
case "used_up":
libaoBtn.setText(R.string.libao_used_up);
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_theme));
break;
case "finish":
libaoBtn.setText(R.string.libao_finish);
@ -198,12 +198,12 @@ public class LibaoUtils {
case "linged":
libaoBtn.setText(R.string.libao_linged);
libaoBtn.setBackgroundResource(R.drawable.button_round_gray_light);
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_subtitleDesc));
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_tertiary));
break;
case "taoed":
libaoBtn.setText(R.string.libao_taoed);
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_theme));
break;
case "copy":
libaoBtn.setText(R.string.libao_copy);
@ -213,13 +213,13 @@ public class LibaoUtils {
case "repeatLinged":
libaoBtn.setText(R.string.libao_repeat_ling);
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_theme));
break;
case "repeatTao":
case "repeatTaoed":
libaoBtn.setText(R.string.libao_repeat_tao);
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
libaoBtn.setTextColor(context.getResources().getColor(R.color.text_theme));
break;
case "unshelve":
libaoBtn.setBackgroundResource(R.drawable.button_border_round_gray);

View File

@ -259,6 +259,7 @@ public class LogUtils {
private static void uploadToReservation(JSONObject object) {
Context context = HaloApp.getInstance().getApplication();
try {
object.put(KEY_EVENT, "appointment");
object.put("version", PackageUtils.getGhVersionName());
object.put("channel", HaloApp.getInstance().getChannel());
object.put("dia", MetaUtil.getBase64EncodedAndroidId());

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.getExternalStorageDirectory().getAbsolutePath() + "/ShareImg/";
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/ShareImg/";
} else {
path = context.getExternalCacheDir().getPath() + "/ShareImg/";
}

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