Compare commits

...

359 Commits

Author SHA1 Message Date
06260a2ae3 refactor: update commit id. 2024-03-12 16:32:36 +08:00
f7972046e7 refactor: update commit id. 2024-03-12 16:00:53 +08:00
b5f1634b19 feat: 合并部分云存档代码 2024-03-12 09:59:48 +08:00
e8e629028b refactor: update vasdk 2024-03-11 10:27:07 +08:00
3f2d0a4db4 refactor: update vasdk commit id. 2024-03-06 14:30:59 +08:00
057590e1d0 refactor: update vasdk commit id. 2024-03-06 13:55:00 +08:00
bcd46e45e2 fix: 谷歌框架安装区分旧版还是新版畅玩组件 2024-03-05 15:01:04 +08:00
1a268eb02f fix: 优化部分启动逻辑&修复个别游戏因为安装架构选择导致黑屏无法启动 2024-03-05 14:35:32 +08:00
6beb746f21 fix: update meta_build.sh 2024-03-04 14:41:56 +08:00
34fafcdfa0 feat: agp 7.1.3 gradle打包产物位置有变更,考虑到插件更新逻辑已变更,不需要在编译光环助手时同步编译插件了,所以修改为手动编译插件,再copy到build/plugin目录 2024-03-01 17:28:51 +08:00
4d2606cc83 refactor: update submodule commit id 2024-03-01 15:19:15 +08:00
8f908b54c7 refactor: update submodule commit id 2024-03-01 14:49:13 +08:00
7af085df34 refactor: update ndownload commit id 2024-03-01 11:01:38 +08:00
00bdb0a3cc refactor: update vasdk commit id. 2024-03-01 10:56:36 +08:00
0d329a19b0 refactor: update vasdk commit id. 2024-03-01 10:56:36 +08:00
2edbfc505c feat: 32位组件安装插件 2024-03-01 10:56:36 +08:00
ee8748a954 refactor: update version 2024-03-01 10:56:36 +08:00
3bdd419183 fix: 插件更新逻辑 2024-03-01 10:56:36 +08:00
7c8c3a4679 refactor: update vasdk commit id. 2024-03-01 10:56:36 +08:00
8fc5be0e51 feat: 添加更新按钮。 2024-03-01 10:56:36 +08:00
6cc73d4b05 fix:修复一体化,畅玩游戏启动判断 2024-03-01 10:56:36 +08:00
fe6405fac3 fix: 修复卸载apk不生效 2024-03-01 10:56:36 +08:00
88dd3ea5ec fix:新旧版本畅玩组件isInstalled语义错误 2024-03-01 10:56:36 +08:00
0641761143 fix:新旧版本畅玩组件isInstalled语义错误 2024-03-01 10:56:36 +08:00
5adde797e1 fix:畅玩游戏无法更新的问题 2024-03-01 10:56:36 +08:00
7c346c632c refactor: update vasdk commit id 2024-03-01 10:56:35 +08:00
17b7101912 refactor: update vasdk commit id 2024-03-01 10:56:35 +08:00
7e1cafee4b refactor: update commit id 2024-03-01 10:56:35 +08:00
03df8e1012 feat: 32位组件更新下载 2024-03-01 10:56:35 +08:00
bb66f4af06 refactor!: 添加测试环境的脚本 2024-03-01 10:56:35 +08:00
6b1e92ee3d refactor!: 添加测试环境的脚本 2024-03-01 10:56:35 +08:00
ec1c92cfe0 feat: new/upgrade接口参数修改 2024-03-01 10:56:35 +08:00
89b85b115e feat: 畅玩32位和插件的更新流程 2024-03-01 10:56:35 +08:00
d4e2788d8d refactor!: 临时修改打包测试版本 2024-03-01 10:55:43 +08:00
865903d0da refactor: 优化畅玩32 debug打包步骤 2024-03-01 10:55:43 +08:00
3afebb1e38 feat: 获取32位组件和插件的接口数据 2024-03-01 10:55:43 +08:00
feab4f4f76 refactor: update commit id 2024-03-01 10:55:43 +08:00
4054f66b4b feat: 修改va配置读取 2024-03-01 10:55:43 +08:00
b5ee2679e9 feat: 修改plugin配置读取 2024-03-01 10:55:43 +08:00
c060480b23 fix: 修复头条,快手等其他flavor脚本打包出错的问题 2024-03-01 10:55:37 +08:00
26f09057ba refactor: upgrade shadow_version to 1.0.4 2024-03-01 10:53:48 +08:00
b1457f795d refactor: update vasdk commit id. 2024-03-01 10:53:48 +08:00
193e4487c9 fix: min sdk version smaller than 21. 2024-03-01 10:53:48 +08:00
32bff3836e refactor: 更新shadow版本至 1.0.3 2024-03-01 10:53:48 +08:00
64c35e9181 refactor: 更新maven拉取顺序 2024-03-01 10:53:48 +08:00
63783e374d refactor: 更新apk文件路径 2024-03-01 10:53:46 +08:00
020222a451 refactor: 下载插件到assets目录 2024-03-01 10:52:04 +08:00
15df636967 refactor: 更新打包脚本 2024-03-01 10:52:01 +08:00
aaa552ffdc feat: 展示64位va插件版本信息 https://jira.shanqu.cc/browse/GHZS-3885 2024-03-01 10:46:44 +08:00
9a372ba269 fix: 过滤va项目的配置&修复错误的assets添加脚步 2024-03-01 10:44:56 +08:00
56383b2938 feat: 光环助手va组件兼容旧版畅玩助手游戏业务 2024-03-01 10:44:56 +08:00
c6f161999d feat: 接入vasdk编译通过 2024-03-01 10:44:56 +08:00
d796739b3c refactor: va模块引用 2024-03-01 10:44:54 +08:00
922c8e5cde feat: 加速器模块占用空间太大,给ci/cd集成增加时间成本,考虑到加速器变更频繁度较低,改为maven引用 2024-03-01 10:43:00 +08:00
e0611ebfca feat: 同步vasdk的代码 2024-03-01 10:43:00 +08:00
fed1f7b90f feat: 接入va模块 2024-03-01 10:42:58 +08:00
fabd160a72 Merge branch 'fix/game_detail_vgame_update' into 'dev'
feat: 修复游戏详情页仅显示一个按钮时,畅玩游戏更新无法正常执行的问题

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

See merge request halo/android/assistant-android!1465
2023-12-05 10:27:39 +08:00
78ff8dcb0a fix: 游戏下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-4364
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-12-01 16:54:40 +08:00
80e7ad9401 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-12-01 10:08:09 +08:00
0c807922d6 chore: 版本更新至 5.32.5 2023-11-29 16:51:00 +08:00
d7f5b573c6 Merge branch 'hotfix/v5.32.4-994/provider_conflict' into 'release'
fix: 移除穿山甲广告 tools 依赖

See merge request halo/android/assistant-android!1463
2023-11-29 16:50:04 +08:00
f9d624b077 fix: 移除穿山甲广告 tools 依赖 2023-11-29 16:48:42 +08:00
a22fa59975 Merge branch 'hotfix/v5.32.4-994/get_app_list_crash' into 'release'
fix: 获取应用列表时偶发的空指针异常 https://sentry.shanqu.cc/organizations/lightgame/issues/343985/?project=22

See merge request halo/android/assistant-android!1460
2023-11-27 10:15:41 +08:00
e68ad6489a fix: 获取应用列表时偶发的空指针异常 https://sentry.shanqu.cc/organizations/lightgame/issues/343985/?project=22 2023-11-27 10:06:09 +08:00
ccd3a98799 Merge branch 'hotfix/v5.32.4-994/deadsystem-crash' into 'release'
fix: catch 部分 DeadSystemException 异常

See merge request halo/android/assistant-android!1458
2023-11-24 11:45:28 +08:00
96026ef9fa fix: catch 部分 DeadSystemException 异常 2023-11-24 11:31:56 +08:00
a9ba7d056b Merge branch 'feat/GHZS-3983' into 'dev'
feat: 游戏下载判断逻辑优化 https://jira.shanqu.cc/browse/GHZS-3982

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

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

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

See merge request halo/android/assistant-android!1424
2023-11-22 17:16:10 +08:00
cbf6f34a9c Merge branch 'hotfix/v5.32.3-993/replace_fragment_crash' into 'release'
fix: 修复底部第四个Tab重复创建Fragment的问题,捕获替换Fragment出现的异常

See merge request halo/android/assistant-android!1455
2023-11-22 13:40:11 +08:00
23c0f12ed3 fix: 修复底部第四个Tab重复创建Fragment的问题,捕获替换Fragment出现的异常 2023-11-22 11:55:19 +08:00
da91dcab59 chore: 版本更新至 5.32.3
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-11-21 17:07:32 +08:00
ee846bc620 Merge branch 'feat/GHZS-4303' into 'release'
feat: 广告回传参数补充 https://jira.shanqu.cc/browse/GHZS-4303

See merge request halo/android/assistant-android!1453
2023-11-21 17:06:22 +08:00
aa3db9330e feat: 广告回传参数补充 https://jira.shanqu.cc/browse/GHZS-4303
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-11-21 16:52:08 +08:00
2393dc2291 chore: 版本更新至 5.32.2
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-11-21 15:03:12 +08:00
cb94bc9f29 Merge branch 'hotfix/v5.32.1-991/crashes' into 'release'
fix: 修复文章详情预加载闪退,修复评论页列表刷新闪退

See merge request halo/android/assistant-android!1452
2023-11-21 15:01:45 +08:00
a60442db41 fix: 修复文章详情预加载闪退,修复评论页列表刷新闪退
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-11-21 14:30:35 +08:00
1eeb34c93a Merge branch 'feature/GHZS-4272-patch' into 'dev'
fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端...

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

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

See merge request halo/android/assistant-android!1447
2023-11-20 14:34:22 +08:00
9691344e67 chore: 版本更新至 5.32.1
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2023-11-20 14:32:54 +08:00
64bdbbf409 Merge branch 'feature-GHZS-4272' into 'dev-5.33.0'
fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端 https://jira.shanqu.cc/browse/GHZS-4272

See merge request halo/android/assistant-android!1446
2023-11-20 10:51:36 +08:00
984bb60e6a fix: 内容搜索新增搜索配置(客户端)-1117测试-客户端 https://jira.shanqu.cc/browse/GHZS-4272 2023-11-20 10:51:36 +08:00
41ba8c3e5a Merge branch 'fix/article_detail_culprit' into 'dev'
fix: 修复不能同时打开两个社区文章详情页面的问题

See merge request halo/android/assistant-android!1445
2023-11-17 15:11:31 +08:00
b203d3a756 fix: 修复不能同时打开两个社区文章详情页面的问题 2023-11-16 14:36:45 +08:00
1461af16b9 feat: 帮助与反馈第二期迭代 https://jira.shanqu.cc/browse/GHZS-3760 2023-11-15 14:14:28 +08:00
14fca95ed6 Merge branch 'feature-GHZS-3949' into 'dev-5.33.0'
fix: 内容搜索新增搜索配置(客-户-端)—1110测试-后端 https://jira.shanqu.cc/browse/GHZS-3949

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

See merge request halo/android/assistant-android!1443
2023-11-15 11:16:14 +08:00
28bca22d93 ci: 变更编译文件存放的 OSS 地址 2023-11-15 11:13:51 +08:00
905571a637 fix:【光环助手】单机插件跳转更新验收问题(1) https://jira.shanqu.cc/browse/GHZS-3870 2023-11-15 11:13:48 +08:00
5757df01e7 Merge branch 'dev-5.33.0-merged-dev' into 'dev-5.33.0'
Dev 5.33.0 merged dev

See merge request halo/android/assistant-android!1436
2023-11-10 14:12:42 +08:00
3f60f85992 Merge branch 'dev' into dev-5.33.0-merged-dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/forum/search/CommunitySearchEventListener.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListFragment.kt
2023-11-10 14:05:20 +08:00
dc9ac67e6e Merge branch 'feat/CWZS-79' into 'dev'
畅玩安装本地apk

See merge request halo/android/assistant-android!1433
2023-11-10 14:00:49 +08:00
8c1d4a3778 feat: SD卡游戏按时间排序 https://jira.shanqu.cc/browse/CWZS-79 2023-11-10 13:58:38 +08:00
7189261c01 Merge branch 'feat/build_jira_comment' into 'dev'
ci: jira 需求下补充 APK 附件评论

See merge request halo/android/assistant-android!1431
2023-11-10 11:20:53 +08:00
86c1781426 ci: jira 需求下补充 APK 附件评论 2023-11-10 11:20:31 +08:00
4812e9258b fix: 过滤gh-files目录下的apk包无法正常解析。只扫描一级目录 2023-11-10 11:10:07 +08:00
b906fe7b47 Merge branch 'feat/build_jira_comment' into 'dev'
ci: jira 需求下补充 APK 附件评论

See merge request halo/android/assistant-android!1428
2023-11-10 10:43:30 +08:00
846fd7222e ci: jira 需求下补充 APK 附件评论 2023-11-10 10:42:55 +08:00
1afabdfd94 Merge branch 'chen/202311/GHZS-3940' into 'dev'
fix:埋点问题:内容内容推荐结果点击事件上报错误 https://jira.shanqu.cc/browse/GHZS-3940

See merge request halo/android/assistant-android!1427
2023-11-10 10:37:44 +08:00
8ed2a13884 fix:埋点问题:内容内容推荐结果点击事件上报错误 https://jira.shanqu.cc/browse/GHZS-3940 2023-11-10 10:34:07 +08:00
52980189ed Merge branch 'chen/202310/GHZS-3730' into 'dev-5.33.0' 2023-11-09 14:01:17 +08:00
852f7734ef feat:论坛搜索排序逻辑优化—客户端 https://jira.shanqu.cc/browse/GHZS-3730 2023-11-09 14:01:17 +08:00
a25503113b Merge branch 'docs/GHZS-3866' into 'dev-5.33.0'
docs: 为首页所有现有的 ViewHolder 备注后台对应的样式名称 https://jira.shanqu.cc/browse/GHZS-3866

See merge request halo/android/assistant-android!1426
2023-11-08 18:03:38 +08:00
0d6b62b361 docs: 为首页所有现有的 ViewHolder 备注后台对应的样式名称 https://jira.shanqu.cc/browse/GHZS-3866 2023-11-08 14:34:29 +08:00
e3b8ea74c1 fix: 处理与 5.32.0 的代码冲突 2023-11-08 11:44:15 +08:00
bf10d5aa42 Merge remote-tracking branch 'origin/dev' into dev-5.33.0
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryFragment.kt
#	app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListFragment.kt
#	app/src/main/java/com/gh/gamecenter/forum/search/UserSearchListFragment.kt
#	app/src/main/res/layout/fragment_list_article_detail_comment.xml
2023-11-08 11:30:16 +08:00
cd13c98ac2 Merge branch 'feature-GHZS-3850' into 'dev'
fix: 【光环助手】深夜模式帖子-相关tab展示错误 https://jira.shanqu.cc/browse/GHZS-3850

See merge request halo/android/assistant-android!1422
2023-11-07 09:50:30 +08:00
2c49b468e6 fix: 【光环助手】深夜模式帖子-相关tab展示错误 https://jira.shanqu.cc/browse/GHZS-3850 2023-11-07 09:45:44 +08:00
d175e895c3 Merge branch 'feat/GHZS-3613' into 'dev'
feat: 设备ID重构 https://jira.shanqu.cc/browse/GHZS-3707

See merge request halo/android/assistant-android!1402
2023-11-06 11:45:52 +08:00
1c0af1be7d feat: 设备ID重构 https://jira.shanqu.cc/browse/GHZS-3707 2023-11-06 11:45:52 +08:00
62f5a479c9 Merge branch 'fix/INTERACT_ACROSS_USERS_crash' into 'dev'
fix: 尝试修复 INTERACT_ACROSS_USERS permission 闪退问题

See merge request halo/android/assistant-android!1420
2023-11-06 10:43:44 +08:00
a87011d5b0 Merge branch 'chen/202311/fix-search-crash-when-exchange-dark' into 'dev'
fix:社区搜索改为懒加载后,切换浅色模式crash

See merge request halo/android/assistant-android!1419
2023-11-06 10:19:29 +08:00
c6c2213a88 fix: 尝试修复 INTERACT_ACROSS_USERS permission 闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/318432/events/ff3774f050c145b2a20ec69545fa3cac/?project=22&query=level%3Afatal&sort=user&statsPeriod=14d 2023-11-06 10:13:53 +08:00
9ede98deea fix:社区搜索改为懒加载后,切换浅色模式crash 2023-11-06 10:13:37 +08:00
e46ec7c416 Merge branch 'feature-GHZS-3350-patch' into 'dev'
feat: 游戏开服/开测消息通知—客户端 https://jira.shanqu.cc/browse/GHZS-3350

See merge request halo/android/assistant-android!1418
2023-11-06 10:10:22 +08:00
d49c6bc3ca feat: 游戏开服/开测消息通知—客户端 https://jira.shanqu.cc/browse/GHZS-3350 2023-11-06 10:10:22 +08:00
2bba43cf26 Merge branch 'feat/GHZS-3837' into 'dev'
feat: 穿山甲广告替换定制版SDK

See merge request halo/android/assistant-android!1415
2023-11-03 17:25:58 +08:00
3efcd71046 Merge branch 'fix/GHZS-3853' into 'dev-5.33.0'
fix: 畅玩游戏反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3853

See merge request halo/android/assistant-android!1417
2023-11-03 16:24:53 +08:00
19f54bb8d2 Merge branch 'feat/upload_test_apk' into 'dev'
feat: 邮件包上传至内部测试平台

See merge request halo/android/assistant-android!1416
2023-11-03 16:20:01 +08:00
ce99eef958 fix: 畅玩游戏反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3853 2023-11-03 16:17:49 +08:00
a167e7ff58 feat: 上传 APK 至内测平台 2023-11-03 16:14:30 +08:00
ddd9032dbf feat: 穿山甲广告替换定制版SDK https://jira.shanqu.cc/browse/GHZS-3836 2023-11-03 10:09:26 +08:00
1062522388 Merge branch 'feat/CWZS-79' into 'dev'
fix: ci-build error

See merge request halo/android/assistant-android!1413
2023-11-02 16:38:03 +08:00
b631c3437c fix: ci-build error 2023-11-02 16:36:37 +08:00
5de5b005bf Merge branch 'feat/CWZS-79' into 'dev'
feat: 测试版本,我的页面添加从SD卡直接安装游戏的畅玩 https://jira.shanqu.cc/browse/CWZS-135

See merge request halo/android/assistant-android!1412
2023-11-02 14:38:55 +08:00
7d99db505b fix: 依赖声明错误 2023-11-02 14:26:39 +08:00
3b3e2e572e feat: 测试版本,我的页面添加从SD卡直接安装游戏的畅玩 https://jira.shanqu.cc/browse/CWZS-135 2023-11-02 14:22:42 +08:00
4f1ccac6fc Merge branch 'fix/GHZS-3754' into 'dev-5.33.0'
fix:【光环助手】跳转链接问题 https://jira.shanqu.cc/browse/GHZS-3754

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

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

See merge request halo/android/assistant-android!1407
2023-10-30 18:04:17 +08:00
edf56c92d5 feat:更新光环编译SDK版本至 34 https://jira.shanqu.cc/browse/GHZS-3769 2023-10-30 18:04:17 +08:00
56eb40740a Merge branch 'feature-GHZS-3350-new' into 'dev'
feat: 游戏开服/开测消息通知—客户端 https://jira.shanqu.cc/browse/GHZS-3350

See merge request halo/android/assistant-android!1406
2023-10-26 14:06:23 +08:00
d697bc7b8a feat: 游戏开服/开测消息通知—客户端 https://jira.shanqu.cc/browse/GHZS-3350 2023-10-26 14:06:22 +08:00
95beddc194 Merge branch 'fix/dark_mode_culprit' into 'dev'
fix: 修复由于社区首页预加载 WebView 资源导致的深色模式状态问题

See merge request halo/android/assistant-android!1405
2023-10-26 09:33:56 +08:00
5e3e4a88f5 fix: 修复由于社区首页预加载 WebView 资源导致的深色模式状态问题 2023-10-26 09:17:31 +08:00
ad6bf59297 Merge branch 'chen/202310/GHZS-3757' into 'dev-5.33.0'
feat:统一设计规范与客户端内代码的命名 https://jira.shanqu.cc/browse/GHZS-3757

See merge request halo/android/assistant-android!1404
2023-10-25 18:01:45 +08:00
42e009b91d feat:统一设计规范与客户端内代码的命名 https://jira.shanqu.cc/browse/GHZS-3757 2023-10-25 17:37:23 +08:00
75dabfef6b Merge branch 'fix/ad_space_gid' into 'dev'
fix: 修复app启动第一次获取广告配置请求没有带上gid的问题

See merge request halo/android/assistant-android!1403
2023-10-25 16:54:41 +08:00
e51e976385 fix: 修复app启动第一次获取广告配置请求没有带上gid的问题 2023-10-25 16:42:33 +08:00
28b9e14487 Merge branch 'feat/GHZS-3502' into 'dev'
feat: APP备案的相关调整 https://jira.shanqu.cc/browse/GHZS-3502

See merge request halo/android/assistant-android!1401
2023-10-25 10:18:36 +08:00
5ee1e823c5 Merge branch 'fix/GHZS-3691' into 'dev'
修复首页下拉弹窗&首页弹窗相关问题 https://jira.shanqu.cc/browse/GHZS-3691

See merge request halo/android/assistant-android!1400
2023-10-25 10:18:32 +08:00
11eee2eb0a 修复首页下拉弹窗&首页弹窗相关问题 https://jira.shanqu.cc/browse/GHZS-3691 2023-10-25 10:18:32 +08:00
42fa273d06 feat: APP备案的相关调整 https://jira.shanqu.cc/browse/GHZS-3502 2023-10-25 09:44:55 +08:00
69dcd407b1 Merge branch 'feat/GHZS-3342' into 'dev'
feat: 游戏下载按钮合并 https://jira.shanqu.cc/browse/GHZS-3342

See merge request halo/android/assistant-android!1368
2023-10-25 09:34:43 +08:00
66722a313f Merge branch 'feat/GHZS-3446' into 'dev'
feat: 广告位管理相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3446

See merge request halo/android/assistant-android!1399
2023-10-24 17:28:58 +08:00
81b0404999 feat: 广告位管理相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3446 2023-10-24 17:28:58 +08:00
79dadfeae6 Merge branch 'fix/game_library_crash' into 'dev'
fix: 修复游戏库点击消息中心出现的闪退问题

See merge request halo/android/assistant-android!1398
2023-10-24 15:55:14 +08:00
601733f257 fix: 修复游戏库点击消息中心出现的闪退问题 2023-10-24 15:31:42 +08:00
48a6bd0d2e feat: 游戏下载按钮合并 https://jira.shanqu.cc/browse/GHZS-3342 2023-10-24 14:21:18 +08:00
dfb89980fe Merge branch 'chen/202309/feature-CWZS-110' into 'dev'
云存档优化

See merge request halo/android/assistant-android!1397
2023-10-23 14:58:19 +08:00
e7d4c598a3 feat:云存档管理相关优化—客户端 https://jira.shanqu.cc/browse/CWZS-110 2023-10-23 14:58:19 +08:00
fe2d0e6a34 Merge branch 'fix/CWZS-127' into 'dev-5.33.0'
fix: 云存档使用存档流程优化—客户端(修复云存档管理页面获取存档配置失败的问题) https://jira.shanqu.cc/browse/CWZS-127

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

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

See merge request halo/android/assistant-android!1394
2023-10-20 15:04:39 +08:00
820e29db23 Merge remote-tracking branch 'origin/dev' into dev-5.33.0 2023-10-20 14:28:21 +08:00
1f05d6e0ba Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-10-20 14:24:24 +08:00
c995846db7 fix: 关编辑器图片格式兼容问题 https://jira.shanqu.cc/browse/GHZS-3744 2023-10-20 11:11:07 +08:00
964b2afaae chore: 版本更新至 5.31.3 2023-10-19 16:29:57 +08:00
7cd4a45915 Merge branch 'feat/GHZS-3682' into 'release'
feat: 关于畅玩游戏在安卓8及以下系统的实名问题 https://jira.shanqu.cc/browse/GHZS-3704

See merge request halo/android/assistant-android!1393
2023-10-19 16:28:43 +08:00
707361e660 feat: 关于畅玩游戏在安卓8及以下系统的实名问题 https://jira.shanqu.cc/browse/GHZS-3704 2023-10-19 16:23:34 +08:00
be4d464bc0 Merge branch 'dev' into 'dev-5.33.0'
Dev

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

See merge request halo/android/assistant-android!1391
2023-10-19 15:30:35 +08:00
b427418ec6 Merge branch 'chen/202309/GHZS-3477' into 'dev' 2023-10-19 15:19:16 +08:00
580a00e1a9 feat:【光环助手】搜索业务埋点需求 https://jira.shanqu.cc/browse/GHZS-3477 2023-10-19 15:19:15 +08:00
7e982e30a3 feat: 云存档使用存档流程优化—客户端 https://jira.shanqu.cc/browse/CWZS-127 2023-10-19 14:19:20 +08:00
0eae5262af Merge branch 'feat/GHZS-3622' into 'dev-5.33.0'
feat: 反馈管理新增包名屏蔽—客户端 https://jira.shanqu.cc/browse/GHZS-3622

See merge request halo/android/assistant-android!1389
2023-10-19 09:55:51 +08:00
6656cbc635 feat: 反馈管理新增包名屏蔽—客户端 https://jira.shanqu.cc/browse/GHZS-3622 2023-10-19 09:55:51 +08:00
1e13ae4815 Merge branch 'feat/GHZS-3675' into 'release'
feat: V5.31.0发布前调整

See merge request halo/android/assistant-android!1388
2023-10-18 17:10:05 +08:00
e18aeb92dd feat: V5.31.0发布前调整 https://jira.shanqu.cc/browse/GHZS-3675 2023-10-18 17:10:05 +08:00
24aaeeee7f Merge branch 'fix-GHZS-dialog-error' into 'release'
fix: 修复DownloadDialog点击继续下载没有反应的问题

See merge request halo/android/assistant-android!1387
2023-10-18 13:58:06 +08:00
a70a397199 fix: 修复DownloadDialog点击继续下载没有反应的问题 2023-10-18 13:58:06 +08:00
7f4d06fbe1 Merge branch 'feat/GHZS-3638' into 'release'
feat: 穿山甲广告SDK更换新版本 https://jira.shanqu.cc/browse/GHZS-3686

