Compare commits

..

173 Commits

Author SHA1 Message Date
1023e0492b feat: 测试插件化
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-25 17:02:54 +08:00
0fda3ecfcd feat: 合规调整-已安装列表权限-2024/4/22(gitlab-ci) https://jira.shanqu.cc/browse/GHZSCY-5250
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-25 11:09:55 +08:00
166abd5c9b feat: 合规调整-已安装列表权限-2024/4/22 https://jira.shanqu.cc/browse/GHZSCY-5250
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-25 11:08:52 +08:00
af3102f6be feat: 合规调整-已安装列表权限-2024/4/22 https://jira.shanqu.cc/browse/GHZSCY-5250
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-25 10:11:45 +08:00
93363f23b4 feat: 合规调整-已安装列表权限-2024/4/22 https://jira.shanqu.cc/browse/GHZSCY-5250
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-24 16:15:31 +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
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
461 changed files with 7284 additions and 10023 deletions

View File

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

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

@ -310,7 +310,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}"
@ -346,8 +345,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}"
@ -360,8 +357,6 @@ dependencies {
implementation "com.lg:easyfloat:${easyFloat}"
implementation "io.github.florent37:shapeofview:${shapeOfView}"
implementation "com.lg:apksig:${apksig}"
implementation "com.lg:gid:${gid}"
@ -413,6 +408,13 @@ dependencies {
exclude group: 'androidx.swiperefreshlayout'
}
internalImplementation(project(':module_internal_test'))
// 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用阿里云推送
def pushProject = findProperty('BUILD_PUSH_TYPE') == 'jg'
? project(':feature:jg_push') : project(':feature:acloud_push')
implementation(pushProject) {
exclude group: 'androidx.swiperefreshlayout'
}
}
File propFile = file('sign.properties')
@ -483,6 +485,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,9 +80,6 @@
### EasyFloat
-keep class com.lzf.easyfloat.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
### 广点通SDK
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.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

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

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卡上写文件 -->
@ -118,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"
@ -313,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" />
@ -329,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" />
@ -370,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" />
@ -412,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" />
@ -488,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" />
@ -502,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" />

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

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

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

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

@ -4,6 +4,7 @@ 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
@ -14,7 +15,9 @@ 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
@ -81,6 +84,10 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
XapkInstaller.updateCurrentInstallStatus()
// 清除桌面角标
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
override fun onActivityPaused(activity: Activity) {

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

@ -589,6 +589,7 @@ object DefaultUrlHandler {
DirectUtils.directToGameDetail(
context,
gameId,
"",
entrance,
autoDownload = false,
traceEvent = null

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

@ -18,7 +18,15 @@ class LandPageAddressHandler : DownloadChainHandler() {
}
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
if (gameEntity.isLandPageAddressDialogShowOnly()) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
} else {
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
}
}
} else {

View File

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

View File

@ -52,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;
@ -69,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.
*/
@ -132,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:
@ -218,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()) {
@ -456,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,

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()
}
@ -64,7 +66,6 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
dismissAllowingStateLoss()
}
@ -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

@ -19,6 +19,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
@ -59,7 +60,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private val mDuration = 3000
private var mDisposable: Disposable? = null
private var mAdapter: PackageCheckAdapter? = null
private var mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
private var mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
@ -325,7 +326,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onResume() {
super.onResume()
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
gameEntity?.packageDialog?.let {
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
callBack?.onConfirm()
@ -363,7 +364,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if (busFour.isInstalledOrUninstalled()) {
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
mAdapter?.notifyDataSetChanged()
}
}
@ -416,7 +417,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
return
}
val allInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
val allInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
callBack.onConfirm()
return

View File

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

View File