See merge request halo/android/assistant-android!1386
2023-10-18 10:02:09 +08:00
690ca33702 Merge branch 'feat/GHZS-3467' into 'dev'
feat: 用户认证优化—客户端 https://jira.shanqu.cc/browse/GHZS-3467

See merge request halo/android/assistant-android!1385
2023-10-17 17:31:06 +08:00
cf6a80dd0d feat: 用户认证优化—客户端 https://jira.shanqu.cc/browse/GHZS-3467 2023-10-17 17:31:06 +08:00
c409b755cf Merge branch 'feat/GHZS-3403' into 'dev'
feat: 首页底部tab第4位修改为可配置—客户端 https://jira.shanqu.cc/browse/GHZS-3403

See merge request halo/android/assistant-android!1384
2023-10-17 11:45:14 +08:00
0399a0cc91 feat: 首页底部tab第4位修改为可配置—客户端 https://jira.shanqu.cc/browse/GHZS-3403 2023-10-17 11:45:14 +08:00
c28d6f3080 feat: 穿山甲广告SDK更换新版本 https://jira.shanqu.cc/browse/GHZS-3686 2023-10-16 16:35:59 +08:00
56501f9f33 Merge branch 'feat/GHZS-3397' into 'dev'
feat: 游戏单功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-3397

See merge request halo/android/assistant-android!1383
2023-10-13 14:20:25 +08:00
ebcf2aaa9e feat: 游戏单功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-3397 2023-10-13 14:20:25 +08:00
0f9f3dc073 Merge branch 'feature-GHZS-article-detail-remove-dev-cache' into 'dev'
feat: halo_test_app.js、halo_test_app.css的预缓存移除

See merge request halo/android/assistant-android!1382
2023-10-12 15:09:53 +08:00
8c92da2ceb feat: halo_test_app.js、halo_test_app.css的预缓存移除 2023-10-12 15:09:53 +08:00
671c59a9de Merge branch 'feature-GHZS-article-detail-modification' into 'dev'
feat: 论坛文章详情WebView预加载

See merge request halo/android/assistant-android!1381
2023-10-12 13:45:11 +08:00
adcb8a4693 feat: 论坛文章详情WebView预加载 2023-10-12 13:45:11 +08:00
95d87858f1 Merge branch 'fix/home_page_memory_leak' into 'dev'
fix: 修复首页悬浮窗和AudioManager造成的内存泄漏问题

See merge request halo/android/assistant-android!1380
2023-10-11 11:23:13 +08:00
0a463b0ddd Merge branch 'chen/202310/GHZS-3652' into 'dev'
fix:修复光环首页部分数据被多线程操作的问题 https://jira.shanqu.cc/browse/GHZS-3652

See merge request halo/android/assistant-android!1379
2023-10-11 11:13:27 +08:00
2da4230d8c fix:修复光环首页部分数据被多线程操作的问题 https://jira.shanqu.cc/browse/GHZS-3652 2023-10-11 11:07:15 +08:00
b00fda2289 fix: 修复首页悬浮窗和AudioManager造成的内存泄漏问题 2023-10-11 11:06:29 +08:00
86790e7b69 Merge branch 'fix/GHZS-3596' into 'dev'
fix: 【光环助手】APP内图片显示问题(1010测试) https://jira.shanqu.cc/browse/GHZS-3596

See merge request halo/android/assistant-android!1378
2023-10-10 17:01:43 +08:00
80ea7303f8 fix: 【光环助手】APP内图片显示问题(1010测试) https://jira.shanqu.cc/browse/GHZS-3596 2023-10-10 16:58:48 +08:00
700831ba26 Merge branch 'fix/GHZS-3596' into 'dev'
fix: 【光环助手】APP内图片显示问题(1010测试) https://jira.shanqu.cc/browse/GHZS-3596

See merge request halo/android/assistant-android!1377
2023-10-10 15:27:00 +08:00
e35950ad89 fix: 【光环助手】APP内图片显示问题(1010测试) https://jira.shanqu.cc/browse/GHZS-3596 2023-10-10 15:15:56 +08:00
0a6b93a8f8 chore: 版本更新至 5.33.0 2023-10-10 14:47:26 +08:00
7be72e76f2 Merge branch 'feature-GHZS-sentry-335870' into 'release'
fix: Sentry关于神策埋点上报导致的空指针异常的BUG

See merge request halo/android/assistant-android!1376
2023-10-10 11:53:39 +08:00
6d5b0eb1e8 fix: Sentry关于神策埋点上报导致的空指针异常的BUG 2023-10-10 11:53:39 +08:00
1890 changed files with 28408 additions and 11401 deletions

View File

@ -61,7 +61,7 @@ android_build:
script:
- export GRADLE_USER_HOME=/home/gitlab-runner/ci-build-cache/$CI_PROJECT_PATH/.gradle
- chmod +x ./gradlew
- ./scripts/jenkins_build.sh -c
- ./scripts/jenkins_build.sh $CI_COMMIT_REF_NAME $BEFORE_COMMIT_SHA $CI_COMMIT_SHA
#设置打包后的产物用于job之间共享
artifacts:
paths:
@ -71,7 +71,7 @@ android_build:
exit_codes: 137
only:
- dev
- dev-5.32.0
- dev-5.33.0
# 代码检查
sonarqube_analysis:
@ -102,7 +102,7 @@ sonarqube_analysis:
exit_codes: 137
only:
- dev
- dev-5.32.0
- dev-5.33.0
## 发送简易检测结果报告
send_sonar_report:
@ -120,11 +120,11 @@ send_sonar_report:
exit_codes: 137
only:
- dev
- dev-5.32.0
- dev-5.33.0
oss-upload&send-email:
tags:
- rancher-k8s
- sysadm-devops
stage: oss-upload&send-email
image: hub.shanqu.cc/devops/android-apk-oss-upload:latest
variables:
@ -132,9 +132,9 @@ oss-upload&send-email:
VAULT_ADDR: https://vault.shanqu.cc # 固定值
VAULT_SECRET_PATH: prod/devops/android-apk-oss-upload # 固定值
VAULT_ROLE: android-apk-oss-upload # 固定值
ENDPOINT: "oss-cn-shenzhen-internal.aliyuncs.com" # 固定值
BUCKET: "shanqu" # 固定值
FILE_PATH: "app/build/tmp/" # APK 存放路径
ENDPOINT: "tos-cn-guangzhou.ivolces.com" # 固定值
BUCKET: "sysadm-public" # 固定值
FILE_PATH: "app/build/tmp/" # APK 存放路径
Email_To_List: $EMAIL_TO_LIST # 邮件接受人列表
Email_Title: "光环助手 $CI_COMMIT_BRANCH" # 邮件标题
PIPELINE_ID: $CI_PIPELINE_ID # 流水线id
@ -149,7 +149,7 @@ oss-upload&send-email:
### 开启上传 ###
- /usr/local/bin/python /upload.py
### 发送邮件
- /usr/local/bin/python /ci-android-mail.py
- /usr/local/bin/python /ci-android-mail-jira-comment.py
only:
- dev
- dev-5.32.0
- dev-5.33.0

3
.gitmodules vendored
View File

@ -11,3 +11,6 @@
[submodule "ndownload"]
path = ndownload
url = ../../../android/ndownload.git
[submodule "vasdk"]
path = vasdk
url = ../../../sdg/android/vasdk.git

View File

@ -73,7 +73,7 @@ android {
versionName rootProject.ext.versionName
applicationId rootProject.ext.applicationId
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt', rootProject.ext.va_proguard_rules
String CORE_EVENT_GAME_CATEGORY = ""
@ -95,8 +95,10 @@ android {
buildConfigField "int", "ACTIVATE_REPORTING_RATIO", "${ACTIVATE_REPORTING_RATIO}"
// All third-party appid/appkey
buildConfigField "boolean", "IS_GAT_APP", "false"
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT}\""
buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "WECHAT_APPID", "\"${WECHAT_APPID}\""
buildConfigField "String", "WECHAT_SECRET", "\"${WECHAT_SECRET}\""
@ -157,9 +159,12 @@ android {
}
}
flavorDimensions("env")
flavorDimensions("env", "region")
sourceSets {
main {
assets.srcDir("${rootProject.buildDir}/plugin")
}
publish {
java.srcDirs = ['src/main/java', "src/default/java"]
}
@ -175,20 +180,31 @@ android {
gdt {
java.srcDirs = ['src/main/java', 'src/gdt/java']
}
gat {
java.srcDirs = ['src/main/java', 'src/gat/java']
}
cn {
java.srcDirs = ['src/main/java', 'src/cn/java']
}
sm {
java.srcDirs = ['src/main/java', 'src/sm/java']
}
}
productFlavors {
// internal 内部测试包使用的 flavor接口包含包括测试和正式环境
internal {
dimension "env"
versionNameSuffix "-debug"
// blame_yangfei: test script lines
//versionNameSuffix "-debug"
buildConfigField "String", "DEV_API_HOST", "\"${DEV_API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_DEV_API_HOST}\""
buildConfigField "String", "DEV_VAPI_HOST", "\"${DEV_VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${DEV_QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "CSJ_APPID", "\"${DEV_CSJ_APPID}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${DEV_CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
// publish 发布时候使用的 flavor接口仅包含正式环境
@ -200,6 +216,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
@ -211,6 +228,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
@ -224,6 +242,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
@ -235,8 +254,40 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
sm {
dimension "env"
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
// 港澳台
gat {
dimension "region"
applicationId rootProject.ext.applicationIdGat
// 支持繁体
resConfigs "zh", "zh-rTW"
buildConfigField "boolean", "IS_GAT_APP", "true"
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT_GAT}\""
buildConfigField "String", "API_HOST", "\"${API_HOST_GAT}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST_GAT}\""
}
cn {
dimension "region"
}
}
}
@ -253,6 +304,7 @@ dependencies {
teaImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/tea/libs')
kuaishouImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/kuaishou/libs')
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
smImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/sm/libs')
testImplementation 'junit:junit:4.12'
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
@ -320,9 +372,9 @@ dependencies {
kapt "com.alibaba:arouter-compiler:$arouterVersion"
implementation project(':ndownload')
implementation project(':vspace-bridge:vspace')
implementation project(':vspace-bridge')
implementation (project(':module_common')) {
implementation(project(':module_common')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_login')) {
@ -359,6 +411,15 @@ dependencies {
implementation(project(':feature:qq_game')) {
exclude group: 'androidx.swiperefreshlayout'
}
internalImplementation(project(':module_internal_test'))
implementation(project(':va-main')) {
exclude group: 'androidx.swiperefreshlayout'
}
debugImplementation "com.bytedance.tools.codelocator:codelocator-core:2.0.3"
compileOnly project(":va-core")
compileOnly project(":va-plugin-host-lib")
implementation project(":va-plugin-host")
implementation project(":va-archive")
}
File propFile = file('sign.properties')

View File

@ -88,7 +88,14 @@
-keep class com.qq.gdt.action.** {*;}
-keep public class com.tencent.turingfd.sdk.**
### 神马 SDK
-dontwarn com.gism.**
-keepclasseswithmembers class * {
native <methods>;
}
-keepclassmembernames class com.contrarywind.view.WheelView {
private int itemsVisible;
}

View File

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

View File

@ -0,0 +1,32 @@
package com.gh.vspace
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.Keep
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.LayoutPersonalOtherItemBinding
import com.gh.vspace.installexternalgames.InstallExternalGameActivity
@Keep
class ExternalGameUsage : IExternalGamesUsage {
override fun addInstallExternalGameButton(viewParent: ViewGroup) {
val context = viewParent.context
viewParent.findViewById<View>(R.id.install_game_from_external) ?: run {
val binding = LayoutPersonalOtherItemBinding.inflate(LayoutInflater.from(context)).apply {
root.id = R.id.install_game_from_external
titleTv.text = context.getString(R.string.title_install_external_game)
iconIv.setImageResource(R.drawable.ic_personal_my_game)
root.setOnClickListener {
VHelper.connectService {
context.startActivity(
InstallExternalGameActivity.getIntent(context)
.apply { flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK })
}
}
}
viewParent.addView(binding.root, 0)
}
}
}

View File

@ -0,0 +1,5 @@
package com.gh.vspace.installexternalgames;
public class Constants {
public static final String TAG = "从SD卡安装";
}

View File

@ -0,0 +1,52 @@
package com.gh.vspace.installexternalgames
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toBinding
class ExternalGameAdapter(private val games: List<ExternalGameUiState>, private val onItemClickListener: OnItemClickListener) :
RecyclerView.Adapter<ExternalGameViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExternalGameViewHolder {
return ExternalGameViewHolder(parent.toBinding())
}
override fun getItemCount(): Int {
return games.size
}
override fun onBindViewHolder(holder: ExternalGameViewHolder, position: Int) {
val item = games[position]
holder.apkInfo.text = item.externalGameEntity.let { item ->
"""
应用程序名:${item.appName}
版本号:${item.apkVersion}
包名: ${item.apkPackageName}
路径:${item.apkPath}
""".trimIndent()
}
holder.update.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)
}
holder.install.goneIf(item.isInstalled) {
holder.install.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)
}
}
holder.uninstall.goneIf(!item.isInstalled) {
holder.uninstall.setOnClickListener {
onItemClickListener.onItemClick(
item,
OnItemClickListener.ClickType.CLICK_UNINSTALL
)
}
}
holder.start.goneIf(!item.isInstalled) {
holder.start.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_START)
}
}
}
}

View File

@ -0,0 +1,11 @@
package com.gh.vspace.installexternalgames
data class ExternalGameEntity(
val cpuAbi: Set<String>,
val apkPath: String,
val apkFileName: String,
val appName: String,
val apkVersion: String,
val apkPackageName: String,
val lastModified: Long,
)

View File

@ -0,0 +1,6 @@
package com.gh.vspace.installexternalgames
data class ExternalGameUiState(
val externalGameEntity: ExternalGameEntity,
val isInstalled: Boolean
)

View File

@ -0,0 +1,12 @@
package com.gh.vspace.installexternalgames
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.databinding.LayoutExternalGameItemBinding
class ExternalGameViewHolder(binding: LayoutExternalGameItemBinding) : RecyclerView.ViewHolder(binding.root) {
val apkInfo = binding.apkFileInfo
val install = binding.btnInstall
val uninstall = binding.btnUninstall
val start = binding.btnStart
val update = binding.btnUpdate
}

View File

@ -0,0 +1,14 @@
package com.gh.vspace.installexternalgames
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.gh.gamecenter.common.base.activity.ToolBarActivity
class InstallExternalGameActivity : ToolBarActivity() {
companion object {
fun getIntent(context: Context): Intent {
return getTargetIntent(context, InstallExternalGameActivity::class.java, InstallExternalGameFragment::class.java, Bundle())
}
}
}

View File

@ -0,0 +1,163 @@
package com.gh.vspace.installexternalgames
import android.app.Dialog
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.util.DialogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.view.divider.HorizontalDividerItemDecoration
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.databinding.FragmentInstallExternalGamesBinding
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.VirtualAppManager
import com.lightgame.download.DownloadEntity
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
private val mViewModel: InstallExternalGameViewModel by lazy { viewModelProvider() }
private lateinit var mBinding: FragmentInstallExternalGamesBinding
private val games = mutableListOf<ExternalGameUiState>()
private var adapter = ExternalGameAdapter(games, this)
private var uninstallDisposable: Disposable? = null
override fun getLayoutId() = 0
override fun getInflatedLayout() =
FragmentInstallExternalGamesBinding.inflate(layoutInflater).apply { mBinding = this }.root
private lateinit var dialog: Dialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setNavigationTitle(getString(com.gh.gamecenter.R.string.title_install_external_game))
initView()
mViewModel.gamesList.observe(this) {
if (dialog.isShowing) {
dialog.dismiss()
}
games.clear()
games.addAll(
it.map {
ExternalGameUiState(it, VHelper.isInstalled(it.apkPackageName))
}
)
adapter.notifyDataSetChanged()
}
mViewModel.scanPaths()
}
private fun initView() {
dialog = DialogUtils.showWaitDialog(requireContext(), "")
mBinding.externalGamesList.let {
it.adapter = adapter
it.layoutManager = LinearLayoutManager(requireContext())
val itemDecoration = HorizontalDividerItemDecoration.Builder(requireContext())
.size(2F.dip2px())
.color(R.color.ui_divider.toColor(requireContext()))
.build()
if (it.itemDecorationCount != 0) {
it.removeItemDecorationAt(0)
}
it.addItemDecoration(itemDecoration)
}
}
override fun onDestroy() {
super.onDestroy()
if (dialog.isShowing) {
dialog.dismiss()
}
if (uninstallDisposable?.isDisposed != true) {
uninstallDisposable?.dispose()
}
}
override fun onItemClick(externalGameUiState: ExternalGameUiState, clickType: OnItemClickListener.ClickType) {
when (clickType) {
OnItemClickListener.ClickType.CLICK_INSTALL -> {
install(externalGameUiState)
}
OnItemClickListener.ClickType.CLICK_UNINSTALL -> {
uninstall(externalGameUiState)
}
OnItemClickListener.ClickType.CLICK_START -> {
start(externalGameUiState)
}
}
}
private fun install(externalGameUiState: ExternalGameUiState) {
val bit =
externalGameUiState.externalGameEntity.cpuAbi.let { if (it.size == 1 && it.contains("armeabi-v7a")) "32" else "64" }
VHelper.install(requireContext(), DownloadEntity().apply {
externalGameUiState.externalGameEntity.apply {
packageName = apkPackageName
path = apkPath
}
}, true)
if (VHelper.showDialogIfVSpaceIsNeeded(
requireContext(),
"",
externalGameUiState.externalGameEntity.appName,
"",
bit = bit
)
) return
dialog.show()
externalGameUiState.externalGameEntity.let {
val intent = VirtualAppManager.getInstallIntent(context, it.apkPath, it.apkPackageName)
requireActivity().startActivity(intent)
}
}
private fun uninstall(externalGameUiState: ExternalGameUiState) {
dialog.show()
uninstallDisposable = Single.create<Void> {
VHelper.uninstall(externalGameUiState.externalGameEntity.apkPackageName)
}.subscribeOn(Schedulers.from(AppExecutor.lightWeightIoExecutor)).observeOn(AndroidSchedulers.mainThread())
.subscribe { t1, t2 ->
if (dialog.isShowing) {
dialog.dismiss()
}
}
}
private fun start(externalGameUiState: ExternalGameUiState) {
val intent = VirtualAppManager.get().getStartGameIntent(
externalGameUiState.externalGameEntity.apkPackageName,
"",
externalGameUiState.externalGameEntity.appName,
"",
MetaUtil.getBase64EncodedAndroidId(),
HaloApp.getInstance().gid,
com.gh.gamecenter.BuildConfig.VERSION_NAME,
HaloApp.getInstance().channel,
"",
""
)
requireActivity().startActivity(intent)
}
}

View File

@ -0,0 +1,64 @@
package com.gh.vspace.installexternalgames
import android.app.Application
import android.content.pm.PackageManager
import android.os.Environment
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.core.runOnIoThread
import com.gh.vspace.VHelper
import com.lg.vspace.helper.compat.NativeLibraryHelperCompat
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
class InstallExternalGameViewModel(application: Application) : AndroidViewModel(application) {
private val _gamesList = MutableLiveData<List<ExternalGameEntity>>(listOf())
val gamesList: LiveData<List<ExternalGameEntity>> = _gamesList
private val pkgManger = getApplication<Application>().packageManager
private var disposable: Disposable = VHelper.callSite.observeOn(AndroidSchedulers.mainThread()).subscribe {
scanPaths()
}
fun scanPaths() {
runOnIoThread {
_gamesList.postValue(Environment.getExternalStorageDirectory().walk().maxDepth(1)
.filter { it.isHidden.not() }
.filter { it.isFile }
.onEach {
Utils.log(Constants.TAG, "获得文件: ${it.name}")
}
.filter { it.extension == "apk" }
.map {
val packageInfo = pkgManger.getPackageArchiveInfo(
it.absolutePath,
PackageManager.GET_META_DATA or PackageManager.GET_ACTIVITIES
)
packageInfo?.let { packageInfo ->
val applicationInfo = packageInfo.applicationInfo
applicationInfo.publicSourceDir = it.absolutePath
applicationInfo.sourceDir = it.absolutePath
ExternalGameEntity(
cpuAbi = NativeLibraryHelperCompat.getPackageAbiList(it.absolutePath),
apkPath = it.absolutePath,
apkFileName = it.name,
apkPackageName = packageInfo.packageName,
apkVersion = packageInfo.versionName,
appName = pkgManger.getApplicationLabel(applicationInfo).toString(),
lastModified = it.lastModified()
)
}
}.filterNotNull()
.toList().sortedByDescending { it.lastModified }
)
}
}
override fun onCleared() {
super.onCleared()
disposable.dispose()
}
}

View File

@ -0,0 +1,11 @@
package com.gh.vspace.installexternalgames
interface OnItemClickListener {
enum class ClickType {
CLICK_INSTALL, CLICK_UNINSTALL, CLICK_START
}
fun onItemClick(externalGameUiState: ExternalGameUiState, clickType: ClickType)
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/external_games_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/apk_file_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
tools:text="文件名:\n路径" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_install"
android:visibility="gone"
tools:visibility="visible" />
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_update"
android:visibility="visible"
tools:visibility="visible" />
<Button
android:id="@+id/btn_uninstall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_uninstall"
android:visibility="gone"
tools:visibility="visible" />
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_start"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</LinearLayout>

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="install_game_from_external" type="id" />
</resources>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title_install_external_game">从SD卡安装</string>
<string name="text_install">安装</string>
<string name="text_update">更新</string>
<string name="text_uninstall">卸载</string>
<string name="text_start">启动</string>
</resources>

Binary file not shown.

View File

@ -78,11 +78,36 @@
androidx.constraintlayout.compose,
androidx.compose.ui.test.manifest,
com.bytedance.sdk.openadsdk,
com.bykv.vk.openvk,
com.bytedance.tools,
androidx.compose.ui.tooling.preview,
com.tencent.qqmini,
com.tencent.qqmini.minigame.external,
com.tencent.qqmini.minigame.opensdk,
com.tencent.qqmini.union.ad" />
com.tencent.qqmini.union.ad,
com.lg.vspace,
io.lg.va.common,
com.va.floating,
com.lg.cloud,
com.lg.archive,
com.lg.vclient,
com.va.realname,
com.lg.vspace.flavor,
com.lg.update,
com.lg.login,
com.lg.accelerator,
com.lody.virtual,
com.lg.core,
com.lg.ads,
com.lg.common,
com.lg.vspace.network,
com.lody.virtual.lib.res,
com.va.host,
com.lg.vspace.plugin.host,
com.lg.plugin.constant,
com.bytedance.tools.codelocator,
org.chickenhook.restrictionbypass,
com.lody.virtual.sandhook,com.lg.vspace.common" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -97,6 +122,9 @@
android:name="android.permission.GET_TASKS"
tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
tools:node="remove"/>
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
@ -474,6 +502,14 @@
android:name="com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.fuli.kaifu.ServersCalendarManagementActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.fuli.kaifu.ServersSubscribedGameListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.answer.draft.AnswerDraftActivity"
android:screenOrientation="portrait" />
@ -754,7 +790,15 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qgame.QGameSubjectActivity"
android:name="com.gh.gamecenter.gamecollection.hotlist.GameCollectionListDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.UserAuthActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.SplashAdActivity"
android:screenOrientation="portrait" />
@ -768,7 +812,8 @@
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
@ -812,6 +857,8 @@
<!-- tools:node="remove" />-->
<!-- </provider>-->
<service android:name = "com.gh.gamecenter.install.InstallService" />
<receiver
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
android:exported="false">

File diff suppressed because one or more lines are too long

View File

@ -17,6 +17,7 @@ import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
@ -65,7 +66,8 @@ object AdDelegateHelper {
private const val AD_SDK_CSJ = "穿山甲"
private const val AD_SDK_BEIZI = "倍孜"
private const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
const val AD_TYPE_OWNER = "owner_ads" // 自有广告
private const val KEY_CACHE_CONFIG = "cache_config" // 放在 SP 里的广告缓存(避免接口加载问题)
@ -73,6 +75,9 @@ object AdDelegateHelper {
HaloApp.getInstance().getSharedPreferences("AdConfig", Context.MODE_PRIVATE)
}
var isShowingSplashAd = false // 是否正在显示开屏广告
var gameSearchKeyword = ""
fun initAdSdk(context: Context) {
// 初始化 Beizi
if (mBeiziAdImpl == null) {
@ -85,7 +90,8 @@ object AdDelegateHelper {
if (mCsjAdImpl == null) {
mCsjAdImpl =
ARouter.getInstance().build(RouteConsts.provider.csjAd).navigation() as? ICsjAdProvider
mCsjAdImpl?.initSDK(context, BuildConfig.CSJ_APPID, HaloApp.getInstance().oaid)
val csjAppId = if (EnvHelper.isDevEnv) BuildConfig.DEV_CSJ_APPID else BuildConfig.CSJ_APPID
mCsjAdImpl?.initSDK(context, csjAppId, HaloApp.getInstance().oaid)
// 监听亮色/暗色模式切换
DarkModeUtils.registerModeChangeListener {
val topActivity = CurrentActivityHolder.getCurrentActivity() ?: return@registerModeChangeListener
@ -98,19 +104,21 @@ object AdDelegateHelper {
* 请求接口获取广告相关配置
*/
@SuppressLint("CheckResult")
fun requestAdConfig(isFromRetry: Boolean) {
fun requestAdConfig(isFromRetry: Boolean, keyword: String = "", callback: (() -> Unit)? = null) {
// mAdConfigList 不为空不需要重试
if (isFromRetry && mAdConfigList != null) {
return
}
val paramsMap = if (keyword.isNotEmpty()) mapOf("keyword" to keyword) else mapOf()
RetrofitManager.getInstance()
.newApi
.adConfig
.getAdConfig(paramsMap)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<List<AdConfig>>() {
override fun onSuccess(data: List<AdConfig>) {
gameSearchKeyword = keyword
handleAdConfig(data)
callback?.invoke()
// 缓存数据到 SP 供接口请求失败用
SPUtils.setString(mAdConfigSp, KEY_CACHE_CONFIG, data.toJson())
@ -124,6 +132,8 @@ object AdDelegateHelper {
if (cachedConfig != null) {
handleAdConfig(cachedConfig)
}
callback?.invoke()
}
})
}
@ -146,10 +156,18 @@ object AdDelegateHelper {
* 处理广告配置
*/
fun handleAdConfig(configList: List<AdConfig>) {
mGameSearchAdList.clear()
mSplashAd = null
mDownloadManagerAd = null
mVGameLaunchAd = null
for (config in configList) {
// 处理返回的数据
when (config.location) {
"halo_launch" -> mSplashAd = config
"halo_launch" -> {
config.ownerAd?.startAd?.let { it.id = config.ownerAd.id }
mSplashAd = config
}
"download_manager" -> mDownloadManagerAd = config
"game_search" -> config.let { mGameSearchAdList.add(it) }
"helper_launch" -> mVGameLaunchAd = config
@ -159,9 +177,99 @@ object AdDelegateHelper {
/**
* 是否需要显示开屏广告
* @param isHotLaunch 是否为热启动
*/
fun shouldShowStartUpAd(): Boolean {
fun shouldShowStartUpAd(isHotLaunch: Boolean): Boolean {
return mSplashAd != null
&& !isShowingSplashAd
&& (!isHotLaunch || shouldShowStartUpAdWhenHotLaunch())
&& !isMatchAdFreeRule(mSplashAd)
&& isMatchStartUpAdDisplayRule()
}
/**
* 热启动是否需要显示开屏广告
*/
private fun shouldShowStartUpAdWhenHotLaunch() = mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
/**
* 是否需要显示下载管理广告
*/
fun shouldShowDownloadManagerAd(): Boolean {
return mDownloadManagerAd != null && !isMatchAdFreeRule(mDownloadManagerAd) && isMatchDownloadManagerAdDisplayRule()
}
/**
* 是否需要显示游戏搜索广告
*/
fun shouldShowGameSearchAd(adConfig: AdConfig): Boolean {
return !isMatchAdFreeRule(adConfig) && isMatchGameSearchAdDisplayRule(adConfig)
}
/**
* 是否在免广告时长内
*/
private fun isMatchAdFreeRule(adConfig: AdConfig?): Boolean {
adConfig?.displayRule?.run {
if (adFreeDuration > 0) {
val ghInstalledDurationInHours = (System.currentTimeMillis() - PackageUtils.getInstalledTime(
HaloApp.getInstance(),
BuildConfig.APPLICATION_ID
)).toFloat() / 1000 / 3600
return ghInstalledDurationInHours < adFreeDuration
} else {
return false
}
}
return false
}
/**
* 是否大于开屏广告展示间隔时长
*/
private fun isMatchStartUpAdDisplayRule(): Boolean {
mSplashAd?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
* 是否大于广告管理展示间隔时长
*/
private fun isMatchDownloadManagerAdDisplayRule(): Boolean {
mDownloadManagerAd?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
* 是否大于游戏搜索展示间隔时长
*/
private fun isMatchGameSearchAdDisplayRule(adConfig: AdConfig?): Boolean {
adConfig?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
@ -185,49 +293,124 @@ object AdDelegateHelper {
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
isHotLaunch: Boolean,
hideAction: () -> Unit
) {
val hideCallback = {
isShowingSplashAd = false
hideAction.invoke()
}
if (mSplashAd != null) {
if (mSplashAd!!.displayRule.adSource == AD_TYPE_SDK) {
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
if (isSuccess) {
hideCallback.invoke()
} else {
if (mSplashAd?.displayRule?.onFailedAction == "show") {
sdkStartAdContainer.visibility = View.GONE
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
} else {
hideCallback.invoke()
}
}
}
// 第三方广告的数据为空,按加载失败处理
if (mSplashAd?.thirdPartyAd == null) {
sdkSplashCallback.invoke(false)
return
}
if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
sdkStartAdContainer.visibility = View.VISIBLE
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, sdkSplashCallback)
} else if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
sdkStartAdContainer.visibility = View.VISIBLE
requestCsjSplashAd(
when (if (isHotLaunch) mSplashAd!!.displayRule.hotStartSplashAd?.type else mSplashAd!!.displayRule.adSource) {
AD_TYPE_SDK -> {
isShowingSplashAd = true
requestThirdPartySplashAd(
activity,
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
sdkSplashCallback
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
}
AD_TYPE_OWNER -> {
isShowingSplashAd = true
requestStandardSplashAd(
activity,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
}
} else {
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
}
} else {
hideCallback.invoke()
}
}
/**
* 获取第三方开屏广告
*/
private fun requestThirdPartySplashAd(
activity: Activity,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
hideCallback: () -> Unit
) {
val 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) {
hideCallback.invoke()
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
} else {
if (mSplashAd?.displayRule?.adSource == AD_TYPE_SDK && mSplashAd?.displayRule?.onFailedAction == "show" && !isHotLaunch) {
sdkStartAdContainer.visibility = View.GONE
requestStandardSplashAd(
activity,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
} else {
hideCallback.invoke()
}
}
}
// 第三方广告的数据为空,按加载失败处理
if (mSplashAd?.thirdPartyAd == null) {
sdkSplashCallback.invoke(false)
return
}
if (mSplashAd?.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) {
sdkStartAdContainer.visibility = View.VISIBLE
requestCsjSplashAd(
activity,
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
sdkStartAdContainer,
timeout,
sdkSplashCallback
)
}
}
@ -242,6 +425,7 @@ object AdDelegateHelper {
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
timeout: Int,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mCsjAdImpl == null) {
@ -255,6 +439,7 @@ object AdDelegateHelper {
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
timeout,
callback,
)
}
@ -268,12 +453,13 @@ object AdDelegateHelper {
adsFl: FrameLayout,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
timeout: Long,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mBeiziAdImpl == null) {
callback.invoke(false)
} else {
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, callback)
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, timeout, callback)
}
}
@ -281,13 +467,41 @@ object AdDelegateHelper {
* 显示自有的开屏广告
*/
private fun requestStandardSplashAd(
splashAd: StartupAdEntity?,
activity: Activity,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
hideCallback: () -> Unit
) {
val splashAd = mSplashAd?.ownerAd?.startAd
val onEmptyCallback = {
if (mSplashAd?.displayRule?.adSource == AD_TYPE_OWNER && mSplashAd?.displayRule?.onFailedAction == "show" && mSplashAd?.thirdPartyAd != null) {
// 自有广告为空时,显示第三方广告
requestThirdPartySplashAd(
activity,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsViewGroup,
handler,
isHotLaunch,
hideCallback
)
} else {
hideCallback.invoke()
}
}
if (splashAd == null) {
hideCallback.invoke()
onEmptyCallback.invoke()
return
}
@ -300,7 +514,7 @@ object AdDelegateHelper {
) {
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
} else {
hideCallback.invoke()
onEmptyCallback.invoke()
}
"everyday" -> {
@ -311,7 +525,7 @@ object AdDelegateHelper {
) {
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
} else {
hideCallback.invoke()
onEmptyCallback.invoke()
}
}
@ -332,7 +546,9 @@ object AdDelegateHelper {
val jumpBtn: View = startAdContainer.findViewById(R.id.jumpBtn)
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
val icpContainer: View? = startAdContainer.findViewById(R.id.startAdIcpContainer)
startAdContainer.visibility = View.VISIBLE
icpContainer?.visibility = View.VISIBLE
jumpDetailBtn.text = ad.desc
jumpDetailBtn.setDrawableEnd(
AppCompatResources.getDrawable(
@ -372,13 +588,14 @@ object AdDelegateHelper {
} else {
LogUtils.logStartAd("start_ads", ad)
}
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
handler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
}
/**
* 获取信息流广告
* 获取第三方信息流广告
*/
fun requestFlowAd(
fun requestThirdPartyFlowAd(
fragment: Fragment,
slotId: String,
adContainerView: ViewGroup,
@ -389,9 +606,9 @@ object AdDelegateHelper {
}
/**
* 获取 Banner 广告
* 获取第三方 Banner 广告
*/
fun requestBannerAd(
fun requestThirdPartyBannerAd(
fragment: Fragment,
containerView: ViewGroup,
ad: AdConfig.ThirdPartyAd,

View File

@ -233,7 +233,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mKeyboardHeightProvider = KeyboardHeightProvider(this)
mRichEditor.post { mKeyboardHeightProvider?.start() }
mRichEditor.enableForceDark(DarkModeUtils.isDarkModeOn(this))
mRichEditor.setEditorBackgroundColor(R.color.background_white.toColor(this))
mRichEditor.setEditorBackgroundColor(R.color.ui_surface.toColor(this))
mRichEditor.setEditorFontColor(if (mIsDarkModeOn) Color.parseColor("#C2C2C2") else Color.parseColor("#4A4A4A"))
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
@ -797,9 +797,9 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
override fun onDarkModeChanged() {
super.onDarkModeChanged()
updateStatusBarColor(R.color.background_white, R.color.background_white)
updateStatusBarColor(R.color.ui_surface, R.color.ui_surface)
mRichEditor.enableForceDark(DarkModeUtils.isDarkModeOn(this))
mRichEditor.setEditorBackgroundColor(R.color.background_white.toColor(this))
mRichEditor.setEditorBackgroundColor(R.color.ui_surface.toColor(this))
mRichEditor.setEditorFontColor(if (mIsDarkModeOn) Color.parseColor("#C2C2C2") else Color.parseColor("#4A4A4A"))
}

View File

@ -28,6 +28,7 @@ import com.gh.gamecenter.retrofit.service.ApiService
import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.google.gson.JsonObject
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@ -38,6 +39,10 @@ import okhttp3.ResponseBody
import retrofit2.HttpException
import java.io.File
import java.io.FileOutputStream
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap
import kotlin.collections.set
// TODO: 移动到module_bbs模块
@ -124,8 +129,17 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
}
val map = LinkedHashMap<String, String>()
for (key in imageUrlMap.keys) {
map[MD5Utils.getUrlMD5(key)] = FILE_HOST + key.decodeURI()
mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrlMap[key] ?: ""
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) ?: ""
map[MD5Utils.getUrlMD5(key)] = transformedImgUrl
mapImages[transformedImgUrl.decodeURI()] = imageUrlMap[key] ?: ""
} else {
map[MD5Utils.getUrlMD5(key)] = localFileUri
mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrlMap[key] ?: ""
}
}
chooseImagesUploadSuccess.value = map
}

View File

@ -4,20 +4,26 @@ import android.app.Activity
import android.app.Application
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.FloatingBackViewManager
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.SingletonWebActivity
import com.gh.gamecenter.SkipActivity
import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.authorization.AuthorizationActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.ui.launcher.LaunchActivity
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
private var isFromBackgroundToForeground = false // 是否后台回到前台
private var activityCount = 0
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
@ -25,6 +31,19 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity) {
GlobalActivityManager.currentActivity = activity
activityCount ++
if (activityCount == 1 && isFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isSkippingThirdParty
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
&& activity !is SplashAdActivity
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
isFromBackgroundToForeground = false
}
}
override fun onActivityResumed(activity: Activity) {
@ -56,6 +75,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
if (activity is AppCompatActivity
&& activity !is LaunchActivity
&& activity !is LoginActivity
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
@ -74,7 +95,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityStopped(activity: Activity) {
// do nothing
activityCount --
isFromBackgroundToForeground = activityCount <= 0
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

View File

@ -69,9 +69,14 @@ class DefaultJsApi(
val entrance: String = "",
private var mFragment: Fragment? = null,
private var mBbsId: String? = "",
private var mOriginUrl: String?= "",
private var mOriginUrl: String? = "",
private val mForumName: String? = ""
) {
companion object {
private const val SOURCE_ENTRANCE = "webView"
}
private var mLoginHandler: CompletionHandler<Any>? = null
private var mDownloadWatcher: DataWatcher? = null // 下载观察者
private var mDownloadUrlSet: HashSet<String>? = null // 下载的 url 集合
@ -215,7 +220,7 @@ class DefaultJsApi(
runOnUiThread {
// 若畅玩列表中安装了,优先启动畅玩游戏
if (VHelper.isInstalled(packageName)) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "", "", "")) {
VHelper.validateVSpaceBeforeAction(context, packageName, null) {
VHelper.launch(context, packageName)
}
} else {
@ -230,7 +235,14 @@ class DefaultJsApi(
val context = CurrentActivityHolder.getCurrentActivity()
context?.startActivity(ImageViewerActivity.getIntent(context, imageEvent.imageList, imageEvent.position, "浏览器"))
context?.startActivity(
ImageViewerActivity.getIntent(
context,
imageEvent.imageList,
imageEvent.position,
"浏览器"
)
)
}
@JavascriptInterface
@ -279,11 +291,18 @@ class DefaultJsApi(
/**
* 打开论坛搜索页
* 如果用户是从 webView跳转到论坛搜索页则sourceEntrance为空
*/
@JavascriptInterface
fun openForumSearch(msg: Any) {
runOnUiThread {
DirectUtils.directToForumOrUserSearch(context, mBbsId ?: "", entrance.ifBlank { "内部网页" })
DirectUtils.directToForumOrUserSearch(
context,
mBbsId ?: "",
entrance.ifBlank { "内部网页" },
SOURCE_ENTRANCE,
mForumName ?: ""
)
}
}
@ -385,7 +404,7 @@ class DefaultJsApi(
@JavascriptInterface
fun showQaFeedbackDialog(msg: Any) {
val mHelpAndFeedbackHelp =
val mHelpAndFeedbackHelp =
ARouter.getInstance().build(RouteConsts.provider.helpAndFeedback).navigation() as? IHelpAndFeedbackProvider
mHelpAndFeedbackHelp?.showQaFeedbackDialogFragment(context as AppCompatActivity, msg.toString())
}
@ -531,10 +550,9 @@ class DefaultJsApi(
@JavascriptInterface
fun installDownloadedGame(event: Any) {
val url = event.toString()
val vUrl = VHelper.getVUrl(url)
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(url, null, false)
?: DownloadManager.getInstance().getDownloadEntitySnapshot(vUrl, null, false)
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(url, null)
?: DownloadManager.getInstance().getDownloadEntitySnapshot(url, null)
NewFlatLogUtils.logGameInstall(
gameId = downloadEntity?.gameId ?: "",
@ -549,7 +567,7 @@ class DefaultJsApi(
)
downloadEntity?.let {
PackageInstaller.install(context, it, showUnzipToast = false)
PackageInstaller.install(context, it, showUnzipToast = false, ignoreAsVGame = false)
}
}
@ -750,6 +768,7 @@ class DefaultJsApi(
var status: String = "" // DOWNLOADING, PAUSED, DOWNLOADED, ERROR, UNKNOWN
) {
companion object {
fun fromDownloadEntity(downloadEntity: DownloadEntity): SimpleDownloadEntity {
val status: String = when (downloadEntity.status) {
add,

View File

@ -1,23 +1,21 @@
package com.gh.common.chain
import android.content.Context
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.feature.entity.GameEntity
class BrowserInstallHandler : ChainHandler() {
class BrowserInstallHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
BrowserInstallHelper.showBrowserInstallHintDialog(
context,
gameEntity,
gameEntity.isVGame() || gameEntity.isSplitXApk()
asVGame || gameEntity.isSplitXApk()
) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
}

View File

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

View File

@ -1,24 +0,0 @@
package com.gh.common.chain
import android.content.Context
import com.gh.gamecenter.feature.entity.GameEntity
abstract class ChainHandler {
private var next: ChainHandler? = null
var processEndCallback: ((Any?) -> Unit)? = null
fun setNext(next: ChainHandler?) {
this.next = next
}
fun getNext(): ChainHandler? {
return next
}
fun hasNext(): Boolean {
return next != null
}
abstract fun handleRequest(context: Context, gameEntity: GameEntity)
}

View File

@ -5,15 +5,15 @@ import com.gh.common.util.DialogUtils
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.feature.entity.GameEntity
class CheckDownloadHandler : ChainHandler() {
class CheckDownloadHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(isSubscribe)
processEndCallback?.invoke(asVGame, isSubscribe)
}
}

View File

@ -4,19 +4,20 @@ import android.content.Context
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.feature.entity.GameEntity
class CheckStoragePermissionHandler : ChainHandler() {
class CheckStoragePermissionHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
PermissionHelper.checkStoragePermissionBeforeAction(
context,
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese
gameEntity.categoryChinese,
gameEntity.getApk().firstOrNull()?.format,
) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
}

View File

@ -1,22 +1,22 @@
package com.gh.common.chain
class ChainBuilder {
class DownloadChainBuilder {
private val handlers: MutableList<ChainHandler> = ArrayList()
private val handlers: MutableList<DownloadChainHandler> = ArrayList()
private var processEndCallback: ((Any?) -> Unit)? = null
private var processEndCallback: ((asVGame: Boolean, Any?) -> Unit)? = null
fun setProcessEndCallback(callback: (Any?) -> Unit): ChainBuilder {
fun setProcessEndCallback(callback: (asVGame: Boolean, Any?) -> Unit): DownloadChainBuilder {
processEndCallback = callback
return this
}
fun addHandler(handler: ChainHandler): ChainBuilder {
fun addHandler(handler: DownloadChainHandler): DownloadChainBuilder {
handlers.add(handler)
return this
}
fun buildHandlerChain(): ChainHandler? {
fun buildHandlerChain(): DownloadChainHandler? {
for (i in handlers.indices) {
handlers[i].processEndCallback = processEndCallback
if (i + 1 < handlers.size) {

View File

@ -0,0 +1,40 @@
package com.gh.common.chain
import android.content.Context
import com.gh.gamecenter.feature.entity.GameEntity
abstract class DownloadChainHandler {
private var next: DownloadChainHandler? = null
// asVGame: 当前下载是否以畅玩游戏来进行
var processEndCallback: ((asVGame: Boolean, Any?) -> Unit)? = null
/**
* 设置下一个处理者
*/
fun setNext(next: DownloadChainHandler?) {
this.next = next
}
/**
* 获取下一个处理者
*/
fun getNext(): DownloadChainHandler? {
return next
}
/**
* 是否存在下一个处理者
*/
fun hasNext(): Boolean {
return next != null
}
/**
* 处理请求
* @param gameEntity 游戏实体
* @param asVGame 是否作为畅玩游戏进行
*/
abstract fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean)
}

View File

@ -3,21 +3,18 @@ package com.gh.common.chain
import android.content.Context
import com.gh.common.util.DownloadDialogHelper
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.feature.entity.GameEntity
class DownloadDialogHelperHandler : ChainHandler() {
class DownloadDialogHelperHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback {
override fun onCallback() {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {
processEndCallback?.invoke(null)
}
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
})
}
}
}

View File

@ -5,14 +5,14 @@ import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
class GamePermissionHandler : ChainHandler() {
class GamePermissionHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
}

View File

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

View File

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

View File

@ -5,14 +5,14 @@ import androidx.appcompat.app.AppCompatActivity
import com.gh.common.dialog.PackageCheckDialogFragment
import com.gh.gamecenter.feature.entity.GameEntity
class PackageCheckHandler : ChainHandler() {
class PackageCheckHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
PackageCheckDialogFragment.show((context as AppCompatActivity), gameEntity) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
}

View File

@ -4,18 +4,20 @@ import android.content.Context
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.feature.entity.GameEntity
class UnsupportedFeatureHandler : ChainHandler() {
class UnsupportedFeatureHandler : DownloadChainHandler() {
override fun handleRequest(
context: Context, gameEntity: GameEntity
context: Context,
gameEntity: GameEntity,
asVGame: Boolean
) {
if (shouldShowUnsupportedFeatureDialog()) {
DialogHelper.showUnsupportedFeatureDialog(context)
} else {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
}

View File

@ -5,31 +5,27 @@ import com.gh.common.simulator.NewSimulatorGameManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.gamecenter.feature.entity.GameEntity
class UpdateNewSimulatorHandler: ChainHandler() {
class UpdateNewSimulatorHandler: DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
NewSimulatorGameManager.showUpdateNewsSimulator(context, gameEntity) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
}
else{
} else {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
}
}
}
else{
} else {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
}
}
}
}

View File

@ -4,15 +4,23 @@ import android.content.Context
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.vspace.VHelper
class ValidateVSpaceHandler : ChainHandler() {
class ValidateVSpaceHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
val closure = {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
if (asVGame) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
closure.invoke()
}
} else {
closure.invoke()
}
}
}

View File

@ -7,14 +7,14 @@ import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.feature.entity.GameEntity
class VersionNumberHandler : ChainHandler() {
class VersionNumberHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
val confirmCallback = {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(null)
processEndCallback?.invoke(asVGame, null)
}
}
if (!gameEntity.isShowVersionNumber()) {

View File

@ -8,7 +8,6 @@ import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.util.AdHelper;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
@ -22,14 +21,18 @@ import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.AppEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
import com.gh.gamecenter.entity.VNewSetting;
import com.gh.gamecenter.entity.VSetting;
import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.utils.ContentBlockedHelper;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.retrofit.service.VApiService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
@ -42,8 +45,12 @@ import java.io.IOException;
import java.util.List;
import java.util.Locale;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;
import okhttp3.ResponseBody;
public class Config {
@ -72,6 +79,10 @@ public class Config {
private static NewApiSettingsEntity.NightMode mNightModeSetting;
private static SimulatorEntity mNewSimulatorEntity;
private static VSetting mVSetting;
private static VNewSetting mVNewSetting;
private static AppEntity mNew32UpdateEntity;
public static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
private static GameGuidePopupEntity mGameGuidePopupEntity;
private static SharedPreferences mDefaultSharedPreferences;
@ -305,6 +316,27 @@ public class Config {
return mVSetting;
}
@Nullable
public static VNewSetting getVNewSettingEntity() {
if (mVNewSetting == null) {
try {
String json = SPUtils.getString(Constants.SP_V_NEW_SETTINGS);
if (!TextUtils.isEmpty(json)) {
mVNewSetting = GsonUtils.fromJson(json, VNewSetting.class);
vNewSettingSubject.onNext(mVNewSetting);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return mVNewSetting;
}
@Nullable
public static AppEntity getNew32UpdateEntity() {
return mNew32UpdateEntity;
}
/**
* 请求网络数据,尝试刷新畅玩相关配置
*/
@ -325,6 +357,36 @@ public class Config {
});
}
@SuppressLint("CheckResult")
public static void getNewSetting() {
VApiService vApi = RetrofitManager.getInstance().getVApi();
vApi.getNewSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT).flatMap(new Function<VNewSetting, SingleSource<AppEntity>>() {
@Override
public SingleSource<AppEntity> apply(VNewSetting data) throws Exception {
mVNewSetting = data;
vNewSettingSubject.onNext(mVNewSetting);
SPUtils.setString(Constants.SP_V_NEW_SETTINGS, GsonUtils.toJson(data));
if (data.getVa() != null && data.getVa().getArch32() != null) {
String versionNameByPackageName = PackageUtils.getVersionNameByPackageName(data.getVa().getArch32().getPackageName());
return vApi.getNewPackageUpdate(
BuildConfig.VERSION_NAME,
versionNameByPackageName != null ? versionNameByPackageName : "",
HaloApp.getInstance().getChannel()
);
}
return Single.error(new IllegalStateException("VNewSetting entity is not expected"));
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<AppEntity>() {
@Override
public void onSuccess(AppEntity data) {
mNew32UpdateEntity = data;
}
});
}
@Nullable
public static GameGuidePopupEntity getGameGuidePopupEntity() {
return mGameGuidePopupEntity;
@ -403,6 +465,7 @@ public class Config {
});
refreshVSettingEntity();
getNewSetting();
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
@ -460,6 +523,11 @@ public class Config {
DarkModeUtils.INSTANCE.initDarkMode();
}
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
// 刷新屏蔽字段
if (mNewApiSettingsEntity.getGameShieldContents() != null) {
ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
}
}
});
}

View File

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

View File

@ -3,27 +3,21 @@ package com.gh.common.databind;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.chain.BrowserInstallHandler;
import com.gh.common.chain.CertificationHandler;
import com.gh.common.chain.ChainBuilder;
import com.gh.common.chain.ChainHandler;
import com.gh.common.chain.DownloadChainBuilder;
import com.gh.common.chain.DownloadChainHandler;
import com.gh.common.chain.CheckDownloadHandler;
import com.gh.common.chain.CheckStoragePermissionHandler;
import com.gh.common.chain.DownloadDialogHelperHandler;
@ -46,7 +40,6 @@ import com.gh.common.util.DialogUtils;
import com.gh.common.util.GameUtils;
import com.gh.common.util.GameViewUtils;
import com.gh.common.util.LogUtils;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageLauncher;
import com.gh.common.util.PackageUtils;
@ -57,26 +50,16 @@ import com.gh.download.server.BrowserInstallHelper;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.baselist.LoadStatus;
import com.gh.gamecenter.common.callback.OnViewClickListener;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
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.common.view.DrawableView;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.NumberUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.entity.ServerCalendarEntity;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.entity.TestEntity;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
@ -85,14 +68,11 @@ import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.gamecenter.feature.view.GameIconView;
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VDownloadManagerActivity;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -100,134 +80,8 @@ import java.util.List;
/**
* Created by khy on 12/02/18.
*/
public class BindingAdapters {
public static void loadIcon(SimpleDraweeView view, String imageUrl) {
ImageUtils.displayIcon(view, imageUrl);
}
public static void loadImage(SimpleDraweeView view, String imageUrl) {
ImageUtils.display(view, imageUrl);
}
public static void setTextSize(TextView view, int number) {
view.setTextSize(number);
}
public static void setTypeface(TextView view, String type) {
if (type == null) return;
switch (type) {
case "bold":
view.setTypeface(null, Typeface.BOLD);
break;
case "italic":
view.setTypeface(null, Typeface.ITALIC);
break;
case "bold_italic":
view.setTypeface(null, Typeface.BOLD_ITALIC);
break;
default:
view.setTypeface(null, Typeface.NORMAL);
break;
}
}
public static void addDetailKaiFuView(LinearLayout view, List<ServerCalendarEntity> list
, OnViewClickListener listener, Boolean isReadyPatch) {
if (list == null) return;
view.removeAllViews();
for (int i = 0; i < list.size() + 1; i++) { // 1 is Title
View inflate = LayoutInflater.from(view.getContext()).inflate(R.layout.kaifu_detail_item_row, null);
KaifuDetailItemRowBinding binding = KaifuDetailItemRowBinding.bind(inflate);
binding.getRoot().setBackgroundColor(isReadyPatch != null && isReadyPatch ? ExtensionsKt.toColor(R.color.theme) : ExtensionsKt.toColor(R.color.white));
binding.getRoot().setPadding(DisplayUtils.dip2px(1), DisplayUtils.dip2px(1), DisplayUtils.dip2px(1), i == list.size() ? DisplayUtils.dip2px(1) : 0);
ServerCalendarEntity serverEntity = list.get(i - 1);
binding.timeTv.setText(i == 0 ? "时间" : serverEntity.getFormatTime("HH:mm"));
binding.remarkTv.setText(i == 0 ? "备注" : serverEntity.getRemark());
binding.nameTv.setText(i == 0 ? "名字" : (TextUtils.isEmpty(serverEntity.getNote()) ? "-" : serverEntity.getNote()));
if (i != 0) {
binding.getRoot().setOnClickListener(v -> {
listener.onClick(v, isReadyPatch != null && isReadyPatch ? serverEntity : null);
});
// 滑动冲突处理
binding.getRoot().setOnTouchListener((v, event) -> {
if (list.size() > 5) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
EventBus.getDefault().post(new EBReuse("CalenderDown"));
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
EventBus.getDefault().post(new EBReuse("CalenderCancel"));
}
}
return false;
});
}
view.addView(inflate);
}
}
// 如果超过10000则转换为1.0W
public static void transSimpleCount(TextView view, int count) {
view.setText(NumberUtils.transSimpleCount(count));
}
public static void textColorFromString(TextView tv, String hexString) {
if (TextUtils.isEmpty(hexString)) return;
try {
tv.setTextColor(Color.parseColor(hexString));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void showHide(View view, Boolean show) {
if (show != null && show) {
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.GONE);
}
}
public static void goneIf(View view, Boolean gone) {
if (gone != null && gone) {
view.setVisibility(View.GONE);
} else {
view.setVisibility(View.VISIBLE);
}
}
/**
* lazy 的 paddingTop
*/
public static void lazyPaddingLeft(View view, int paddingLeftInDp) {
view.setPadding(DisplayUtils.dip2px(paddingLeftInDp), view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom());
}
/**
* lazy 的 paddingTop
*/
public static void lazyPaddingTop(View view, int paddingTopInDp) {
view.setPadding(view.getPaddingLeft(), DisplayUtils.dip2px(paddingTopInDp), view.getPaddingRight(), view.getPaddingBottom());
}
/**
* lazy 的 paddingBottom
*/
public static void lazyPaddingBottom(View view, int paddingBottomInDp) {
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), DisplayUtils.dip2px(paddingBottomInDp));
}
public static void visibleInvisible(View view, Boolean show) {
if (show != null && show) {
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.INVISIBLE);
}
}
public static void setMessageUnread(TextView view, int unreadCount) {
if (unreadCount < 100) {
view.setText(String.valueOf(unreadCount));
@ -236,119 +90,12 @@ public class BindingAdapters {
}
}
public static void setServerTypePadding(TextView view, String serverType) {
int paddRight = 0;
if (TextUtils.isEmpty(serverType)) {
} else {
if ("删档内测".equals(serverType) || "不删档内测".equals(serverType)) {
if ("删档内测".equals(serverType)) {
paddRight = DisplayUtils.dip2px(view.getContext(), 50);
} else {
paddRight = DisplayUtils.dip2px(view.getContext(), 60);
}
} else {
paddRight = DisplayUtils.dip2px(view.getContext(), 30);
}
}
view.setPadding(0, 0, paddRight, 0);
}
public static void setServerType(TextView view, String serverType) {
view.setText(serverType);
if ("删档内测".equals(serverType) || "不删档内测".equals(serverType)) {
view.setBackgroundResource(R.drawable.textview_server_tag);
} else {
view.setBackgroundResource(R.drawable.textview_orange_up);
}
}
public static void setGame(View view, GameEntity gameEntity) {
if (gameEntity != null && view instanceof GameIconView) {
((GameIconView) view).displayGameIcon(gameEntity);
}
}
public static void setGameIcon(View view, GameEntity gameEntity) {
if (gameEntity != null && view instanceof GameIconView) {
((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript(), gameEntity.getIconFloat());
}
}
public static void setArticleType(TextView view, String articleType) {
NewsUtils.setNewsType(view, articleType, 0, 0);
}
public static void setDetailDownloadText(TextView view, GameEntity gameEntity) {
if (gameEntity == null || gameEntity.getApk().isEmpty()) {
view.setBackgroundResource(R.drawable.game_item_btn_pause_style);
view.setTextColor(0xFF999999);
view.setClickable(false);
}
}
public static void setLiBaoBtn(TextView view, String status) {
if (TextUtils.isEmpty(status)) return;
switch (status) {
case "coming":
view.setText(R.string.libao_coming);
view.setBackgroundResource(R.drawable.textview_blue_style);
break;
case "ling":
view.setText(R.string.libao_ling);
view.setBackgroundResource(R.drawable.textview_green_style);
break;
case "tao":
view.setText(R.string.libao_tao);
view.setBackgroundResource(R.drawable.textview_orange_style);
break;
case "used_up":
view.setText(R.string.libao_used_up);
view.setBackgroundResource(R.drawable.textview_cancel_up);
break;
case "finish":
view.setText(R.string.libao_finish);
view.setBackgroundResource(R.drawable.textview_cancel_up);
break;
case "linged":
view.setText(R.string.libao_linged);
view.setBackgroundResource(R.drawable.libao_linged_style);
view.setTextColor(ContextCompat.getColorStateList(view.getContext(), R.color.libao_linged_selector));
break;
case "taoed":
view.setText(R.string.libao_taoed);
view.setBackgroundResource(R.drawable.libao_taoed_style);
view.setTextColor(ContextCompat.getColorStateList(view.getContext(), R.color.libao_taoed_selector));
break;
case "copy":
view.setText(R.string.libao_copy);
view.setBackgroundResource(R.drawable.textview_blue_style);
break;
case "repeatLing":
view.setText(R.string.libao_repeat_ling);
view.setBackgroundResource(R.drawable.textview_cancel_up);
break;
case "repeatLinged":
view.setText(R.string.libao_repeat_ling);
view.setBackgroundResource(R.drawable.textview_green_style);
break;
case "repeatTao":
view.setText(R.string.libao_repeat_tao);
view.setBackgroundResource(R.drawable.textview_cancel_up);
break;
case "repeatTaoed":
view.setText(R.string.libao_repeat_tao);
view.setBackgroundResource(R.drawable.textview_orange_style);
break;
case "unshelve":
view.setBackgroundResource(R.drawable.textview_cancel_style);
view.setText(R.string.libao_unshelve);
break;
default:
view.setBackgroundResource(R.drawable.textview_cancel_style);
view.setText("异常");
}
}
// 大图下的进度条
public static void setDownloadButton(DownloadButton progressBar,
GameEntity gameEntity,
@ -376,13 +123,9 @@ public class BindingAdapters {
switch (progressBar.getButtonStyle()) {
case DOWNLOADING_PLUGIN:
case DOWNLOADING_NORMAL:
if (gameEntity.isVGame()) {
v.getContext().startActivity(VDownloadManagerActivity.getIntent(v.getContext(), true));
} else {
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().get(0).getUrl(), entrance);
v.getContext().startActivity(intent);
}
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().get(0).getUrl(), entrance);
v.getContext().startActivity(intent);
break;
case NONE:
Utils.toast(v.getContext(), "该游戏已关闭下载");
@ -405,7 +148,7 @@ public class BindingAdapters {
}
}
ChainBuilder builder = new ChainBuilder();
DownloadChainBuilder builder = new DownloadChainBuilder();
builder.addHandler(new UnsupportedFeatureHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CheckStoragePermissionHandler());
@ -419,22 +162,33 @@ public class BindingAdapters {
builder.addHandler(new OverseaDownloadHandler());
builder.addHandler(new CheckDownloadHandler());
builder.setProcessEndCallback(o -> {
download(v.getContext(), progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
download(v.getContext(),
progressBar,
gameEntity,
traceEvent,
asVGame,
(boolean) isSubscribe,
entrance,
location);
return null;
});
final ChainHandler chainHandler = builder.buildHandlerChain();
final DownloadChainHandler chainHandler = builder.buildHandlerChain();
if (chainHandler != null) {
chainHandler.handleRequest(v.getContext(), gameEntity);
chainHandler.handleRequest(
v.getContext(),
gameEntity,
GameUtils.shouldPerformAsVGame(gameEntity)
);
}
} else {
ChainBuilder builder = new ChainBuilder();
DownloadChainBuilder builder = new DownloadChainBuilder();
builder.addHandler(new UnsupportedFeatureHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
builder.setProcessEndCallback(o -> {
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
DownloadDialog.showDownloadDialog(
v.getContext(),
gameEntity,
@ -443,9 +197,13 @@ public class BindingAdapters {
location + ":" + gameEntity.getName());
return null;
});
final ChainHandler chainHandler = builder.buildHandlerChain();
final DownloadChainHandler chainHandler = builder.buildHandlerChain();
if (chainHandler != null) {
chainHandler.handleRequest(v.getContext(), gameEntity);
chainHandler.handleRequest(
v.getContext(),
gameEntity,
GameUtils.shouldPerformAsVGame(gameEntity)
);
}
}
}
@ -458,7 +216,14 @@ public class BindingAdapters {
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
download(v.getContext(), progressBar, gameEntity, traceEvent, false, entrance, location);
download(v.getContext(),
progressBar,
gameEntity,
traceEvent,
false,
false,
entrance,
location);
return;
}
@ -467,12 +232,7 @@ public class BindingAdapters {
return;
}
if (gameEntity.isVGame()) {
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity, null);
return;
}
PackageLauncher.launchApp(v.getContext(), gameEntity, gameEntity.getApk().get(0).getPackageName());
PackageLauncher.launch(v.getContext(), gameEntity, null);
} else {
DownloadDialog.showDownloadDialog(
v.getContext(),
@ -500,13 +260,12 @@ public class BindingAdapters {
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
if (gameEntity.isVGame()) {
VHelper.installOrLaunch(v.getContext(), gameEntity, null);
return;
}
if (downloadEntity != null) {
PackageInstaller.install(v.getContext(), downloadEntity);
if (ExtensionsKt.isLocalDownloadInDualDownloadMode(downloadEntity)) {
PackageInstaller.install(v.getContext(), downloadEntity);
} else {
VHelper.installOrLaunch(v.getContext(), gameEntity, null);
}
}
}
break;
@ -592,7 +351,7 @@ public class BindingAdapters {
}
} else {
String status = GameUtils.getDownloadBtnText(progressBar.getContext(), gameEntity, PluginLocation.only_game);
String status = GameUtils.getDownloadBtnText(progressBar.getContext(), gameEntity, true, false, PluginLocation.only_game);
switch (status) {
case "插件化":
progressBar.setButtonStyle(DownloadButton.ButtonStyle.PLUGIN);
@ -664,24 +423,6 @@ public class BindingAdapters {
}
}
/*private static void download(DownloadProgressBar progressBar, GameEntity gameEntity, ExposureEvent traceEvent, @Nullable String entrance, @Nullable String location, View v) {
if (gameEntity.getApk().size() == 1) {
ApkEntity apk = gameEntity.getApk().get(0);
DownloadDialogHelper.findAvailableDialogAndShow(
v.getContext(),
gameEntity,
apk,
() -> {
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
});
} else {
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
entrance, location + gameEntity.getName(), traceEvent);
}
}*/
private static void updateReservation(DownloadButton progressBar, GameEntity gameEntity) {
// 显示预约
if (gameEntity.isReservable()) {
@ -701,45 +442,35 @@ public class BindingAdapters {
DownloadButton progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
boolean asVGame,
boolean isSubscribe,
String entrance,
String location) {
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
}
String str = progressBar.getText().toString();
String method;
if (str.contains("更新")) {
method = "更新";
} else if (str.contains("插件化")) {
method = "插件化";
} else {
method = progressBar.getContext().getString(R.string.download);
}
String buttonText = progressBar.getText();
ApkEntity apkEntity = gameEntity.getApk().get(0);
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(progressBar.getContext(),
apkEntity,
gameEntity,
method,
asVGame,
gameEntity.isDualBtnModeEnabled(),
entrance,
location + gameEntity.getName(),
isSubscribe,
traceEvent);
progressBar.setProgress(0);
progressBar.setButtonStyle("插件化".equals(method) ?
progressBar.setButtonStyle(buttonText.contains("插件化") ?
DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN : DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
} else {
Utils.toast(progressBar.getContext(), msg);
}
}
public static void setGameLabelList(LinearLayout layout, List<TagStyleEntity> tagStyle) {
GameViewUtils.setLabelList(layout.getContext(), layout, tagStyle);
}
// 包含测试开服标签
public static void setGameTags(LinearLayout layout, GameEntity gameEntity) {
try {
@ -809,12 +540,6 @@ public class BindingAdapters {
}
}
public static void isRefreshing(SwipeRefreshLayout layout, LoadStatus status) {
if (status != LoadStatus.INIT_LOADING && status != LoadStatus.LIST_LOADING) {
layout.setRefreshing(false);
}
}
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
String gameName;
@ -836,30 +561,6 @@ public class BindingAdapters {
}
public static void setCommunityImage(SimpleDraweeView imageView, List<String> images, List<CommunityVideoEntity> videos) {
if (videos.size() > 0) {
CommunityVideoEntity videoEntity = videos.get(0);
ImageUtils.display(imageView, videoEntity.getPoster());
imageView.setVisibility(View.VISIBLE);
} else if (images.size() > 0) {
imageView.setVisibility(View.VISIBLE);
ImageUtils.display(imageView, images.get(0));
} else {
imageView.setVisibility(View.GONE);
}
}
public static void setCommunityVideoDuration(TextView mVideoDuration, List<CommunityVideoEntity> videos) {
if (videos != null && videos.size() > 0) {
CommunityVideoEntity videoEntity = videos.get(0);
mVideoDuration.setBackground(DrawableView.getOvalDrawable(R.color.black_alpha_50, 999F));
mVideoDuration.setText(videoEntity.getDuration());
mVideoDuration.setVisibility(View.VISIBLE);
} else {
mVideoDuration.setVisibility(View.GONE);
}
}
public static void setGameTags(TextView view, List<TagStyleEntity> tags, int maxTags) {
if (tags == null) {
view.setText("");
@ -887,16 +588,4 @@ public class BindingAdapters {
}
view.setText(span);
}
public static void setVideoData(TextView view, int count) {
if (count > 0) {
ExtensionsKt.setDrawableStart(view, ContextCompat.getDrawable(view.getContext(), R.drawable.ic_video_data_up), null, null);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.text_EA3333));
view.setText(count + "");
} else {
ExtensionsKt.removeDrawable(view);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.text_subtitleDesc));
view.setText("-");
}
}
}

View File

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

View File

@ -60,7 +60,7 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
if (index == notEmptySite.size - 1) bottomMargin = 8F.dip2px()
}
siteTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14F)
siteTv.setTextColor(R.color.theme_font.toColor(requireContext()))
siteTv.setTextColor(R.color.text_theme.toColor(requireContext()))
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {

View File

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

View File

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

View File

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

View File

@ -96,9 +96,9 @@ object ExposureUtils {
}
@JvmStatic
fun getDownloadType(apkEntity: ApkEntity, gameId: String, isVGame: Boolean): DownloadType {
fun getDownloadType(apkEntity: ApkEntity, gameId: String, asVGame: Boolean): DownloadType {
return when {
isVGame -> getVGameDownloadType(apkEntity, gameId)
asVGame -> getVGameDownloadType(apkEntity, gameId)
PackageUtils.isInstalled(
HaloApp.getInstance().application,
apkEntity.packageName
@ -109,7 +109,7 @@ object ExposureUtils {
private fun getVGameDownloadType(apkEntity: ApkEntity, gameId: String): DownloadType {
return when {
PackagesManager.isCanUpdate(gameId, apkEntity.packageName) -> DownloadType.FUN_UPDATE
PackagesManager.isCanUpdate(gameId, apkEntity.packageName, asVGame = true) -> DownloadType.FUN_UPDATE
else -> DownloadType.FUN_DOWNLOAD
}
}

View File

@ -41,6 +41,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
if (gameEntityList == null) {
processNext()
} else {
updateStatus(STATUS_VALID)
onProcess()
}
} else {

View File

@ -20,7 +20,7 @@ class FloatingWindowHandler(priority: Int) : PriorityChainHandler(priority) {
mWindowList = windowList
if (mFragment != null) {
preProcess()
doPreProcess()
}
}
@ -32,15 +32,16 @@ class FloatingWindowHandler(priority: Int) : PriorityChainHandler(priority) {
mRecyclerView = recyclerView
if (mWindowList != null) {
preProcess()
doPreProcess()
}
}
private fun preProcess() {
private fun doPreProcess() {
Utils.log(TAG, "FloatingWindowHandler preProcess windowSize is -> ${mWindowList?.size}")
if (getStatus() == STATUS_PENDING) {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
onProcess()
} else {
processNext()

View File

@ -14,6 +14,7 @@ class HomePushHandler(priority: Int): PriorityChainHandler(priority) {
if (getStatus() == STATUS_PENDING) {
if (shouldShow && homeFragment != null) {
updateStatus(STATUS_VALID)
onProcess()
} else {
processNext()

View File

@ -20,6 +20,7 @@ class PrivacyPolicyDialogHandler(priority: Int) : PriorityChainHandler(priority)
if (privacyPolicyEntity == null) {
processNext()
} else {
updateStatus(STATUS_VALID)
onProcess()
}
} else {

View File

@ -21,6 +21,7 @@ class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
if (reserveData.isNullOrEmpty()) {
processNext()
} else {
updateStatus(STATUS_VALID)
onProcess()
}
} else {

View File

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

View File

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

View File

@ -120,6 +120,10 @@ class DirectProviderImpl : IDirectProvider {
return DirectUtils.directToQGameHome(context)
}
override fun directToExternalBrowser(context: Context, url: String) {
DirectUtils.directToExternalBrowser(context, url)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -3,6 +3,7 @@ package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.exposure.ExposureSource
@ -39,13 +40,16 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
gameId = boundedObject.id
gameName = boundedObject.name ?: ""
gameCategory = boundedObject.category ?: ""
downloadStatus = if (boundedObject.isVGame()) {
"畅玩"
} else if (boundedObject.downloadStatus == "demo") {
"试玩"
} else {
"下载"
}
downloadStatus =
if (boundedObject.isVGamePreferred()) {
"畅玩"
} else {
if (boundedObject.downloadStatus == "demo") {
"试玩"
} else {
"下载"
}
}
gameTypeInChinese = boundedObject.categoryChinese
downloadStatusInChinese = boundedObject.downloadStatusChinese
gameSchemaType = boundedObject.gameBitChinese
@ -68,7 +72,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
gameId = boundedObject.gameId
gameName = boundedObject.name ?: ""
gameCategory = boundedObject.getGameCategory()
downloadStatus = if (boundedObject.isVGame()) "畅玩" else "下载"
downloadStatus = if (boundedObject.asVGame()) "畅玩" else "下载"
packageName = boundedObject.packageName
exposureSourceList = boundedObject.exposureTrace?.toObject<ExposureEvent>()?.source
}
@ -93,9 +97,18 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
}
// 预约状态不上报
if (downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVABLE
&& downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVED
) {
if (downloadButton.buttonStyle == DownloadButton.ButtonStyle.NORMAL
|| downloadButton.buttonStyle == DownloadButton.ButtonStyle.PLUGIN) {
val text = downloadButton.text.ifEmpty {
downloadButton.getTag(R.string.download) ?: ""
}.toString()
val downloadType = if (text.contains("畅玩")) {
"畅玩下载"
} else {
"本地下载"
}
// 上报神策点击事件
SensorsBridge.trackEventWithExposureSource(
@ -107,6 +120,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
"download_status", downloadStatusInChinese,
"button_name", downloadButton.text,
"game_schema_type", gameSchemaType,
"download_type", downloadType,
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,

View File

@ -9,8 +9,8 @@ import com.gh.gamecenter.core.provider.IGameSubstituteRepositoryProvider
@Route(path = RouteConsts.provider.gameSubstituteRepository, name = "GameSubstituteRepositoryHelper暴露服务")
class GameSubstituteRepositoryProviderImpl : IGameSubstituteRepositoryProvider {
override fun updateSubstitutableGames() {
GameSubstituteRepositoryHelper.updateSubstitutableGames()
override fun updateHistoricInstalledGameSet() {
GameSubstituteRepositoryHelper.updateHistoricInstalledGameSet()
}
override fun init(context: Context?) {

View File

@ -11,7 +11,7 @@ import com.lightgame.download.DownloadEntity
class PackageInstallerProviderImpl : IPackageInstallerProvider {
override fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) {
PackageInstaller.install(context, downloadEntity, showUnzipToast)
PackageInstaller.install(context, downloadEntity, showUnzipToast, false)
}
override fun uninstall(context: Context, path: String) {

View File

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

View File

@ -21,10 +21,6 @@ class WebProviderImpl : IWebProvider {
return WebActivity.getBindWechatIntent(context)
}
override fun getSecurityCertificationIntent(context: Context): Intent {
return WebActivity.getSecurityCertificationIntent(context)
}
override fun getQAIntent(
context: Context?,
url: String?,

View File

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

View File

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

View File

@ -1,15 +1,8 @@
package com.gh.common.util
import com.gh.common.constant.Config
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.entity.NewApiSettingsEntity
import com.gh.gamecenter.entity.StartupAdEntity
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
object AdHelper {

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import android.os.Build;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.entity.NewsDetailEntity;
@ -54,7 +55,7 @@ public class DataCollectionUtils {
map.put("location", downloadEntity.getLocation());
map.put(EntranceConsts.KEY_ENTRANCE, downloadEntity.getEntrance());
map.put("installed", downloadEntity.getInstalled());
map.put("network", NetworkUtils.getConnectedType(context));
map.put("network", MetaUtil.getMeta().getNetwork());
DataCollectionManager.onEvent(context, "download", map);
}
@ -118,7 +119,7 @@ public class DataCollectionUtils {
map.put("key", args[0]);
map.put("game_id", args[3]);
map.put("game_name", args[4]);
map.put("netword", NetworkUtils.getConnectedType(context));
map.put("netword", MetaUtil.getMeta().getNetwork());
map.put("type", "search");
map.put("device_type", android.os.Build.MODEL);
map.put("device_system", android.os.Build.VERSION.SDK_INT + "=" + android.os.Build.VERSION.RELEASE);
@ -136,7 +137,7 @@ public class DataCollectionUtils {
map.put("key", args[0]);
map.put("game_id", args[3]);
map.put("game_name", args[4]);
map.put("netword", NetworkUtils.getConnectedType(context));
map.put("netword", MetaUtil.getMeta().getNetwork());
map.put("type", "click");
map.put("device_type", android.os.Build.MODEL);
map.put("device_system", android.os.Build.VERSION.SDK_INT + "=" + android.os.Build.VERSION.RELEASE);

View File

@ -9,15 +9,16 @@ import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.ad.AdDelegateHelper;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.base.activity.BaseActivity;
import com.gh.gamecenter.common.constant.Constants;
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.AppExecutor;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.SPUtils;
@ -114,19 +115,24 @@ public class DataUtils {
Utils.log("Gid", gid);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
String originalGid = HaloApp.getInstance().getGid();
HaloApp.getInstance().setGid(gid);
// gid 变更时上报 gid 变更日志
if (!TextUtils.isEmpty(originalGid) && !originalGid.equals(gid)) {
NewFlatLogUtils.logGidChanged(originalGid, gid);
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
String savedGid = SPUtils.getString(Constants.GID);
if (!TextUtils.isEmpty(savedGid)) {
gid = savedGid;
} else {
SPUtils.setString(Constants.GID, gid);
}
SensorsBridge.setGid(gid);
HaloApp.getInstance().setGid(gid);
// 更新广告配置
ExtensionsKt.doOnMainProcessOnly(HaloApp.getInstance(), () -> {
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
});
// 避免重复调用
if (!TextUtils.isEmpty(gid) && !gid.equals(originalGid)) {
GameSubstituteRepositoryHelper.updateSubstitutableGames();
if (!TextUtils.isEmpty(gid)) {
GameSubstituteRepositoryHelper.updateHistoricInstalledGameSet();
}
getDeviceCertification(gid);
@ -172,9 +178,11 @@ public class DataUtils {
if (idCardEntity != null) {
boolean isCertificated = !TextUtils.isEmpty(data.getIdCard().getId());
boolean isAdult = data.getIdCard().getMinor() == null || !data.getIdCard().getMinor();
boolean isCertificating = data.getIdCard().getStatus() == 1;
values.put(GhContentProvider.KEY_IS_CERTIFICATED, isCertificated); // 是否认证
values.put(GhContentProvider.KEY_IS_ADULT, isAdult); // 是否成年
values.put(GhContentProvider.KEY_IS_CERTIFICATING, isCertificating); // 是否认证中
if (!isCertificated) {
RealNameHelper.updateCertificationStatus(0);
@ -188,6 +196,7 @@ public class DataUtils {
} else {
values.put(GhContentProvider.KEY_IS_CERTIFICATED, false);
values.put(GhContentProvider.KEY_IS_ADULT, false);
values.put(GhContentProvider.KEY_IS_CERTIFICATING, false);
RealNameHelper.updateCertificationStatus(0);
}

View File

@ -1,16 +1,20 @@
package com.gh.common.util;
import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import com.gh.common.constant.Config;
import com.gh.common.filter.RegionSetting;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.gamecenter.feature.view.DownloadButton;
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;
@ -18,7 +22,6 @@ import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
@ -30,163 +33,125 @@ import java.util.Objects;
* Created by khy on 27/06/17.
* 详情下载工具类
*/
public class DetailDownloadUtils {
public static void detailInitDownload(DetailViewHolder viewHolder, boolean isCheck) {
String downloadAddWord = viewHolder.gameEntity.getDownloadAddWord();
public static void updateViewHolder(DetailViewHolder viewHolder) {
updateViewHolder(viewHolder, false);
}
/**
* 更新底部下载区域
* @param viewHolder 下载区域的包裹
* @param ignoreDownloadEntity 忽略下载实体(往往用于下载异常时)
*/
public static void updateViewHolder(DetailViewHolder viewHolder, boolean ignoreDownloadEntity) {
GameEntity gameEntity = viewHolder.getGameEntity();
String downloadAddWord = gameEntity.getDownloadAddWord();
// 隐藏下载按钮上的畅玩文案
if (viewHolder.getOverlayTv() != null) {
viewHolder.getOverlayTv().setVisibility(View.GONE);
}
if (viewHolder.mMultiVersionDownloadTv != null) {
viewHolder.mMultiVersionDownloadTv.setVisibility(View.GONE);
// 多版本下载箭头
if (viewHolder.getMultiVersionDownloadTv() != null) {
viewHolder.getMultiVersionDownloadTv().setVisibility(View.GONE);
}
if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) && !"光环助手".equals(viewHolder.gameEntity.getName())) {
viewHolder.downloadBottom.setVisibility(View.VISIBLE);
// 根据预置的配置更新 ViewHolder 的状态 (譬如青少年模式、下载内容为空等)
if (updateViewHolderWithPredefinedConfig(viewHolder, gameEntity)) {
return;
}
// 游戏只包含单 APK 的情况
if (gameEntity.getApk().size() == 1) {
boolean showVGame = false; // 真下载按钮(DownloadButton)是否需要显示为畅玩,包括单按钮显示和双按钮显示
boolean showDualDownloadButton = false; // 是否显示双下载按钮
int gameDownloadMode = gameEntity.getGameDownloadButtonMode(); // 获取游戏的下载按钮模式
DownloadEntity downloadEntity = null;
if (!ignoreDownloadEntity) {
downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
}
// 不支持双下载按钮的情况时(新闻详情、礼包详情页),优选一个下载方式显示
if (!viewHolder.isSupportDualButton()) {
boolean performAsVGame = GameUtils.shouldPerformAsVGame(gameEntity);
if (performAsVGame) {
gameDownloadMode = GameEntity.GAME_DOWNLOAD_BUTTON_MODE_VGAME;
} else {
gameDownloadMode = GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DOWNLOAD;
}
}
if (gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DOWNLOAD) {
showVGame = false;
if (viewHolder.getLocalDownloadContainer() != null) {
viewHolder.getLocalDownloadContainer().setVisibility(View.GONE);
}
} else if (gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_VGAME) {
showVGame = true;
if (viewHolder.getLocalDownloadContainer() != null) {
viewHolder.getLocalDownloadContainer().setVisibility(View.GONE);
}
} else if (gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL) {
showVGame = true;
showDualDownloadButton = true;
if (viewHolder.getLocalDownloadContainer() != null) {
viewHolder.getLocalDownloadContainer().setVisibility(View.VISIBLE);
}
// 畅玩未安装,且当前下载的默认类型为"普通下载",且用户未安装时,禁用双按钮,禁用畅玩
if (!VHelper.isInstalled(gameEntity.getUniquePackageName())
&& !PackagesManager.isInstalled(gameEntity.getUniquePackageName())
&& downloadEntity != null
&& ExtensionsKt.isLocalDownloadInDualDownloadMode(downloadEntity)
) {
viewHolder.getDownloadPb().setVisibility(View.GONE);
if (viewHolder.getOverlayTv() != null) {
viewHolder.getOverlayTv().setVisibility(View.GONE);
}
} else {
viewHolder.getDownloadPb().setVisibility(View.VISIBLE);
}
}
// 更新默认的下载按钮
updateWithSingleApk(
gameEntity,
viewHolder,
viewHolder.getDownloadPb(),
downloadAddWord,
showVGame,
showDualDownloadButton,
downloadEntity
);
if (showDualDownloadButton) {
// 双下载按钮时更新占位的下载按钮
updateWithSingleApk(
gameEntity,
viewHolder,
viewHolder.getLocalDownloadButton(),
downloadAddWord,
false,
true,
downloadEntity
);
}
} else {
viewHolder.downloadBottom.setVisibility(View.GONE);
return;
}
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
viewHolder.mDownloadPb.setText("查看");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.TEENAGER_MODE);
return;
}
if (viewHolder.gameEntity.isSpecialDownload()) {
viewHolder.mDownloadPb.setText("查看下载资源");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.SPECIAL_DOWNLOAD);
return;
}
if (viewHolder.gameEntity.isReservable()) {
if (!ReservationRepository.thisGameHasBeenReserved(viewHolder.gameEntity.getId())) {
if (TextUtils.isEmpty(downloadAddWord)) {
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》", viewHolder.gameEntity.getName()));
} else {
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》%s", viewHolder.gameEntity.getName(), downloadAddWord));
}
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.RESERVABLE);
} else {
viewHolder.mDownloadPb.setText("已预约《" + viewHolder.gameEntity.getName() + "");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.RESERVED);
}
return;
}
final RegionSetting.GameH5Download gameH5Download = RegionSettingHelper.getGameH5DownloadByGameId(viewHolder.gameEntity.getId());
if (gameH5Download != null) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "查看详情" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
return;
}
if (viewHolder.gameEntity.isVGame() && !viewHolder.gameEntity.getApk().isEmpty()) {
String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity, PluginLocation.only_game);
if (viewHolder.context.getString(R.string.launch).equals(status)) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else if (viewHolder.context.getString(R.string.install).equals(status)) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
}
String downloadText;
if (viewHolder.context.getString(R.string.launch).equals(status) || viewHolder.context.getString(R.string.install).equals(status) || viewHolder.context.getString(R.string.download).equals(status)) {
downloadText = "";
if (viewHolder.getOverlayTv() != null) {
viewHolder.getOverlayTv().setVisibility(View.VISIBLE);
}
} else if (viewHolder.context.getString(R.string.attempt).equals(status)) {
downloadText = status + getDownloadSizeText(viewHolder);
} else {
downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder);
}
viewHolder.mDownloadPb.setText(downloadText);
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity);
// 在下载管理找不到下载实体,到畅玩数据库里找
if (downloadEntity == null && viewHolder.gameEntity.isVGame()) {
String packageName = viewHolder.gameEntity.getUniquePackageName();
if (!TextUtils.isEmpty(packageName)) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName);
}
}
if (downloadEntity != null) {
viewHolder.downloadEntity = downloadEntity;
detailInvalidate(viewHolder);
}
return;
}
if (viewHolder.gameEntity.getApk().isEmpty() || viewHolder.gameEntity.getDownloadOffStatus() != null) {
LinkEntity h5LinkEntity = viewHolder.gameEntity.getH5Link();
if (h5LinkEntity != null) {
if ("play".equals(h5LinkEntity.getType())) {
String defaultString = String.format("开始玩" + "《%s》", viewHolder.gameEntity.getName());
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(h5LinkEntity.getText()) ? defaultString : h5LinkEntity.getText());
} else {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(h5LinkEntity.getText()) ? "查看" : h5LinkEntity.getText());
}
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.H5_GAME);
} else {
if ("dialog".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "查看详情" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.NONE_WITH_HINT);
} else if ("updating".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "更新中" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.UPDATING);
} else {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "暂无下载" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.NONE);
}
}
} else if (viewHolder.gameEntity.getApk().size() == 1) {
String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity, PluginLocation.only_game);
if (viewHolder.context.getString(R.string.pluggable).equals(status)) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.PLUGIN);
} else if (viewHolder.context.getString(R.string.launch).equals(status)) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else if (viewHolder.context.getString(R.string.install).equals(status)) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
}
String downloadText;
if (viewHolder.isNewsDetail) {
downloadText = status;
} else if (viewHolder.context.getString(R.string.pluggable).equals(status)) {
downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "" + downloadAddWord) + getDownloadSizeText(viewHolder);
} else if (viewHolder.context.getString(R.string.launch).equals(status)) {
downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord);
} else if (viewHolder.context.getString(R.string.attempt).equals(status)) {
downloadText = status + getDownloadSizeText(viewHolder);
} else if (viewHolder.context.getString(R.string.install).equals(status)) {
downloadText = viewHolder.context.getString(R.string.install);
} else {
downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder);
}
viewHolder.mDownloadPb.setText(downloadText);
} else {
viewHolder.mMultiVersionDownloadTv.setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord));
viewHolder.mMultiVersionDownloadTv.setVisibility(View.VISIBLE);
viewHolder.mDownloadPb.setText("");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity);
// 游戏包含多 APK 的情况
viewHolder.getMultiVersionDownloadTv().setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord));
viewHolder.getMultiVersionDownloadTv().setVisibility(View.VISIBLE);
viewHolder.getDownloadPb().setText("");
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
if (downloadEntity != null) {
switch (downloadEntity.getStatus()) {
case downloading:
viewHolder.mDownloadTips.setVisibility(View.VISIBLE);
ExtensionsKt.setDownloadTipsAnimation(viewHolder.mDownloadTips, true);
viewHolder.getDownloadTips().setVisibility(View.VISIBLE);
ExtensionsKt.setDownloadTipsAnimation(viewHolder.getDownloadTips(), true);
break;
case done:
case pause:
@ -195,73 +160,347 @@ public class DetailDownloadUtils {
case subscribe:
case neterror:
case overflow:
viewHolder.mDownloadTips.setVisibility(View.VISIBLE);
ExtensionsKt.setDownloadTipsAnimation(viewHolder.mDownloadTips, false);
viewHolder.getDownloadTips().setVisibility(View.VISIBLE);
ExtensionsKt.setDownloadTipsAnimation(viewHolder.getDownloadTips(), false);
break;
default:
viewHolder.mDownloadTips.setVisibility(View.GONE);
viewHolder.getDownloadTips().setVisibility(View.GONE);
break;
}
} else {
viewHolder.mDownloadTips.setVisibility(View.GONE);
viewHolder.getDownloadTips().setVisibility(View.GONE);
}
}
}
if (isCheck && viewHolder.gameEntity.getApk().size() == 1) {
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity);
/**
* 更新只有单个 APK 文件时候的下载按钮状态
*
* @param downloadButton 下载按钮,可能是真的下载按钮也可能只是占位下载按钮
* @param downloadAddWord 下载按钮的补充文案
* @param showAsVGame 是否显示为畅玩游戏
* @param showDualDownloadButton 是否正显示为双下载按钮
*/
// 在下载管理找不到下载实体,到畅玩数据库里找
if (downloadEntity == null && viewHolder.gameEntity.isVGame()) {
String packageName = viewHolder.gameEntity.getUniquePackageName();
if (!TextUtils.isEmpty(packageName)) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName);
private static void updateWithSingleApk(GameEntity gameEntity,
DetailViewHolder viewHolder,
DownloadButton downloadButton,
String downloadAddWord,
boolean showAsVGame,
boolean showDualDownloadButton,
DownloadEntity downloadEntity) {
Context context = viewHolder.getContext();
TextView overlayTv = viewHolder.getOverlayTv();
String status = GameUtils.getDownloadBtnText(context, gameEntity, false, showAsVGame, PluginLocation.only_game);
if (showAsVGame) {
// 显示为畅玩游戏
if (context.getString(R.string.launch).equals(status)) {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
}
String btnText;
if (showDualDownloadButton
&& (context.getString(R.string.launch).equals(status) || context.getString(R.string.install).equals(status) || context.getString(R.string.smooth).equals(status) || context.getString(R.string.update).equals(status))) {
if (context.getString(R.string.smooth).equals(status)) {
btnText = context.getString(R.string.download_v);
} else if (context.getString(R.string.update).equals(status)) {
btnText = context.getString(R.string.update_v);
} else {
btnText = context.getString(R.string.launch_v);
}
if (overlayTv != null && downloadButton.getVisibility() != View.GONE) {
overlayTv.setVisibility(View.VISIBLE);
overlayTv.setText(btnText);
downloadButton.setText("");
}
} else {
btnText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder);
if (overlayTv != null && downloadButton.getVisibility() != View.GONE) {
if (context.getString(R.string.launch).equals(status)
|| context.getString(R.string.install).equals(status)) {
overlayTv.setVisibility(View.VISIBLE);
overlayTv.setText("启动(畅玩)");
} else {
overlayTv.setVisibility(View.GONE);
downloadButton.setText(btnText);
}
} else {
if (overlayTv != null) {
overlayTv.setVisibility(View.GONE);
}
downloadButton.setText(btnText);
}
}
if (downloadEntity != null) {
viewHolder.downloadEntity = downloadEntity;
detailInvalidate(viewHolder);
// 在下载管理找不到下载实体,到畅玩数据库里找
if (downloadEntity == null) {
String packageName = gameEntity.getUniquePackageName();
if (!TextUtils.isEmpty(packageName)) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.getId(), packageName);
}
}
} else {
// 非畅玩,显示为普通游戏
if (context.getString(R.string.pluggable).equals(status)) {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.PLUGIN);
} else if (context.getString(R.string.launch).equals(status)) {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else if (context.getString(R.string.install).equals(status)) {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
} else {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
}
if (showDualDownloadButton && viewHolder.getLocalDownloadSizeTv() != null) {
viewHolder.getLocalDownloadSizeTv().setVisibility(View.GONE);
String size = viewHolder.getGameEntity().getApk().get(0).getSize();
if (size != null) {
String sizeWithoutDigit = size.replaceAll("(?<=\\d)\\.[0-9]+(?!\\d)", "");
viewHolder.getLocalDownloadSizeTv().setText(sizeWithoutDigit);
}
// 若双下载按钮时,下载的游戏是以畅玩游戏下载的,把 downloadEntity 置空,避免把按钮更新到错误的状态
if (downloadEntity != null && ExtensionsKt.isVGameDownloadInDualDownloadMode(downloadEntity)) {
downloadEntity = null;
}
}
String btnText;
String extraBtnText;
if (viewHolder.isNewsDetail()) {
btnText = status;
extraBtnText = status;
} else if (context.getString(R.string.pluggable).equals(status)) {
btnText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "" + downloadAddWord) + getDownloadSizeText(viewHolder);
extraBtnText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "" + downloadAddWord);
} else if (context.getString(R.string.launch).equals(status)) {
btnText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord);
extraBtnText = context.getString(R.string.launch_local);
} else if (context.getString(R.string.attempt).equals(status)) {
btnText = status + getDownloadSizeText(viewHolder);
extraBtnText = status;
if (showDualDownloadButton
&& viewHolder.getLocalDownloadContainer() != null
&& viewHolder.getLocalDownloadContainer().getVisibility() == View.VISIBLE) {
viewHolder.getLocalDownloadSizeTv().setVisibility(View.VISIBLE);
}
} else if (context.getString(R.string.install).equals(status)) {
btnText = context.getString(R.string.install);
extraBtnText = context.getString(R.string.install_local);
} else if (context.getString(R.string.update).equals(status)) {
btnText = context.getString(R.string.update);
extraBtnText = context.getString(R.string.update_local);
if (showDualDownloadButton
&& viewHolder.getLocalDownloadContainer() != null
&& viewHolder.getLocalDownloadContainer().getVisibility() == View.VISIBLE) {
viewHolder.getLocalDownloadSizeTv().setVisibility(View.VISIBLE);
}
} else {
btnText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder);
extraBtnText = context.getString(R.string.download_local);
if (showDualDownloadButton
&& viewHolder.getLocalDownloadContainer() != null
&& viewHolder.getLocalDownloadContainer().getVisibility() == View.VISIBLE) {
viewHolder.getLocalDownloadSizeTv().setVisibility(View.VISIBLE);
}
}
downloadButton.setText(btnText);
if (viewHolder.getLocalDownloadTitleTv() != null) {
viewHolder.getLocalDownloadTitleTv().setText(extraBtnText);
}
}
if (overlayTv != null && overlayTv.getVisibility() == View.VISIBLE) {
downloadButton.setTag(R.string.download, overlayTv.getText());
} else {
downloadButton.setTag(R.string.download, downloadButton.getText());
}
if (downloadEntity == null) return;
if (handleDownloadButtonAsXapk(downloadEntity, downloadButton)) {
return;
}
// 非完成状态显示下载按钮
if (downloadEntity.getStatus() != DownloadStatus.done) {
viewHolder.getDownloadPb().setVisibility(View.VISIBLE);
}
// 存在未完成的下载任务或不显示双按钮时,隐藏本地下载按钮
if (viewHolder.getLocalDownloadContainer() != null) {
if (downloadEntity.getStatus() != DownloadStatus.done) {
viewHolder.getLocalDownloadContainer().setVisibility(View.GONE);
} else if (showDualDownloadButton) {
viewHolder.getLocalDownloadContainer().setVisibility(View.VISIBLE);
} else {
viewHolder.getLocalDownloadContainer().setVisibility(View.GONE);
}
}
downloadButton.setProgress((int) (downloadEntity.getPercent() * 10));
if (overlayTv != null
&& downloadEntity.getStatus() != DownloadStatus.done) {
overlayTv.setVisibility(View.GONE);
}
if (showAsVGame) {
updateVStyleDownloadButton(viewHolder, downloadButton, downloadEntity, status);
} else {
updateDefaultStyleDownloadButton(context, viewHolder, downloadButton, gameEntity, downloadEntity);
}
}
/**
* 根据预置的配置更新 ViewHolder 的状态
*
* @return 是否已经是最终状态,返回 true 表示已应用当前配置,返回 false 表示不应用当前配置
*/
private static boolean updateViewHolderWithPredefinedConfig(DetailViewHolder viewHolder, GameEntity gameEntity) {
String downloadAddWord = gameEntity.getDownloadAddWord();
// 不满足条件的部分游戏隐藏下载按钮
if (Config.isShowDownload(gameEntity.getId())
&& !"光环助手".equals(gameEntity.getName())) {
viewHolder.getDownloadBottom().setVisibility(View.VISIBLE);
} else {
viewHolder.getDownloadBottom().setVisibility(View.GONE);
return true;
}
// 青少年模式显示为查看
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
viewHolder.getDownloadPb().setText("查看");
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.TEENAGER_MODE);
return true;
}
// 预约
if (gameEntity.isReservable()) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
if (TextUtils.isEmpty(downloadAddWord)) {
viewHolder.getDownloadPb().setText(String.format("预约" + "《%s》", gameEntity.getName()));
} else {
viewHolder.getDownloadPb().setText(String.format("预约" + "《%s》%s", gameEntity.getName(), downloadAddWord));
}
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.RESERVABLE);
} else {
viewHolder.getDownloadPb().setText("已预约《" + gameEntity.getName() + "");
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.RESERVED);
}
return true;
}
// 国际服 H5 弹窗
final RegionSetting.GameH5Download gameH5Download = RegionSettingHelper.getGameH5DownloadByGameId(gameEntity.getId());
if (gameH5Download != null) {
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(gameEntity.getDownloadOffText()) ? "查看详情" : gameEntity.getDownloadOffText());
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
return true;
}
// 特殊下载
if (gameEntity.isSpecialDownload()) {
viewHolder.getDownloadPb().setText("查看下载资源");
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.SPECIAL_DOWNLOAD);
return true;
}
// 处理不存在 APK 文件或游戏状态为关闭时的情况
if (gameEntity.getApk().isEmpty() || gameEntity.getDownloadOffStatus() != null) {
LinkEntity h5LinkEntity = gameEntity.getH5Link();
if (h5LinkEntity != null) {
if ("play".equals(h5LinkEntity.getType())) {
String defaultString = String.format("开始玩" + "《%s》", gameEntity.getName());
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(h5LinkEntity.getText()) ? defaultString : h5LinkEntity.getText());
} else {
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(h5LinkEntity.getText()) ? "查看" : h5LinkEntity.getText());
}
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.H5_GAME);
} else {
if ("dialog".equals(gameEntity.getDownloadOffStatus())) {
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(gameEntity.getDownloadOffText()) ? "查看详情" : gameEntity.getDownloadOffText());
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NONE_WITH_HINT);
} else if ("updating".equals(gameEntity.getDownloadOffStatus())) {
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(gameEntity.getDownloadOffText()) ? "更新中" : gameEntity.getDownloadOffText());
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.UPDATING);
} else {
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(gameEntity.getDownloadOffText()) ? "暂无下载" : gameEntity.getDownloadOffText());
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NONE);
}
}
return true;
}
return false;
}
private static String getDownloadSizeText(DetailViewHolder viewHolder) {
return String.format("%s", viewHolder.gameEntity.getApk().get(0).getSize());
return String.format("%s", viewHolder.getGameEntity().getApk().get(0).getSize());
}
public static void detailInvalidate(DetailViewHolder viewHolder) {
DownloadEntity downloadEntity = viewHolder.downloadEntity;
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
private static void updateVStyleDownloadButton(DetailViewHolder viewHolder,
DownloadButton downloadButton,
DownloadEntity downloadEntity,
String status) {
switch (downloadEntity.getStatus()) {
case redirected:
case downloading:
downloadButton.setText("游戏加载中 " + downloadEntity.getPercent() + "%");
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
break;
case waiting:
downloadButton.setText(R.string.waiting);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.WAITING);
break;
case overflow:
case timeout:
case neterror:
case subscribe:
case diskisfull:
case diskioerror:
case pause:
downloadButton.setText("继续加载 " + downloadEntity.getPercent() + "%");
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
break;
case done:
if (!status.contains("更新")) {
if (VHelper.isInstalled(downloadEntity.getPackageName())) {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else {
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
}
if (XapkUnzipStatus.SUCCESS.name().equals(xapkStatus) && XapkInstaller.INSTANCE.isInstalling(downloadEntity.getPath())) {
viewHolder.mDownloadPb.setText("游戏安装中");
viewHolder.mDownloadPb.setProgress(100);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
return;
}
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
viewHolder.mDownloadPb.setText("游戏解压中 " + percent + "%");
viewHolder.mDownloadPb.setProgress((int) (Float.valueOf(percent) * 10));
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.XAPK_UNZIPPING);
return;
} else if (XapkUnzipStatus.FAILURE.name().equals(xapkStatus)) {
viewHolder.mDownloadPb.setText(R.string.install);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.XAPK_FAILURE);
return;
}
viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
if (viewHolder.getOverlayTv() != null) {
viewHolder.getOverlayTv().setVisibility(View.GONE);
}
if (viewHolder.gameEntity.isVGame()) {
updateVStyleButton(viewHolder);
return;
downloadButton.setText("");
}
break;
case cancel:
case hijack:
case notfound:
case uncertificated:
case unqualified:
case unavailable:
case banned:
updateViewHolder(viewHolder, true);
break;
default:
break;
}
}
private static void updateDefaultStyleDownloadButton(
Context context,
DetailViewHolder viewHolder,
DownloadButton downloadButton,
GameEntity gameEntity,
DownloadEntity downloadEntity) {
switch (downloadEntity.getStatus()) {
case timeout:
case neterror:
@ -274,55 +513,37 @@ public class DetailDownloadUtils {
case overflow:
String downloadingText = "游戏加载中 " + downloadEntity.getPercent() + "%";
String resumeText = "继续加载 " + downloadEntity.getPercent() + "%";
viewHolder.mDownloadPb.setText((downloadEntity.getStatus() == DownloadStatus.downloading || downloadEntity.getStatus() == DownloadStatus.redirected) ? downloadingText : resumeText);
downloadButton.setText((downloadEntity.getStatus() == DownloadStatus.downloading || downloadEntity.getStatus() == DownloadStatus.redirected) ? downloadingText : resumeText);
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
}
break;
case waiting:
viewHolder.mDownloadPb.setText(R.string.waiting);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.WAITING);
downloadButton.setText(R.string.waiting);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.WAITING);
break;
case done:
if (SimulatorGameManager.isSimulatorGame(viewHolder.gameEntity)) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(viewHolder.context, viewHolder.gameEntity.getSimulator().getApk().getPackageName());
boolean isInstalledNewSimulator = SimulatorGameManager.isNewSimulatorInstalled(viewHolder.context);
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
boolean isInstalledNewSimulator = SimulatorGameManager.isNewSimulatorInstalled(context);
if (isInstalled || isInstalledNewSimulator) {
viewHolder.mDownloadPb.setText(R.string.launch);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
downloadButton.setText(R.string.launch);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else {
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
downloadButton.setText(R.string.browser_install_install);
} else {
viewHolder.mDownloadPb.setText(R.string.install);
}
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
}
} else if (viewHolder.gameEntity.isVGame()) {
if (!viewHolder.mDownloadPb.getText().toString().contains("更新")) {
if (VHelper.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
}
viewHolder.mDownloadPb.setText("");
if (viewHolder.getOverlayTv() != null) {
viewHolder.getOverlayTv().setVisibility(View.VISIBLE);
downloadButton.setText(R.string.install);
}
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
}
} else {
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
downloadButton.setText(R.string.browser_install_install);
} else {
viewHolder.mDownloadPb.setText(R.string.install);
}
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_PLUGIN);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
downloadButton.setText(R.string.install);
}
}
@ -334,50 +555,35 @@ public class DetailDownloadUtils {
case unqualified:
case unavailable:
case banned:
detailInitDownload(viewHolder, false);
updateViewHolder(viewHolder, true);
break;
default:
break;
}
}
private static void updateVStyleButton(DetailViewHolder viewHolder) {
switch (viewHolder.downloadEntity.getStatus()) {
case redirected:
case downloading:
viewHolder.mDownloadPb.setText("游戏加载中 " + viewHolder.downloadEntity.getPercent() + "%");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
break;
case waiting:
viewHolder.mDownloadPb.setText(R.string.waiting);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
break;
case overflow:
case timeout:
case neterror:
case subscribe:
case diskisfull:
case diskioerror:
case pause:
viewHolder.mDownloadPb.setText("继续加载 " + viewHolder.downloadEntity.getPercent() + "%");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
break;
case done:
if (!viewHolder.mDownloadPb.getText().toString().contains("更新")) {
if (VHelper.isInstalled(viewHolder.downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
}
private static boolean handleDownloadButtonAsXapk(DownloadEntity downloadEntity, DownloadButton downloadButton) {
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
viewHolder.mDownloadPb.setText("");
if (viewHolder.getOverlayTv() != null) {
viewHolder.getOverlayTv().setVisibility(View.VISIBLE);
}
}
break;
default:
break;
if (XapkUnzipStatus.SUCCESS.name().equals(xapkStatus) && XapkInstaller.INSTANCE.isInstalling(downloadEntity.getPath())) {
downloadButton.setText("游戏安装中");
downloadButton.setProgress(100);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
return true;
}
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
downloadButton.setText("游戏解压中 " + percent + "%");
downloadButton.setProgress((int) (Float.valueOf(percent) * 10));
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.XAPK_UNZIPPING);
return true;
} else if (XapkUnzipStatus.FAILURE.name().equals(xapkStatus)) {
downloadButton.setText(R.string.install);
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.XAPK_FAILURE);
return true;
}
return false;
}
}

View File

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

View File

@ -37,6 +37,7 @@ import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.discovery.DiscoveryActivity
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
@ -58,9 +59,12 @@ import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActi
import com.gh.gamecenter.game.upload.GameSubmissionActivity
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionListDetailActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarManagementActivity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersSubscribedGameListActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
@ -154,7 +158,8 @@ object DirectUtils {
"bbs_video",
"explore_column",
"game_explore",
"column_test_v2"
"column_test_v2",
"game_list_collection"
)
fun directToLinkPage(
@ -189,6 +194,8 @@ object DirectUtils {
}
}
"game_server_calendar" -> directToGameServerCalendar(context, linkEntity.link)
"column", "游戏专题" -> directToSubject(
context, linkEntity.link
?: "", linkEntity.text, BaseActivity.mergeEntranceAndPath(entrance, path), exposureEvent
@ -314,6 +321,8 @@ object DirectUtils {
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa_list" -> directToHelpAndFeedback(context)
"qa_collection", "Q&A合集" -> directToQaCollection(
context, linkEntity.text
?: "", linkEntity.link
@ -444,6 +453,14 @@ object DirectUtils {
"qq_mini_game_column" -> directToQGameHome(context)
"game_list_collection" -> directToGameCollectionListDetail(
context,
linkEntity.link ?: "",
linkEntity.text ?: "",
linkEntity.explain,
entrance
)
"" -> {
// do nothing
}
@ -532,12 +549,13 @@ object DirectUtils {
* 跳转至游戏日历表
*/
@JvmStatic
fun directToGameServerCalendar(context: Context, gameId: String?) {
fun directToGameServerCalendar(context: Context, gameId: String?, kaifuTime: Long = 0) {
val bundle = Bundle()
bundle.putString(KEY_TO, ServersCalendarActivity::class.java.name)
bundle.putParcelable(GameEntity::class.java.simpleName, GameEntity().apply {
id = gameId ?: ""
})
bundle.putLong(KEY_KAIFU_TIME, kaifuTime)
bundle.putParcelable(GameDetailServer::class.java.simpleName, GameDetailServer())
bundle.putParcelable(MeEntity::class.java.simpleName, MeEntity())
jumpActivity(context, bundle)
@ -830,27 +848,6 @@ object DirectUtils {
jumpActivity(context, bundle)
}
/**
* 跳转到下载管理器并开始下载 [gameId] 和 [packageName] 用于唯一确定一个下载文件
*/
@JvmStatic
fun directToDownloadManagerAndStartDownload(
context: Context,
gameId: String? = "",
packageName: String? = "",
entrance: String? = null
) {
DownloadHelper.createABrandNewDownloadTaskQuietly(gameId, packageName) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, DownloadManagerActivity.TAG)
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_PACKAGENAME, packageName)
bundle.putBoolean(KEY_AUTO_DOWNLOAD, true)
jumpActivity(context, bundle)
}
}
@JvmStatic
fun directToDownloadManagerAndStartUpdate(
context: Context,
@ -864,7 +861,7 @@ object DirectUtils {
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_PACKAGENAME, packageName)
bundle.putInt(BaseFragment_TabLayout.PAGE_INDEX, INDEX_UPDATE)
jumpActivity(context, bundle)
jumpActivityCompat(context, bundle)
}
@JvmStatic
@ -925,9 +922,9 @@ object DirectUtils {
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(browserIntent)
} catch (e: ActivityNotFoundException) {
} catch (e: Exception) {
e.printStackTrace()
Utils.toast(context, "跳转地址无效")
url.copyTextAndToast(context.getString(R.string.direct_to_external_browser_failed_toast))
}
}
@ -1125,7 +1122,8 @@ object DirectUtils {
act: String = "",
paginationType: String = "",
fieldId: String = "",
sectionName: String = ""
sectionName: String = "",
isHomeVideo: Boolean = false
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
@ -1143,6 +1141,7 @@ object DirectUtils {
bundle.putString(KEY_PAGINATION_TYPE, paginationType)
bundle.putString(KEY_FIELD_ID, fieldId)
bundle.putString(KEY_SECTION_NAME, sectionName)
bundle.putBoolean(KEY_IS_HOME_VIDEO, isHomeVideo)
jumpActivity(context, bundle)
} else {
DialogHelper.showVideoUnsupportedDialog(context)
@ -1942,7 +1941,8 @@ object DirectUtils {
fromRatingKey: Boolean = false,
diagnosis: String = "",
forceLogin: Boolean = true,
requestCode: Int? = null
requestCode: Int? = null,
isSmoothGame: Boolean = false
) {
val intent = HelpAndFeedbackBridge.getIntent(
context,
@ -1955,7 +1955,8 @@ object DirectUtils {
qaContentId,
fromRatingKey,
diagnosis,
forceLogin
forceLogin,
isSmoothGame
)
if (requestCode != null) {
(context as Activity).startActivityForResult(intent, requestCode)
@ -1969,8 +1970,14 @@ object DirectUtils {
* @param bbsId, 为空时搜索全范围的内容,不为空时搜索该 bbsId 对应的内容
*/
@JvmStatic
fun directToForumOrUserSearch(context: Context, bbsId: String, entrance: String) {
context.startActivity(ForumOrUserSearchActivity.getIntent(context, bbsId, entrance))
fun directToForumOrUserSearch(
context: Context,
bbsId: String,
entrance: String,
sourceEntrance: String,
forumName: String
) {
context.startActivity(ForumOrUserSearchActivity.getIntent(context, bbsId, entrance, sourceEntrance, forumName))
}
@JvmStatic
@ -2101,4 +2108,42 @@ object DirectUtils {
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
.navigation()
}
// 跳转游戏单合集详情
@JvmStatic
fun directToGameCollectionListDetail(
context: Context,
collectionId: String,
collectionName: String,
explain: String,
entrance: String = ""
) {
context.startActivity(
GameCollectionListDetailActivity.getIntent(
context,
GameCollectionListEntity(id = collectionId, name = collectionName, explain = explain),
entrance
)
)
}
/**
* 跳转到游戏订阅页面
* @param context 上下文
*/
@JvmStatic
fun directToServersSubscribedGameList(context: Context) {
context.startActivity(ServersSubscribedGameListActivity.getIntent(context))
}
/**
* 跳转到开服订阅页面
* @param context 上下文
*/
@JvmStatic
fun directToServersCalendarManagement(context: Context, entrance: String) {
CheckLoginUtils.checkLogin(context, entrance) {
context.startActivity(ServersCalendarManagementActivity.getIntent(context))
}
}
}

View File

@ -42,6 +42,7 @@ object DownloadDialogHelper {
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
callback.onCallback()
},
cancelClickCallback = {
SensorsBridge.trackGameDownloadDialogClick(
@ -50,7 +51,6 @@ object DownloadDialogHelper {
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
callback.onCallback()
},
touchOutsideCallback = {
SensorsBridge.trackGameDownloadDialogClick(

View File

@ -1,63 +0,0 @@
package com.gh.common.util
import com.gh.common.filter.RegionSettingHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
/**
* 不想写这个类的,但是与其在一个糟糕的类里插入同样的代码,我想独立写一个类相较而已还没那么糟糕
*/
object DownloadHelper {
/**
* 根据 game_id 和 packageName 悄悄地开启一个下载任务,如果可以的话
* @param block 成功添加下载任务后执行的代码块
*/
fun createABrandNewDownloadTaskQuietly(gameId: String? = "", packageName: String? = "", block: () -> Unit) {
if (RegionSettingHelper.shouldThisGameBeFiltered(gameId)) {
return
}
RetrofitManager.getInstance()
.api
.getGameDigest(gameId)
.map(ApkActiveUtils.filterMapper)
.subscribeOn(Schedulers.io())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(response: GameEntity?) {
response?.let {
if (response.getApk().size > 1) {
for (apk in response.getApk()) {
if (packageName == apk.packageName) {
DownloadManager.createDownload(
HaloApp.getInstance().application,
apk, response, "", EntranceConsts.ENTRANCE_RECOMMEND, "", false, null
)
block.invoke()
}
}
} else if (response.getApk().size == 1) {
DownloadManager.createDownload(
HaloApp.getInstance().application,
response, "", EntranceConsts.ENTRANCE_RECOMMEND, "", false, null
)
block.invoke()
}
}
}
override fun onFailure(e: HttpException?) {
e?.printStackTrace()
block.invoke()
}
})
}
}

View File

@ -122,7 +122,7 @@ object DownloadItemUtils {
fun updateItemWithReserveStatus(holder: GameViewHolder, gameEntity: GameEntity) {
if ("download" == gameEntity.reserveStatus) {
// 已上线
updateItem(holder.gameDownloadBtn.context, gameEntity, holder, false)
updateItem(holder.gameDownloadBtn.context, gameEntity, holder)
} else if ("appointment" == gameEntity.reserveStatus) {
// 已预约
holder.gameDownloadBtn.text = "已预约"
@ -133,25 +133,35 @@ object DownloadItemUtils {
}
fun updateItem(
context: Context, gameEntity: GameEntity, holder: GameViewHolder,
isShowPlatform: Boolean, hideDownloadBtnIfNoAvailableContent: Boolean
context: Context,
gameEntity: GameEntity,
holder: GameViewHolder,
hideDownloadBtnIfNoAvailableContent: Boolean
) {
updateItem(
context,
gameEntity,
holder,
isShowPlatform,
PluginLocation.only_game,
hideDownloadBtnIfNoAvailableContent,
null
context = context,
gameEntity = gameEntity,
holder = holder,
pluginLocation = PluginLocation.only_game,
hideDownloadBtnIfNoAvailableContent = hideDownloadBtnIfNoAvailableContent,
briefStyle = null
)
}
fun updateItem(
context: Context, gameEntity: GameEntity, holder: GameViewHolder,
isShowPlatform: Boolean, briefStyle: String?
context: Context,
gameEntity: GameEntity,
holder: GameViewHolder,
briefStyle: String?
) {
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, false, briefStyle)
updateItem(
context = context,
gameEntity = gameEntity,
holder = holder,
pluginLocation = PluginLocation.only_game,
hideDownloadBtnIfNoAvailableContent = false,
briefStyle = briefStyle
)
}
@JvmStatic
@ -160,7 +170,6 @@ object DownloadItemUtils {
context: Context,
gameEntity: GameEntity,
holder: GameViewHolder,
isShowPlatform: Boolean,
pluginLocation: PluginLocation? = PluginLocation.only_game,
hideDownloadBtnIfNoAvailableContent: Boolean = false,
briefStyle: String? = null,
@ -286,12 +295,54 @@ object DownloadItemUtils {
}
}
} else if (gameEntity.getApk().size == 1) {
// 优先从下载管理获取 downloadEntity
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
// 来自于下载管理的实体快照
val entityFromDownloadManager = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
// 是否正在下载中
val isDownloading = entityFromDownloadManager != null && entityFromDownloadManager.status != DownloadStatus.done
// 是否已安装至本地
val isInstalledLocally = PackagesManager.isInstalled(gameEntity.getUniquePackageName())
// 来自于畅玩安装列表的实体快照,若存在,代表游戏已下载并成功安装
val entityFromInstalledVGame = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
// 是否已安装至畅玩
val isInstalledToVSpace = entityFromInstalledVGame != null
// 是否处于待安装状态 (仅本地安装有这个状态)
val isPendingToInstall = if (entityFromDownloadManager?.status != DownloadStatus.done) {
false
} else {
entityFromDownloadManager.isLocalDownloadInDualDownloadMode()
&& (!isInstalledLocally || entityFromDownloadManager.isUpdate)
}
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在代表游戏已下载并成功安装
if (downloadEntity == null && gameEntity.isVGame()) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
// 列表按钮显示的优先级
// 1. 都未安装,且不存在下载任务,按后台配置显示的状态优先
// 2. 存在未完成的下载任务时,下载任务优先
// 3. 存在待安装任务时,待安装任务优先
// 4. 存在一个已安装,已安装的显示优先
// 5. 都已安装,按后台配置显示的状态优先
val isVGamePreferred = if (!isInstalledLocally && !isInstalledToVSpace && entityFromDownloadManager == null) {
gameEntity.isVGamePreferred()
} else if (isDownloading || isPendingToInstall) {
entityFromDownloadManager?.isVGameDownloadInDualDownloadMode() == true
} else if (isInstalledLocally && isInstalledToVSpace) {
gameEntity.isVGamePreferred()
} else if (isInstalledLocally) {
false
} else if (isInstalledToVSpace) {
true
} else {
gameEntity.isVGamePreferred()
}
val downloadEntity: DownloadEntity? = if (isDownloading) {
entityFromDownloadManager
} else if (isPendingToInstall) {
entityFromDownloadManager
} else {
if (isVGamePreferred) {
entityFromInstalledVGame ?: entityFromDownloadManager
} else {
entityFromDownloadManager
}
}
if (downloadEntity != null) {
@ -300,11 +351,12 @@ object DownloadItemUtils {
DownloadStatus.done -> {
if (downloadEntity.isSimulatorGame() && gameEntity.simulator != null) {
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
} else if (downloadEntity.isVGame()) {
} else if (isVGamePreferred) {
buttonStyle =
if (PackagesManager.isCanUpdate(
downloadEntity.gameId,
downloadEntity.packageName
downloadEntity.packageName,
asVGame = true
)
) {
setText(R.string.update)
@ -333,8 +385,19 @@ object DownloadItemUtils {
return
}
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
setText(R.string.install)
if (PackagesManager.isInstalled(downloadEntity.packageName) && !downloadEntity.isUpdate) {
// 双下载按钮快速安装时存在已下载的安装包过时,需要重新下载的情况
if (PackagesManager.isCanUpdate(downloadEntity.gameId, downloadEntity.packageName)) {
buttonStyle = DownloadButton.ButtonStyle.NORMAL
setText(R.string.update)
} else {
buttonStyle = DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
setText(R.string.launch)
}
} else {
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
setText(R.string.install)
}
}
buttonStyle =
if (downloadEntity.isPluggable && PackagesManager.isInstalled(downloadEntity.packageName)) {
@ -827,6 +890,7 @@ object DownloadItemUtils {
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese,
gameEntity.getApk().firstOrNull()?.format,
clickRunnable
)
}
@ -836,17 +900,21 @@ object DownloadItemUtils {
allStateClickCallback?.onCallback()
clickCallback?.onCallback()
ChainBuilder().apply {
DownloadChainBuilder().apply {
addHandler(GamePermissionHandler())
addHandler(CheckStoragePermissionHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
}
.setProcessEndCallback {
.setProcessEndCallback { _, _ ->
DownloadDialog.showDownloadDialog(view.context, gameEntity, traceEvent, entrance, location)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
?.handleRequest(
context,
gameEntity,
GameUtils.shouldPerformAsVGame(gameEntity)
)
}
}
}
@ -866,8 +934,11 @@ object DownloadItemUtils {
val str = if (downloadBtn is DownloadButton) downloadBtn.text else context.getString(R.string.download)
if (gameEntity.getApk().isEmpty()) return
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
val shouldPerformAsVGame = GameUtils.shouldPerformAsVGame(gameEntity)
if (str == context.getString(R.string.download)) {
ChainBuilder().apply {
DownloadChainBuilder().apply {
addHandler(UnsupportedFeatureHandler())
addHandler(UpdateNewSimulatorHandler())
addHandler(GamePermissionHandler())
@ -879,14 +950,14 @@ object DownloadItemUtils {
addHandler(LandPageAddressHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback {
download(context, gameEntity, downloadBtn, entrance, location, it as Boolean, traceEvent)
.setProcessEndCallback { asVGame, isSubscribe ->
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
?.handleRequest(context, gameEntity, shouldPerformAsVGame)
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str == context.getString(R.string.attempt)) {
ChainBuilder().apply {
DownloadChainBuilder().apply {
addHandler(UnsupportedFeatureHandler())
addHandler(UpdateNewSimulatorHandler())
addHandler(GamePermissionHandler())
@ -899,14 +970,14 @@ object DownloadItemUtils {
addHandler(OverseaDownloadHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback {
download(context, gameEntity, downloadBtn, entrance, location, it as Boolean, traceEvent)
.setProcessEndCallback { asVGame, isSubscribe ->
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
?.handleRequest(context, gameEntity, shouldPerformAsVGame)
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str == context.getString(R.string.smooth)) {
ChainBuilder().apply {
DownloadChainBuilder().apply {
addHandler(UnsupportedFeatureHandler())
addHandler(GamePermissionHandler())
addHandler(PackageCheckHandler())
@ -919,25 +990,25 @@ object DownloadItemUtils {
addHandler(ValidateVSpaceHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback {
download(context, gameEntity, downloadBtn, entrance, location, it as Boolean, traceEvent)
.setProcessEndCallback { asVGame, isSubscribe ->
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
?.handleRequest(context, gameEntity, shouldPerformAsVGame)
} else if (str.contains("")) {
if (gameEntity.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
ChainBuilder().apply {
DownloadChainBuilder().apply {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback {
plugin(context, gameEntity, downloadBtn, entrance, location, it as Boolean, traceEvent)
.setProcessEndCallback { _, isSubscribe ->
plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
?.handleRequest(context, gameEntity, shouldPerformAsVGame)
}
} else if (str == context.getString(R.string.install)) {
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.url)
@ -978,11 +1049,7 @@ object DownloadItemUtils {
}
}
if (gameEntity.isVGame()) {
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
} else {
install(context, gameEntity, position, adapter, refreshCallback)
}
install(context, gameEntity, position, adapter, refreshCallback)
} else if (str == context.getString(R.string.launch)) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
@ -994,7 +1061,16 @@ object DownloadItemUtils {
if (downloadEntity != null) {
val file = File(downloadEntity.path)
if (!file.exists()) {
download(context, gameEntity, downloadBtn, entrance, location, false, traceEvent)
download(
context = context,
gameEntity = gameEntity,
downloadBtn = downloadBtn,
entrance = entrance,
location = location,
asVGame = false,
isSubscribe = false,
traceEvent = traceEvent
)
return
}
NewFlatLogUtils.logSimulatorGameCardClick("启动")
@ -1003,21 +1079,17 @@ object DownloadItemUtils {
return
}
if (gameEntity.isVGame()) {
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
return
}
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
PackageLauncher.launch(context, gameEntity)
} else if (str == context.getString(R.string.update)) {
if (gameEntity.isVGame()) {
if (shouldPerformAsVGame) {
VHelper.updateOrReDownload(gameEntity)
return
}
ChainBuilder()
DownloadChainBuilder()
.apply {
addHandler(LandPageAddressHandler())
}.setProcessEndCallback {
}.setProcessEndCallback { asVGame, _ ->
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
DialogUtils.checkDownload(
context,
@ -1026,21 +1098,16 @@ object DownloadItemUtils {
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
update(context, gameEntity, entrance, location, asVGame, isSubscribe, traceEvent)
}
}
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
?.handleRequest(context, gameEntity, false)
} else {
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在代表游戏已下载并成功安装
if (downloadEntity == null && gameEntity.isVGame()) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
}
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
// 尝试从 gameEntity 里找已绑定的 downloadEntity
if (downloadEntity == null) {
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
}
@ -1056,7 +1123,7 @@ object DownloadItemUtils {
}
when (str) {
context.getString(R.string.resume) -> {
DownloadManager.getInstance().resume(downloadEntity, true)
DownloadManager.getInstance().resume(downloadEntity, false)
}
context.getString(R.string.waiting) -> {
@ -1078,6 +1145,7 @@ object DownloadItemUtils {
downloadBtn: View?,
entrance: String,
location: String,
asVGame: Boolean,
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
@ -1088,7 +1156,7 @@ object DownloadItemUtils {
DownloadManager.createDownload(
context,
gameEntity,
context.getString(R.string.download),
asVGame,
entrance,
location,
isSubscribe,
@ -1123,7 +1191,7 @@ object DownloadItemUtils {
) {
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
DownloadManager.createDownload(context, gameEntity, false, entrance, location, isSubscribe, traceEvent)
ToastUtils.toast(gameEntity.name + "已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
@ -1187,9 +1255,19 @@ object DownloadItemUtils {
gameEntity: GameEntity,
entrance: String,
location: String,
asVGame: Boolean,
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
// 执行更新操作前,先清理历史下载任务,避免冲突
if (gameEntity.getApk().size == 1 && !asVGame) {
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity != null) {
DownloadManager.getInstance().cancel(downloadEntity.url)
}
}
DownloadManager.createDownload(context, gameEntity, asVGame, entrance, location, isSubscribe, traceEvent)
}
}

View File

@ -15,7 +15,7 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.isSimulatorGame
import com.gh.gamecenter.common.utils.isVGame
import com.gh.gamecenter.common.utils.asVGame
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SpeedUtils
@ -57,65 +57,65 @@ object DownloadNotificationHelper {
intent.putExtra(EntranceConsts.KEY_URL, entity.url)
intent.putExtra(EntranceConsts.KEY_PATH, entity.path)
intent.action = ACTION_INSTALL
} else if (entity.isVGame()) {
} else if (entity.asVGame()) {
intent.action = ACTION_VDOWNLOAD
} else {
intent.action = ACTION_DOWNLOAD
}
val pendingIntent = PendingIntent.getBroadcast(
HaloApp.getInstance().application,
downloadNotificationId,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(DOWNLOAD_CHANNEL_ID, DOWNLOAD_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW)
notificationManager.createNotificationChannel(channel)
}
val whenTime = 1000 * 60 * (System.currentTimeMillis() / 1000 / 60)
val builder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
.setContentTitle(entity.name)
.setSmallIcon(getNotificationIcon())
.setContentIntent(pendingIntent)
.setGroup(DOWNLOAD_GROUP_KEY)
.setWhen(whenTime)
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {
builder.setContentText("" + entity.name + "》解压失败,点击查看详情~")
} else {
when (entity.status) {
DownloadStatus.downloading -> builder.setContentText(
String.format(
"%s(剩%s)",
SpeedUtils.getSpeed(entity.speed),
SpeedUtils.getRemainTime(entity.size, entity.progress, entity.speed * 1024)
)
)
DownloadStatus.done -> builder.setContentText("下载完成,点击立即安装")
DownloadStatus.waiting -> builder.setContentText("等待中")
DownloadStatus.subscribe,
DownloadStatus.timeout,
DownloadStatus.diskisfull,
DownloadStatus.diskioerror,
DownloadStatus.neterror -> builder.setContentText("已暂停连接WiFi自动下载")
else -> builder.setContentText("暂停中")
}
builder.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
}
when (entity.status) {
DownloadStatus.done -> {
builder.setSortKey("A")
builder.setOngoing(true) // 垃圾华为 sortKey 不起效 priority 也不起效,要将下载完成任务的通知置顶只能设置为 ongoing喷了
}
DownloadStatus.downloading -> builder.setSortKey("B")
else -> builder.setSortKey("C")
}
tryCatchInRelease {
val pendingIntent = PendingIntent.getBroadcast(
HaloApp.getInstance().application,
downloadNotificationId,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(DOWNLOAD_CHANNEL_ID, DOWNLOAD_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW)
notificationManager.createNotificationChannel(channel)
}
val whenTime = 1000 * 60 * (System.currentTimeMillis() / 1000 / 60)
val builder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
.setContentTitle(entity.name)
.setSmallIcon(getNotificationIcon())
.setContentIntent(pendingIntent)
.setGroup(DOWNLOAD_GROUP_KEY)
.setWhen(whenTime)
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {
builder.setContentText("" + entity.name + "》解压失败,点击查看详情~")
} else {
when (entity.status) {
DownloadStatus.downloading -> builder.setContentText(
String.format(
"%s(剩%s)",
SpeedUtils.getSpeed(entity.speed),
SpeedUtils.getRemainTime(entity.size, entity.progress, entity.speed * 1024)
)
)
DownloadStatus.done -> builder.setContentText("下载完成,点击立即安装")
DownloadStatus.waiting -> builder.setContentText("等待中")
DownloadStatus.subscribe,
DownloadStatus.timeout,
DownloadStatus.diskisfull,
DownloadStatus.diskioerror,
DownloadStatus.neterror -> builder.setContentText("已暂停连接WiFi自动下载")
else -> builder.setContentText("暂停中")
}
builder.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
}
when (entity.status) {
DownloadStatus.done -> {
builder.setSortKey("A")
builder.setOngoing(true) // 垃圾华为 sortKey 不起效 priority 也不起效,要将下载完成任务的通知置顶只能设置为 ongoing喷了
}
DownloadStatus.downloading -> builder.setSortKey("B")
else -> builder.setSortKey("C")
}
val notification = builder.build() // 可能会抛出异常
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {

View File

@ -8,6 +8,7 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.base.activity.BaseActivity
@ -22,7 +23,6 @@ import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
@ -172,6 +172,33 @@ object DownloadObserver {
ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载")
}
// 删除任务
downloadEntity.status = DownloadStatus.cancel
downloadManager.cancel(downloadEntity.url)
} else if (DownloadStatus.isCertificating == downloadEntity.status) {
// 未接入防沉迷系统
val currentActivity = AppManager.getInstance().currentActivity()
if (currentActivity != null) {
DialogHelper.showDialog(
context = currentActivity,
title = "实名提示",
content = "您当前的身份信息正在认证中,根据相关政策要求,该游戏需通过认证后才能进行下载",
cancelText = "知道了",
confirmText = "查看实名认证",
cancelClickCallback = null,
confirmClickCallback = {
currentActivity.startActivity(
ShellActivity.getIntent(
currentActivity,
ShellActivity.Type.REAL_NAME_INFO,
))
}
)
} else {
ToastUtils.toast("您当前的身份信息正在认证中,根据相关政策要求,该游戏需通过认证后才能进行下载")
}
// 删除任务
downloadEntity.status = DownloadStatus.cancel
downloadManager.cancel(downloadEntity.url)
@ -274,13 +301,13 @@ object DownloadObserver {
)
else -> {
if (!downloadEntity.isVGame()) {
if (!downloadEntity.asVGame()) {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
}
}
} else {
if (!downloadEntity.isVGame()) {
if (!downloadEntity.asVGame()) {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
}
@ -315,11 +342,9 @@ object DownloadObserver {
Utils.toast(mApplication, R.string.install_failure_hint)
downloadManager.cancel(downloadEntity.url)
} else {
if (PackageUtils.isCanLaunchSetup(
mApplication,
downloadEntity.path
) || downloadType == Constants.SMOOTH_GAME
) {
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)
|| downloadType == Constants.VGAME
|| downloadType == Constants.DUAL_DOWNLOAD_VGAME) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
tryWithDefaultCatch {
NewFlatLogUtils.logGameInstall(
@ -333,7 +358,7 @@ object DownloadObserver {
gameName = downloadEntity.name,
action = "自动安装"
)
PackageInstaller.install(mApplication, downloadEntity, false)
PackageInstaller.install(mApplication, downloadEntity, false, ignoreAsVGame = false)
}
} else {
// 弹出卸载提示框
@ -401,7 +426,7 @@ object DownloadObserver {
private fun statDoneEvent(downloadEntity: DownloadEntity) {
var type: ExposureUtils.DownloadType
if (downloadEntity.isUpdate) {
if (downloadEntity.isVGame()) {
if (downloadEntity.asVGame()) {
type = ExposureUtils.DownloadType.FUN_UPDATE
} else {
type = ExposureUtils.DownloadType.UPDATE
@ -410,7 +435,7 @@ object DownloadObserver {
}
}
} else {
type = if (downloadEntity.isVGame()) {
type = if (downloadEntity.asVGame()) {
ExposureUtils.DownloadType.FUN_DOWNLOAD
} else {
ExposureUtils.DownloadType.DOWNLOAD
@ -450,7 +475,7 @@ object DownloadObserver {
type
)
if (downloadEntity.isVGame()) {
if (downloadEntity.asVGame()) {
SensorsBridge.trackEventWithExposureSource(
"HaloFunGameDownloadDone",
exposureEvent?.source,
@ -464,11 +489,18 @@ object DownloadObserver {
"space_schema_type",
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
)
} else if(downloadEntity.gameId == Constants.HALO_FUN_NEW_32_GAME_ID) {
SensorsBridge.trackEvent(
"HaloFunDownloadDone",
"space_schema_type",
"32位(新)"
)
}
if (downloadEntity.gameId != Constants.GHZS_GAME_ID
&& downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD
&& downloadEntity.gameId != Constants.HALO_FUN_GAME_ID) {
&& downloadEntity.gameId != Constants.HALO_FUN_GAME_ID
&& downloadEntity.gameId != Constants.HALO_FUN_NEW_32_GAME_ID) {
SensorsBridge.trackEventWithExposureSource(
"DownloadProcessFinish",
exposureEvent?.source,
@ -481,7 +513,8 @@ object DownloadObserver {
"page_business_id", getCurrentPageEntity().pageBusinessId,
"last_page_name", getLastPageEntity().pageName,
"last_page_id", getLastPageEntity().pageId,
"last_page_business_id", getLastPageEntity().pageBusinessId
"last_page_business_id", getLastPageEntity().pageBusinessId,
"download_type", if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
)
}

View File

@ -18,7 +18,6 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.login.user.LoginTag
import com.halo.assistant.fragment.user.UserInfoEditFragment
import com.halo.assistant.fragment.user.VerifyPhoneFragment
import com.lightgame.utils.AppManager
@ -236,7 +235,7 @@ object ErrorHelper {
)
}
binding.hintTv.text = errorEntity.data?.text
binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
binding.hintTv.setTextColor(R.color.text_theme.toColor(context))
binding.hintTv.setOnClickListener {
errorEntity.data?.toLinkEntity()?.let { entity ->
DirectUtils.directToLinkPage(context, entity, "实名提醒弹窗", "")
@ -297,7 +296,7 @@ object ErrorHelper {
)
}
binding.hintTv.text = errorEntity.data?.text
binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
binding.hintTv.setTextColor(R.color.text_theme.toColor(context))
binding.hintTv.setOnClickListener {
errorEntity.data?.toLinkEntity()?.let { entity ->
DirectUtils.directToLinkPage(context, entity, "手机号验证", "")

View File

@ -28,7 +28,6 @@ import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.feature.entity.ApkEntity
@ -204,10 +203,16 @@ object GameActivityDownloadHelper {
) {
val apk = getApk(gameEntity, event, true) ?: return
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game)
if (downloadEntity != null &&
str != context.getString(R.string.install) &&
str != context.getString(R.string.launch)
val str = GameUtils.getDownloadBtnText(
context = context,
gameEntity = gameEntity,
isFromList = true,
fixedAsVGame = false,
pluginLocation = PluginLocation.only_game
)
if (downloadEntity != null
&& str != context.getString(R.string.install)
&& str != context.getString(R.string.launch)
) {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
@ -261,7 +266,7 @@ object GameActivityDownloadHelper {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
download(context, gameEntity, apk, false, isSubscribe, entrance, location, traceEvent)
}
}
}
@ -277,7 +282,7 @@ object GameActivityDownloadHelper {
location: String,
traceEvent: ExposureEvent
) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(
@ -287,7 +292,7 @@ object GameActivityDownloadHelper {
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
download(context, gameEntity, apk, true, isSubscribe, entrance, location, traceEvent)
}
}
}
@ -354,12 +359,10 @@ object GameActivityDownloadHelper {
}
}
if (gameEntity.isVGame()) {
if (downloadEntity?.isVGameDownloadInDualDownloadMode() == true) {
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
} else {
downloadEntity?.run {
install(context, gameEntity, apk, this)
}
downloadEntity?.run { install(context, gameEntity, apk, this) }
}
}
@ -383,7 +386,16 @@ object GameActivityDownloadHelper {
if (simulatorDownloadEntity != null) {
val file = File(simulatorDownloadEntity.path)
if (!file.exists()) {
download(context, gameEntity, apk, false, entrance, location, traceEvent)
download(
context = context,
gameEntity = gameEntity,
apk = apk,
asVGame = false,
isSubscribe = false,
entrance = entrance,
location = location,
traceEvent = traceEvent
)
return
}
NewFlatLogUtils.logSimulatorGameCardClick("启动")
@ -392,15 +404,7 @@ object GameActivityDownloadHelper {
return
}
if (gameEntity.isVGame()) {
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
return
}
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
}
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
PackageLauncher.launch(context, gameEntity)
}
// 处理更新状态
@ -463,6 +467,7 @@ object GameActivityDownloadHelper {
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
asVGame: Boolean,
isSubscribe: Boolean,
entrance: String,
location: String,
@ -470,11 +475,7 @@ object GameActivityDownloadHelper {
) {
val msg = FileUtils.isCanDownload(context, apk.size)
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(
context, apk, gameEntity, context.getString(
R.string.download
), entrance, location, isSubscribe, traceEvent
)
DownloadManager.createDownload(context, apk, gameEntity, asVGame, gameEntity.isDualBtnModeEnabled(), entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
@ -499,7 +500,7 @@ object GameActivityDownloadHelper {
) {
val msg = FileUtils.isCanDownload(context, apk.size)
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
DownloadManager.createDownload(context, apk, gameEntity, false, false, entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
@ -554,7 +555,7 @@ object GameActivityDownloadHelper {
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
DownloadManager.createDownload(context, apk, gameEntity, false, false, entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)

View File

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

View File

@ -1,272 +0,0 @@
package com.gh.common.util;
import android.content.Context;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.gh.common.constant.Config;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.ApkLink;
import com.gh.gamecenter.feature.entity.GameCollectionEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import java.util.ArrayList;
import java.util.List;
public class GameUtils {
/**
* 去除与重复sourceList相同的数据
*/
public static List<GameEntity> removeDuplicateData(List<GameEntity> sourceList, List<GameEntity> rawList) {
if (sourceList == null || sourceList.isEmpty()
|| rawList == null || rawList.isEmpty()) {
return rawList;
}
String id;
for (int i = 0; i < rawList.size(); i++) {
id = rawList.get(i).getId();
for (GameEntity gameEntity : sourceList) {
if (id.equals(gameEntity.getId())) {
rawList.remove(i);
i--;
break;
}
}
}
return rawList;
}
/**
* 设置下载按钮状态
*/
public static void setDownloadBtnStatus(Context context, GameEntity gameEntity, DownloadButton downloadBtn, PluginLocation pluginLocation) {
// getDownloadBtnText 里包括查询数据库、根据包名读取包体 meta 信息等
AppExecutor.getLightWeightIoExecutor().execute(() -> {
String status = getDownloadBtnText(context, gameEntity, pluginLocation);
AppExecutor.getUiExecutor().execute(() -> {
downloadBtn.setText(status);
if (context.getString(R.string.pluggable).equals(status)) {
downloadBtn.setButtonStyle(DownloadButton.ButtonStyle.PLUGIN);
String pluginDesc = gameEntity.getPluginDesc();
if (pluginDesc.length() > 3) pluginDesc = pluginDesc.substring(0, 3);
downloadBtn.setText((pluginDesc + ""));
} else {
downloadBtn.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
}
});
});
}
/**
* 获取下载按钮文案 (相对耗时,请优先在子线程调用)
*/
@WorkerThread
public static String getDownloadBtnText(Context context, GameEntity gameEntity, PluginLocation pluginLocation) {
if (gameEntity.getApk().size() > 1) {
return "";
}
int doneCount = 0; // 下载完成数量
int pluginCount = 0; // 可插件化数量
int updateCount = 0; // 可更新数量
int installCount = 0; // 已安装数量
boolean isRelatedEmulatorInstalled = false; // 若该游戏是模拟器游戏时其对应的模拟器是否已经安装
boolean isInstalledNewSimulator = false;// 是否安装新模拟器
DownloadEntity downloadEntity = null;
Object gh_id;
apkFor:
for (ApkEntity apkEntity : gameEntity.getApk()) {
// filter by packageName
SettingsEntity settings = Config.getSettings();
if (settings != null && gameEntity.getApk().size() > 1) {
for (String pkgName : settings.getGameDownloadBlackList()) {
if (pkgName.equals(apkEntity.getPackageName())) {
continue apkFor;
}
}
}
downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
// 在下载管理找不到下载实体,并且为畅玩游戏的时候到畅玩数据库里找
if (downloadEntity == null && gameEntity.isVGame()) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.getId(), apkEntity.getPackageName());
}
if (downloadEntity != null) {
if (downloadEntity.getStatus().equals(DownloadStatus.done)) {
doneCount++;
} else if (downloadEntity.isPluggable()) {
pluginCount++;
} else if (downloadEntity.isUpdate()) {
updateCount++;
}
}
if (PackagesManager.INSTANCE.isCanUpdate(gameEntity.getId(), apkEntity.getPackageName())) {
updateCount++;
}
if (PackagesManager.isInstalled(apkEntity.getPackageName())) {
gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
if (!TextUtils.isEmpty(apkEntity.getGhVersion())
&& !PackageUtils.isSignedByGh(context, apkEntity.getPackageName())
&& apkEntity.isShowPlugin(pluginLocation)) {
pluginCount++;
} else if (gh_id == null
|| gh_id.equals(gameEntity.getId())
// 当使用镜像时,可能会存在镜像 gh_id 与当前游戏 id 不一样的情况,这时也让它通过,避免装完还是显示`下载`
|| gameEntity.shouldUseMirrorInfo()) {
installCount++;
}
}
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
isInstalledNewSimulator = SimulatorGameManager.isNewSimulatorInstalled(context);
DownloadEntity simulatorDownloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apkEntity.getUrl());
if (simulatorDownloadEntity != null && gameEntity.getSimulator() != null) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
if (isInstalled) {
installCount++;
isRelatedEmulatorInstalled = true;
} else {
doneCount++;
}
}
}
}
if ((isRelatedEmulatorInstalled || isInstalledNewSimulator) && doneCount != 0) {
return context.getString(R.string.launch);
}
if (gameEntity.isVGame()) {
// 如果 doneCount 为 0 或者数据库为空
// 表明本地并没有此游戏的数据库数据,需要重新下载
if (doneCount == 0
|| downloadEntity == null
|| !VHelper.isInstalled(downloadEntity.getPackageName())) {
installCount = 0;
} else {
doneCount = 0;
installCount = 1;
}
}
if (doneCount != 0) {
return context.getString(R.string.install);
} else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
return context.getString(R.string.pluggable);
} else if (updateCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
return context.getString(R.string.update);
} else if (installCount != 0) {
return context.getString(R.string.launch);
} else if ("demo".equals(gameEntity.getDownloadStatus())) {
return context.getString(R.string.attempt);
} else {
if (gameEntity.isVGame()) {
return context.getString(R.string.smooth);
} else {
if (Constants.V_GAME.equals(gameEntity.getDownloadStatus())
|| Constants.V_GAME_32.equals(gameEntity.getDownloadStatus())) {
GameEntity.GameCategory gameCategory = gameEntity.getGameCategory();
if (gameCategory.equals(GameEntity.GameCategory.ONLINE_GAME)
|| gameCategory.equals(GameEntity.GameCategory.INTERNATIONAL_ONLINE_GAME)) {
return context.getString(R.string.download);
} else {
return context.getString(R.string.attempt);
}
} else {
return context.getString(R.string.download);
}
}
}
}
/**
* 获取GameUpdateEntity(插件化)
*/
public static GameUpdateEntity getGameUpdateEntity(GameEntity gameEntity, ApkEntity apkEntity) {
GameUpdateEntity gameUpdateEntity = new GameUpdateEntity();
gameUpdateEntity.setId(gameEntity.getId());
gameUpdateEntity.setIcon(gameEntity.getIcon());
gameUpdateEntity.setRawIcon(gameEntity.getRawIcon());
gameUpdateEntity.setIconSubscript(gameEntity.getIconSubscript());
gameUpdateEntity.setIconFloat(gameEntity.getIconFloat());
gameUpdateEntity.setName(gameEntity.getName());
gameUpdateEntity.setPackageName(apkEntity.getPackageName());
gameUpdateEntity.setSize(apkEntity.getSize());
gameUpdateEntity.setVersion(apkEntity.getVersion());
gameUpdateEntity.setGhVersion(apkEntity.getGhVersion());
gameUpdateEntity.setUrl(apkEntity.getUrl());
gameUpdateEntity.setPlatform(apkEntity.getPlatform());
gameUpdateEntity.setEtag(apkEntity.getEtag());
gameUpdateEntity.setPluggable(true);
gameUpdateEntity.setTagStyle(gameEntity.getTagStyle());
gameUpdateEntity.setBrief(gameEntity.getBrief());
gameUpdateEntity.setPlugin(apkEntity.getPlugin());
gameUpdateEntity.setDownload(gameEntity.getDownload());
gameUpdateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
gameUpdateEntity.setPluginDesc(gameEntity.getPluginDesc());
gameUpdateEntity.setFormat(apkEntity.getFormat());
gameUpdateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
gameUpdateEntity.setCategory(gameEntity.getCategory());
GameCollectionEntity pluggableCollection = getPluggableCollectionFromGameEntity(gameEntity, apkEntity.getPackageName());
if (pluggableCollection != null) {
gameUpdateEntity.setPluggableCollection(pluggableCollection);
}
return gameUpdateEntity;
}
@Nullable
public static GameCollectionEntity getPluggableCollectionFromGameEntity(GameEntity gameEntity, String targetPkg) {
// 添加插件化包所在的合集
for (GameCollectionEntity collectionEntity : gameEntity.getCollection()) {
if (collectionEntity.getPackages().contains(targetPkg)) {
ArrayList<ApkEntity> saveApkEntity = new ArrayList<>();
for (String pkg : collectionEntity.getPackages()) {
for (ApkEntity apk : gameEntity.getApk()) {
if (pkg.equals(apk.getPackageName())) {
saveApkEntity.add(apk);
break;
}
}
}
ArrayList<ApkLink> apkLinks = gameEntity.getApkLink();
if (apkLinks != null) {
for (ApkLink apkLink : apkLinks) {
if (apkLink.getCollection().equals(collectionEntity.getId())) {
ApkEntity element = new ApkEntity();
element.setApkLink(apkLink);
if (saveApkEntity.size() > apkLink.getSort()) {
saveApkEntity.add(apkLink.getSort(), element);
} else {
saveApkEntity.add(element);
}
}
}
}
collectionEntity.setSaveApkEntity(saveApkEntity);
return collectionEntity;
}
}
return null;
}
}

View File

@ -0,0 +1,343 @@
package com.gh.common.util
import android.content.Context
import android.text.TextUtils
import androidx.annotation.WorkerThread
import com.gh.common.constant.Config
import com.gh.common.simulator.SimulatorGameManager.findDownloadEntityByUrl
import com.gh.common.simulator.SimulatorGameManager.isNewSimulatorInstalled
import com.gh.common.simulator.SimulatorGameManager.isSimulatorGame
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.isLocalDownloadInDualDownloadMode
import com.gh.gamecenter.common.utils.isVGameDownloadInDualDownloadMode
import com.gh.gamecenter.core.AppExecutor.lightWeightIoExecutor
import com.gh.gamecenter.core.AppExecutor.uiExecutor
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.feature.entity.*
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.manager.PackagesManager.isCanUpdate
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
object GameUtils {
/**
* 去除与重复sourceList相同的数据
*/
fun removeDuplicateData(sourceList: MutableList<GameEntity>?, rawList: MutableList<GameEntity>?): MutableList<GameEntity>? {
if (sourceList.isNullOrEmpty() || rawList.isNullOrEmpty()) {
return rawList
}
var id: String
var i = 0
while (i < rawList.size) {
id = rawList[i].id
for (gameEntity in sourceList) {
if (id == gameEntity.id) {
rawList.removeAt(i)
i--
break
}
}
i++
}
return rawList
}
/**
* 设置下载按钮状态
*/
fun setDownloadBtnStatus(
context: Context,
gameEntity: GameEntity,
downloadBtn: DownloadButton,
pluginLocation: PluginLocation?
) {
// getDownloadBtnText 里包括查询数据库、根据包名读取包体 meta 信息等
lightWeightIoExecutor.execute {
val status = getDownloadBtnText(
context = context,
gameEntity = gameEntity,
isFromList = true,
fixedAsVGame = false,
pluginLocation = pluginLocation
)
uiExecutor.execute {
downloadBtn.text = status
if (context.getString(R.string.pluggable) == status) {
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.PLUGIN
var pluginDesc = gameEntity.pluginDesc
if (pluginDesc.length > 3) pluginDesc = pluginDesc.substring(0, 3)
downloadBtn.text = pluginDesc + ""
} else {
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
}
}
}
}
/**
* 获取下载按钮文案 (相对耗时,请优先在子线程调用)
*
* @param isFromList 调用方是否来源自普通列表 (普通列表根据优先级确定是显示成畅玩状态还是普通下载状态)
* @param fixedAsVGame 固定以畅玩游戏的类型来获取状态
*/
@WorkerThread
@JvmStatic
fun getDownloadBtnText(context: Context,
gameEntity: GameEntity,
isFromList: Boolean,
fixedAsVGame: Boolean,
pluginLocation: PluginLocation?): String {
if (gameEntity.getApk().size > 1) {
return ""
}
var doneCount = 0 // 下载完成数量
var pluginCount = 0 // 可插件化数量
var updateCount = 0 // 可更新数量
var installCount = 0 // 已安装数量
var isRelatedEmulatorInstalled = false // 若该游戏是模拟器游戏时其对应的模拟器是否已经安装
var isInstalledNewSimulator = false // 是否安装新模拟器
var downloadEntity: DownloadEntity? = null
var performAsVGame = false // 是否使用了畅玩作为 downloadEntity
var gh_id: Any?
apkFor@ for (apkEntity in gameEntity.getApk()) {
val isInstalledLocally = PackagesManager.isInstalled(apkEntity.packageName)
// filter by packageName
val settings = Config.getSettings()
if (settings != null && gameEntity.getApk().size > 1) {
for (pkgName in settings.gameDownloadBlackList) {
if (pkgName == apkEntity.packageName) {
continue@apkFor
}
}
}
downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
// 已安装的畅玩游戏实体
val vGameDownloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, apkEntity.packageName)
performAsVGame = if (fixedAsVGame) {
true
} else if (isFromList) {
if (vGameDownloadEntity == null && isInstalledLocally) {
false
} else {
gameEntity.isVGamePreferred()
}
} else {
false
}
// 畅玩状态优先,且畅玩实体不为空时将 downloadEntity 置为畅玩实体
if (performAsVGame && vGameDownloadEntity != null) {
downloadEntity = vGameDownloadEntity
} else if (!performAsVGame && !isFromList && downloadEntity?.isVGameDownloadInDualDownloadMode() == true) {
// 下载的任务是由畅玩触发的,游戏详情页不需判定为需要安装
downloadEntity = null
} else if (performAsVGame && !isFromList && downloadEntity?.isLocalDownloadInDualDownloadMode() == true) {
// 下载的任务是由下载安装触发的,游戏详情页不需判定为需要安装
downloadEntity = null
}
if (downloadEntity != null) {
if (downloadEntity.status == DownloadStatus.done) {
doneCount++
} else if (downloadEntity.isPluggable) {
pluginCount++
} else if (downloadEntity.isUpdate) {
updateCount++
}
}
if (isCanUpdate(gameEntity.id, apkEntity.packageName, performAsVGame)) {
updateCount++
}
if (isInstalledLocally) {
gh_id = PackageUtils.getMetaData(context, apkEntity.packageName, "gh_id")
if (!TextUtils.isEmpty(apkEntity.ghVersion)
&& !PackageUtils.isSignedByGh(context, apkEntity.packageName)
&& apkEntity.isShowPlugin(pluginLocation!!)
) {
pluginCount++
} else if (gh_id == null || gh_id == gameEntity.id || gameEntity.shouldUseMirrorInfo()) {
installCount++
}
}
if (isSimulatorGame(gameEntity)) {
isInstalledNewSimulator = isNewSimulatorInstalled(context)
val simulatorDownloadEntity = findDownloadEntityByUrl(apkEntity.url)
if (simulatorDownloadEntity != null && gameEntity.simulator != null) {
val isInstalled =
PackageUtils.isInstalledFromAllPackage(context, gameEntity.simulator!!.apk!!.packageName)
if (isInstalled) {
installCount++
isRelatedEmulatorInstalled = true
} else {
doneCount++
}
}
}
}
if ((isRelatedEmulatorInstalled || isInstalledNewSimulator) && doneCount != 0) {
return context.getString(R.string.launch)
}
if (performAsVGame) {
// 如果 doneCount 为 0 或者数据库为空
// 表明本地并没有此游戏的数据库数据,需要重新下载
if (doneCount == 0 || downloadEntity == null || !VHelper.isInstalled(downloadEntity.packageName)) {
installCount = 0
} else {
doneCount = 0
installCount = 1
}
} else {
if (gameEntity.isDualBtnModeEnabled()) {
// 双下载按钮模式下,若非更新,排除已安装的情况来影响按钮状态
if (installCount != 0 && doneCount != 0 && downloadEntity?.isUpdate == false) {
doneCount = 0
}
}
}
return if (doneCount != 0) {
context.getString(R.string.install)
} else if (pluginCount != 0 && !isSimulatorGame(gameEntity)) {
context.getString(R.string.pluggable)
} else if (updateCount != 0 && !isSimulatorGame(gameEntity)) {
context.getString(R.string.update)
} else if (installCount != 0) {
context.getString(R.string.launch)
} else if ("demo" == gameEntity.downloadStatus) {
context.getString(R.string.attempt)
} else {
if (performAsVGame) {
context.getString(R.string.smooth)
} else {
// if (Constants.V_GAME == gameEntity.downloadStatus || Constants.V_GAME_32 == gameEntity.downloadStatus) {
// val gameCategory = gameEntity.getGameCategory()
// if (gameCategory == GameEntity.GameCategory.ONLINE_GAME
// || gameCategory == GameEntity.GameCategory.INTERNATIONAL_ONLINE_GAME) {
// context.getString(R.string.download)
// } else {
// context.getString(R.string.attempt)
// }
// } else {
context.getString(R.string.download)
// }
}
}
}
/**
* 获取GameUpdateEntity(插件化)
*/
fun getGameUpdateEntity(gameEntity: GameEntity, apkEntity: ApkEntity): GameUpdateEntity {
val gameUpdateEntity = GameUpdateEntity()
gameUpdateEntity.id = gameEntity.id
gameUpdateEntity.icon = gameEntity.icon
gameUpdateEntity.rawIcon = gameEntity.rawIcon
gameUpdateEntity.iconSubscript = gameEntity.iconSubscript
gameUpdateEntity.iconFloat = gameEntity.iconFloat
gameUpdateEntity.name = gameEntity.name
gameUpdateEntity.packageName = apkEntity.packageName
gameUpdateEntity.size = apkEntity.size
gameUpdateEntity.version = apkEntity.version
gameUpdateEntity.ghVersion = apkEntity.ghVersion
gameUpdateEntity.url = apkEntity.url
gameUpdateEntity.platform = apkEntity.getPlatform()
gameUpdateEntity.etag = apkEntity.etag
gameUpdateEntity.isPluggable = true
gameUpdateEntity.tagStyle = gameEntity.tagStyle
gameUpdateEntity.brief = gameEntity.brief
gameUpdateEntity.plugin = apkEntity.plugin
gameUpdateEntity.download = gameEntity.download
gameUpdateEntity.indexPlugin = gameEntity.indexPlugin
gameUpdateEntity.pluginDesc = gameEntity.pluginDesc
gameUpdateEntity.format = apkEntity.format
gameUpdateEntity.currentVersion = PackageUtils.getVersionNameByPackageName(apkEntity.packageName)
gameUpdateEntity.category = gameEntity.category
val pluggableCollection = getPluggableCollectionFromGameEntity(gameEntity, apkEntity.packageName)
if (pluggableCollection != null) {
gameUpdateEntity.pluggableCollection = pluggableCollection
}
return gameUpdateEntity
}
@JvmStatic
fun getPluggableCollectionFromGameEntity(gameEntity: GameEntity, targetPkg: String?): GameCollectionEntity? {
// 添加插件化包所在的合集
for (collectionEntity in gameEntity.collection) {
if (collectionEntity.packages.contains(targetPkg)) {
val saveApkEntity = ArrayList<ApkEntity>()
for (pkg in collectionEntity.packages) {
for (apk in gameEntity.getApk()) {
if (pkg == apk.packageName) {
saveApkEntity.add(apk)
break
}
}
}
val apkLinks = gameEntity.apkLink
if (apkLinks != null) {
for (apkLink in apkLinks) {
if (apkLink.collection == collectionEntity.id) {
val element = ApkEntity()
element.apkLink = apkLink
if (saveApkEntity.size > apkLink.sort) {
saveApkEntity.add(apkLink.sort, element)
} else {
saveApkEntity.add(element)
}
}
}
}
collectionEntity.saveApkEntity = saveApkEntity
return collectionEntity
}
}
return null
}
/**
* 是否以畅玩游戏的形式来处理
*/
@JvmStatic
fun shouldPerformAsVGame(gameEntity: GameEntity): Boolean {
var performActionAsVGame = false
if (gameEntity.getApk().size != 1) {
performActionAsVGame = false
} else {
when (gameEntity.getGameDownloadButtonMode()) {
GameEntity.GAME_DOWNLOAD_BUTTON_MODE_VGAME -> performActionAsVGame = true
GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DOWNLOAD -> performActionAsVGame = false
GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL -> {
val packageName = gameEntity.getApk().first().packageName
val isInstalledAtDevice = PackagesManager.isInstalled(packageName)
val isInstalledAtVSpace = VHelper.getVDownloadEntitySnapshot(gameEntity.id, packageName) != null
performActionAsVGame = if (isInstalledAtDevice && isInstalledAtVSpace) {
gameEntity.isVGamePreferred()
} else if (isInstalledAtDevice) {
false
} else if (isInstalledAtVSpace) {
true
} else {
gameEntity.isVGamePreferred()
}
}
}
}
return performActionAsVGame
}
}

View File

@ -1,14 +1,15 @@
package com.gh.common.util
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.halo.assistant.HaloApp
object HomeBottomBarHelper {
private const val GAME_BAR_KEY = "game_bar_key"
private const val VIDEO_BAR_KEY = "video_bar_key"
@JvmStatic
fun getDefaultGameBarData(): SubjectRecommendEntity {
@ -28,6 +29,7 @@ object HomeBottomBarHelper {
type = "block",
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,
@ -36,8 +38,42 @@ object HomeBottomBarHelper {
)
}
@JvmStatic
fun getDefaultVideoData(): SubjectRecommendEntity {
try {
val json = SPUtils.getString(VIDEO_BAR_KEY)
if (json.isNotEmpty()) {
return GsonUtils.fromJson(json, SubjectRecommendEntity::class.java)
}
} catch (ignore: Exception) {
}
return getDefaultVideoEntity()
}
@JvmStatic
fun getDefaultVideoEntity(): SubjectRecommendEntity {
val animationCode = HaloApp.getInstance().application.assets
.open("lottie/tab_video.json")
.bufferedReader().use { it.readText() }
return SubjectRecommendEntity(
type = "video_stream",
text = "视频",
name = "视频",
position = 4,
animationCode = animationCode,
default = false,
display = Display()
)
}
@JvmStatic
fun updateDefaultGameBarData(data: SubjectRecommendEntity) {
SPUtils.setString(GAME_BAR_KEY, data.toJson())
}
@JvmStatic
fun updateDefaultVideoBarData(data: SubjectRecommendEntity) {
SPUtils.setString(VIDEO_BAR_KEY, data.toJson())
}
}

View File

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

View File

@ -11,6 +11,7 @@ import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.CommunityEntity;
import com.gh.gamecenter.common.entity.ExposureEntity;
import com.gh.gamecenter.common.exposure.ExposureSource;
import com.gh.gamecenter.common.exposure.meta.Meta;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.loghub.LoghubUtils;
@ -24,7 +25,6 @@ import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PackageDialogEntity;
import com.gh.gamecenter.feature.entity.Questions;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.common.exposure.ExposureSource;
import com.gh.gamecenter.login.user.UserManager;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
@ -259,9 +259,11 @@ public class LogUtils {
private static void uploadToReservation(JSONObject object) {
Context context = HaloApp.getInstance().getApplication();
try {
object.put(KEY_EVENT, "appointment");
object.put("version", PackageUtils.getGhVersionName());
object.put("channel", HaloApp.getInstance().getChannel());
object.put("dia", MetaUtil.getBase64EncodedAndroidId());
object.put("oaid", MetaUtil.INSTANCE.getMeta().getOaid());
object.put("time", Utils.getTime(context));
object.put("network", DeviceUtils.getNetwork(context));
object.put("user_id", UserManager.getInstance().getUserId());
@ -286,6 +288,7 @@ public class LogUtils {
metaObject.put("appVersion", meta.getAppVersion());
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("oaid", meta.getOaid());
metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
@ -568,7 +571,7 @@ public class LogUtils {
}
public static void uploadSearchGame(String event, String location, String key, String searchType) {
uploadSearchClick(event, location, key, searchType, "", "", 0, false);
uploadSearchClick(event, location, key, searchType, "", "", 0, false, "", "");
}
/**
@ -581,7 +584,9 @@ public class LogUtils {
String gameId,
String gameName,
int mirrorDataPosition,
Boolean isAdData) {
Boolean isAdData,
String adSpaceId,
String gameAdSourceId) {
JSONObject object = new JSONObject();
JSONObject payload = new JSONObject();
try {
@ -602,6 +607,8 @@ public class LogUtils {
payload.put("is_mirror2_data", true);
}
payload.put("is_ad_data", isAdData);
payload.put("ad_space_id", adSpaceId);
payload.put("game_ad_source_id", gameAdSourceId);
object.put(KEY_PAY_LOAD, payload);
} catch (JSONException e) {
e.printStackTrace();

View File

@ -566,6 +566,155 @@ object NewFlatLogUtils {
log(json)
}
// 进入社区搜索页面事件
@JvmStatic
fun logAccessToBbsSearch(
location: String,
bbsId: String
) {
json {
KEY_EVENT to "access_to_bbs_search"
"location" to location
"bbs_id" to bbsId
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchingContent(
location: String,
bbsId: String,
searchType: String,
key: String
) {
json {
KEY_EVENT to "searching_content"
"location" to location
"bbs_id" to bbsId
"search_type" to searchType
"key" to key
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchContentClick(
location: String,
bbsId: String,
searchType: String,
key: String,
contentId: String,
type: String,
title: String,
sequence: Int,
button: String
) {
json {
KEY_EVENT to "search_content_click"
"location" to location
"bbs_id" to bbsId
"search_type" to searchType
"key" to key
"content_id" to contentId
"type" to type
"title" to title
"sequence" to sequence
"button" to button
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchContentExposure(
location: String,
bbsId: String,
searchType: String,
searchKey: String,
contentId: String,
type: String,
title: String,
sequence: Int
) {
json {
KEY_EVENT to "search_content_exposure"
"location" to location
"bbs_id" to bbsId
"search_type" to searchType
"key" to searchKey
"content_id" to contentId
"type" to type
"title" to title
"sequence" to sequence
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchBbs(
searchType: String,
searchKey: String
) {
json {
KEY_EVENT to "search_bbs"
"search_type" to searchType
"key" to searchKey
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchBbsClick(
searchType: String,
searchKey: String,
bbsId: String,
sequence: Int,
name: String,
button: String
) {
json {
KEY_EVENT to "search_bbs_click"
"search_type" to searchType
"key" to searchKey
"bbs_id" to bbsId
"sequence" to sequence
"name" to name
"button" to button
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchUser(
searchType: String,
searchKey: String
) {
json {
KEY_EVENT to "search_user"
"search_type" to searchType
"key" to searchKey
parseAndPutMeta()()
}.let(::log)
}
@JvmStatic
fun logSearchUserClick(
searchType: String,
searchKey: String,
userId: String,
name: String,
sequence: Int
) {
json {
KEY_EVENT to "search_user_click"
"search_type" to searchType
"key" to searchKey
"user_id" to userId
"name" to name
"sequence" to sequence
parseAndPutMeta()()
}.let(::log)
}
//点击社区-搜索页返回按钮
@JvmStatic
fun logClickSearchReturn(searchKey: String) {
@ -1124,10 +1273,19 @@ object NewFlatLogUtils {
}
// 存档分享弹窗点击事件
fun logCloudArchiveShareDialogClick(buttonType: String, gameId: String, gameName: String, cloudSaveId: String) {
fun logCloudArchiveShareDialogClick(
buttonType: String,
gameId: String,
gameName: String,
cloudSaveId: String,
cloudSaveName: String,
content: String
) {
val json = json {
"cloud_save_id" to cloudSaveId
KEY_EVENT to "cloud_save_share_dialog_click"
"cloud_save_id" to cloudSaveId
"cloud_save_name" to cloudSaveName
"content" to content
KEY_BUTTON_TYPE to buttonType
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
@ -1177,12 +1335,14 @@ object NewFlatLogUtils {
}
// 上传存档弹窗点击事件
fun logCloudArchiveUploadDialogClick(buttonType: String, gameId: String, gameName: String) {
fun logCloudArchiveUploadDialogClick(gameId: String, gameName: String, cloudSaveId: String, cloudSaveName: String, isSuccess: Boolean) {
val json = json {
KEY_EVENT to "cloud_save_upload_dialog_click"
KEY_BUTTON_TYPE to buttonType
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"cloud_save_id" to cloudSaveId
"cloud_save_name" to cloudSaveName
"is_success" to isSuccess
parseAndPutMeta().invoke(this)
}
log(json)
@ -1623,7 +1783,12 @@ object NewFlatLogUtils {
}
//新游开测详情页点击游戏类型
fun logGameTestDetailGameCategoryClick(tabName: String, gameCategory: String, gameTestStartType: String, isOn: Boolean) {
fun logGameTestDetailGameCategoryClick(
tabName: String,
gameCategory: String,
gameTestStartType: String,
isOn: Boolean
) {
val json = json {
"event" to "game_test_detail_game_category_click"
"tab_name" to tabName
@ -2327,7 +2492,10 @@ object NewFlatLogUtils {
blockId: String,
collectionName: String,
collectionId: String,
text: String
text: String,
linkType: String = "",
linkId: String = "",
linkText: String = ""
) {
val json = json {
KEY_EVENT to "game_list_collection_click"
@ -2337,6 +2505,9 @@ object NewFlatLogUtils {
"game_list_collection_id" to collectionId
"game_list_collection_name" to collectionName
"text" to text
"link_type" to linkType
"link_id" to linkId
"link_text" to linkText
parseAndPutMeta().invoke(this)
}
log(json)
@ -2439,4 +2610,114 @@ object NewFlatLogUtils {
}
log(json)
}
// 点击个人主页的认证文案事件
@JvmStatic
fun logClickAuthText(linkType: String, linkId: String, linkText: String, userId: String, text: String) {
val json = json {
KEY_EVENT to "click_authentication_text"
"link_type" to linkType
"link_id" to linkId
"link_text" to linkText
"link_user_id" to userId
"text" to text
parseAndPutMeta().invoke(this)
}
log(json)
}
// 关闭游戏广告
@JvmStatic
fun logCloseGameAd(
adSpaceId: String,
name: String,
position: String,
type: String,
gameAdSourceId: String,
gameAdSourceName: String
) {
val json = json {
KEY_EVENT to "close_game_ad"
"ad_space_id" to adSpaceId
"name" to name
"position" to position
"type" to type
"game_ad_source_id" to gameAdSourceId
"game_ad_source_name" to gameAdSourceName
parseAndPutMeta().invoke(this)
}
log(json)
}
// 点击游戏广告
@JvmStatic
fun logClickGameAd(
adSpaceId: String,
name: String,
position: String,
type: String,
gameAdSourceId: String,
gameAdSourceName: String,
gameId: String,
gameName: String
) {
val json = json {
KEY_EVENT to "click_game_ad"
"ad_space_id" to adSpaceId
"name" to name
"position" to position
"type" to type
"game_ad_source_id" to gameAdSourceId
"game_ad_source_name" to gameAdSourceName
"game_id" to gameId
"game_name" to gameName
parseAndPutMeta().invoke(this)
}
log(json)
}
// 搜索结果页面点击横幅位卡片
@JvmStatic
fun logGameSearchFirstGameBannerClick(
gameId: String,
gameName: String,
sequence: Int,
linkType: String?,
linkId: String?,
linkText: String?
) {
json {
KEY_EVENT to "game_search_first_game_banner_click"
"game_id" to gameId
"game_name" to gameName
"sequence" to sequence
"link_type" to linkType
"link_id" to linkId
"link_text" to linkText
parseAndPutMeta()(this)
}.let(::log)
}
// 搜索结果页面点击卡片栏卡片
fun logGameSearchFirstGameCardClick(
gameId: String,
gameName: String,
title: String,
sequence: Int,
linkType: String?,
linkId: String?,
linkText: String?
) {
json {
KEY_EVENT to "game_search_first_game_card_click"
"game_id" to gameId
"game_name" to gameName
"title" to title
"sequence" to sequence
"link_type" to linkType
"link_id" to linkId
"link_text" to linkText
parseAndPutMeta()(this)
}.let(::log)
}
}

View File

@ -2158,7 +2158,7 @@ object NewLogUtils {
//点击底部导航栏
@JvmStatic
fun logBottomNavigationClick(navigationName: String, linkType: String, linkText: String, linkId: String = "") {
fun logBottomNavigationClick(navigationName: String, linkType: String, linkText: String, linkId: String = "", sequence: Int) {
val json = json {
KEY_EVENT to "bottom_navigation_click"
"navigation_name" to navigationName
@ -2169,6 +2169,7 @@ object NewLogUtils {
"link_text" to linkText
}
"link_id" to linkId
"sequence" to sequence
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
parseAndPutMeta().invoke(this)
}
@ -2486,4 +2487,209 @@ object NewLogUtils {
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号117
* 事件IDmessage_inform_push
* 事件名称:消息推送事件
* 触发时机:系统触发消息推送
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param sessionMessageType 会话类型
* @param messageType 消息类型
*/
@JvmStatic
fun logMessageInformPush(
gameId: String,
gameName: String,
sessionMessageType: String,
messageType: String
) {
val json = json {
KEY_EVENT to "message_inform_push"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"session_message_type" to sessionMessageType
"message_type" to messageType
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号118
* 事件IDlaunch_server_subscribe_add
* 事件名称:加入开服订阅事件
* 触发时机:点击开服表加入订阅
* @param gameId 游戏ID
* @param gameName 游戏名称
*/
@JvmStatic
fun logLaunchServerSubscribeAdd(
gameId: String,
gameName: String
) {
val json = json {
KEY_EVENT to "launch_server_subscribe_add"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号119
* 事件IDlaunch_server_subscribe_cancel
* 事件名称:取消开服订阅事件
* 触发时机:点击开服表取消订阅
* @param gameId 游戏ID
* @param gameName 游戏名称
*/
@JvmStatic
fun logLaunchServerSubscribeCancel(
gameId: String,
gameName: String
) {
val json = json {
KEY_EVENT to "launch_server_subscribe_cancel"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号120
* 事件IDlaunch_server_subscribe_click
* 事件名称:点击开服订阅事件
* 触发时机:点击开服管理的开服记录
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param launchServerTime 以秒为单位的时间戳,若为日期则是当天0点的时间戳
*/
@JvmStatic
fun logLaunchServerSubscribeClick(
gameId: String,
gameName: String,
launchServerTime: Int
) {
val json = json {
KEY_EVENT to "launch_server_subscribe_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"launch_server_time" to launchServerTime
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号121
* 事件IDlaunch_server_reminder_add
* 事件名称:添加开服提醒事件
* 触发时机:点击开服表的添加提醒
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param reminderTime 设置提醒时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param reminderType 提醒类型: 已知服/未知服
* @param launchServerTime 设置开服时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param serverName 服务器名字
* @param isWechat 是否微信提醒
* @param isApp 是否APP提醒
*/
@JvmStatic
fun logLaunchServerReminderAdd(
gameId: String,
gameName: String,
reminderTime: Int,
reminderType: String,
launchServerTime: Int,
serverName: String,
isWechat: Boolean,
isApp: Boolean
) {
val json = json {
KEY_EVENT to "launch_server_reminder_add"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"reminder_time" to reminderTime
"reminder_type" to reminderType
"launch_server_time" to launchServerTime
"server_name" to serverName
"is_wechat" to isWechat
"is_app" to isApp
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号122
* 事件IDlaunch_server_reminder_cancel
* 事件名称:取消开服提醒事件
* 触发时机:点击开服表的取消提醒
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param reminderTime 设置提醒时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param reminderType 提醒类型: 已知服/未知服
* @param launchServerTime 设置开服时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param serverName 服务器名字
* @param isWechat 是否微信提醒
* @param isApp 是否APP提醒
*/
@JvmStatic
fun logLaunchServerReminderCancel(
gameId: String,
gameName: String,
reminderTime: Int,
reminderType: String,
launchServerTime: Int,
serverName: String,
isWechat: Boolean,
isApp: Boolean
) {
val json = json {
KEY_EVENT to "launch_server_reminder_cancel"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"reminder_time" to reminderTime
"reminder_type" to reminderType
"launch_server_time" to launchServerTime
"server_name" to serverName
"is_wechat" to isWechat
"is_app" to isApp
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号123
* 事件IDlaunch_server_reminder_click
* 事件名称:点击开服提醒事件
* 触发时机:点击开服管理的提醒记录
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param reminderTime 设置提醒时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param status 记录状态: todo 待提醒 coming 即将开服 opened 已开服 has_new 有新服 expired 已过期
*/
@JvmStatic
fun logLaunchServerReminderClick(
gameId: String,
gameName: String,
reminderTime: Int,
status: String,
) {
val json = json {
KEY_EVENT to "launch_server_reminder_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"reminder_time" to reminderTime
"status" to status
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
}

View File

@ -15,13 +15,11 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.categoryChinese
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.install.InstallService
import com.gh.gamecenter.vpn.VpnHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
@ -37,7 +35,7 @@ object PackageInstaller {
*/
@JvmStatic
fun install(context: Context, downloadEntity: DownloadEntity?) {
downloadEntity?.let { install(context, downloadEntity, true) }
downloadEntity?.let { install(context, downloadEntity, showUnzipToast = true, ignoreAsVGame = false) }
}
/**
@ -46,16 +44,25 @@ object PackageInstaller {
* 兼容所有包安装(apk,xapk),后续可加上apks
*
* 主动点击安装如果是xapk则需要toast提示
*
* @param ignoreAsVGame 是否不需要以畅玩形式安装
*
*
*/
@JvmStatic
fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) {
fun install(context: Context,
downloadEntity: DownloadEntity,
showUnzipToast: Boolean,
ignoreAsVGame: Boolean,
) {
val pkgPath = downloadEntity.path
val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()
val isVGame = downloadEntity.getMetaExtra(Constants.SMOOTH_GAME) == "true"
val isDownloadAsVGame = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.VGAME
|| downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.DUAL_DOWNLOAD_VGAME
val currentActivity = CurrentActivityHolder.getCurrentActivity() ?: return
if (isVGame) {
if (!ignoreAsVGame && isDownloadAsVGame) {
VHelper.install(currentActivity, downloadEntity)
return
}
@ -153,6 +160,13 @@ object PackageInstaller {
*/
private fun install(context: Context, pkgPath: String) {
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU && Build.MANUFACTURER.lowercase().contains("xiaomi")) {
val foregroundServiceIntent = Intent(context, InstallService::class.java)
foregroundServiceIntent.putExtra(InstallService.KEY_SERVICE_ACTION, InstallService.START_FOREGROUND)
context.startForegroundService(foregroundServiceIntent)
}
val installIntent = getInstallIntent(context, pkgPath)
context.startActivity(installIntent)
}

View File

@ -1,13 +1,77 @@
package com.gh.common.util
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.utils.isVGameDownloadInDualDownloadMode
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.vspace.VHelper
object PackageLauncher {
/**
* 自动选择启动已安装的畅玩或本地已安装的游戏
* 仅适用于 gameEntity 只有一个 apk 的情况
*/
@JvmStatic
fun launch(
context: Context,
gameEntity: GameEntity,
location: String? = null
) {
if (gameEntity.getApk().isEmpty() || gameEntity.getApk().size > 1) {
return
}
val packageName = gameEntity.getApk().first().packageName
// 根据下载按钮类型进行进行不一样的处理
when (gameEntity.getGameDownloadButtonMode()) {
GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DOWNLOAD -> {
launchApp(context, gameEntity, packageName)
}
GameEntity.GAME_DOWNLOAD_BUTTON_MODE_VGAME -> {
VHelper.installOrLaunch(context as AppCompatActivity, gameEntity, location)
}
GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL -> {
val vGameIsInstalled = VHelper.isInstalled(packageName)
val localGameIsInstalled = PackageUtils.isInstalled(context, packageName)
when {
vGameIsInstalled && localGameIsInstalled -> {
if (gameEntity.isVGamePreferred()) {
VHelper.installOrLaunch(context as AppCompatActivity, gameEntity, location)
} else {
launchApp(context, gameEntity, packageName)
}
}
vGameIsInstalled -> {
VHelper.installOrLaunch(context as AppCompatActivity, gameEntity, location)
}
localGameIsInstalled -> {
launchApp(context, gameEntity, packageName)
}
else -> {
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity?.isVGameDownloadInDualDownloadMode() == true) {
VHelper.installOrLaunch(context as AppCompatActivity, gameEntity, location)
} else {
ToastUtils.toast("下载异常,请重新下载")
}
}
}
}
}
}
/*
* 启动应用
*/

View File

@ -41,7 +41,6 @@ import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.gh.vspace.db.VGameEntity;
import com.halo.assistant.HaloApp;
import com.lg.vspace.VirtualAppManager;
import com.lightgame.utils.Utils;
import net.dongliu.apk.parser.ApkFile;
@ -110,10 +109,12 @@ public class PackageUtils {
return !(MD5Str.equals(MD5Utils.calculateMD5(file)));
}
/*
* 判断是否可以更新只判断gh_version的大小
/**
* 判断是否可以更新
* @param gameEntity 游戏摘要实体
* @param isVGame 是否为畅玩游戏(走特殊的判断更新逻辑)
*/
public static List<GameUpdateEntity> getUpdateData(GameEntity gameEntity) {
public static List<GameUpdateEntity> getUpdateData(GameEntity gameEntity, boolean isVGame) {
List<GameUpdateEntity> updateList = new ArrayList<>();
@ -169,7 +170,7 @@ public class PackageUtils {
boolean shouldShowUpdate = apkEntity.getForce();
// 普通游戏根据本地是否有安装来确定是否 qualified畅玩游戏直接进判断
boolean isUpdateQualified =
gameEntity.isVGame() || (!TextUtils.isEmpty(versionFromRequest) && !TextUtils.isEmpty(versionFromInstalledApp));
isVGame || (!TextUtils.isEmpty(versionFromRequest) && !TextUtils.isEmpty(versionFromInstalledApp));
if (shouldShowUpdate && isUpdateQualified) {
@ -182,12 +183,11 @@ public class PackageUtils {
}
// 畅玩游戏根据 md5 是否一致确定是否需要更新
if (gameEntity.isVGame()) {
if (isVGame) {
VGameEntity vGameEntity = VHelper.getVGameSnapshot(gameEntity.getId(), apkEntity.getPackageName());
if (vGameEntity != null) {
String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(vGameEntity.getDownloadEntity(), Constants.APK_MD5);
String md5FromRequest = apkEntity.getMd5();
apkEntity.setPlatform(VHelper.PLATFORM_V);
shouldShowUpdate = md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame);
} else {
@ -219,6 +219,7 @@ public class PackageUtils {
updateEntity.setFormat(apkEntity.getFormat());
updateEntity.setSignature(apkEntity.getSignature());
updateEntity.setCategory(gameEntity.getCategory());
updateEntity.setVGameUpdate(isVGame);
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
if (gameEntity.isLandPageAddressDialog()) {
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
@ -727,6 +728,13 @@ public class PackageUtils {
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
JSONObject jsonObject = new JSONObject();
// 这里的 pm.getApplicationLabel 有极小机率会返回 null 值 (明明方法标示了返回值 nonnull
// Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
// 所以要是为空就 continue忽略掉它
if (pm.getApplicationLabel(packageInfo.applicationInfo) == null) {
continue;
}
jsonObject.put("name", pm.getApplicationLabel(packageInfo.applicationInfo).toString());
jsonObject.put("package", packageInfo.packageName);
jsonObject.put("version", packageInfo.versionName);

View File

@ -22,8 +22,8 @@ object RealNameHelper {
/**
* 弹未成年人不能下载游戏弹窗
*/
fun showRealNameUnqualifiedDialog(downloadEntity: DownloadEntity) {
val contentText = if (downloadEntity.status == DownloadStatus.done) {
fun showRealNameUnqualifiedDialog(downloadEntity: DownloadEntity?) {
val contentText = if (downloadEntity?.status == DownloadStatus.done) {
"为保护未成年身心健康成长\n" + "根据相关政策要求,该游戏不对未成年人开放"
} else {
"为保护未成年身心健康成长\n" + "根据相关政策要求,该游戏不对未成年人开放下载"
@ -45,7 +45,7 @@ object RealNameHelper {
}
)
}
if (downloadEntity.status != DownloadStatus.done) {
if (downloadEntity != null && downloadEntity.status != DownloadStatus.done) {
DownloadManager.getInstance()
.addInvisiblePendingTask(downloadEntity)
}
@ -54,22 +54,24 @@ object RealNameHelper {
/**
* 弹需要实名弹窗
*/
fun showRealNameUncertificatedDialog(downloadEntity: DownloadEntity) {
fun showRealNameUncertificatedDialog(downloadEntity: DownloadEntity?) {
// 是否强制实名
val isForced = downloadEntity.getMetaExtra("force_real_name") != "false"
val isForced = downloadEntity?.getMetaExtra("force_real_name") != "false"
NewLogUtils.logCertificationTrigger(downloadEntity.gameId, downloadEntity.name)
SensorsBridge.trackEvent(
"VerificationDialogShow",
"game_id",
downloadEntity.gameId,
"game_name",
downloadEntity.name ?: "",
"game_type",
downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: ""
)
downloadEntity?.let {
NewLogUtils.logCertificationTrigger(downloadEntity.gameId, downloadEntity.name)
SensorsBridge.trackEvent(
"VerificationDialogShow",
"game_id",
downloadEntity.gameId,
"game_name",
downloadEntity.name ?: "",
"game_type",
downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: ""
)
}
val contentText = if (downloadEntity.status == DownloadStatus.done) {
val contentText = if (downloadEntity?.status == DownloadStatus.done) {
"为保护未成年身心健康成长\n" + "根据相关政策要求,该游戏不对未成年人开放\n" + "如需完成安装,请前往实名认证"
} else {
"为保护未成年身心健康成长\n" + "根据相关政策要求,该游戏不对未成年人开放下载\n" + "如需下载,请前往实名认证"
@ -98,7 +100,7 @@ object RealNameHelper {
putExtra(EntranceConsts.KEY_IS_FORCED_TO_CERTIFICATE_BUT_WITH_BACKDOOR, !isForced)
}
)
if (downloadEntity.status == DownloadStatus.done) {
if (downloadEntity?.status == DownloadStatus.done) {
pendingInstallPkgPath = downloadEntity.path
}
NewLogUtils.logCertificationHintDialogOptionsClicked("前往实名认证")
@ -123,7 +125,7 @@ object RealNameHelper {
}
}
if (downloadEntity.status != DownloadStatus.done) {
if (downloadEntity != null && downloadEntity.status != DownloadStatus.done) {
DownloadManager.getInstance()
.addInvisiblePendingTask(downloadEntity)
}

View File

@ -23,7 +23,13 @@ object RecommendPopupHelper {
//判断是否为多版本游戏
if (gameEntity.getApk().isEmpty() || gameEntity.getApk().size > 1) return null
val downloadBtnText = GameUtils.getDownloadBtnText(HaloApp.getInstance(), gameEntity, PluginLocation.only_game)
val downloadBtnText = GameUtils.getDownloadBtnText(
context = HaloApp.getInstance(),
gameEntity = gameEntity,
isFromList = false,
fixedAsVGame = false,
pluginLocation = PluginLocation.only_game
)
val filterEntities = arrayListOf<RecommendPopupEntity>()
loop@ for (entity in popups) {

View File

@ -163,7 +163,7 @@ object ReservationHelper {
}, cancelClickCallback = {
cancelListener?.onCancel()
}, uiModificationCallback = {
it.confirmTv.setTextColor(R.color.theme_red.toColor(context))
it.confirmTv.setTextColor(R.color.secondary_red.toColor(context))
}, extraConfig = DialogHelper.Config(centerContent = true, centerTitle = true)
)
}

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