@ -1,89 +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)
process()
} else {
processNext()
}
} else {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
when (getStatus()) {
STATUS_VALID -> {
val floatingWindowProvider =
ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
.navigation() as? IFloatingWindowProvider<WelcomeDialogEntity>
// 强校验所有条件均通过才能显示
if (floatingWindowProvider == null || mFragment == null || mFragment?.isAdded == false || mRecyclerView == null) {
processNext()
return false
}
floatingWindowProvider.showFloatingWindowOnly(
mFragment!!,
mRecyclerView!!,
mWindowList!!,
) {
val welcomeDialog = WelcomeDialogFragment.getInstance(it, true, mFragment)
welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -1,8 +1,6 @@
package com.gh.common.prioritychain
import android.graphics.Bitmap
import androidx.fragment.app.FragmentActivity
import com.gh.gamecenter.common.callback.BiCallback
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
@ -21,20 +19,19 @@ class WelcomeDialogHandler(priority: Int) : PriorityChainHandler(priority) {
// 判断启动本次应用是否已经弹窗,不是的话弹启动弹窗
if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false)
ImageUtils.getBitmap(this.welcomeDialogEntity!!.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)
process()
} else {
updateStatus(STATUS_VALID)
}
}
override fun onSecond(second: Boolean) {
} else {
processNext()
}
})
}
} else {
processNext()
}

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)
}
@ -97,26 +69,6 @@ class DirectProviderImpl : IDirectProvider {
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

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

View File

@ -20,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
@ -167,162 +166,160 @@ class SimulatorDownloadManager private constructor() {
this.gameName = gameName
this.gameType = gameCategoryChinese
PermissionHelper.checkGetInstalledAppsListBeforeAction(context, object : EmptyCallback {
override fun onCallback() {
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
//当没有安装新版本模拟器时候 判断是否隐藏
if (simulator?.active == false && !isInstalledNewSimulator) {
showNoneEmulatorDialog(context)
return
}
var isInstalled = PackageUtils.isInstalledFromAllPackage(
context,
simulator?.apk?.packageName
)
//模拟器管理界面还是用之前的逻辑
if (isInstalledNewSimulator && location != SimulatorLocation.SIMULATOR_MANAGE) {
isInstalled = isInstalledNewSimulator
}
// val versionFromInstalledApp = PackageUtils.getVersionNameByPackageName(simulator?.apk?.packageName)
val shouldShowUpdate =
PackageUtils.isInstalledApkMatchedMd5(simulator?.apk?.packageName, simulator?.apk?.md5)
val showAlertTag = SPUtils.getString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, "") //当天是否弹过
val todayIsShow = showAlertTag == TimeUtils.getToday()
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
if (downloadType == "update" && todayIsShow && location != SimulatorLocation.SIMULATOR_MANAGE) {
return
}
if (downloadType == "download" && isInstalled) {
return
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
val trackableEntity = TrackableEntity(
"模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
message,
positiveText,
negativeText,
trackMtaEvent = true,
cancelClickCallback = {
if (shouldShowUpdate && isInstalled) {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
)
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
if (downloadType == "update" && location != SimulatorLocation.SIMULATOR_MANAGE) {
SPUtils.setString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, TimeUtils.getToday())
}
PermissionHelper.checkGetInstalledAppsListBeforeAction(context) { _ ->
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
//当没有安装新版本模拟器时候 判断是否隐藏
if (simulator?.active == false && !isInstalledNewSimulator) {
showNoneEmulatorDialog(context)
return@checkGetInstalledAppsListBeforeAction
}
})
var isInstalled = PackageUtils.isInstalledFromAllPackage(
context,
simulator?.apk?.packageName
)
//模拟器管理界面还是用之前的逻辑
if (isInstalledNewSimulator && location != SimulatorLocation.SIMULATOR_MANAGE) {
isInstalled = isInstalledNewSimulator
}
// val versionFromInstalledApp = PackageUtils.getVersionNameByPackageName(simulator?.apk?.packageName)
val shouldShowUpdate =
PackageUtils.isInstalledApkMatchedMd5(simulator?.apk?.packageName, simulator?.apk?.md5)
val showAlertTag = SPUtils.getString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, "") //当天是否弹过
val todayIsShow = showAlertTag == TimeUtils.getToday()
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
if (downloadType == "update" && todayIsShow && location != SimulatorLocation.SIMULATOR_MANAGE) {
return@checkGetInstalledAppsListBeforeAction
}
if (downloadType == "download" && isInstalled) {
return@checkGetInstalledAppsListBeforeAction
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
val trackableEntity = TrackableEntity(
"模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
message,
positiveText,
negativeText,
trackMtaEvent = true,
cancelClickCallback = {
if (shouldShowUpdate && isInstalled) {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
)
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
if (downloadType == "update" && location != SimulatorLocation.SIMULATOR_MANAGE) {
SPUtils.setString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, TimeUtils.getToday())
}
}
}
fun showDownloadingDialog(

View File

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

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

@ -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;
@ -126,9 +125,7 @@ public class DataUtils {
HaloApp.getInstance().setGid(gid);
// 更新广告配置
ExtensionsKt.doOnMainProcessOnly(HaloApp.getInstance(), () -> {
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
});
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
getDeviceCertification(gid);
@ -148,7 +145,8 @@ public class DataUtils {
@Override
public void onFailure(String s) {
MtaHelper.onEventWithBasicDeviceInfo("开发辅助", "GID 获取异常", s);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
}
});
}

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

View File

@ -82,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 {
@ -578,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(
@ -631,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();

View File

@ -48,7 +48,7 @@ import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.forum.home.CommunityActivity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
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
@ -166,7 +166,11 @@ object DirectUtils {
"article_center",
"video_stream",
"libao",
"community_home"
"community_home",
"bbs_section",
"qa",
"feedback",
"toolkit"
)
fun directToLinkPage(
@ -191,6 +195,7 @@ object DirectUtils {
if (exposureEvent != null) {
directToGameDetail(
context, linkEntity.link
?: "", linkEntity.text
?: "", BaseActivity.mergeEntranceAndPath(entrance, path), traceEvent = exposureEvent
)
} else {
@ -749,6 +754,7 @@ object DirectUtils {
fun directToGameDetail(
context: Context,
id: String,
name: String = "",
entrance: String? = null,
autoDownload: Boolean? = null,
tab: String? = "",
@ -768,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)
}
@ -1619,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)
}
/**
* 跳转至地址信息
@ -1903,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)

View File

@ -46,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
@ -1060,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()) {
@ -1154,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,
@ -1192,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 + "已加入下载队列")
@ -1219,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
@ -1227,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

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

View File

@ -41,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
@ -385,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()) {
@ -432,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

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

@ -35,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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@ import com.gh.gamecenter.forum.detail.ForumDetailFragment
import com.gh.gamecenter.forum.home.CommunityHomeFragment
import com.gh.gamecenter.fragment.ReloadFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailFragment
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListWrapperFragment
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.gamedetail.GameDetailFragment
@ -185,7 +185,7 @@ object ViewPagerFragmentHelper {
}
// 通用内容合集详情页
TYPE_COMMON_COLLECTION -> {
className = CommonCollectionDetailFragment::class.java.name
className = CustomCommonCollectionDetailFragment::class.java.name
bundle.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
bundle.putString(EntranceConsts.KEY_COLUMNNAME, entity.text)
}

View File

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

View File

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

View File

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

View File

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

View File

@ -25,36 +25,44 @@ import com.gh.gamecenter.feature.entity.CustomPageTrackData;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.common.history.HistoryHelper;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.DataCollectionUtils;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LunchType;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.AppDebugConfig;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.download.DownloadedGameIdAndPackageNameDao;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.HomePluggableFilterEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.vspace.VHelper;
import com.gh.ndownload.NDataChanger;
import com.gh.ndownload.NDownloadBridge;
import com.gh.ndownload.NDownloadService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.download.ConnectionUtils;
import com.lightgame.download.DataWatcher;
@ -63,7 +71,6 @@ import com.lightgame.download.DownloadDao;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.DownloadStatusListener;
import com.lightgame.download.FileUtils;
import com.lightgame.download.HttpDnsManager;
import com.lightgame.utils.Utils;
@ -249,7 +256,9 @@ public class DownloadManager implements DownloadStatusListener {
String location,
boolean isSubscribe,
@Nullable ExposureEvent traceEvent) {
createDownload(context, gameEntity.getApk().get(0), gameEntity, asVGame, gameEntity.isDualBtnModeEnabled(), entrance, location, isSubscribe, traceEvent);
if (!gameEntity.getApk().isEmpty()) {
createDownload(context, gameEntity.getApk().get(0), gameEntity, asVGame, gameEntity.isDualBtnModeEnabled(), entrance, location, isSubscribe, traceEvent);
}
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@ import com.lg.download.*
import com.lg.ndownload.DownloadConfig
import com.lg.ndownload.DownloadDbManager
import com.lg.ndownload.DownloadQueue
import com.lightgame.download.FileUtils
import com.gh.gamecenter.common.utils.FileUtils
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

View File

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

View File

@ -17,7 +17,6 @@ import static com.gh.gamecenter.common.utils.ExtensionsKt.observableToMain;
import static com.gh.gamecenter.login.utils.LoginHelper.WEIBO_SCOPE;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -57,7 +56,6 @@ import com.gh.common.util.DataUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ErrorHelper;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
import com.gh.common.util.PackageInstaller;
@ -72,6 +70,7 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.constant.CommonConsts;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.entity.SuggestType;
import com.gh.gamecenter.common.eventbus.EBNetworkState;
import com.gh.gamecenter.common.eventbus.EBReuse;
@ -80,6 +79,7 @@ import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.common.utils.ShareUtils;
@ -93,13 +93,11 @@ import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.StartupAdEntity;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.home.custom.model.CustomPageShareRepository;
import com.gh.gamecenter.home.skip.PackageSkipActivity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.retrofit.RetrofitManager;
@ -115,14 +113,11 @@ import com.google.gson.reflect.TypeToken;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.openapi.IWBAPI;
import com.sina.weibo.sdk.openapi.WBAPIFactory;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;
@ -136,14 +131,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import kotlin.jvm.functions.Function1;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
@ -179,6 +171,8 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel = new ViewModelProvider(this, new MainWrapperViewModel.Factory(HaloApp.getInstance()))
.get(MainWrapperViewModel.class);
DisplayUtils.updateGlobalScreen(this);
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);
@ -229,7 +223,7 @@ public class MainActivity extends BaseActivity {
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手发生了闪退,建议安装到最新版本修复异常"
, "马上反馈", "马上安装修复",
() -> {
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "crash", true, "desc", null);
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "", "crash", true, "desc", null);
return null;
},
() -> {
@ -324,8 +318,7 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel.requestAllDialogData();
// TODO 去掉一键登录?
QuickLoginHelper.getPhoneInfo();
// QuickLoginHelper.getPhoneInfo();
// TODO 搞清楚为什么这里要获取微信相关配置
WechatBindHelper.getWechatConfig(null);
@ -499,7 +492,12 @@ public class MainActivity extends BaseActivity {
ViewGroup startAdContainer = findViewById(R.id.startAdContainer);
ViewGroup sdkStartAdContainer = findViewById(R.id.sdkStartAdContainer);
FrameLayout adsFl = findViewById(R.id.adsFl);
View icpContainer = findViewById(R.id.sdkStartAdIcpContainer);
if (icpContainer != null) {
icpContainer.setOnClickListener((view) -> {
// consume click event
});
}
int screenWidthInPx = DisplayUtils.getScreenWidth(this);
int screenHeightInPx = DisplayUtils.getScreenHeight(this)
+ DisplayUtils.getStatusBarHeight(this.getResources())
@ -540,6 +538,21 @@ public class MainActivity extends BaseActivity {
if (COUNTDOWN_MAX_COUNT < mCountdownCount) {
AdDelegateHelper.INSTANCE.setShowingSplashAd(false);
hideSplashAd();
if (msg.obj instanceof StartupAdEntity) {
StartupAdEntity ad = (StartupAdEntity) msg.obj;
LinkEntity linkEntity = ad.getJump();
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.getId(),
"link_type",
linkEntity.getType(),
"link_id",
linkEntity.getLink(),
"link_text",
linkEntity.getText());
}
} else {
TextView jumpBtn = findViewById(R.id.jumpBtn);
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - mCountdownCount));
@ -682,15 +695,18 @@ public class MainActivity extends BaseActivity {
try {
GameEntity gameEntity = GsonUtils.getGson().fromJson(json, new TypeToken<GameEntity>() {
}.getType());
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
ToastUtils.showToast("文件已被删除,无法启动");
return;
}
if (gameEntity != null) {
String apkUrl = gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl();
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apkUrl);
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
ToastUtils.showToast("文件已被删除,无法启动");
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
}
}
} catch (JsonSyntaxException exception) {
exception.printStackTrace();

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_BROWSER;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_PUSH;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ANSWER;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ARTICLE;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_CATEGORY;
@ -129,6 +130,10 @@ public class SkipActivity extends BaseActivity {
String qaId = uri.getQueryParameter("qa_id");
String qaContentId = uri.getQueryParameter(EntranceConsts.KEY_QA_CONTENT_ID);
String qaTitle = uri.getQueryParameter(EntranceConsts.KEY_QA_TITLE);
String isFromPushString = uri.getQueryParameter(EntranceConsts.KEY_IS_FROM_PUSH);
boolean isFromPush = !TextUtils.isEmpty(isFromPushString) && isFromPushString.equals("true");
String entrance = isFromPush ? ENTRANCE_PUSH : ENTRANCE_BROWSER;
String pathName = isFromPush ? ENTRANCE_PUSH : "浏览器";
if (host != null) {
Intent intent;
@ -141,40 +146,40 @@ public class SkipActivity extends BaseActivity {
createShortcut(uri);
return;
case HOST_ARTICLE:
DirectUtils.directToArticle(this, path, ENTRANCE_BROWSER);
DirectUtils.directToArticle(this, path, entrance);
break;
case HOST_GAME:
DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null);
DirectUtils.directToGameDetail(this, path, "", entrance, "true".equals(uri.getQueryParameter("auto_download")), to, null);
break;
case HOST_COLUMN:
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER, null, false);
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), entrance, null, false);
break;
case HOST_SUGGESTION:
if (!TextUtils.isEmpty(qaId)) {
DirectUtils.directToQa(this, qaTitle, qaId);
} else {
// 插件反馈跳转到意见反馈分类页
DirectUtils.directToFeedback(this, content, isQaFeedback, qaContentId, true, false, EntranceConsts.ENTRANCE_BROWSER);
DirectUtils.directToFeedback(this, content, isQaFeedback, qaContentId, true, false, entrance);
}
break;
case HOST_DOWNLOAD:
DirectUtils.directToDownloadManagerAndStartUpdate(this, path, uri.getQueryParameter(KEY_PACKAGENAME), ENTRANCE_BROWSER);
DirectUtils.directToDownloadManagerAndStartUpdate(this, path, uri.getQueryParameter(KEY_PACKAGENAME), entrance);
break;
case HOST_ANSWER:
DirectUtils.directToAnswerDetail(this, path, ENTRANCE_BROWSER, "浏览器");
DirectUtils.directToAnswerDetail(this, path, entrance, pathName);
break;
case HOST_QUESTION:
DirectUtils.directToQuestionDetail(this, path, ENTRANCE_BROWSER, "浏览器", "");
DirectUtils.directToQuestionDetail(this, path, entrance, pathName, "");
break;
case HOST_TOOLBOX:
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), ENTRANCE_BROWSER);
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), entrance);
break;
case HOST_COMMUNITY:
DirectUtils.directToHomeCommunityTab(this);
break;
// 社区文章格式一
case "community.article":
DirectUtils.directToCommunityArticle(this, uri.getQueryParameter("articleId"), uri.getQueryParameter("communityId"), ENTRANCE_BROWSER, "浏览器", "");
DirectUtils.directToCommunityArticle(this, uri.getQueryParameter("articleId"), uri.getQueryParameter("communityId"), entrance, pathName, "");
break;
// 社区文章格式二
case "communities":
@ -195,13 +200,13 @@ public class SkipActivity extends BaseActivity {
}
}
if ("articles".equals(type)) {
DirectUtils.directToCommunityArticle(this, typeId, communityId, ENTRANCE_BROWSER, "浏览器", "");
DirectUtils.directToCommunityArticle(this, typeId, communityId, entrance, pathName, "");
break;
}
break;
case HOST_VIDEO:
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.HOTTEST_GAME_VIDEO.getValue(),
false, id, ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer, "");
false, id, entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer, "");
break;
case HOST_UPLOAD_VIDEO://跳转上传视频
String titleParameter = uri.getQueryParameter("title");
@ -215,13 +220,13 @@ public class SkipActivity extends BaseActivity {
VideoLinkEntity linkEntity = new VideoLinkEntity(title, categoryId, link, tagActivityId, tagActivityName);
SimpleGameEntity simpleGameEntity = new SimpleGameEntity(gameId != null ? gameId : "", gameName != null ? gameName : "", "", "");
Bundle nextToBundle = VideoManagerActivity.getVideoManagerBundle(linkEntity, simpleGameEntity, EntranceConsts.ENTRANCE_BROWSER, "");
CheckLoginUtils.checkLogin(this, nextToBundle, true, EntranceConsts.ENTRANCE_BROWSER, () ->
DirectUtils.directToVideoManager(SkipActivity.this, linkEntity, simpleGameEntity, EntranceConsts.ENTRANCE_BROWSER, "浏览器"));
Bundle nextToBundle = VideoManagerActivity.getVideoManagerBundle(linkEntity, simpleGameEntity, entrance, "");
CheckLoginUtils.checkLogin(this, nextToBundle, true, entrance, () ->
DirectUtils.directToVideoManager(SkipActivity.this, linkEntity, simpleGameEntity, entrance, pathName));
break;
case HOST_VIDEO_SINGLE:
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.getValue(),
false, "", ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer, "");
false, "", entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer, "");
break;
case HOST_VIDEO_MORE:
gameId = uri.getQueryParameter("gameId");
@ -238,7 +243,7 @@ public class SkipActivity extends BaseActivity {
location = path;
}
DirectUtils.directToLegacyVideoDetail(this, path, location,
false, TextUtils.isEmpty(gameId) ? "" : gameId, ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer,
false, TextUtils.isEmpty(gameId) ? "" : gameId, entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer,
TextUtils.isEmpty(type) ? "" : type, TextUtils.isEmpty(act) ? "" : act, TextUtils.isEmpty(paginationType) ? "page" : paginationType, TextUtils.isEmpty(fieldId) ? "" : fieldId,
TextUtils.isEmpty(sectionName) ? "" : sectionName, false, "");
break;
@ -246,10 +251,10 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToHomeVideoTab(this);
break;
case HOST_VIDEO_STREAMING_DESC:
DirectUtils.directToGameDetailVideoStreaming(this, path, ENTRANCE_BROWSER);
DirectUtils.directToGameDetailVideoStreaming(this, path, entrance);
break;
case HOST_VIDEO_COLLECTION:
DirectUtils.directToGameVideo(this, path, ENTRANCE_BROWSER, "浏览器");
DirectUtils.directToGameVideo(this, path, entrance, pathName);
break;
case HOST_QQ:
bundle = new Bundle();
@ -278,32 +283,32 @@ public class SkipActivity extends BaseActivity {
EntranceUtils.jumpActivityCompat(this, bundle);
break;
case EntranceConsts.HOST_VIDEO_DETAIL:
DirectUtils.directToVideoDetail(this, path, ENTRANCE_BROWSER, "", "");
DirectUtils.directToVideoDetail(this, path, entrance, "", "");
break;
case HOST_LIBAO:
DirectUtils.directToGiftDetail(this, path, ENTRANCE_BROWSER);
DirectUtils.directToGiftDetail(this, path, entrance);
break;
case HOST_USERHOME:
String position = uri.getQueryParameter("position");
String subTypeString = uri.getQueryParameter("sub_type");
String subGameType = uri.getQueryParameter("sub_game_type");
DirectUtils.directToHomeActivity(this, path, subTypeString, subGameType, TextUtils.isEmpty(position) ? -1 : Integer.parseInt(position), ENTRANCE_BROWSER, "浏览器");
DirectUtils.directToHomeActivity(this, path, subTypeString, subGameType, TextUtils.isEmpty(position) ? -1 : Integer.parseInt(position), entrance, pathName);
break;
case HOST_COMMUNITY_COLUMN:
CommunityEntity community = new CommunityEntity();
community.setId(uri.getQueryParameter("community_id"));
community.setName(uri.getQueryParameter("community_name"));
String columnId = uri.getQueryParameter("column_id");
DirectUtils.directToCommunityColumn(this, community, columnId, ENTRANCE_BROWSER, "");
DirectUtils.directToCommunityColumn(this, community, columnId, entrance, "");
break;
case HOST_CATEGORY:
title = uri.getQueryParameter("title");
DirectUtils.directCategoryDirectory(this, path, title, ENTRANCE_BROWSER, "浏览器");
DirectUtils.directCategoryDirectory(this, path, title, entrance, pathName);
break;
case HOST_COLUMN_COLLECTION:
DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "", "", "", "", null,false);
DirectUtils.directToColumnCollection(this, path, -1, entrance, "", "", "", "", null,false);
break;
case EntranceConsts.HOST_BLOCK:
name = uri.getQueryParameter("name");
@ -315,11 +320,11 @@ public class SkipActivity extends BaseActivity {
break;
case EntranceConsts.HOST_SERVER_BLOCK:
DirectUtils.directToGameServers(this, ENTRANCE_BROWSER, "浏览器", null);
DirectUtils.directToGameServers(this, entrance, pathName, null);
break;
case EntranceConsts.HOST_AMWAY_BLOCK:
DirectUtils.directToAmway(this, null, ENTRANCE_BROWSER, "浏览器");
DirectUtils.directToAmway(this, null, entrance, pathName);
break;
case EntranceConsts.HOST_HELP:
@ -332,11 +337,11 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToQaCollection(this, name, path);
break;
case EntranceConsts.HOST_GAME_UPLOAD:
DirectUtils.directGameUpload(this, ENTRANCE_BROWSER, "浏览器");
DirectUtils.directGameUpload(this, entrance, pathName);
break;
case EntranceConsts.HOST_GAME_ZONE:
String zoneUrl = uri.getQueryParameter("url");
DirectUtils.directGameZone(this, path, zoneUrl, ENTRANCE_BROWSER);
DirectUtils.directGameZone(this, path, zoneUrl, entrance);
break;
case EntranceConsts.HOST_LINK:
try {
@ -345,7 +350,7 @@ public class SkipActivity extends BaseActivity {
byte[] linkData = Base64.decode(dataString, Base64.DEFAULT);
String linkDataString = new String(linkData, "UTF-8");
LinkEntity le = GsonUtils.INSTANCE.getGson().fromJson(linkDataString, LinkEntity.class);
DirectUtils.directToLinkPage(this, le, ENTRANCE_BROWSER, "", "");
DirectUtils.directToLinkPage(this, le, entrance, "", "");
}
} catch (Exception e) {
e.printStackTrace();
@ -360,7 +365,7 @@ public class SkipActivity extends BaseActivity {
this,
uri.getQueryParameter(EntranceConsts.KEY_GAME_ID),
uri.getQueryParameter(EntranceConsts.KEY_GAME_NAME),
EntranceConsts.ENTRANCE_BROWSER);
entrance);
break;
case EntranceConsts.HOST_GAME_CALENDAR:
DirectUtils.directToGameServerCalendar(this, uri.getQueryParameter(EntranceConsts.KEY_GAME_ID), 0);
@ -370,26 +375,26 @@ public class SkipActivity extends BaseActivity {
break;
case EntranceConsts.HOST_FORUM_DETAIL:
String sectionId = uri.getQueryParameter("section_id");
DirectUtils.directForumDetailSection(this, id, sectionId, ENTRANCE_BROWSER);
DirectUtils.directForumDetailSection(this, id, sectionId, entrance);
break;
case EntranceConsts.HOST_GAME_RATING_DETAIL:
DirectUtils.directToGameRatingDetail(this, uri.getQueryParameter(EntranceConsts.KEY_GAME_ID), uri.getQueryParameter(EntranceConsts.KEY_COMMENT_ID), ENTRANCE_BROWSER);
DirectUtils.directToGameRatingDetail(this, uri.getQueryParameter(EntranceConsts.KEY_GAME_ID), uri.getQueryParameter(EntranceConsts.KEY_COMMENT_ID), entrance);
break;
case EntranceConsts.HOST_FORUM:
DirectUtils.directToHomeCommunityTab(this);
break;
case EntranceConsts.HOST_HELP_AND_FEEDBACK:
if ("vgame".equals(suggestionType)) {
DirectUtils.directToHelpAndFeedback(this, content, isQaFeedback, qaContentId, false, true, EntranceConsts.ENTRANCE_BROWSER);
DirectUtils.directToHelpAndFeedback(this, content, isQaFeedback, qaContentId, false, true, entrance);
} else {
DirectUtils.directToHelpAndFeedback(this, content, isQaFeedback, qaContentId, true, false, EntranceConsts.ENTRANCE_BROWSER);
DirectUtils.directToHelpAndFeedback(this, content, isQaFeedback, qaContentId, true, false, entrance);
}
break;
case HOST_GAME_COLLECTION_DETAIL:
DirectUtils.directToGameCollectionDetail(this, path, ENTRANCE_BROWSER, "", null);
DirectUtils.directToGameCollectionDetail(this, path, entrance, "", null);
break;
case HOST_GAME_COLLECTION_SQUARE:
DirectUtils.directToGameCollectionSquare(this, ENTRANCE_BROWSER, "", "", "", "", "", null);
DirectUtils.directToGameCollectionSquare(this, entrance, "", "", "", "", "", null);
break;
case HOST_QQ_GAME:
String extJson = uri.getQueryParameter("ext");

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Message
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
@ -37,6 +38,11 @@ class SplashAdActivity : BaseActivity() {
val startAdContainer = findViewById<ViewGroup>(R.id.startAdContainer)
val sdkStartAdContainer = findViewById<ViewGroup>(R.id.sdkStartAdContainer)
val adsFl = findViewById<FrameLayout>(R.id.adsFl)
val icpContainer = findViewById<View>(R.id.sdkStartAdIcpContainer)
icpContainer?.setOnClickListener {
// consume click event
}
val screenWidthInPx = DisplayUtils.getScreenWidth(this)
val screenHeightInPx = (DisplayUtils.getScreenHeight(this)

View File

@ -197,15 +197,7 @@ class SplashScreenActivity : BaseActivity() {
// 尝试获取安装应用列表权限并启动首页(不在乎结果)
private fun requestGetInstallListPermissionAndLaunchMainActivity() {
if (PackageUtils.isSupportGetInstalledAppsPermission(this)
&& PermissionHelper.isGetInstalledListPermissionDisabled(this)
) {
PermissionHelper.requestGetInstalledAppsListPermission(this, true) {
launchMainActivity()
}
} else {
launchMainActivity()
}
launchMainActivity()
}
// 删除更新后的光环助手包
@ -293,7 +285,6 @@ class SplashScreenActivity : BaseActivity() {
if (today != time) {
// 获取版本代码、名称
PlatformUtils.getInstance(applicationContext).getPlatform()
TagUtils.getInstance(applicationContext).getTag()
}
// 更新本地时间

View File

@ -269,9 +269,9 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
if (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.inviteFriends) {
IntegralLogHelper.INSTANCE.logInviteResult("成功", "微博");
}
if (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal ||
if (ShareUtils.additionalParams != null && (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal ||
ShareUtils.shareEntrance == ShareUtils.ShareEntrance.communityArticle ||
ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video) {
ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video)) {
com.gh.gamecenter.common.utils.NewLogUtils.logShareResult(ShareUtils.additionalParams, true);
SensorsBridge.trackArticleShareResult(
ShareUtils.additionalParams.getCustomerType(),
@ -319,9 +319,9 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
com.gh.gamecenter.common.utils.NewLogUtils.logShareResult(ShareUtils.additionalParams, false);
}
if(ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video
if(ShareUtils.additionalParams != null && (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video
|| ShareUtils.shareEntrance == ShareUtils.ShareEntrance.communityArticle
|| ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal)
|| ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal))
{
SensorsBridge.trackArticleShareResult(
ShareUtils.additionalParams.getCustomerType(),

View File

@ -7,6 +7,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
@ -17,17 +18,18 @@ import android.widget.TextView;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import com.gh.gamecenter.common.utils.BitmapUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.BitmapUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.KcGameSelectItemBinding;
import com.gh.gamecenter.feature.entity.InstallGameEntity;
import com.gh.gamecenter.common.retrofit.Response;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.RuntimeUtils;
@ -84,6 +86,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
Observable.create(emitter -> {
// 扫描和获取apk数据 分步操作 尽量避免 StackoverflowError
FindAllAPKPath(Environment.getExternalStorageDirectory());
FindAllAPKPath(mContext.getFilesDir());
LoadApkData();
emitter.onComplete();
})
@ -186,7 +189,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
}
private int doType(String packageName) {
List<PackageInfo> pakageinfos = PackageUtils.getInstalledPackages(mContext, 0);
List<PackageInfo> pakageinfos = PackageHelper.INSTANCE.getInstalledPackages(mContext, 0);
for (PackageInfo pi : pakageinfos) {
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
String pi_packageName = pi.packageName;
@ -213,6 +216,10 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
DecimalFormat df = new DecimalFormat("#.00");
String sizeName = df.format(size) + "MB";
View itemView = holder.itemView;
Drawable background = ContextCompat.getDrawable(itemView.getContext(), R.drawable.reuse_listview_item_style);
itemView.setBackground(background);
holder.binding.selectGameCbRl.setVisibility(View.VISIBLE);
holder.binding.selectGameBtn.setVisibility(View.VISIBLE);
if (mSelectPosition.get(position)) {

View File

@ -205,7 +205,7 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
GameEntity gameEntity = mLibaoEntity.getGame().toGameEntity();
GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, holder.binding.gameSubtitleTv, null, null, false, null, false, null);
} else {
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null, mLibaoEntity.getGame().getIconFloat());
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null, null);
}
holder.binding.libaodetailName.setText(mLibaoEntity.getName());
if (TextUtils.isEmpty(mLibaoEntity.getPlatform())) {

View File

@ -297,7 +297,7 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
if (mConcernEntity.getGame() != null) {
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGame().getIcon(), mConcernEntity.getGame().getIconSubscript(), mConcernEntity.getGame().getIconFloat());
} else {
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGameIcon(), null, mConcernEntity.getGame().getIconFloat());
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGameIcon(), null, null);
}
viewHolder.binding.newsDigestTitle.setText(mConcernEntity.getGameName());
NewsUtils.setNewsPublishOn(viewHolder.binding.newsDigestTime, mConcernEntity.getTime());

View File

@ -47,7 +47,6 @@ import com.gh.gamecenter.teenagermode.TeenagerModeActivity.Companion.getIntent
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import org.greenrobot.eventbus.EventBus
import java.io.File
@ -177,6 +176,15 @@ class DetailViewHolder(
private val mGameEntity: GameEntity = mViewHolder.gameEntity
private var mDownloadEntity: DownloadEntity? = null
private fun showLandPageAddressDialogIfNeeded() {
if (mGameEntity.isLandPageAddressDialog() && !mGameEntity.isLandPageAddressDialogShowOnly()) {
// 第三方落地页为开启状态并且展示状态不为“仅显示弹窗”,需要在点击确认后显示弹窗
DialogUtils.showLandPageAddressDialog(mViewHolder.context, mGameEntity) {
DirectUtils.directToExternalBrowser(mViewHolder.context, mGameEntity.landPageAddressDialog!!.link!!)
}
}
}
override fun onClick(v: View) {
v.tag = null
@ -245,13 +253,17 @@ class DetailViewHolder(
val offStatus = mGameEntity.downloadOffStatus
if (offStatus != null && "off" != offStatus) {
if ("dialog" == offStatus) {
showOffServiceDialog(mGameEntity.downloadOffDialog)
showOffServiceDialog(mGameEntity.downloadOffDialog) {
showLandPageAddressDialogIfNeeded()
}
} else if ("toast" == offStatus) {
EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING))
ToastUtils.toast("该游戏因故暂不提供下载,具体详情可在相关评论中查看,敬请谅解~")
showLandPageAddressDialogIfNeeded()
}
} else {
ToastUtils.toast("该游戏已关闭下载")
showLandPageAddressDialogIfNeeded()
}
}
@ -278,7 +290,7 @@ class DetailViewHolder(
NewSimulatorGameManager.showUpdateNewsSimulator(mViewHolder.context, mGameEntity, null)
return
}
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(mGameEntity.getApk()[0].url)
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(mGameEntity.getApk().firstOrNull()?.url)
if (downloadEntity != null) {
val file = File(downloadEntity.path)
if (!file.exists()) {
@ -331,7 +343,7 @@ class DetailViewHolder(
gameName = mGameEntity.name ?: "",
action = "主动安装"
)
val (_, _, _, url) = mGameEntity.getApk()[0]
val url = mGameEntity.getApk().firstOrNull()?.url
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(url)
if (mGameEntity.simulator != null) {
val isInstalled = PackageUtils.isInstalledFromAllPackage(
@ -453,7 +465,10 @@ class DetailViewHolder(
}
}
ButtonStyle.UPDATING -> ToastUtils.toast("正在加急更新版本,敬请后续留意")
ButtonStyle.UPDATING -> {
ToastUtils.toast("正在加急更新版本,敬请后续留意")
showLandPageAddressDialogIfNeeded()
}
ButtonStyle.TEENAGER_MODE -> {
SensorsBridge.trackAdolescentModeDialogShow(
mGameEntity.id,
@ -523,7 +538,7 @@ class DetailViewHolder(
else -> if (mGameEntity.getApk().isNotEmpty()) {
val intent = DownloadManagerActivity.getDownloadMangerIntent(
mViewHolder.context,
mGameEntity.getApk()[0].url,
mGameEntity.getApk().firstOrNull()?.url,
StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])")
)
mViewHolder.context.startActivity(intent)
@ -531,8 +546,8 @@ class DetailViewHolder(
}
}
private fun showOffServiceDialog(dialog: GameEntity.Dialog?) {
val dialogFragment = GameOffServiceDialogFragment.getInstance(dialog!!)
private fun showOffServiceDialog(dialog: GameEntity.Dialog?, callback: () -> Unit) {
val dialogFragment = GameOffServiceDialogFragment.getInstance(dialog!!, callback)
dialogFragment.show((mViewHolder.context as FragmentActivity).supportFragmentManager, "off_service_dialog")
}
@ -545,8 +560,8 @@ class DetailViewHolder(
ToastUtils.toast("暂时无法下载,请稍后再试")
return
}
val apkEntity = mGameEntity.getApk()[0]
val msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity.size)
val apkEntity = mGameEntity.getApk().firstOrNull()
val msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity?.size ?: "")
if (TextUtils.isEmpty(msg)) {
val btnContainsUpdateText = mViewHolder.context.getString(R.string.update_v) == buttonText
|| buttonText.contains(mViewHolder.context.getString(R.string.update))

View File

@ -34,6 +34,6 @@ class GameImageViewHolder(var binding: GameImageItemBinding) : BaseRecyclerViewH
binding.gameImageIcon.hierarchy.roundingParams = roundingParams
}
ImageUtils.display(binding.gameImageIcon, entity.image, width)
ImageUtils.displayWithAdaptiveHeight(binding.gameImageIcon, entity.image, width)
}
}

View File

@ -272,12 +272,6 @@ class AmwayAdapter(
}
binding.commentContainer.setOnClickListener {
val exposureSource = if (useAlternativeLayout) {
arrayListOf(ExposureSource("新首页"), ExposureSource("安利墙"))
} else {
arrayListOf(ExposureSource("安利墙"))
}.toJson()
val intent = RatingReplyActivity.getIntent(
context = context,
gameId = amway.game.id,
@ -285,7 +279,7 @@ class AmwayAdapter(
comment = amway.comment,
commentId = amway.comment.id,
showKeyboardIfReplyListIsEmpty = false,
exposureSource = exposureSource,
exposureSource = basicExposureSource.toJson(),
entrance = viewModel.entrance ?: "",
path = EntranceConsts.ENTRANCE_AMWAY
)

View File

@ -142,8 +142,8 @@ class AmwayFragment : LazyListFragment<AmwayListItemData, AmwayViewModel>() {
override fun provideListAdapter(): ListAdapter<*> {
if (mAdapter == null) {
val basicExposureSource = arrayListOf<ExposureSource>().apply {
arguments?.getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE)?.let {
add(it)
arguments?.getParcelableArrayList<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)?.let {
addAll(it)
}
add(ExposureSource("安利墙", ""))
}
@ -160,14 +160,13 @@ class AmwayFragment : LazyListFragment<AmwayListItemData, AmwayViewModel>() {
mDefaultBinding?.run {
nightMaskView.goneIf(!mIsDarkModeOn)
if (!mIsFromMainWrapper) {
// toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
// [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
(toolbar.layoutParams as MarginLayoutParams).topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
WindowInsetsCompat.CONSUMED
}
} else {
// toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
// [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
(toolbar.layoutParams as MarginLayoutParams).topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
WindowInsetsCompat.CONSUMED
}
if (mIsFromMainWrapper) {
(toolbar.layoutParams as MarginLayoutParams).topMargin = statusBarHeight
}
@ -212,11 +211,6 @@ class AmwayFragment : LazyListFragment<AmwayListItemData, AmwayViewModel>() {
mListRefresh?.isEnabled = absOffset <= 2
}
if (mIsFromMainWrapper) {
fab.layoutParams = (fab.layoutParams as MarginLayoutParams).apply {
setMargins(0, 0, 14F.dip2px(), 72F.dip2px())
}
}
fab.setOnClickListener {
MtaHelper.onEvent("发表评论", "进入", "上墙")
ifLogin("安利墙") {

View File

@ -89,7 +89,7 @@ class AuthorizationActivity : ToolBarActivity() {
}
private fun initData() {
if (mToken.isNotEmpty()) return
if (mToken.isNotEmpty() || isFinishing) return
val loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
mViewModel.getAccessToken(listOf(mContent), {
mToken = it

View File

@ -493,7 +493,7 @@ class CategoryV2Fragment : LazyFragment() {
override fun onDarkModeChanged() {
super.onDarkModeChanged()
getItemMenu(R.id.menu_search).setIcon(R.drawable.ic_column_search)
getItemMenu(R.id.menu_search)?.setIcon(R.drawable.ic_column_search)
mBinding?.categoryRv?.adapter?.run {
mBinding?.categoryRv?.recycledViewPool?.clear()
notifyItemRangeChanged(0, itemCount)

View File

@ -21,8 +21,8 @@ import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.CategoryGameItemBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
@ -178,7 +178,7 @@ class CategoryV2ListAdapter(
trackEvent.put("game_status", gameEntity.category)
trackEvent.put(
"inclusion_size",
if (gameEntity.getApk().size == 1) gameEntity.getApk()[0].size ?: "" else ""
gameEntity.getApk().firstOrNull()?.size ?: ""
)
} catch (e: JSONException) {
e.printStackTrace()

View File

@ -23,7 +23,6 @@ import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.vspace.VArchiveHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import org.greenrobot.eventbus.EventBus
class MyArchiveOptionDialogFragment(

View File

@ -12,21 +12,26 @@ import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import com.gh.gamecenter.common.callback.OnListClickListener;
import com.gh.gamecenter.common.constant.ItemViewType;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.common.utils.ImageUtils;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.util.NewsUtils;
import com.gh.gamecenter.core.utils.NumberUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
import com.gh.gamecenter.adapter.viewholder.NewsImage1ViewHolder;
import com.gh.gamecenter.adapter.viewholder.NewsImage2ViewHolder;
import com.gh.gamecenter.adapter.viewholder.NewsImage3ViewHolder;
import com.gh.gamecenter.common.baselist.ListAdapter;
import com.gh.gamecenter.common.callback.OnListClickListener;
import com.gh.gamecenter.common.constant.ItemViewType;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.NumberUtils;
import com.gh.gamecenter.databinding.NewsImage1ItemBinding;
import com.gh.gamecenter.databinding.NewsImage2ItemBinding;
import com.gh.gamecenter.databinding.NewsImage3ItemBinding;
@ -34,7 +39,6 @@ import com.gh.gamecenter.databinding.PopupHistoryOptionBinding;
import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.history.ManageOption;
import com.gh.gamecenter.manager.VisitManager;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import org.json.JSONException;
@ -43,12 +47,9 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Locale;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import kotlin.collections.CollectionsKt;
/**
* Created by khy on 18/07/17.
@ -212,7 +213,7 @@ public class ArticleAdapter extends ListAdapter<NewsEntity> {
final NewsEntity newsEntity = mEntityList.get(position);
viewHolder.setClickData(newsEntity);
if (newsEntity.getThumbnail() != null && newsEntity.getThumbnail().getUrl() != null) {
ImageUtils.display(viewHolder.binding.newsImage1Thumb, newsEntity.getThumbnail().getUrl().get(0));
ImageUtils.display(viewHolder.binding.newsImage1Thumb, CollectionsKt.firstOrNull(newsEntity.getThumbnail().getUrl()));
} else {
ImageUtils.display(viewHolder.binding.newsImage1Thumb, R.drawable.message_image_placeholder);
}
@ -269,9 +270,11 @@ public class ArticleAdapter extends ListAdapter<NewsEntity> {
viewHolder.binding.newsImage2Title.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
viewHolder.binding.newsImage2Title.setTextColor(ContextCompat.getColor(mContext, R.color.hint));
}
ImageUtils.display(viewHolder.binding.newsImage2Thumb1, newsEntity.getThumbnail().getUrl().get(0));
ImageUtils.display(viewHolder.binding.newsImage2Thumb2, newsEntity.getThumbnail().getUrl().get(1));
ImageUtils.display(viewHolder.binding.newsImage2Thumb3, newsEntity.getThumbnail().getUrl().get(2));
if (newsEntity.getThumbnail() != null && newsEntity.getThumbnail().getUrl() != null) {
ImageUtils.display(viewHolder.binding.newsImage2Thumb1, CollectionsKt.getOrNull(newsEntity.getThumbnail().getUrl(), 0));
ImageUtils.display(viewHolder.binding.newsImage2Thumb2, CollectionsKt.getOrNull(newsEntity.getThumbnail().getUrl(), 1));
ImageUtils.display(viewHolder.binding.newsImage2Thumb3, CollectionsKt.getOrNull(newsEntity.getThumbnail().getUrl(), 2));
}
int views = newsEntity.getViews();
if (views == 0) {
viewHolder.binding.newsImage2Read.setVisibility(View.GONE);
@ -297,8 +300,10 @@ public class ArticleAdapter extends ListAdapter<NewsEntity> {
viewHolder.binding.selectIv.setVisibility(mCurrentOption == ManageOption.OPTION_MANAGER ? View.GONE : View.VISIBLE);
viewHolder.binding.selectIv.setChecked(selectItems.contains(newsEntity.getId()));
ImageUtils.display(viewHolder.binding.newsImage3Thumb, newsEntity.getThumbnail().getUrl().get(0),
mContext.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(mContext, 40));
if (newsEntity.getThumbnail() != null && newsEntity.getThumbnail().getUrl() != null) {
ImageUtils.displayWithAdaptiveHeight(viewHolder.binding.newsImage3Thumb, CollectionsKt.firstOrNull(newsEntity.getThumbnail().getUrl()),
mContext.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(mContext, 40));
}
int views = newsEntity.getViews();
if (views == 0) {
viewHolder.binding.newsImage3Read.setVisibility(View.GONE);

View File

@ -17,8 +17,8 @@ import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.InterestedGameEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Observable
@ -78,7 +78,7 @@ class DiscoveryViewModel(application: Application) : ListViewModel<GameEntity, D
itemDataList.add(
DiscoveryItemData(
cardPosition = 2,
interestImageCardLabel = mDiscoveryGameCardLabelMap["卡片二"]?.get(0)
interestImageCardLabel = mDiscoveryGameCardLabelMap["卡片二"]?.firstOrNull()
)
)
insertCount++

View File

@ -28,6 +28,7 @@ import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.IconFloat;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
@ -44,7 +45,6 @@ import com.lightgame.adapter.BaseRecyclerAdapter;
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 org.greenrobot.eventbus.EventBus;

View File

@ -153,7 +153,7 @@ class NewInstalledGameFragment : ToolbarFragment() {
reuseNoneData.reuseNoneDataDescTv.text = " 及时获悉游戏最新的更新消息"
reuseNoneData.reuseResetLoadTv.text = "去开启"
reuseNoneData.reuseResetLoadTv.setOnClickListener {
PermissionHelper.requestGetInstalledAppsListPermission(requireActivity()) {
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(requireActivity()) {
updateNoDataView()
PackageRepository.initData()
}

View File

@ -10,18 +10,23 @@ import androidx.core.view.setPadding
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.IExposable
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageLauncher
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.databinding.ItemUpdatableGameBinding
import com.gh.gamecenter.databinding.ItemUpdatableGameHeaderBinding
import com.gh.gamecenter.databinding.ItemUpdatableOtherGameHintBinding
import com.gh.gamecenter.databinding.LayoutPopupOptionItemBinding
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.exposure.ExposureEvent
@ -188,6 +193,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
DirectUtils.directToGameDetail(
context = context,
id = update.id,
name = update.name ?: "",
entrance = mViewModel.entrance,
traceEvent = update.exposureEvent
)
@ -383,70 +389,21 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
updateBtn.putWidgetBusinessName("下载管理")
updateBtn.putObject(update)
updateBtn.setOnClickListener {
val str: String = updateBtn.text.toString()
val str: String = updateBtn.text
if ("更新" == str || str.contains("")) {
// 这里用 CurrentActivity 不用 view.context 的原因是
// view.context 在 5.0 以下设备会使用 TintContextWrapper 包一层导致类型转换异常
if ("更新" == str && update.isLandPageAddressDialog()) {// 第三方落地页跳转直接展示跳转弹窗
DialogUtils.showLandPageAddressDialog(it.context, update.transformGameEntity()) {// 跳转第三方落地页
DirectUtils.directToExternalBrowser(it.context, update.landPageAddressDialog!!.link!!)
if (update.isLandPageAddressDialogShowOnly()) {
updateOrPluggable(updateBtn, update, downloadEntity, pluginDesc)
} else {
DirectUtils.directToExternalBrowser(it.context, update.landPageAddressDialog!!.link!!)
}
}
return@setOnClickListener
}
(CurrentActivityHolder.getCurrentActivity() as? FragmentActivity)?.checkStoragePermissionBeforeAction(
gameId = update.id,
gameName = update.name ?: "",
gameType = update.categoryChinese,
gameFormat = update.format,
) {
DialogUtils.checkDownload(
updateBtn.context,
update.size,
update.id,
update.name ?: "",
update.categoryChinese
) { isSubscribe: Boolean ->
if (str.contains("")) {
if (update.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(
updateBtn.context,
update.transformGameEntity(),
update.exposureEvent,
mViewModel.entrance,
pluginDesc + "化:" + update.name
)
return@checkDownload
} else {
updateBtn.text = "0%"
updateBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN
updateBtn.progress = 0
}
} else {
updateBtn.text = "0%"
updateBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
updateBtn.progress = 0
}
// 如果历史下载 downloadEntity 不为空,且版本与当前需要更新的不一致,先移除旧任务再执行更新
if ((downloadEntity?.isVGameDownloadInDualDownloadMode() == true
|| downloadEntity?.isLocalDownloadInDualDownloadMode() == true)
&& (update.version != downloadEntity.versionName)
) {
DownloadManager.getInstance().cancel(downloadEntity.url ?: "")
}
mViewModel.update(update, isSubscribe)
mViewModel.refreshList()
EventBus.getDefault()
.post(
EBSkip(
DownloadManagerActivity.TAG,
DownloadManagerActivity.INDEX_DOWNLOAD
)
)
}
}
updateOrPluggable(updateBtn, update, downloadEntity, pluginDesc)
} else if (updateBtn.context.getString(R.string.launch) == str) {
PackageLauncher.launchApp(updateBtn.context, packageName = update.packageName)
} else if (updateBtn.context.getString(R.string.resume) == str) {
@ -483,6 +440,68 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
}
}
private fun updateOrPluggable(
updateBtn: DownloadButton,
update: GameUpdateEntity,
downloadEntity: DownloadEntity?,
pluginDesc: String
) {
val str: String = updateBtn.text
(CurrentActivityHolder.getCurrentActivity() as? FragmentActivity)?.checkStoragePermissionBeforeAction(
gameId = update.id,
gameName = update.name ?: "",
gameType = update.categoryChinese,
gameFormat = update.format,
) {
DialogUtils.checkDownload(
updateBtn.context,
update.size,
update.id,
update.name ?: "",
update.categoryChinese
) { isSubscribe: Boolean ->
if (str.contains("")) {
if (update.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(
updateBtn.context,
update.transformGameEntity(),
update.exposureEvent,
mViewModel.entrance,
pluginDesc + "化:" + update.name
)
return@checkDownload
} else {
updateBtn.text = "0%"
updateBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN
updateBtn.progress = 0
}
} else {
updateBtn.text = "0%"
updateBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
updateBtn.progress = 0
}
// 如果历史下载 downloadEntity 不为空,且版本与当前需要更新的不一致,先移除旧任务再执行更新
if ((downloadEntity?.isVGameDownloadInDualDownloadMode() == true
|| downloadEntity?.isLocalDownloadInDualDownloadMode() == true)
&& (update.version != downloadEntity.versionName)
) {
DownloadManager.getInstance().cancel(downloadEntity.url ?: "")
}
mViewModel.update(update, isSubscribe)
mViewModel.refreshList()
EventBus.getDefault()
.post(
EBSkip(
DownloadManagerActivity.TAG,
DownloadManagerActivity.INDEX_DOWNLOAD
)
)
}
}
}
private fun generateExposureEvent(updateEntity: GameUpdateEntity) {
updateEntity.exposureEvent =
createEvent(updateEntity.transformGameEntity(), mExposureSource)

View File

@ -4,7 +4,6 @@ import android.view.View
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
@ -12,12 +11,10 @@ import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentGameUpdatableBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
@ -40,7 +37,6 @@ class UpdatableGameFragment : LazyFragment() {
}
}
override fun getRealLayoutId() = R.layout.fragment_game_updatable
override fun onRealLayoutInflated(inflatedView: View) {
mBinding = FragmentGameUpdatableBinding.bind(inflatedView)
@ -104,15 +100,14 @@ class UpdatableGameFragment : LazyFragment() {
noDataContainer.reuseNoneDataDescTv.text = "及时获悉游戏最新的更新消息"
noDataContainer.reuseResetLoadTv.text = "去开启"
noDataContainer.reuseResetLoadTv.setOnClickListener {
PermissionHelper.requestGetInstalledAppsListPermission(
requireActivity(),
false,
object : EmptyCallback {
override fun onCallback() {
updateNoDataView()
PackageRepository.initData()
}
})
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(
requireActivity()
) { isGranted ->
if (isGranted) {
updateNoDataView()
PackageRepository.initData()
}
}
}
} else {
noDataContainer.reuseNoneDataIv.visibility = View.VISIBLE

View File

@ -13,6 +13,8 @@ class AdConfig(
val displayRule: DisplayRule,
@SerializedName("third_party_ads")
val thirdPartyAd: ThirdPartyAd? = null,
@SerializedName("third_party_ads_1")
val hotStartThirdPartyAd: ThirdPartyAd? = null, // 热启动开屏广告
@SerializedName("owner_ads")
val ownerAd: OwnerAdEntity? = null,
) {

View File

@ -11,16 +11,33 @@ data class CommonCollectionEntity(
val type: String = "",
val style: String = "",
val more: Int = 0,
val layout: Int = -1, // 对应自定义页面的layout样式
@SerializedName("home_page_style")
val homePageStyle: String = "horizontal_sliding", //首页样式 横排滑动horizontal_sliding 竖排一行两个1-2
@SerializedName("vertical_line")
val verticalLine: String = "", // 竖排时才有数据,代表竖排行数控制
@SerializedName("common_collection_content")
val collectionList: MutableList<CommonCollectionContentEntity> = mutableListOf()
)
) {
val layoutChinese: String
get() = when (layout) {
0 -> "轮播banner"
1 -> "导航栏"
2 -> "金刚区"
3 -> "横向滑动banner"
4 -> "双列banner"
5 -> "横排竖式卡片"
6 -> "双列竖式卡片"
7 -> "竖式图文列表"
8 -> "横排图文列表"
else -> ""
}
}
@Parcelize
data class CommonCollectionContentEntity(
@SerializedName("_id")
private val _id: String? = null,
val title: String = "",
val style: String = "",
val image: String = "",
@ -30,4 +47,8 @@ data class CommonCollectionContentEntity(
var addedContent1: String? = "",
@SerializedName("added_content_2")
var addedContent2: String? = "",
) : Parcelable
) : Parcelable {
val id: String
get() = _id ?: ""
}

View File

@ -2,12 +2,10 @@ package com.gh.gamecenter.entity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.entity.*
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.IgnoredOnParcel
import java.util.*
import kotlin.collections.ArrayList
data class GameUpdateEntity(
@SerializedName("game_id")
@ -76,9 +74,8 @@ data class GameUpdateEntity(
/**
* 是否为 mod 游戏,根据是否有 mod 标签来判断,不受镜像、游戏屏蔽影响
*/
val isModdedGame by lazy {
tagStyle.any { it.name.lowercase(Locale.getDefault()) == "mod" }
}
val isModdedGame: Boolean
get() = tagStyle.any { it.name.lowercase(Locale.getDefault()) == "mod" }
fun isShowPlugin(location: PluginLocation): Boolean {
@ -95,6 +92,11 @@ data class GameUpdateEntity(
return landPageAddressDialog?.let { it.status == "on" } ?: false
}
/**
* 第三方落地页的状态是否为“仅显示弹窗”
*/
fun isLandPageAddressDialogShowOnly(): Boolean = landPageAddressDialog?.showOnly == true
fun transformGameEntity(): GameEntity {
val gameEntity = GameEntity()
gameEntity.id = id

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
@ -17,6 +18,8 @@ data class HomeRecommend(
val display: Display = Display(),
@SerializedName("image")
private val _image: String? = null,
@SerializedName("link_community")
private val community: CommunityEntity? = null,
// 绑定的曝光实体
var exposureEvent: ExposureEvent? = null,
@ -31,7 +34,8 @@ data class HomeRecommend(
type = linkType,
display = display,
link = linkId,
text = linkText
text = linkText,
community = community
)
}
}

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
@ -19,7 +20,9 @@ data class HomeSlide(
val title: String = "",
val text: String = "",
@SerializedName("placeholder_color")
val placeholderColor: String = "#5C9599"
val placeholderColor: String = "#5C9599",
@SerializedName("link_community")
val community: CommunityEntity? = null
) {
fun transformLinkEntity(): LinkEntity {
@ -27,7 +30,8 @@ data class HomeSlide(
name = title,
type = linkType,
link = linkId,
text = linkText
text = linkText,
community = community
)
}
}

View File

@ -8,6 +8,8 @@ data class PullDownPush(
val id: String = "",
@SerializedName("pop_switch")
val popSwitch: String = "",
@SerializedName("put_away_switch")
val putAwaySwitch: String = "", // 自动收起never永不、video_finished视频播放完毕视频必填、nn秒后5-15秒后
val description: String = "",
@SerializedName("img_url")
val imgUrl: String = "",

View File

@ -9,7 +9,7 @@ class StartupAdEntity(
var id: String,
val desc: String,
val button: Boolean,
val jump: LinkEntity,
val jump: LinkEntity = LinkEntity(),
val img: String = "",
// 显示规则: none无, each每一次打开, everyday每一天一次, once一次
val rule: String = "",

View File

@ -26,6 +26,8 @@ class SubjectSettingEntity(
var filterOptions: List<String> = ArrayList(), // 过滤选项,推荐、最新、评分、更新
@SerializedName("ad_icon_active")
var adIconActive: Boolean = false,
@SerializedName("column_style")
var columnStyle: String = "", // 对应自定义页面的专题样式
) : Parcelable {
@Parcelize
class TypeEntity(

View File

@ -134,9 +134,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
override fun onLoadRefresh() {
super.onLoadRefresh()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
// Fixhttps://sentry.shanqu.cc/organizations/lightgame/issues/288994/?project=22&query=LazyListFragment&statsPeriod=14d
// Fragment在内存泄露的情况下调用requireView()会触发崩溃这里替换为getView()方法
// TODO 解决Fragment内存泄露的问题
@ -145,9 +147,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
override fun onLoadDone() {
super.onLoadDone()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
view?.setBackgroundColor(Color.TRANSPARENT)
mBaseHandler.postDelayed(Runnable {
tryCatchInRelease {
@ -159,25 +163,31 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
override fun onLoadError() {
super.onLoadError()
mBinding.nestedScrollNoConnection.root.visibility = View.VISIBLE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.VISIBLE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
view?.setBackgroundColor(Color.TRANSPARENT)
}
override fun onLoadEmpty() {
super.onLoadEmpty()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.VISIBLE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.VISIBLE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
view?.setBackgroundColor(Color.TRANSPARENT)
}
override fun loadNotFound() {
super.loadNotFound()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.VISIBLE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.VISIBLE
}
}
override fun hideRefreshingLayout() {

View File

@ -16,7 +16,10 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.view.animation.AnimationUtils
import android.widget.*
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
@ -38,7 +41,6 @@ import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
import com.facebook.drawee.generic.RoundingParams
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.browse.BrowseTimer
import com.gh.common.browse.ValueBrowseTimer
import com.gh.common.browse.asObserver
import com.gh.common.browse.withLifecycle
@ -57,6 +59,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.databinding.ItemIconTabBinding
import com.gh.gamecenter.common.databinding.PopupAllTabsBinding
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.common.mvvm.Status
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.utils.*
@ -65,7 +68,9 @@ import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.FragmentForumDetailBinding
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.entity.ApplyModeratorStatusEntity
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.eventbus.EBForumFollowChange
import com.gh.gamecenter.eventbus.EBTopCommunityChanged
import com.gh.gamecenter.eventbus.EBTypeChange
@ -92,7 +97,6 @@ import com.halo.assistant.fragment.WebFragment
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import com.gh.gamecenter.common.mvvm.Resource
import kotlin.math.abs
class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
@ -259,9 +263,11 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mViewModel?.forumDetail?.observe(viewLifecycleOwner, browseTimer.asObserver())
ViewCompat.setOnApplyWindowInsetsListener(mBinding.forumAppbar) { _, insets ->
(mBinding.toolbar.layoutParams as MarginLayoutParams).topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
WindowInsetsCompat.CONSUMED
if (!mIsFromTabWrapper) {
ViewCompat.setOnApplyWindowInsetsListener(mBinding.forumAppbar) { _, insets ->
(mBinding.toolbar.layoutParams as MarginLayoutParams).topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
WindowInsetsCompat.CONSUMED
}
}
if (mIsFromMainWrapper) {
(mBinding.toolbar.layoutParams as MarginLayoutParams).topMargin = DisplayUtils.getStatusBarHeight(requireContext().resources)

View File

@ -25,6 +25,8 @@ import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
import io.reactivex.disposables.Disposable
import java.util.*
import android.os.Handler
import android.os.Looper
class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
StandardGSYVideoPlayer(context, attrs) {
@ -49,6 +51,8 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
private var mStartTrackRunnable: Runnable? = null
private var mStopTrackRunnable: Runnable? = null
private val mTrackHandler = Handler(Looper.getMainLooper())
override fun getLayoutId(): Int {
return R.layout.layout_article_item_video
}
@ -265,7 +269,7 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
&& currentState != CURRENT_STATE_PLAYING_BUFFERING_START) {// 上报开始视频播放埋点
// 视频停止播放后再恢复播放的间隔时间未超过3秒则取消上报结束视频播放埋点
mStopTrackRunnable?.let { runnable ->
handler.removeCallbacks(runnable)
mTrackHandler.removeCallbacks(runnable)
}
mVideoEntity?.let {
@ -286,7 +290,7 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
mStartTrackRunnable = it
}
// 埋点要求视频播放3秒后再上报埋点
handler.postDelayed(startTrackRunnable, 3000)
mTrackHandler.postDelayed(startTrackRunnable, 3000)
}
} else if (currentState != state
&& (state == CURRENT_STATE_AUTO_COMPLETE
@ -296,7 +300,7 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
) {// 上报结束视频播放埋点
// 从开始播放视频到停止播放视频的间隔时间没有超过3秒则取消上报开始视频播放埋点
this.mStartTrackRunnable?.let {
handler.removeCallbacks(it)
mTrackHandler.removeCallbacks(it)
mStartTrackRunnable = null
} ?: let {
mVideoEntity?.let {
@ -317,7 +321,7 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
this.mStopTrackRunnable = it
}
// 埋点要求停止视频播放3秒后再上报埋点
handler.postDelayed(stopTrackRunnable, 3000)
mTrackHandler.postDelayed(stopTrackRunnable, 3000)
}
}
}
@ -409,7 +413,7 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
val shareUrl = if (isPublishEnv()) {
"https://m.ghzs666.com/video/${it.id}"
} else {
"https://resource.ghzs.com/page/video_play/video/video.html?video=${it.id}"
"https://dev-and-static.ghzs66.com/page/video_play/video/video.html?video=${it.id}"
}
val additionalParams = AdditionalParamsEntity().apply {
contentType = "视频帖"

View File

@ -8,23 +8,24 @@ import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
import com.gh.gamecenter.common.avoidcallback.Callback
import com.gh.common.dialog.ApplyModeratorDialogFragment
import com.gh.common.util.*
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
import com.gh.gamecenter.common.avoidcallback.Callback
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.core.utils.ClickUtils
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.utils.ClickUtils
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.FragmentApplyModeratorBinding
import com.gh.gamecenter.entity.ApplyModeratorStatusEntity
import com.gh.gamecenter.entity.ApplyModeratorTaskEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.core.utils.ToastUtils
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
@ -175,19 +176,19 @@ class ApplyModeratorFragment : ToolbarFragment() {
private fun checkStatus(status: ApplyModeratorStatusEntity) {
if (mDataList.size > 0) {
if (status.condition.etiquette) {
mDataList[0].finishedTask = true
mDataList.firstOrNull()?.finishedTask = true
mAdapter?.notifyItemChanged(0)
}
if (status.condition.idCard) {
mDataList[1].finishedTask = true
mDataList.getOrNull(1)?.finishedTask = true
mAdapter?.notifyItemChanged(1)
}
if (status.condition.activity) {
mDataList[2].finishedTask = true
mDataList.getOrNull(2)?.finishedTask = true
mAdapter?.notifyItemChanged(2)
}
if (status.condition.choiceness) {
mDataList[3].finishedTask = true
mDataList.getOrNull(3)?.finishedTask = true
mAdapter?.notifyItemChanged(3)
}
var allFinished = true

View File

@ -45,6 +45,12 @@ class UpdateDialogFragment : BaseDialogFragment() {
private var mIsDisplayingDownloadingStyle = false // 是否正在显示更新中样式
private val mDataWatcher = object : DataWatcher() {
override fun onDataInit(downloadEntity: DownloadEntity) {
super.onDataInit(downloadEntity)
onDataChanged(downloadEntity)
}
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.name.contains("光环助手")) {
if (mIsDisplayingDownloadingStyle) {
@ -74,13 +80,11 @@ class UpdateDialogFragment : BaseDialogFragment() {
return
}
DownloadManager.getInstance().addObserver(mDataWatcher)
mUpdateEntity = arguments?.getParcelable(UPDATE_ENTITY)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
showUpdateHintStyle(requireContext(), mUpdateEntity!!)
showUpdateHintStyle(requireContext(), mUpdateEntity!!, true)
return mBinding.root
}
@ -109,8 +113,14 @@ class UpdateDialogFragment : BaseDialogFragment() {
mDismissCallback?.onCallback()
}
override fun onDestroyView() {
super.onDestroyView()
override fun onStart() {
super.onStart()
DownloadManager.getInstance().addObserver(mDataWatcher)
}
override fun onStop() {
super.onStop()
DownloadManager.getInstance().removeObserver(mDataWatcher)
}
@ -120,7 +130,9 @@ class UpdateDialogFragment : BaseDialogFragment() {
* @param context 上下文
* @param updateEntity 更新实体
*/
private fun showUpdateHintStyle(context: Context, updateEntity: AppEntity) {
private fun showUpdateHintStyle(context: Context,
updateEntity: AppEntity,
invokeByViewCreated: Boolean) {
mIsDisplayingDownloadingStyle = false
val updateHintBinding = mBinding.updateHintContainerView
@ -200,12 +212,15 @@ class UpdateDialogFragment : BaseDialogFragment() {
)
}
SensorsBridge.trackVersionUpdateDialogShow(
keyDialogReminderTime = mUpdateEntity?.alert,
keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
)
if (invokeByViewCreated) {
SensorsBridge.trackVersionUpdateDialogShow(
keyDialogReminderTime = mUpdateEntity?.alert,
keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
)
DataLogUtils.uploadUpgradeLog(context, "notice") //上传更新通知弹窗数据
}
DataLogUtils.uploadUpgradeLog(context, "notice") //上传更新通知弹窗数据
}
/**
@ -294,13 +309,8 @@ class UpdateDialogFragment : BaseDialogFragment() {
if (DownloadStatus.done == downloadEntity.status) {
DownloadManager.getInstance().cancel(downloadEntity.url, false, true, false)
try {
dismiss()
} catch (ignored: IllegalArgumentException) {
// do nothing
}
if (updateEntity.isForce) {
AppExecutor.uiExecutor.executeWithDelay({ UpdateHelper.exitApp() }, 1000L)
tryWithDefaultCatch {
showUpdateHintStyle(requireContext(), updateEntity, false)
}
} else if (DownloadStatus.neterror == downloadEntity.status) {
ToastUtils.toast("网络错误,请稍后重试")

View File

@ -1,37 +1,26 @@
package com.gh.gamecenter.fragment
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.animation.PathInterpolator
import android.widget.RelativeLayout
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
import com.gh.gamecenter.common.view.WrapContentDraweeView
import com.gh.gamecenter.core.provider.IFloatingWindowProvider
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.addListener
import com.gh.gamecenter.databinding.DialogWelcomeBinding
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.halo.assistant.HaloApp
@ -44,12 +33,6 @@ class WelcomeDialogFragment : BaseDialogFragment() {
private var mDismissListener: (() -> Unit)? = null
private var mShowEnterAnimation: Boolean = false
private var mShowExitAnimation: Boolean = false
// 触发此 dialogFragment 的 fragment可能为空
private var mTriggerFragment: BaseLazyFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -67,11 +50,6 @@ class WelcomeDialogFragment : BaseDialogFragment() {
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(root)
if (mShowEnterAnimation) {
dialog.window?.setDimAmount(0F)
} else {
dialog.window?.setDimAmount(0.5F)
}
dialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
return dialog
}
@ -93,22 +71,6 @@ class WelcomeDialogFragment : BaseDialogFragment() {
mWelcomeEntity?.let {
DirectUtils.directToLinkPage(requireContext(), it, EntranceConsts.ENTRANCE_WELCOME, "", "首页弹窗")
if (mShowEnterAnimation) {
val floatingWindowProvider =
ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
.navigation() as? IFloatingWindowProvider<WelcomeDialogEntity>
floatingWindowProvider?.logWindowClicked(
action = "点击弹窗跳转页面",
windowId = mWelcomeEntity?.floatingWindowId ?: "",
source = "首页",
gameId = "",
gameName = "",
linkId = mWelcomeEntity?.link ?: "",
linkType = mWelcomeEntity?.type ?: "",
linkText = mWelcomeEntity?.text ?: ""
)
}
}
dismissAllowingStateLoss()
@ -123,10 +85,6 @@ class WelcomeDialogFragment : BaseDialogFragment() {
} else {
mBinding.ivClose.visibility = View.VISIBLE
}
if (mShowEnterAnimation) {
performAnimation(true)
}
}
mBinding.ivOpeningCover.registerLoadingCallback(null)
@ -134,33 +92,11 @@ class WelcomeDialogFragment : BaseDialogFragment() {
})
mBinding.ivCloseBackup.setOnClickListener {
val floatingWindowProvider =
ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
.navigation() as? IFloatingWindowProvider<WelcomeDialogEntity>
// 来源 fragment 是否不可见
if (mTriggerFragment?.isCurrentlyVisible() == false) {
mShowExitAnimation = false
} else {
floatingWindowProvider?.showHiddenWindow(requireActivity())
}
if (mShowExitAnimation) {
dismissWithAnimation()
} else {
dismissAllowingStateLoss()
}
dismissAllowingStateLoss()
}
mBinding.ivClose.setOnClickListener { mBinding.ivCloseBackup.performClick() }
ImageUtils.displayWithoutMemoryCache(mBinding.ivOpeningCover, mWelcomeEntity?.icon)
// 弹起启动弹窗时,把右下角悬浮窗置为隐藏
val floatingWindowProvider =
ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
.navigation() as? IFloatingWindowProvider<WelcomeDialogEntity>
floatingWindowProvider?.hideWindow(requireActivity())
return mBinding.root
}
@ -180,132 +116,14 @@ class WelcomeDialogFragment : BaseDialogFragment() {
mDismissListener = dismissListener
}
/**
* 显示动画
* @param isEnterAnimation 是否为进入动画
*/
private fun performAnimation(isEnterAnimation: Boolean) {
// 贝塞尔曲线需要 Android 版本大于 Android 5.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val screenWidth = DisplayUtils.getScreenWidth(requireActivity())
val screenHeight = DisplayUtils.getScreenHeight(requireActivity())
val statusBarHeight = DisplayUtils.getStatusBarHeight(requireContext().resources)
// 最大宽度为 300dp
val maxWidth = 300F
val initialWidth = 1F
val containerWidth = mBinding.container.width
val containerHeight = containerWidth / mBinding.ivOpeningCover.aspectRatio + 54F.dip2px()
val location = IntArray(2)
mBinding.container.getLocationOnScreen(location)
val xOffsetToTheScreen = location[0]
// 由于显示的时机问题mBinding.container.getLocationOnScreen(location) 获取到的纵座标不一定是真实在屏幕的高度,这里手动计算
val yOffsetToTheScreen = (screenHeight - containerHeight) / 2 + statusBarHeight
val scaleRatio = initialWidth / maxWidth
// 获取动画原点的 X, Y 座标,由于 scale 会变化,所以需要结合 scale 进行计算
val initialX = (screenWidth - 40F.dip2px() - xOffsetToTheScreen) - (containerWidth * (1 - scaleRatio)) / 2
val initialY =
(screenHeight - 156F.dip2px() - yOffsetToTheScreen) - (containerHeight * (1 - scaleRatio)) / 2 + statusBarHeight
val startX = if (isEnterAnimation) initialX else 0F
val startY = if (isEnterAnimation) initialY else 0F
val startScale = if (isEnterAnimation) scaleRatio else 1F
val endScale = if (isEnterAnimation) 1F else scaleRatio
val endX = if (isEnterAnimation) 0F else initialX
val endY = if (isEnterAnimation) 0F else initialY
val enteringTranslationXInterpolator = PathInterpolator(0.4F, 1.6F, 0.4F, 1.24F)
val enteringTranslationYInterpolator = PathInterpolator(0.4F, 1.8F, 0.4F, 1.24F)
val exitingTranslationXInterpolator = PathInterpolator(0.6F, -0.24F, 0.6F, -0.6F)
val exitingTranslationYInterpolator = PathInterpolator(0.6F, -0.24F, 0.6F, -0.2F)
val enteringScaleInterpolator = PathInterpolator(0.61F, 1F, 0.88F, 1F)
val exitingScaleInterpolator = PathInterpolator(0.12F, 0F, 0.39F, 0F)
val translationXAnimator =
ObjectAnimator.ofFloat(mBinding.container, "translationX", startX, endX).apply {
interpolator =
if (isEnterAnimation) enteringTranslationXInterpolator else exitingTranslationXInterpolator
}
val translationYAnimator =
ObjectAnimator.ofFloat(mBinding.container, "translationY", startY, endY).apply {
interpolator =
if (isEnterAnimation) enteringTranslationYInterpolator else exitingTranslationYInterpolator
}
val scaleXAnimator = ObjectAnimator.ofFloat(mBinding.container, "scaleX", startScale, endScale).apply {
addUpdateListener {
val dimAmount = it.animatedValue as Float / 2
dialog?.window?.setDimAmount(dimAmount)
// 避免与原有悬浮窗重叠,退出动画执行到 95% 进度后隐藏
if (!isEnterAnimation && (it.animatedValue as Float) < 0.05F) {
mBinding.container.visibility = View.GONE
} else {
mBinding.container.visibility = View.VISIBLE
}
}
}
val scaleYAnimator = ObjectAnimator.ofFloat(mBinding.container, "scaleY", startScale, endScale)
val scaleAnimatorSet = AnimatorSet().apply {
playTogether(scaleXAnimator, scaleYAnimator)
interpolator = if (isEnterAnimation) enteringScaleInterpolator else exitingScaleInterpolator
}
mBinding.root.pivotX = mBinding.root.width / 2F
mBinding.root.pivotY = mBinding.root.height / 2F
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val translationAnimatorSet = AnimatorSet().apply {
playTogether(translationXAnimator, translationYAnimator)
}
AnimatorSet().apply {
playTogether(
scaleAnimatorSet,
translationAnimatorSet
)
addListener(
onStart = {
mBinding.container.isClickable = false
mBinding.ivOpeningCover.isClickable = false
mBinding.ivClose.isClickable = false
},
onEnd = {
if (!isEnterAnimation) {
dismissAllowingStateLoss()
}
mBinding.container.isClickable = true
mBinding.ivOpeningCover.isClickable = true
mBinding.ivClose.isClickable = true
}
)
duration = ANIMATION_DURATION
}.start()
}
}
private fun dismissWithAnimation() {
performAnimation(false)
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
// 仅不显示进入动画的首页弹窗记录 id
if (!mShowEnterAnimation) {
val sp = PreferenceManager.getDefaultSharedPreferences(context?.applicationContext)
// 首页弹窗记录 id
val sp = PreferenceManager.getDefaultSharedPreferences(context?.applicationContext)
SPUtils.setString(sp, Constants.SP_LAST_OPENING_ID, mWelcomeEntity?.id)
SPUtils.setLong(sp, Constants.SP_LAST_OPENING_TIME, mWelcomeEntity?.time ?: 0L)
}
SPUtils.setString(sp, Constants.SP_LAST_OPENING_ID, mWelcomeEntity?.id)
SPUtils.setLong(sp, Constants.SP_LAST_OPENING_TIME, mWelcomeEntity?.time ?: 0L)
mDismissListener?.invoke()
LogUtils.uploadWelcomeDialog(
@ -320,14 +138,8 @@ class WelcomeDialogFragment : BaseDialogFragment() {
companion object {
const val TAG = "welcome_dialog"
const val ANIMATION_DURATION = 800L
@JvmStatic
fun getInstance(
welcomeEntity: WelcomeDialogEntity?,
withAnimation: Boolean = false,
triggerFragment: BaseLazyFragment? = null
) = WelcomeDialogFragment().apply {
fun getInstance(welcomeEntity: WelcomeDialogEntity?) = WelcomeDialogFragment().apply {
arguments = Bundle()
arguments?.putParcelable(TAG, welcomeEntity)
LogUtils.uploadWelcomeDialog(
@ -338,21 +150,6 @@ class WelcomeDialogFragment : BaseDialogFragment() {
welcomeEntity?.text
)
mTriggerFragment = triggerFragment
// 低于 Android 5.0 禁用动画,因为贝塞尔曲线需要 5.0+ 支持
mShowEnterAnimation = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
false
} else {
withAnimation
}
mShowExitAnimation = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
false
} else {
withAnimation || welcomeEntity?.shouldShowExitAnimation == true
}
SensorsBridge.trackEvent("HomeDialogShow")
}
}

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