Compare commits

...

110 Commits

Author SHA1 Message Date
0de167960a fix:通用内容合集组件优化—前端部分-0620测试—客户端 https://jira.shanqu.cc/browse/GHZSCY-5821 2024-06-25 17:38:21 +08:00
4df1eac504 fix:https://jira.shanqu.cc/browse/GHZSCY-5790 通用内容合集组件优化—前端部分-0620测试—客户端 2024-06-24 15:04:12 +08:00
3b19baeb99 feat:通用内容合集组件优化—前端部分-0620测试—客户端 https://jira.shanqu.cc/browse/GHZSCY-5264 2024-06-21 17:08:34 +08:00
f8678a605b feat:通用内容合集组件优化—前端部分—客户端 https://jira.shanqu.cc/browse/GHZSCY-5294 2024-06-12 09:46:00 +08:00
5204a58a73 ci 2024-06-11 18:00:08 +08:00
569f2ed741 feat:通用内容合集组件优化—前端部分—客户端 https://jira.shanqu.cc/browse/GHZSCY-5294 2024-06-11 17:59:04 +08:00
21e7198589 Merge branch 'feat/GHZSCY-5631' into 'dev'
fix: 仅支持32位架构的设备屏蔽畅玩下载方式 https://jira.shanqu.cc/browse/GHZSCY-5631

See merge request halo/android/assistant-android!1696
2024-06-07 15:58:06 +08:00
d6c97bc215 feat: 仅支持32位架构的设备屏蔽畅玩下载方式 https://jira.shanqu.cc/browse/GHZSCY-5631
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-06-07 15:51:54 +08:00
321e9b6ee6 Merge branch 'fix/GHZSCY-5593' into 'dev'
fix: 微信账号登陆后助手后台程序异常 https://jira.shanqu.cc/browse/GHZSCY-5593

See merge request halo/android/assistant-android!1697
2024-06-07 15:49:50 +08:00
7cc3e7ec67 Merge remote-tracking branch 'refs/remotes/origin/dev' into dev 2024-06-07 15:47:53 +08:00
08dac2eb42 Merge branch 'fix/oaid_error' into 'dev'
fix: 修复因为 OAID 获取过慢导致的实名相关信息绑定失败问题

See merge request halo/android/assistant-android!1698
2024-06-07 15:46:37 +08:00
85c7746206 fix: 修复因为 OAID 获取过慢导致的实名相关信息绑定失败问题 https://jira.shanqu.cc/browse/GHZSCY-5629 2024-06-07 15:46:02 +08:00
a35700e2f7 Merge remote-tracking branch 'refs/remotes/origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java
2024-06-07 15:42:36 +08:00
6a44294338 Merge branch 'fix/GHZSCY-5390' into 'dev'
fix:【光环助手】下拉弹窗弹出时快速上滑页面时的页面显示异常问题 https://jira.shanqu.cc/browse/GHZSCY-5390

See merge request halo/android/assistant-android!1699
2024-06-07 10:31:52 +08:00
b8c275d8fc fix:【光环助手】下拉弹窗弹出时快速上滑页面时的页面显示异常问题 https://jira.shanqu.cc/browse/GHZSCY-5390 2024-06-07 10:31:52 +08:00
638bf86d1e Merge branch 'fix/GHZSCY-5418' into 'dev'
fix: 测试问题-2024/5/20-客户端(问题3) https://jira.shanqu.cc/browse/GHZSCY-5418

See merge request halo/android/assistant-android!1690
2024-06-05 17:29:34 +08:00
158c46f210 fix: 测试问题-2024/5/20-客户端(问题3) https://jira.shanqu.cc/browse/GHZSCY-5418 2024-06-05 17:29:34 +08:00
a28ef7d20b Merge branch 'feat/GHZSCY-5377' into 'dev'
feat: 【光环助手】注销账号-深色模式显示问题(增加js查询深色模式方法) https://jira.shanqu.cc/browse/GHZSCY-5377

See merge request halo/android/assistant-android!1692
2024-06-05 17:29:12 +08:00
bae20a4e7d feat: 【光环助手】注销账号-深色模式显示问题(增加js查询深色模式方法) https://jira.shanqu.cc/browse/GHZSCY-5377 2024-06-05 17:29:12 +08:00
4a2f0896bb Merge branch 'hotfix/v5.35.5-1055/crashes' into 'release'
fix: 修复 5.35.5 线上闪退

See merge request halo/android/assistant-android!1693
2024-06-05 15:00:34 +08:00
51ccc532d5 fix: 修复安装数据上报闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/365934
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-06-05 14:48:54 +08:00
1bf977f3e4 fix: 修复安利墙点赞闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/379887/
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-06-05 14:48:54 +08:00
52d160a0e0 fix: 微信账号登陆后助手后台程序异常 https://jira.shanqu.cc/browse/GHZSCY-5593
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-06-05 10:09:07 +08:00
cbba9c09b5 Merge branch 'docs/GHZSCY-5350' into 'dev'
docs: 补充 Activity 类名注释 https://jira.shanqu.cc/browse/GHZSCY-5350

See merge request halo/android/assistant-android!1689
2024-06-03 17:24:12 +08:00
3c877ada98 Merge branch 'feature-GHZS-5398' into 'dev'
fix:【光环助手】游戏详情-大家都在玩 神策埋点问题 https://jira.shanqu.cc/browse/GHZSCY-5398

See merge request halo/android/assistant-android!1683
2024-05-28 11:18:43 +08:00
9b95e01d33 fix:【光环助手】游戏详情-大家都在玩 神策埋点问题 https://jira.shanqu.cc/browse/GHZSCY-5398 2024-05-28 11:18:42 +08:00
567576fc04 Merge branch 'feat/GHZSCY-5124' into 'dev'
合并消息中心相关需求

See merge request halo/android/assistant-android!1685
2024-05-28 09:59:36 +08:00
1b7913a00e feat: 订阅&推送体系-消息中心不展示隐藏状态或已删除游戏的会话,及其消息—客户端 https://jira.shanqu.cc/browse/GHZSCY-5395 2024-05-28 09:44:22 +08:00
05e2719e1c feat: 订阅&推送体系-消息中心补全消息删除功能—客户端 https://jira.shanqu.cc/browse/GHZSCY-5124 2024-05-28 09:44:22 +08:00
8ed10c411a Merge branch 'feat/GHZS-4308' into 'dev'
feat: 更换日志上报SDK https://jira.shanqu.cc/browse/GHZSCY-4308

See merge request halo/android/assistant-android!1522
2024-05-27 10:10:41 +08:00
f9f4bb84b4 feat: 更换日志上报SDK https://jira.shanqu.cc/browse/GHZS-4308 2024-05-24 16:53:19 +08:00
44a2e616ab Merge branch 'feat/log_all_redirected_host' into 'dev'
feat: 游戏下载host上报 https://jira.shanqu.cc/browse/GHZSCY-5476

See merge request halo/android/assistant-android!1680
2024-05-24 15:54:35 +08:00
fffd3ef789 feat: 游戏下载host上报 https://jira.shanqu.cc/browse/GHZSCY-5476 2024-05-24 15:18:22 +08:00
d53782b8de Merge branch 'fix/GHZSCY-5231' into 'dev'
fix:【光环助手】轮播banner刷新时蒙层消失 https://jira.shanqu.cc/browse/GHZSCY-5231

See merge request halo/android/assistant-android!1679
2024-05-22 15:01:47 +08:00
b16c5d723b fix:【光环助手】轮播banner刷新时蒙层消失 https://jira.shanqu.cc/browse/GHZSCY-5231 2024-05-22 14:44:00 +08:00
1dfd636283 Merge branch 'feature-GHZS-5385' into 'dev'
feat: 【光环助手】QQ小游戏支付唤起问题 https://jira.shanqu.cc/browse/GHZSCY-5385

See merge request halo/android/assistant-android!1668
2024-05-22 11:02:38 +08:00
65feed01f4 feat: 【光环助手】QQ小游戏支付唤起问题 https://jira.shanqu.cc/browse/GHZSCY-5385 2024-05-22 11:02:38 +08:00
2a596bd2a0 Merge branch 'fix/vivo_crash' into 'dev'
fix: 修复在 vivo 的 Android 14  设备上点击剪贴板功能时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/277509

See merge request halo/android/assistant-android!1677
2024-05-21 11:03:28 +08:00
16c4f1016c fix: 修复在 vivo 的 Android 14 设备上点击剪贴板功能时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/277509 2024-05-20 18:19:23 +08:00
1ced82c1f6 Merge branch 'fix/GHZSCY-5372' into 'dev'
fix:【光环助手】开服表bug https://jira.shanqu.cc/browse/GHZSCY-5372

See merge request halo/android/assistant-android!1676
2024-05-20 11:43:37 +08:00
078c9204af fix:【光环助手】开服表bug https://jira.shanqu.cc/browse/GHZSCY-5372 2024-05-20 11:43:37 +08:00
68818b3409 Merge branch 'feat/GHZSCY-5080' into 'dev'
feat:【光环助手】工具新增跳转类型配置 https://jira.shanqu.cc/browse/GHZSCY-4618

See merge request halo/android/assistant-android!1675
2024-05-17 17:53:13 +08:00
7d4aa34d12 feat:【光环助手】工具新增跳转类型配置 https://jira.shanqu.cc/browse/GHZSCY-4618 2024-05-17 17:53:13 +08:00
2a27e0f467 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-05-16 16:01:28 +08:00
54ee8a9c69 chore: 版本更新至 5.35.5 2024-05-16 11:36:57 +08:00
2b44efd6b3 Merge branch 'hotfix/v5.35.4-1054/wrong_install_status' into 'release'
fix: 修复安装游戏回到光环时的安装状态更新问题

See merge request halo/android/assistant-android!1673
2024-05-16 11:32:46 +08:00
d62c8beb30 fix: 修复安装游戏回到光环时的安装状态更新问题 2024-05-16 11:22:04 +08:00
155ec08280 Merge branch 'fix/image_display_issue' into 'dev'
fix: 修复图片显示问题

See merge request halo/android/assistant-android!1672
2024-05-16 10:54:14 +08:00
d46aa81dbe chore: 版本更新至 5.35.4 2024-05-15 16:30:39 +08:00
51c0bf27cf Merge branch 'hotfix/v5.35.3-1053/wrong_update_status' into 'release'
fix: 修复使用跳转落地页下载安装的游戏更新时下载按钮的更新问题;修复安装同包名同版本不同游戏 id 的游戏时下载按钮的更新问题

See merge request halo/android/assistant-android!1670
2024-05-15 16:29:48 +08:00
43eb4c88c9 fix: 修复普通图片显示的锯齿问题 (还原为加载 View 大小的图片),移除冗余的图片加载高度入参 2024-05-15 16:21:15 +08:00
06b2d2b416 Merge branch 'hotfix/v5.35.3-1053/packagename_null_crash' into 'release'
fix: 修复部分位置跳转安装因为包名为空而产生的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/385367

See merge request halo/android/assistant-android!1671
2024-05-15 16:00:11 +08:00
af7580a6a6 fix: 修复部分位置跳转安装因为包名为空而产生的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/385367 2024-05-15 15:57:37 +08:00
1e4375ec8a fix: 修复使用跳转落地页下载安装的游戏更新时下载按钮的更新问题;修复安装同包名同版本不同游戏 id 的游戏时下载按钮的更新问题 2024-05-15 15:31:41 +08:00
195247a5c3 fix: 修复重登录时,用户头像不能正常显示的问题 2024-05-14 18:10:58 +08:00
dd65bc8bc2 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-05-14 17:38:18 +08:00
196e719358 chore: 版本更新至 5.35.3 2024-05-14 17:13:10 +08:00
b1c267b179 Merge branch 'fix/rank_loading_issue' into 'dev'
fix: 修复进入排行榜页面时全量加载所有页面导致页面卡顿的问题

See merge request halo/android/assistant-android!1669
2024-05-14 16:18:34 +08:00
a2679c8dbd fix: 修复进入排行榜页面时全量加载所有页面导致页面卡顿的问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-14 16:14:36 +08:00
c9e1816be0 Merge branch 'feat/remove_useless_legacy_code' into 'dev'
feat: 移除部分冗余的历史代码,关闭部分意义不大的日志输出(有需要时再手动开启)

See merge request halo/android/assistant-android!1667
2024-05-14 15:07:00 +08:00
a1f0455d5a feat: 移除部分冗余的历史代码,关闭部分意义不大的日志输出(有需要时再手动开启)
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-14 15:02:00 +08:00
5b3f4b6104 Merge branch 'chen/202405/GHZSCY-5378' into 'dev'
fix:【光环助手】游戏专题点击神策埋点问题 https://jira.shanqu.cc/browse/GHZSCY-5378

See merge request halo/android/assistant-android!1666
2024-05-14 11:02:42 +08:00
fe4e9d9d3b fix:【光环助手】游戏专题点击神策埋点问题 https://jira.shanqu.cc/browse/GHZSCY-5378 2024-05-14 10:58:57 +08:00
dd051b4d13 Merge branch 'hotfix/v5.35.2-1052/logout_crash' into 'release'
fix: 修复退出登录出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/385028/?project=22

See merge request halo/android/assistant-android!1665
2024-05-14 09:45:26 +08:00
e7f756555c fix: 修复退出登录出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/385028/?project=22 2024-05-14 09:39:57 +08:00
9488837e9e Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2024-05-10 14:14:17 +08:00
b8c4f1403b chore: 版本更新至 5.35.2 2024-05-10 11:18:37 +08:00
b88698c2a3 Merge branch 'hotfix/v5.35.1-1051/crashes' into 'release'
fix: 修复 5.35.1 线上闪退问题

See merge request halo/android/assistant-android!1662
2024-05-10 11:17:13 +08:00
c897d5ad0f fix: 修复多线程更新已安装列表时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/384726 https://sentry.shanqu.cc/organizations/lightgame/issues/384682
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-10 10:53:41 +08:00
037f453a75 fix: 修复小米设备安装 APKS 格式 XAPK 包时候的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/384710
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-10 10:51:38 +08:00
ad3a3c1341 Merge branch 'hotfix/v5.35.1-1051/hot_launch_splash_ad' into 'release'
fix: 修复移除第三方广告SDK后错误展示热启动广告的问题

See merge request halo/android/assistant-android!1661
2024-05-09 17:45:06 +08:00
ba320f7740 fix: 修复移除第三方广告SDK后错误展示热启动广告的问题 2024-05-09 17:19:33 +08:00
f3dbc0b779 Merge branch 'hotfix/v5.35.1-1051/update_notify_issue' into 'release'
fix: 修复更新应用时遗漏模拟卸载监听导致的状态变更异常问题

See merge request halo/android/assistant-android!1660
2024-05-09 15:40:05 +08:00
0c518ac40e fix: 修复更新应用时遗漏模拟卸载监听导致的状态变更异常问题 2024-05-09 15:37:45 +08:00
ccc0140bba docs: 补充 Activity 类名注释 https://jira.shanqu.cc/browse/GHZSCY-5350 2024-05-09 15:12:01 +08:00
bf57118900 Merge branch 'hotfix/v5.35.1-1051/init_crash' into 'release'
fix: 修复部分 downloadEntity versionName 而导致的启动闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/384612

See merge request halo/android/assistant-android!1659
2024-05-09 13:42:04 +08:00
b80a14f2b1 fix: 修复部分 downloadEntity versionName 而导致的启动闪退问题
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-09 11:48:43 +08:00
1450064640 chore: 版本更新至 5.35.1 2024-05-09 10:26:59 +08:00
90e19d5099 Merge branch 'feat/GHZSCY-5342' into 'release'
feat: 关于移除监听广播后的相关优化 https://jira.shanqu.cc/browse/GHZSCY-5342

See merge request halo/android/assistant-android!1657
2024-05-09 10:25:59 +08:00
383124dc36 feat: 关于移除监听广播后的相关优化(处理错误注释) https://jira.shanqu.cc/browse/GHZSCY-5342
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-09 10:21:28 +08:00
6d6ce2613a feat: 关于移除监听广播后的相关优化 https://jira.shanqu.cc/browse/GHZSCY-5342 2024-05-09 09:21:34 +08:00
8569264b82 feat: 合规调整-已安装列表权限-2024/4/22 https://jira.shanqu.cc/browse/GHZSCY-5250 2024-05-09 09:21:34 +08:00
59667abf09 feat: 合规调整-2024/4/30-后台静默监听行为 https://jira.shanqu.cc/browse/GHZSCY-5331 2024-05-09 09:21:34 +08:00
5201637326 Merge branch 'docs/GHZSCY-5350' into 'dev'
docs: 补充 Activity 类名注释 https://jira.shanqu.cc/browse/GHZSCY-5350

See merge request halo/android/assistant-android!1656
2024-05-08 17:04:41 +08:00
417c41c8a0 docs: 补充 Activity 类名注释 https://jira.shanqu.cc/browse/GHZSCY-5350 2024-05-08 16:59:53 +08:00
b651ef8617 Merge branch 'hotfix/v5.35.0-1050/GHZSCY-5329' into 'release'
fix: 优化 gid 的获取逻辑,避免部分接口请求时因为 gid 为空供导致异常 https://jira.shanqu.cc/browse/GHZSCY-5329

See merge request halo/android/assistant-android!1654
2024-05-08 11:14:46 +08:00
af67894d4e Merge branch 'fix/GHZSCY-5339' into 'dev'
fix: 游戏专题-游戏替换问题 https://jira.shanqu.cc/browse/GHZSCY-5329

See merge request halo/android/assistant-android!1655
2024-05-08 11:10:23 +08:00
76e17eddd7 fix: 优化 gid 的获取逻辑,避免部分接口请求时因为 gid 为空供导致异常 https://jira.shanqu.cc/browse/GHZSCY-5329 2024-05-08 10:03:02 +08:00
f8c9c41eb0 Merge branch 'feat/GHZSCY-5281' into 'dev'
feat: 搜索业务-游戏搜索结果页面补充神策埋点—客户端 https://jira.shanqu.cc/browse/GHZSCY-5281

See merge request halo/android/assistant-android!1653
2024-05-07 18:01:46 +08:00
40ac173389 feat: 搜索业务-游戏搜索结果页面补充神策埋点—客户端 https://jira.shanqu.cc/browse/GHZSCY-5281 2024-05-07 18:01:46 +08:00
c6bc7ca6cc fix: 游戏专题-游戏替换问题 https://jira.shanqu.cc/browse/GHZSCY-5329
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-07 11:51:50 +08:00
f01e08aec9 Merge branch 'hotfix/v5.35.0-1050/crashes' into 'release'
fix: 修复线上闪退问题

See merge request halo/android/assistant-android!1652
2024-05-07 11:02:11 +08:00
faddf5d7b6 fix: 收到卸载广播时移除调用 MutableCollections.removeAll() 方法引起的数组越界异常 (MutableCollections.removeAll()线程不安全) https://sentry.shanqu.cc/organizations/lightgame/issues/242447
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-07 10:38:55 +08:00
81cf2f0ddc fix: 部分镜像游戏开关切换时由于不同接口更新不及时导致的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/378659
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-07 09:56:29 +08:00
198561d15a fix: 收到卸载广播时移除调用 MutableCollections.removeAll() 方法引起的数组越界异常 (MutableCollections.removeAll()线程不安全) https://sentry.shanqu.cc/organizations/lightgame/issues/242447
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-07 09:42:44 +08:00
1e721b699c fix: 修复存储空间不足时进行数据库删除操作引起的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/381076
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-05-06 17:58:50 +08:00
8f48dfd347 Merge branch 'fix-community_browsing_duration_error' into 'release'
fix: 使用ViewPager2导致CommunityBrowsingDuration埋点上报异常的问题

See merge request halo/android/assistant-android!1651
2024-04-30 15:04:50 +08:00
bc811a2882 fix: 使用ViewPager2导致CommunityBrowsingDuration埋点上报异常的问题 2024-04-30 14:56:42 +08:00
bdccbc4c28 chore: 版本更新至 5.36.0 2024-04-29 14:51:06 +08:00
bfd986fdfd Merge remote-tracking branch 'origin/release' into dev 2024-04-28 10:59:46 +08:00
a2bd5e01e0 Merge branch 'hotfix/v5.35.0-1050/jpush_clear_badge' into 'release'
fix: 修复极光推送清除角标提前获取信息的问题

See merge request halo/android/assistant-android!1649
2024-04-28 10:43:11 +08:00
844d227f19 fix: 修复极光推送清除角标提前获取信息的问题 2024-04-28 10:26:20 +08:00
8b1f92e9c4 Merge branch 'chen/202404/GHZSCY-5293' into 'dev'
fix:【光环助手】新游开测右上角显示 https://jira.shanqu.cc/browse/GHZSCY-5293

See merge request halo/android/assistant-android!1648
2024-04-28 10:12:25 +08:00
f5834d440b fix:【光环助手】新游开测右上角显示 https://jira.shanqu.cc/browse/GHZSCY-5293 2024-04-28 10:09:20 +08:00
f982bf6478 Merge branch 'hotfix/v5.35.0-1050/disable_jpush_auto_init' into 'release'
fix: 移除极光推送通过 ContentProvider 自动初始化的问题

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

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

See merge request halo/android/assistant-android!1646
2024-04-25 10:36:50 +08:00
6beb060e63 fix: 【光环助手】开屏广告神策埋点数据上报问题 https://jira.shanqu.cc/browse/GHZSCY-5261 2024-04-25 10:31:22 +08:00
d11ccba0b7 feat: 穿山甲广告SDK更换新版本与信息流广告优化 https://jira.shanqu.cc/browse/GHZSCY-5243
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-04-22 16:29:42 +08:00
306 changed files with 5409 additions and 1764 deletions

View File

@ -72,6 +72,7 @@ android_build:
only:
- dev
- release
- feat/GHZSCY-5294
# 代码检查
sonarqube_analysis:
@ -103,6 +104,7 @@ sonarqube_analysis:
only:
- dev
- release
- feat/GHZSCY-5294
## 发送简易检测结果报告
send_sonar_report:
@ -121,6 +123,7 @@ send_sonar_report:
only:
- dev
- release
- feat/GHZSCY-5294
oss-upload&send-email:
tags:
@ -152,4 +155,5 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail-jira-comment.py
only:
- dev
- release
- release
- feat/GHZSCY-5294

View File

@ -126,6 +126,10 @@ android {
}
}
packagingOptions {
exclude 'META-INF/gradle/incremental.annotation.processors'
}
buildTypes {
debug {
debuggable true
@ -357,7 +361,9 @@ dependencies {
implementation "com.lg:easyfloat:${easyFloat}"
implementation "com.lg:apksig:${apksig}"
implementation ("com.lg:apksig:${apksig}") {
exclude group: 'com.google.protobuf'
}
implementation "com.lg:gid:${gid}"
@ -401,7 +407,7 @@ dependencies {
implementation(project(':feature:pkg'))
implementation(project(':feature:oaid'))
implementation(project(':feature:floating-window'))
implementation(project(':feature:csj_ad'))
// implementation(project(':feature:csj_ad'))
// implementation(project(':feature:beizi_startup_ad'))
implementation(project(':feature:xapk-installer'))
implementation(project(':feature:qq_game')) {
@ -409,12 +415,13 @@ dependencies {
}
internalImplementation(project(':module_internal_test'))
// 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用阿里云推送
def pushProject = findProperty('BUILD_PUSH_TYPE') == 'jg'
? project(':feature:jg_push') : project(':feature:acloud_push')
implementation(pushProject) {
exclude group: 'androidx.swiperefreshlayout'
}
// def pushProperty = findProperty('BUILD_PUSH_TYPE')
// // 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用极光推送
// def pushProject = (pushProperty == null || pushProperty == 'jg')
// ? project(':feature:jg_push') : project(':feature:acloud_push')
// implementation(pushProject) {
// exclude group: 'androidx.swiperefreshlayout'
// }
}
File propFile = file('sign.properties')
@ -568,7 +575,9 @@ andResGuard {
"R.id.cardMask",
"R.id.cardGradientMask",
"R.id.gameIconIv",
"R.id.titleContainer"
"R.id.titleContainer",
"R.id.v_bubble_background",
"R.id.tv_bubble"
]
compressFilePattern = [
"*.png",

View File

@ -191,10 +191,11 @@ object AdDelegateHelper {
}
/**
* 热启动是否需要显示开屏广告
* 热启动是否需要显示开屏广告(目前只展示第三方广告)
*/
private fun shouldShowStartUpAdWhenHotLaunch() =
mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK && mSplashAd?.hotStartThirdPartyAd != null
private fun shouldShowStartUpAdWhenHotLaunch() = (mCsjAdImpl != null || mBeiziAdImpl != null)
&& mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
&& mSplashAd?.hotStartThirdPartyAd != null
/**
* 是否需要显示下载管理广告

View File

@ -45,6 +45,14 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
isFromBackgroundToForeground = false
}
if (activityCount == 1) {
// 清除桌面角标
if (activity !is SplashScreenActivity && activity !is AuthorizationActivity) {
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
}
}
override fun onActivityResumed(activity: Activity) {
@ -84,10 +92,6 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
XapkInstaller.updateCurrentInstallStatus()
// 清除桌面角标
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
override fun onActivityPaused(activity: Activity) {

View File

@ -34,7 +34,10 @@ import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.SensorsEvent
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
@ -69,7 +72,7 @@ class DefaultJsApi(
private var mFragment: Fragment? = null,
private var mBbsId: String? = "",
private var mOriginUrl: String? = "",
private val mForumName: String? = ""
private val mForumName: String? = "",
) {
companion object {
@ -89,6 +92,11 @@ class DefaultJsApi(
}
}
@JavascriptInterface
fun isEnableForceDark(msg: Any): Boolean {
return DarkModeUtils.isWebViewForceDarkEnabled
}
@JavascriptInterface
fun isGhzs(msg: Any): String {
return "true"

View File

@ -1,6 +1,7 @@
package com.gh.common.constant;
import android.annotation.SuppressLint;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
@ -28,6 +29,7 @@ import com.gh.gamecenter.entity.VSetting;
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.receiver.PackageChangeBroadcastReceiver;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
@ -94,8 +96,7 @@ public class Config {
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
// 加载完设置后刷新下
PackageHelper.initList();
PackageHelper.refreshList();
}
@Nullable
@ -332,8 +333,31 @@ public class Config {
if (mNewApiSettingsEntity.getGameShieldContents() != null) {
ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
}
// 更新安装列表是否开启的配置
// if (mNewApiSettingsEntity.getInstalledComplianceSwitch() != null) {
// PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(mNewApiSettingsEntity.getInstalledComplianceSwitch());
// } else {
// PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(false);
// }
// 更新包名监听是否开启
if (mNewApiSettingsEntity.isPackageObserveEnable()) {
observePackageChange(mNewApiSettingsEntity.getPackageObserveActions());
}
}
});
}
}
public static void observePackageChange(NewApiSettingsEntity.PackageObserveActions packageObserveActions) {
PackageChangeBroadcastReceiver receiver = new PackageChangeBroadcastReceiver(packageObserveActions);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(packageObserveActions.getAdd());
intentFilter.addAction(packageObserveActions.getRem());
intentFilter.addAction(packageObserveActions.getRep());
intentFilter.addDataScheme("package");
HaloApp.getInstance().registerReceiver(receiver, intentFilter);
}
}

View File

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

View File

@ -1,13 +1,13 @@
package com.gh.common.exposure
import com.aliyun.sls.android.producer.Log
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.loghub.LoghubHelper
import com.gh.gamecenter.common.loghub.TLogHubHelper
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.lightgame.utils.Utils
import com.volcengine.model.tls.LogItem
/**
* A handful tool for committing logs to aliyun loghub.
@ -78,19 +78,20 @@ object ExposureManager {
private fun uploadExposures(eventSet: HashSet<ExposureEvent>, forced: Boolean) {
eventSet.forEach {
LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced)
TLogHubHelper.sendLog(buildLog(it), LOG_STORE)
// LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced)
// it.recycle()
}
}
private fun buildLog(event: ExposureEvent) = Log().apply {
putContent("id", event.id)
putContent("payload", event.payload.toJson())
putContent("event", event.event.toString())
putContent("source", eliminateMultipleBrackets(event.source.toJson()))
putContent("meta", event.meta.toJson())
putContent("real_millisecond", event.timeInMillisecond.toString())
putContent(
private fun buildLog(event: ExposureEvent) = LogItem(System.currentTimeMillis()).apply {
addContent("__id", event.id)
addContent("payload", event.payload.toJson())
addContent("event", event.event.toString())
addContent("source", eliminateMultipleBrackets(event.source.toJson()))
addContent("meta", event.meta.toJson())
addContent("real_millisecond", event.timeInMillisecond.toString())
addContent(
"e-traces", if (event.eTrace != null) {
eliminateMultipleBrackets(event.eTrace?.toJson() ?: "")
} else ""

View File

@ -9,10 +9,12 @@ import androidx.fragment.app.FragmentActivity
import com.gh.common.iinterface.ISuperiorChain
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.DialogEntity
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
@ -42,12 +44,13 @@ object GlobalPriorityChainHelper : ISuperiorChain {
return activity is FragmentActivity
&& !activity.isFinishing
&& activity !is SplashScreenActivity
&& activity !is SplashAdActivity
}
/**
* 预启动所有的优先级弹窗管理链
*/
fun preStart() {
fun preStart(withSpecialDelay: Boolean) {
val launchRedirectHandler = LaunchRedirectHandler(-101)
val updateDialogHandler = UpdateDialogHandler(-100)
val privacyPolicyDialogHandler = PrivacyPolicyDialogHandler(-99)
@ -64,8 +67,13 @@ object GlobalPriorityChainHelper : ISuperiorChain {
launchRedirectHandler.doPreProcess()
updateDialogHandler.doPreProcess()
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
// 首次启动延迟 300ms保证请求首次启动时已经获取到了 GID 、 OAID 等标记
val requestDelay = if (withSpecialDelay) 300L else 0L
AppExecutor.uiExecutor.executeWithDelay({
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
}, requestDelay)
}
/**
@ -123,6 +131,17 @@ object GlobalPriorityChainHelper : ISuperiorChain {
mainChain.resume()
}
/**
* 添加新的 handler 到优先级弹窗管理链 (插队!)
*/
fun queueNewHandler(handler: PriorityChainHandler) {
if (mainChain.isHandlerQueueEmpty()) {
observeLifecycle()
}
mainChain.addHandler(handler)
}
/**
* 请求首页启动弹窗相关的数据并执行相关 handler 的 preProcess
*/

View File

@ -0,0 +1,28 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.common.base.GlobalActivityManager
class RequestInstalledListPermissionHandler : PriorityChainHandler(-1000) {
init {
updateStatus(STATUS_VALID)
}
override fun onProcess(): Boolean {
val currentActivity = GlobalActivityManager.currentActivity ?: return false
if (currentActivity !is FragmentActivity) return false
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(
activity = currentActivity,
ignorePermanentlyDenied = true
) {
processNext()
}
return true
}
}

View File

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

@ -3,6 +3,7 @@ package com.gh.common.provider
import android.content.Context
import android.content.pm.PackageInfo
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
@ -23,7 +24,7 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
}
override fun getInstalledPackages(context: Context, flag: Int): List<PackageInfo> {
return PackageUtils.getInstalledPackages(context, flag)
return PackageHelper.getInstalledPackages(context, flag)
}
override fun getApkSignatureByPackageName(context: Context, packageName: String): Array<String> {
@ -38,6 +39,10 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
return PackageUtils.isSignedByGh(context, packageName)
}
override fun isInstalledWithLauncherIcon(context: Context, packageName: String): Boolean {
return PackageUtils.isInstalled(context, packageName)
}
override fun getInstalledTime(context: Context, packageName: String): Long {
return PackageUtils.getInstalledTime(context, packageName)
}

View File

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

View File

@ -1,17 +1,14 @@
package com.gh.common.util;
import android.content.Context;
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;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadEntity;
import java.util.HashMap;
@ -32,7 +29,7 @@ public class DataCollectionUtils {
map.put("type", android.os.Build.MODEL);
map.put("system", android.os.Build.VERSION.SDK_INT + "=" + android.os.Build.VERSION.RELEASE);
// WIFI实时
DataCollectionManager.onEvent(context, "error", map, NetworkUtils.isWifiConnected(context));
DataCollectionManager.onEvent(context, "error", map, true);
}
// 上传下载数据(开始、完成)

View File

@ -14,12 +14,10 @@ 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.core.AppExecutor;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.login.entity.IdCardEntity;
@ -32,8 +30,6 @@ import com.halo.assistant.HaloApp;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import io.reactivex.schedulers.Schedulers;
import io.sentry.Sentry;
import io.sentry.android.core.SentryAndroid;
@ -108,45 +104,51 @@ public class DataUtils {
}
public static void getGid() {
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
@Override
public void onSuccess(String gid) {
Utils.log("Gid", gid);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
String savedGid = SPUtils.getString(Constants.GID);
if (!TextUtils.isEmpty(savedGid)) {
HaloApp.getInstance().setGid(savedGid);
onGidReceived(savedGid);
} else {
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
@Override
public void onSuccess(String gid) {
Utils.log("Gid", gid);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
String savedGid = SPUtils.getString(Constants.GID);
if (!TextUtils.isEmpty(savedGid)) {
gid = savedGid;
} else {
SPUtils.setString(Constants.GID, gid);
onGidReceived(gid);
}
HaloApp.getInstance().setGid(gid);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
getDeviceCertification(gid);
// 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
MetaUtil.INSTANCE.refreshMeta();
ContentValues values = new ContentValues();
values.put(GhContentProvider.KEY_GID, gid);
values.put(GhContentProvider.KEY_ANDROID_ID, MetaUtil.getBase64EncodedAndroidId());
try {
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/device"), values);
} catch (Exception exception) {
SentryHelper.INSTANCE.onEvent("DEVICE_INSERT_ERROR", "exception_digest", exception.getLocalizedMessage());
exception.printStackTrace();
@Override
public void onFailure(String s) {
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
}
}
});
}
}
@Override
public void onFailure(String s) {
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
private static void onGidReceived(String gid) {
HaloApp.getInstance().setGid(gid);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
getDeviceCertification(gid);
// 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
MetaUtil.INSTANCE.refreshMeta();
AppExecutor.getIoExecutor().execute(() -> {
ContentValues values = new ContentValues();
values.put(GhContentProvider.KEY_GID, gid);
values.put(GhContentProvider.KEY_ANDROID_ID, MetaUtil.getBase64EncodedAndroidId());
try {
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/device"), values);
} catch (Exception exception) {
SentryHelper.INSTANCE.onEvent("DEVICE_INSERT_ERROR", "exception_digest", exception.getLocalizedMessage());
exception.printStackTrace();
}
});
}

View File

@ -1988,7 +1988,7 @@ object DirectUtils {
val qGameProvider = ARouter
.getInstance()
.build(RouteConsts.provider.qGame)
.navigation() as IQGameProvider<*>
.navigation() as IQGameProvider
qGameProvider.setLoginInfo(activity, userId, userName, userToken)
qGameProvider.launchGame(activity, qqGameId) { _, _ ->
RetrofitManager

View File

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

View File

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

View File

@ -0,0 +1,161 @@
package com.gh.common.util
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.gh.download.DownloadManager
import com.gh.download.PackageObserver
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
object PackageChangeHelper : DefaultLifecycleObserver {
private const val TAG = "PackageChangeHelper"
private const val INSTALL_PENDING = 1
private const val UNINSTALL_PENDING = 2
private const val UPDATE_PENDING = 3
// <包名pending 类型,应用版本> Triple
private var pendingPackagePair: Triple<String, Int, String>? = null
private var pendingGhId: String ? = null
/**
* 添加一个等待中,待确定是否已成功安装的应用
*/
fun addInstallPendingPackage(packageName: String) {
val installData = PackagesManager.getInstalledData(packageName)
if (installData == null) {
Utils.log(TAG, "添加了: $packageName 包名等待安装成功")
pendingPackagePair = Triple(packageName, INSTALL_PENDING, "")
} else {
Utils.log(TAG, "添加了: $packageName 包名等待安装更新成功")
val ghId = PackageUtils.getGhId(packageName)
// 记录光环插件相关信息,用于安装成功后的处理
if (ghId != null) {
pendingGhId = ghId.toString()
}
pendingPackagePair = Triple(packageName, UPDATE_PENDING, installData.version)
}
}
/**
* 添加一个等待中,待确定是否已成功卸载的应用
*/
fun addUninstallPendingPackage(packageName: String) {
Utils.log(TAG, "添加了: $packageName 包名等待卸载成功")
pendingPackagePair = Triple(packageName, UNINSTALL_PENDING, "")
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
if (pendingPackagePair != null) {
val packageName = pendingPackagePair?.first ?: return
val isInstallPending = pendingPackagePair?.second == INSTALL_PENDING
val isUninstallPending = pendingPackagePair?.second == UNINSTALL_PENDING
val isUpdatePending = pendingPackagePair?.second == UPDATE_PENDING
val pendingVersion = pendingPackagePair?.third ?: ""
val installedVersionName = PackageUtils.getVersionNameByPackageName(packageName)
val isInstalled = installedVersionName != null
if (isInstallPending && isInstalled) {
pendingPackagePair = null
pendingGhId = null
PackageRepository.addInstalledGame(packageName)
performInstallSuccessAction(packageName)
} else if (isUninstallPending && !isInstalled) {
pendingPackagePair = null
pendingGhId = null
performUninstallSuccessAction(packageName)
} else if (isUpdatePending) {
val isUpdateValid = if (installedVersionName != pendingVersion) {
true
} else {
!pendingGhId.isNullOrEmpty() && pendingGhId != PackageUtils.getGhId(packageName).toString()
}
pendingPackagePair = null
pendingGhId = null
if (isUpdateValid) {
performUninstallSuccessAction(packageName)
performInstallSuccessAction(packageName)
}
}
}
}
fun addInstall(packageName: String) {
performInstallSuccessAction(packageName)
}
fun addUpdate(packageName: String) {
performUninstallSuccessAction(packageName)
performInstallSuccessAction(packageName)
}
/**
* 对应包名安装成功后的操作,继承至 PackageChangeBroadcastObserver
*/
private fun performInstallSuccessAction(packageName: String, withLog: Boolean = true) {
Utils.log(TAG, "安装了: $packageName 包名的程序")
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)
val gameId = if (downloadEntity != null && downloadEntity.gameId != null) downloadEntity.gameId else ""
val gameName = if (downloadEntity != null && downloadEntity.name != null) downloadEntity.name else ""
if (withLog) {
NewFlatLogUtils.logGameInstallComplete(gameId, gameName)
SensorsBridge.trackInstallGameFinish(gameId, gameName)
}
InstallUtils.getInstance().removeInstall(packageName)
PackageHelper.refreshLocalPackageList()
val versionName = PackageUtils.getVersionNameByPackageName(packageName)
val installEb = EBPackage(EBPackage.TYPE_INSTALLED, packageName, versionName)
PackageObserver.onPackageChanged(installEb)
EventBus.getDefault().post(installEb)
}
fun addUninstall(packageName: String) {
performUninstallSuccessAction(packageName)
}
/**
* 对应包名卸载成功后的操作,继承至 PackageChangeBroadcastObserver
*/
private fun performUninstallSuccessAction(packageName: String, withLog: Boolean = true) {
Utils.log(TAG, "卸载了: $packageName 包名的程序")
val install = PackagesManager.getInstalledData(packageName)
val gameId = if (install?.id != null) install.id else ""
val gameName = if (install?.name != null) install.name else ""
if (withLog) {
NewFlatLogUtils.logGameUninstallComplete(gameId!!, gameName!!)
SensorsBridge.trackUnloadGameFinish(gameId, gameName)
}
InstallUtils.getInstance().removeUninstall(packageName)
PackageHelper.refreshLocalPackageList()
val uninstallEb = EBPackage(EBPackage.TYPE_UNINSTALLED, packageName, "")
PackageObserver.onPackageChanged(uninstallEb)
EventBus.getDefault().post(uninstallEb)
}
}

View File

@ -1,24 +1,81 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.os.Build
import android.provider.Settings
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.constant.Config
import com.gh.common.prioritychain.GlobalPriorityChainHelper
import com.gh.common.prioritychain.RequestInstalledListPermissionHandler
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.common.utils.PermissionHelper.isGetInstalledListPermissionDisabled
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.WhitePackageListEntity
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
object PackageHelper {
private const val TAG = "PackageHelper"
private const val SP_GET_INSTALLED_API_AGREED = "get_installed_api_agreed"
private const val UNKNOWN = -1
private const val UNSUPPORTED = 0
private const val SUPPORTED = 1
private const val ENABLED = 2
private const val DISABLED = 3
private var lastInstalledPackageListTime = 0L
private var cachedInstalledPackagesList: List<PackageInfo> = arrayListOf()
private var isGetInstalledPackagesApiAgreed = true // 用户是否已经同意使用已安装应用列表 API
private var isGetInstalledPackagesApiAgreedRequired = DISABLED // 需要用户手动授权才获取已安装应用列表的功能的开关
private var isGetInstalledPackagesPermissionSupported = UNKNOWN // 设备是否支持禁用获取已安装应用列表
// 评论黑名单包名列表,避免用户安装了 Xposed Installer 这样的工具,也能在包含该安装包的游戏详情页评论
var commentPackageNameBlackList = arrayListOf<String>()
private var _commentPackageNameBlackList = arrayListOf<String>()
val commentPackageNameBlackList: ArrayList<String> = _commentPackageNameBlackList
// 关闭下载的包列表
var downloadPackageNameBlackList = arrayListOf<String>()
private var _downloadPackageNameBlackList = arrayListOf<String>()
val downloadPackageNameBlackList: ArrayList<String> = _downloadPackageNameBlackList
// 本地已安装的包去掉关闭下载的包后的列表
var validLocalPackageNameSet = hashSetOf<String>()
private var _validLocalPackageNameSet = hashSetOf<String>()
val validLocalPackageNameSet: HashSet<String> = _validLocalPackageNameSet
// 游戏包名匹配列表
var relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
private var _relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
val relatedPackageList: ArrayList<SettingsEntity.GameWithPackages> = _relatedPackageList
// 接口控制的已安装应用列表获取开关状态 (UI 显示)
private var _installedPackageApiSwitchStatusLiveData = MutableLiveData<Boolean>()
val installedPackageApiSwitchStatusLiveData: LiveData<Boolean> = _installedPackageApiSwitchStatusLiveData
// 本地已安装包的列表
var localPackageNameSet = hashSetOf<String>()
@ -31,6 +88,22 @@ object PackageHelper {
}
}
/**
* 获取已安装的白名单列表(为了在没有已安装应用列表获取能力的时候也能正常判断更新、插件化)
*/
@SuppressLint("CheckResult")
fun getInstalledWhiteList() {
RetrofitManager.getInstance().newApi.installWhitelist
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<WhitePackageListEntity>() {
override fun onSuccess(data: WhitePackageListEntity) {
data.data?.let {
addInstalledButMissingPackages(it)
}
}
})
}
@JvmStatic
fun refreshLocalPackageList() {
localPackageNameSet = getAllPackageName(HaloApp.getInstance().application)
@ -38,33 +111,26 @@ object PackageHelper {
}
@JvmStatic
fun initList() {
Config.getSettings()?.gameCommentBlackList?.let {
commentPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList?.let {
downloadPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gamePackageMatch?.let {
relatedPackageList = ArrayList(it)
}
fun refreshList() {
Config.getSettings()?.gameCommentBlackList?.let { _commentPackageNameBlackList = ArrayList(it) }
Config.getSettings()?.gameDownloadBlackList?.let { _downloadPackageNameBlackList = ArrayList(it) }
Config.getSettings()?.gamePackageMatch?.let { _relatedPackageList = ArrayList(it) }
Config.getSettings()?.gameDownloadBlackList
updateValidPackageNameList()
}
private fun updateValidPackageNameList() {
validLocalPackageNameSet =
_validLocalPackageNameSet =
localPackageNameSet.filterNot { p -> downloadPackageNameBlackList.contains(p) }.toHashSet()
}
/*
/**
* 获取所有已安装的软件的包名、版本(非系统应用)
*/
private fun getAllPackageName(context: Context): HashSet<String> {
val set = HashSet<String>()
return try {
val packageInfos = PackageUtils.getInstalledPackages(context, 0)
val packageInfos = getInstalledPackages(context, 0)
for (packageInfo in packageInfos) {
if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
if (context.packageName != packageInfo.packageName) {
@ -79,4 +145,357 @@ object PackageHelper {
}
}
/**
* 弃用已安装列表缓存
*/
fun dumpInstalledListCache() {
lastInstalledPackageListTime = 0
}
/**
* 在超时后,若后台没有开启获取已安装应用列表的功能,默认以接口不控制的方式获取已安装应用列表
*/
fun fallbackInstalledPackageApiSwitchAfterTimeout(timeout: Long) {
CoroutineScope(SupervisorJob()).launch {
delay(timeout)
if (isGetInstalledPackagesApiAgreedRequired == UNKNOWN) {
Utils.log(TAG, "后台没有开启获取已安装应用列表的功能,超时后默认以接口不控制的方式获取已安装应用列表")
updateIsGetInstalledPackagesApiAgreedRequired(false)
}
}
}
/**
* 更新已安装应用列表获取开关状态
*/
fun updateIsGetInstalledPackagesApiAgreedRequired(isEnabled: Boolean) {
// 若状态不为 unknown 或者用户已经同意使用了,无需再更新
if (isGetInstalledPackagesApiAgreedRequired != UNKNOWN || isGetInstalledPackagesApiAgreed()) {
Utils.log(TAG, "installedPackageApiSwitchStatus 不为 UNKNOWN无需再更新")
return
}
if (isEnabled) {
getInstalledWhiteList()
_installedPackageApiSwitchStatusLiveData.postValue(true)
isGetInstalledPackagesApiAgreedRequired = ENABLED
} else {
isGetInstalledPackagesApiAgreedRequired = DISABLED
if (isSupportGetInstalledAppsPermission(HaloApp.getInstance())) {
GlobalPriorityChainHelper.queueNewHandler(RequestInstalledListPermissionHandler())
} else {
agreeOnGetInstalledPackagesApi()
}
}
}
/**
* 用户是否已经允许了调用获取已安装应用列表接口
* 优先用内存的值,没有再从 SP 中获取并更新
*/
fun isGetInstalledPackagesApiAgreed(): Boolean {
return isGetInstalledPackagesApiAgreed
|| (SPUtils.getBoolean(SP_GET_INSTALLED_API_AGREED).also { isGetInstalledPackagesApiAgreed = it })
}
fun isGetInstalledPackagesApiAgreedRequired(): Boolean {
return isGetInstalledPackagesApiAgreedRequired == ENABLED
}
/**
* 同意使用已安装应用列表 API
*/
private fun agreeOnGetInstalledPackagesApi() {
isGetInstalledPackagesApiAgreed = true
SPUtils.setBoolean(SP_GET_INSTALLED_API_AGREED, true)
_installedPackageApiSwitchStatusLiveData.postValue(false)
}
/**
* 获取已安装应用列表
*/
fun getInstalledPackages(context: Context?, flags: Int): List<PackageInfo> {
Utils.log(TAG, "即将获取已安装应用列表")
// 用户未同意使用已安装应用列表 API返回空列表
if (!isGetInstalledPackagesApiAgreed()) {
Utils.log(TAG, "用户未同意使用已安装应用列表 API返回空列表")
return cachedInstalledPackagesList
}
// 简单 debounce 过于频繁的获取已安装应用列表调用
if (System.currentTimeMillis() - lastInstalledPackageListTime < 3000 && cachedInstalledPackagesList.isNotEmpty()) {
Utils.log(TAG, "使用了缓存的已安装应用列表")
return cachedInstalledPackagesList
}
var shouldGetNewInstalledPackagedList = false
// 当前设备是否支持限制获取已安装应用列表的功能
if (isSupportGetInstalledAppsPermission(context!!)) {
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能")
// 当前设备是否支持禁用了获取已安装应用列表
if (!isGetInstalledListPermissionDisabled(context)) {
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能")
shouldGetNewInstalledPackagedList = true
} else {
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能")
}
} else {
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能")
shouldGetNewInstalledPackagedList = true
}
if (shouldGetNewInstalledPackagedList) {
lastInstalledPackageListTime = System.currentTimeMillis()
cachedInstalledPackagesList = getInstalledPackagesInternal(context, flags)
}
return cachedInstalledPackagesList
}
/**
* 显示获取已安装应用列表的对话框并请求权限
*/
fun showGetInstallAppsListDialogAndRequestPermissionIfNeeded(
activity: FragmentActivity,
ignorePermanentlyDenied: Boolean = false,
resultClosure: (Boolean) -> Unit
) {
val globalOnPermissionGrantedClosure = {
agreeOnGetInstalledPackagesApi()
// 进行包名初始化相关的操作
PackageRepository.initData()
refreshLocalPackageList()
refreshList()
}
if (isSupportGetInstalledAppsPermission(activity)) {
// 若系统已经授予了获取应用列表的权限,直接进行授权成功回调
if (!isGetInstalledListPermissionDisabled(activity)) {
globalOnPermissionGrantedClosure.invoke()
resultClosure.invoke(true)
return
}
PermissionHelper.showGetInstalledAppsListPermissionDialog(
activity = activity,
requestPermission = true,
ignorePermanentlyDenied = ignorePermanentlyDenied
) { isGranted ->
if (isGranted) {
SensorsBridge.trackInstalledListPermissionsResult("成功")
globalOnPermissionGrantedClosure.invoke()
resultClosure.invoke(true)
trackInstalledListAfterDelay()
} else {
resultClosure.invoke(false)
SensorsBridge.trackInstalledListPermissionsResult("拒绝")
}
}
} else {
val hintDialog = PermissionHelper.showGetInstalledAppsListPermissionDialog(
activity = activity,
requestPermission = false,
) {
// do nothing
}
SensorsBridge.trackInstalledListPermissionsCustomDialogShow()
val noticeDialog = DialogHelper.showGuideDialog(
context = activity,
title = "权限申请",
content = "是否允许“光环助手”获取已安装的应用信息",
confirmText = "开启",
cancelText = "拒绝",
confirmClickCallback = {
SensorsBridge.trackInstalledListPermissionsCustomClick("开启")
globalOnPermissionGrantedClosure.invoke()
resultClosure.invoke(true)
trackInstalledListAfterDelay()
},
cancelClickCallback = {
resultClosure.invoke(false)
SensorsBridge.trackInstalledListPermissionsCustomClick("拒绝")
}
)
noticeDialog?.setOnDismissListener {
hintDialog?.dismiss()
}
}
}
/**
* 延迟5秒后上报已安装应用列表
*/
private fun trackInstalledListAfterDelay() {
CoroutineScope(SupervisorJob()).launch {
delay(5000)
SensorsBridge.trackNumberOfInstalledList(localPackageNameSet.size, localPackageNameSet)
}
}
/**
* 是否支持动态获取已安装应用列表权限
*/
fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
// 若存在缓存,直接返回缓存结果。
if (isGetInstalledPackagesPermissionSupported != UNKNOWN) {
return isGetInstalledPackagesPermissionSupported != UNSUPPORTED
}
try {
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
val flag =
Settings.Secure.getInt(context.contentResolver, "oem_installed_apps_runtime_permission_enable", 0)
if (flag == 1) {
isGetInstalledPackagesPermissionSupported = SUPPORTED
return true
}
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
val packageManager = context.packageManager
val permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (permissionInfo.protection == PermissionInfo.PROTECTION_DANGEROUS) {
isGetInstalledPackagesPermissionSupported = SUPPORTED
return true
} else {
isGetInstalledPackagesPermissionSupported = UNSUPPORTED
return false
}
} else {
isGetInstalledPackagesPermissionSupported = UNSUPPORTED
return false
}
} catch (e: PackageManager.NameNotFoundException) {
isGetInstalledPackagesPermissionSupported = UNSUPPORTED
return false
}
}
/**
* 确保指定包名的应用在已安装了的情况下能正常收录
*/
fun addInstalledButMissingPackages(packageNameSet: HashSet<String>) {
Utils.log(TAG, "addInstalledButMissingPackages 检查已安装但未收录的应用")
val installedPackageNameSet: HashSet<String> = hashSetOf()
for (packageName in packageNameSet) {
if (!PackagesManager.isInstalled(packageName)
&& PackageUtils.getVersionNameByPackageName(packageName) != null
) {
installedPackageNameSet.add(packageName)
}
}
Utils.log(TAG, "addInstalledButMissingPackages 需要请求接口获取的包数量为 ${installedPackageNameSet.size}")
PackageRepository.addInstalledGames(
pkgNameList = ArrayList(installedPackageNameSet),
updateInstallStatus = true
)
}
fun refreshWrongInstallStatus(packageNameSet: MutableSet<String>) {
runOnIoThread {
Utils.log(TAG, "refreshWrongInstallStatus 检查安装状态异常的应用")
val installedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val uninstalledButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val updatedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
for (packageName in packageNameSet) {
val installedVersionName = PackageUtils.getVersionNameByPackageName(packageName)
if (!PackagesManager.isInstalled(packageName)
&& installedVersionName != null
) {
installedButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& installedVersionName == null) {
uninstalledButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& installedVersionName != null
&& !PackagesManager.isInstalledWithSpecificVersion(packageName, installedVersionName)) {
updatedButKeepingWrongStatusPackageNameSet.add(packageName)
}
}
Utils.log(TAG, "refreshWrongInstallStatus 需要更新已安装状态的包数量为 ${installedButKeepingWrongStatusPackageNameSet.size}")
Utils.log(TAG, "refreshWrongInstallStatus 需要更新已更新状态的包数量为 ${updatedButKeepingWrongStatusPackageNameSet.size}")
Utils.log(TAG, "refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}")
runOnUiThread {
if (installedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in installedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addInstall(packageName)
}
}
if (uninstalledButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in uninstalledButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUninstall(packageName)
}
}
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUpdate(packageName)
}
}
}
}
}
/**
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632
*/
private fun getInstalledPackagesInternal(context: Context, flags: Int): List<PackageInfo> {
Utils.log(TAG, "调用系统 API 获取已安装应用列表")
val pm = context.packageManager
try {
return pm.getInstalledPackages(flags)
} catch (ignored: java.lang.Exception) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
val process: Process
val result: MutableList<PackageInfo> = java.util.ArrayList()
var bufferedReader: BufferedReader? = null
try {
process = Runtime.getRuntime().exec("pm list packages")
bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
var line: String
while ((bufferedReader.readLine().also { line = it }) != null) {
val packageName = line.substring(line.indexOf(':') + 1)
val packageInfo = pm.getPackageInfo(packageName, flags)
result.add(packageInfo)
}
process.waitFor()
} catch (e: java.lang.Exception) {
e.printStackTrace()
if (e is InterruptedException) {
Thread.currentThread().interrupt()
}
} finally {
if (bufferedReader != null) try {
bufferedReader.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
return result
}
}

View File

@ -108,6 +108,12 @@ object PackageInstaller {
return
}
val packageName = downloadEntity?.packageName ?: PackageUtils.getPackageNameByPath(context, pkgPath)
packageName?.let {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
try {
// 判断是否需要使用浏览器来进行安装
if (BrowserInstallHelper.isUseBrowserToInstallEnabled()
@ -250,6 +256,8 @@ object PackageInstaller {
fun uninstallForPackageName(context: Context, pkn: String?) {
if (pkn.isNullOrEmpty()) return
PackageChangeHelper.addUninstallPendingPackage(pkn)
val uninstallIntent = Intent()
uninstallIntent.action = Intent.ACTION_DELETE
uninstallIntent.addCategory(Intent.CATEGORY_DEFAULT)

View File

@ -7,14 +7,12 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionInfo;
import android.content.pm.Signature;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.NonNull;
@ -29,8 +27,6 @@ import com.gh.common.xapk.XapkInstaller;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.PackageFlavorHelper;
import com.gh.gamecenter.common.utils.PermissionHelper;
import com.gh.gamecenter.core.utils.MD5Utils;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.feature.entity.ApkEntity;
@ -49,12 +45,10 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@ -68,20 +62,14 @@ import java.util.zip.ZipFile;
public class PackageUtils {
private static long mLastInstalledPackageListTime = 0L;
private static List<PackageInfo> mInstalledPackageList = null;
private static final String TAG = "PackageUtils";
// 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知0 代表不支持, 1 代表支持
private static int mIsSupportGetInstalledListPermission = -1;
public static String getInstallPackageInfoSourceDir(String packageName) {
try {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).applicationInfo.sourceDir;
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return null;
}
@ -319,7 +307,7 @@ public class PackageUtils {
return new String[]{null, null};
}
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return new String[]{null, null};
}
@ -599,7 +587,7 @@ public class PackageUtils {
.getPackageInfo(packageName, 0);
return packageInfo.firstInstallTime;
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return 0;
}
@ -626,7 +614,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager()
.getPackageInfo(BuildConfig.APPLICATION_ID, 0).lastUpdateTime;
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return 0;
@ -640,7 +628,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return null;
}
@ -653,7 +641,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return 0;
}
@ -667,7 +655,7 @@ public class PackageUtils {
PackageManager packageManager = context.getApplicationContext().getPackageManager();
return packageManager.getApplicationIcon(packageName);
} catch (NameNotFoundException e) {
e.printStackTrace();
// do nothing
}
return null;
}
@ -677,7 +665,7 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageName(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
@ -690,7 +678,7 @@ public class PackageUtils {
public static ArrayList<String> getAllPackageNameIncludeGh(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
list.add(packageInfo.packageName);
@ -704,11 +692,9 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageNameIncludeSystemApps(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
list.add(packageInfo.packageName);
}
list.add(packageInfo.packageName);
}
return list;
}
@ -717,7 +703,7 @@ public class PackageUtils {
JSONArray jsonArray = new JSONArray();
try {
PackageManager pm = context.getPackageManager();
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
JSONObject jsonObject = new JSONObject();
@ -758,7 +744,6 @@ public class PackageUtils {
}
}
/**
* 启动应用
* 请使用 PackageLauncher.launchApp()
@ -778,22 +763,6 @@ public class PackageUtils {
}
}
/*
* 根据包名,获取软件名称
*/
public static String getNameByPackageName(Context context, String packageName) {
try {
PackageManager pm = context.getApplicationContext().getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(
packageName, 0);
return applicationInfo.loadLabel(pm).toString();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* todo 统一判断
* <p>
@ -912,8 +881,8 @@ public class PackageUtils {
String packageName = context.getApplicationContext().getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName) && appProcess.importance
== ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appProcess.processName.equals(packageName)
&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
@ -924,132 +893,6 @@ public class PackageUtils {
return false;
}
/**
* 弃用已安装列表缓存
*/
public static void dumpInstalledListCache() {
mLastInstalledPackageListTime = 0;
}
public static List<PackageInfo> getInstalledPackages(Context context, int flags) {
Utils.log(TAG, "即将获取已安装应用列表");
// 简单 debounce 掉过于频繁的调用获取已安装列表调用
if (System.currentTimeMillis() - mLastInstalledPackageListTime < 1000
&& mInstalledPackageList != null
&& mInstalledPackageList.size() > 0) {
Utils.log(TAG, "使用了缓存的已安装应用列表");
return new ArrayList<>(mInstalledPackageList);
}
// 是否需要调用系统 API 获取最新的已安装应用列表
boolean shouldGetNewInstalledPackagedList = false;
// 当前设备是否支持限制获取已安装应用列表的功能
if (isSupportGetInstalledAppsPermission(context)) {
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能");
// 当前设备是否支持禁用了获取已安装应用列表
if (!PermissionHelper.isGetInstalledListPermissionDisabled(context)) {
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能");
shouldGetNewInstalledPackagedList = true;
} else {
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能");
}
} else {
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能");
shouldGetNewInstalledPackagedList = true;
}
if (shouldGetNewInstalledPackagedList) {
mLastInstalledPackageListTime = System.currentTimeMillis();
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
}
if (mInstalledPackageList == null) {
mInstalledPackageList = new ArrayList<>();
}
return mInstalledPackageList;
}
public static boolean isSupportGetInstalledAppsPermission(Context context) {
// 若存在缓存,直接返回缓存结果。为 0 代表不支持,为 1 代表支持
if (mIsSupportGetInstalledListPermission != -1) {
return mIsSupportGetInstalledListPermission != 0;
}
try {
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
int flag = Settings.Secure.getInt(context.getContentResolver(), "oem_installed_apps_runtime_permission_enable", 0);
if (flag == 1) {
mIsSupportGetInstalledListPermission = 1;
return true;
}
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
PackageManager packageManager = context.getPackageManager();
PermissionInfo permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS) {
mIsSupportGetInstalledListPermission = 1;
return true;
} else {
mIsSupportGetInstalledListPermission = 0;
return false;
}
} else {
mIsSupportGetInstalledListPermission = 0;
return false;
}
} catch (NameNotFoundException e) {
mIsSupportGetInstalledListPermission = 0;
return false;
}
}
/**
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632
*/
private static List<PackageInfo> getInstalledPackagesInternal(Context context, int flags) {
Utils.log(TAG, "调用系统 API 获取已安装应用列表");
final PackageManager pm = context.getPackageManager();
try {
return pm.getInstalledPackages(flags);
} catch (Exception ignored) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
Process process;
List<PackageInfo> result = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
process = Runtime.getRuntime().exec("pm list packages");
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
final String packageName = line.substring(line.indexOf(':') + 1);
final PackageInfo packageInfo = pm.getPackageInfo(packageName, flags);
result.add(packageInfo);
}
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
} finally {
if (bufferedReader != null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static String getWebviewPath(Context context) {
final PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(context);
return webViewPackageInfo != null ? webViewPackageInfo.applicationInfo.sourceDir : null;

View File

@ -0,0 +1,18 @@
package com.gh.common.view
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintLayout
class InterceptTouchContainView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : FrameLayout(context, attrs, defStyleAttr) {
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return true
}
}

View File

@ -10,8 +10,8 @@ import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.exposure.meta.MetaUtil.getMeta
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.ndownload.NDataChanger
import com.gh.ndownload.NDownloadBridge
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
@ -124,6 +124,7 @@ object DownloadDataHelper {
val payloadObject = JSONObject()
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("redirected_host_list", downloadEntity.meta[NDownloadBridge.REDIRECTED_HOST_LIST] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
@ -212,6 +213,7 @@ object DownloadDataHelper {
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("redirected_host_list", downloadEntity.meta[NDownloadBridge.REDIRECTED_HOST_LIST] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
@ -251,6 +253,7 @@ object DownloadDataHelper {
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("redirected_host_list", downloadEntity.meta[NDownloadBridge.REDIRECTED_HOST_LIST] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
@ -315,6 +318,7 @@ object DownloadDataHelper {
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("redirected_host_list", downloadEntity.meta[NDownloadBridge.REDIRECTED_HOST_LIST] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
@ -357,6 +361,7 @@ object DownloadDataHelper {
sheet = JSONObject()
sheet.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
sheet.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
sheet.put("redirected_host_list", downloadEntity.meta[NDownloadBridge.REDIRECTED_HOST_LIST] ?: "unknown")
sheet.put("game_id", downloadEntity.gameId)
sheet.put("platform", downloadEntity.platform)
sheet.put("package", downloadEntity.packageName)
@ -376,6 +381,7 @@ object DownloadDataHelper {
"path",
downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown"
) // 初始化记录的 path 为空
sheet.put("redirected_host_list", downloadEntity.meta[NDownloadBridge.REDIRECTED_HOST_LIST] ?: "unknown")
sheet.put("total_size", downloadEntity.size / 1024 / 1024) // 初始化记录的 total_size 有可能为0
sheet.put("progress_size", downloadEntity.progress / 1024 - progressSize)
sheet.put("current_progress_size", downloadEntity.progress / 1024)

View File

@ -22,7 +22,6 @@ import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.entity.CustomPageTrackData;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.common.history.HistoryHelper;
@ -34,16 +33,10 @@ import com.gh.common.util.LunchType;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.AppDebugConfig;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
import com.gh.gamecenter.core.utils.SPUtils;
@ -55,7 +48,6 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.packagehelper.PackageRepository;
@ -64,7 +56,6 @@ import com.gh.ndownload.NDownloadBridge;
import com.gh.ndownload.NDownloadService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.download.ConnectionUtils;
import com.lightgame.download.DataWatcher;
import com.lightgame.download.DownloadConfig;
import com.lightgame.download.DownloadDao;
@ -179,9 +170,6 @@ public class DownloadManager implements DownloadStatusListener {
mUpdateMarks = SPUtils.getStringSet(UPDATE_IS_READ_MARK);
// 只有下载模块需要这坨东西,因此移动到这里初始化
ConnectionUtils.initHttpsUrlConnection(mContext);
updateDownloadMetaMap();
lastTimeMap = new ArrayMap<>();

View File

@ -14,7 +14,7 @@ import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper
import com.gh.gamecenter.core.utils.UrlFilterUtils
@ -153,7 +153,7 @@ object PackageObserver {
}
}
runOnIoThread { postNewlyInstalledApp(gameId, packageName) }
AppExecutor.logExecutor.execute { postNewlyInstalledApp(gameId, packageName) }
}
if (EBPackage.TYPE_UNINSTALLED == busFour.type) {

View File

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

View File

@ -10,6 +10,9 @@ import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.game.GameFragment
/**
* 板块
*/
class BlockActivity : DownloadToolbarActivity() {
companion object {

View File

@ -14,6 +14,7 @@ import com.halo.assistant.fragment.ApkCleanerFragment;
/**
* Created by khy on 2017/1/24.
* 清理安装包
*/
@Route(path = RouteConsts.activity.cleanApkActivity)
public class CleanApkActivity extends ToolBarActivity {

View File

@ -16,6 +16,7 @@ import java.util.ArrayList;
/**
* Created by khy on 18/07/17.
* 我的收藏
*/
public class CollectionActivity extends ToolBarActivity {
@Override

View File

@ -23,6 +23,9 @@ import java.lang.ref.SoftReference;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
/**
* 裁剪图片
*/
public class CropImageActivity extends ToolBarActivity {
protected CropImageCustom mCropImageCustom;

View File

@ -24,7 +24,7 @@ import com.halo.assistant.HaloApp
/**
* Created by khy on 2017/3/24.
* 游戏详情适配器
* 游戏详情
*/
class GameDetailActivity : DownloadToolbarActivity() {

View File

@ -16,6 +16,7 @@ import java.util.ArrayList;
/**
* Created by khy on 2016/12/12.
* 礼包中心
*/
@Deprecated
public class LibaoActivity extends ToolBarActivity {

View File

@ -285,9 +285,6 @@ public class MainActivity extends BaseActivity {
// 耗时操作
AppExecutor.getIoExecutor().execute(() -> {
// 上传数据
DataCollectionManager.getInstance().upload();
// 初始化PlatformUtils
PlatformUtils.getInstance(getApplicationContext());
@ -556,7 +553,10 @@ public class MainActivity extends BaseActivity {
} else {
TextView jumpBtn = findViewById(R.id.jumpBtn);
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - mCountdownCount));
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
Message newMsg = Message.obtain();
newMsg.what = COUNTDOWN_AD;
newMsg.obj = msg.obj;
mBaseHandler.sendMessageDelayed(newMsg, 1000);
}
}
}
@ -877,13 +877,6 @@ public class MainActivity extends BaseActivity {
return true;
}
@Override
public void finish() {
// 上传数据
DataCollectionManager.getInstance().statClickData();
super.finish();
}
@Override
protected void onSaveInstanceState(@NotNull Bundle outState) {
super.onSaveInstanceState(outState);

View File

@ -29,6 +29,9 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.concurrent.TimeUnit
/**
* 游戏搜索页
*/
open class SearchActivity : BaseActivity() {
lateinit var searchEt: EditText

View File

@ -48,6 +48,7 @@ import io.reactivex.functions.Consumer;
/**
* Created by khy on 2016/11/7.
* 分享卡片
*/
public class ShareCardPicActivity extends ToolBarActivity {

View File

@ -21,6 +21,7 @@ import com.tencent.tauth.Tencent;
/**
* Created by khy on 2017/2/6.
* 分享光环
*/
public class ShareGhActivity extends ToolBarActivity {

View File

@ -197,7 +197,7 @@ class SplashScreenActivity : BaseActivity() {
// 尝试获取安装应用列表权限并启动首页(不在乎结果)
private fun requestGetInstallListPermissionAndLaunchMainActivity() {
if (PackageUtils.isSupportGetInstalledAppsPermission(this)
if (PackageHelper.isSupportGetInstalledAppsPermission(this)
&& PermissionHelper.isGetInstalledListPermissionDisabled(this)
) {
PermissionHelper.requestGetInstalledAppsListPermission(this, true) {

View File

@ -7,6 +7,9 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.halo.assistant.fragment.user.UserInfoFragment
/**
* 编辑资料
*/
class UserInfoActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.login.user.UserViewModel
import com.halo.assistant.fragment.user.UserInfoEditFragment
/**
* 修改个人信息
*/
class UserInfoEditActivity : ToolBarActivity() {
companion object {
fun getIntent(context: Context, editType: String): Intent {

View File

@ -8,6 +8,7 @@ import com.halo.assistant.fragment.user.SelectRegionFragment;
/**
* Created by khy on 25/09/17.
* 选择地区
*/
public class UserRegionActivity extends ToolBarActivity {

View File

@ -18,6 +18,7 @@ import android.widget.TextView;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.R;
@ -188,7 +189,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
}
private int doType(String packageName) {
List<PackageInfo> pakageinfos = PackageUtils.getInstalledPackages(mContext, 0);
List<PackageInfo> pakageinfos = PackageHelper.INSTANCE.getInstalledPackages(mContext, 0);
for (PackageInfo pi : pakageinfos) {
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
String pi_packageName = pi.packageName;

View File

@ -1,7 +1,14 @@
package com.gh.gamecenter.adapter.viewholder
import android.graphics.Paint
import android.widget.TextView
import androidx.core.view.marginStart
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.home.custom.model.CustomPageData
class SearchGameFooterViewHolder(val binding: SearchGameFooterBinding) : BaseRecyclerViewHolder<Any>(binding.root)
class PersonalHomeRatingViewHolder(val binding: PersonalHomeRatingBinding) : BaseRecyclerViewHolder<Any>(binding.root)
@ -22,4 +29,62 @@ class CommonCollectionImageTextItemViewHolder(val binding: CommonCollectionImage
BaseRecyclerViewHolder<Any>(binding.root)
class CommonCollectionDetailTwoItemHorizontalViewHolder(val binding: CommonCollectionDetailTwoItemHorizontalCustomBinding) :
BaseRecyclerViewHolder<Any>(binding.root)
BaseRecyclerViewHolder<Any>(binding.root)
class CustomCollectionDetailRecommendCardViewHolder(
val binding: RecyclerRecommendCardCommonContentCollectionDetailCustomBinding
) : BaseRecyclerViewHolder<Any>(binding.root) {
fun bind(item: CustomPageData.RecommendCard) {
ImageUtils.display(binding.ivCover, item.image)
binding.tvTitle.text = item.title
binding.tvLabel.text = item.tag
binding.tvPrice.text = item.highlight.text
binding.tvOriginalPrice.text = if (item.deletion.isShowCurrencySymbol) {
itemView.context.getString(R.string.price_with_symbol, item.deletion.text)
} else {
item.deletion.text
}
binding.tvOriginalPrice.paint.flags = Paint.STRIKE_THRU_TEXT_FLAG
binding.tvCopy.text = item.addedContent
binding.tvPriceSymbol.goneIf(!item.highlight.isShowCurrencySymbol)
binding.root.post {
val views = mutableListOf(
binding.tvPrice,
binding.tvOriginalPrice,
binding.tvCopy,
)
if (item.highlight.isShowCurrencySymbol) {
views.add(0, binding.tvPriceSymbol)
}
binding.tvLabel.goneIf(item.tag.isBlank()) {
views.add(binding.tvLabel)
}
views.forEach {
it.goneIf(false)
}
hideOutOfBoundViewsIfNeed(views)
}
}
/**
* 计算统一排的view能否完整显示在 itemView 内,如果显示不下,则根据优先级依次隐藏优先级较低的
* 数据中的View优先级由高到低排列最后一个优先级最低
*/
private fun hideOutOfBoundViewsIfNeed(views: MutableList<TextView>) {
if (views.isEmpty()) {
return
}
val totalWidth = views.sumOf {
it.width + it.marginStart
}
if (totalWidth > itemView.width) {
views.removeLast().goneIf(true)
hideOutOfBoundViewsIfNeed(views)
}
}
}

View File

@ -45,7 +45,7 @@ import kotlin.math.abs
class AmwayFragment : LazyListFragment<AmwayListItemData, AmwayViewModel>() {
private lateinit var mViewModel: AmwayViewModel
private val mViewModel: AmwayViewModel by lazy { viewModelProvider() }
private val mElapsedHelper by lazy { TimeElapsedHelper() }
private lateinit var mExposureListener: ExposureListener
@ -131,14 +131,13 @@ class AmwayFragment : LazyListFragment<AmwayListItemData, AmwayViewModel>() {
}
}
override fun provideListViewModel(): AmwayViewModel {
mViewModel = viewModelProvider()
return mViewModel
}
override fun getItemDecoration() = VerticalItemDecoration(context, 12F, false)
.apply { mItemDecoration = this }
override fun provideListViewModel(): AmwayViewModel? {
return mViewModel
}
override fun provideListAdapter(): ListAdapter<*> {
if (mAdapter == null) {
val basicExposureSource = arrayListOf<ExposureSource>().apply {

View File

@ -15,7 +15,9 @@ import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.ActivityAuthorizationBinding
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.vspace.VHelper
import com.lightgame.utils.Utils
/**
* @author : liujiarui
@ -162,9 +164,12 @@ class AuthorizationActivity : ToolBarActivity() {
private fun checkLogin(block: () -> Unit) {
//判断光环是否登陆
CheckLoginUtils.checkLogin(this, "光环助手授权登陆") {
if (CheckLoginUtils.isLogin()) {
initData()
block()
} else {
Utils.toast(this, "需要登录")
startActivity(LoginActivity.getIntent(this, "光环助手授权登陆"))
}
}

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 新分类2.0
*/
class CategoryV2Activity : DownloadToolbarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -41,6 +41,9 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
/**
* 云存档管理
*/
class CloudArchiveManagerActivity : BaseActivity_TabLayout(), ArchiveLimitSelectedListener {
private lateinit var mBinding: ActivityCloudArchiveManagerBinding

View File

@ -1,120 +0,0 @@
package com.gh.gamecenter.db;
import android.content.Context;
import com.gh.gamecenter.db.info.DataCollectionInfo;
import com.j256.ormlite.dao.Dao;
import java.sql.SQLException;
import java.util.List;
// TODO 这个数据库其实没有用了,上传到 loghub 已经有相关的逻辑处理,有空删掉它
public class DataCollectionDao {
private DatabaseHelper helper;
private Dao<DataCollectionInfo, String> dao;
public DataCollectionDao(Context context) {
try {
helper = DatabaseHelper.getHelper(context);
dao = helper.getDao(DataCollectionInfo.class);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查找一个数据
*/
public List<DataCollectionInfo> findByType(String type) {
try {
return dao.queryForEq("type", type);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 添加一个数据
*/
public void add(DataCollectionInfo entity) {
try {
dao.create(entity);
} catch (Exception e) {
// java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
e.printStackTrace();
}
}
/**
* 删除一个数据
*/
public void delete(String id) {
try {
dao.deleteById(id);
} catch (Exception e) {
// java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
e.printStackTrace();
}
}
/**
* 删除一组数据
*/
public void delete(List<String> ids) {
try {
dao.deleteIds(ids);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据id获取某一个数据
*/
public DataCollectionInfo find(String id) {
try {
return dao.queryForId(id);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取所有的数据
*/
public List<DataCollectionInfo> getAll() {
try {
return dao.queryForAll();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取点击数据
*/
public List<DataCollectionInfo> getClickData() {
try {
return dao.queryForEq("type", "click-item");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 更新数据
*/
public void update(DataCollectionInfo entity) {
try {
dao.update(entity);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -5,9 +5,7 @@ import android.database.sqlite.SQLiteDatabase;
import androidx.collection.ArrayMap;
import com.gh.gamecenter.db.info.DataCollectionInfo;
import com.gh.gamecenter.db.info.GameTrendsInfo;
import com.gh.gamecenter.db.info.PackageInfo;
import com.gh.gamecenter.db.info.SearchHistoryInfo;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
@ -52,8 +50,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
try {
Utils.log("DatabaseHelper onCreate");
TableUtils.createTable(connectionSource, SearchHistoryInfo.class);
TableUtils.createTable(connectionSource, DataCollectionInfo.class);
TableUtils.createTable(connectionSource, PackageInfo.class);
TableUtils.createTable(connectionSource, GameTrendsInfo.class);
} catch (SQLException e) {
e.printStackTrace();
@ -65,8 +61,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
try {
Utils.log("DatabaseHelper onUpgrade");
TableUtils.dropTable(connectionSource, SearchHistoryInfo.class, true);
TableUtils.dropTable(connectionSource, DataCollectionInfo.class, true);
TableUtils.dropTable(connectionSource, PackageInfo.class, true);
TableUtils.dropTable(connectionSource, GameTrendsInfo.class, true);
onCreate(database, connectionSource);
} catch (SQLException e) {

View File

@ -1,65 +0,0 @@
package com.gh.gamecenter.db.info;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import java.io.Serializable;
@DatabaseTable(tableName = "tb_datacollection")
public class DataCollectionInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3196892351397147390L;
@DatabaseField(id = true, columnName = "id")
private String id;
@DatabaseField(columnName = "type")
private String type;
@DatabaseField(columnName = "data")
private String data;
public DataCollectionInfo() {
}
public DataCollectionInfo(String id, String type, String data) {
this.id = id;
this.type = type;
this.data = data;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public String toString() {
return "DataCollectionEntity [id=" + id + ", type=" + type + ", data="
+ data + "]";
}
}

View File

@ -1,42 +0,0 @@
package com.gh.gamecenter.db.info;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import java.io.Serializable;
@DatabaseTable(tableName = "tb_package")
public class PackageInfo implements Serializable {
@DatabaseField(id = true, columnName = "packageName")
private String packageName;
@DatabaseField(columnName = "time")
private long time;
public PackageInfo() {
}
public PackageInfo(String packageName, long time) {
this.packageName = packageName;
this.time = time;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
}

View File

@ -21,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.HomePluggableHelper
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.DownloadManagerActivity
@ -276,6 +277,12 @@ class DownloadFragment : BaseFragment_TabLayout() {
if (mBinding.adGameItemContainer.isVisible) {
DownloadManager.getInstance().addObserver(mDataWatcher)
}
refreshInstallStatus()
}
private fun refreshInstallStatus() {
PackageHelper.refreshWrongInstallStatus(PackagesManager.getInstalledSet())
}
override fun onParentActivityFinish() {

View File

@ -10,8 +10,8 @@ import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.PackageHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.eventbus.EBReuse
@ -29,7 +29,6 @@ import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
@ -147,15 +146,20 @@ class NewInstalledGameFragment : ToolbarFragment() {
}
mBinding.run {
if (PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())) {
val isGetInstalledListDisagreed = PackageHelper.isGetInstalledPackagesApiAgreedRequired()
&& !PackageHelper.isGetInstalledPackagesApiAgreed()
val isGetInstalledListPermissionDisabled = PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())
if (isGetInstalledListDisagreed || isGetInstalledListPermissionDisabled) {
reuseNoneData.reuseNoneDataIv.visibility = View.GONE
reuseNoneData.reuseNoneDataTv.text = "开启应用列表权限"
reuseNoneData.reuseNoneDataDescTv.text = " 及时获悉游戏最新的更新消息"
reuseNoneData.reuseResetLoadTv.text = "去开启"
reuseNoneData.reuseResetLoadTv.setOnClickListener {
PermissionHelper.requestGetInstalledAppsListPermission(requireActivity()) {
updateNoDataView()
PackageRepository.initData()
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(requireActivity()) { isGranted ->
if (isGranted) {
updateNoDataView()
}
}
}
} else {

View File

@ -3,8 +3,8 @@ package com.gh.gamecenter.download
import android.view.View
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
@ -12,12 +12,10 @@ import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentGameUpdatableBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
@ -40,7 +38,6 @@ class UpdatableGameFragment : LazyFragment() {
}
}
override fun getRealLayoutId() = R.layout.fragment_game_updatable
override fun onRealLayoutInflated(inflatedView: View) {
mBinding = FragmentGameUpdatableBinding.bind(inflatedView)
@ -98,21 +95,21 @@ class UpdatableGameFragment : LazyFragment() {
noDataContainer.reuseResetLoadTv.layoutParams = layoutParam
noDataContainer.reuseResetLoadTv.visibility = View.VISIBLE
noDataContainer.reuseNoneDataDescTv.visibility = View.VISIBLE
if (PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())) {
val isGetInstalledListDisagreed = !PackageHelper.isGetInstalledPackagesApiAgreed()
val isGetInstalledListPermissionDisabled = PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())
if (isGetInstalledListDisagreed || isGetInstalledListPermissionDisabled) {
noDataContainer.reuseNoneDataIv.visibility = View.GONE
noDataContainer.reuseNoneDataTv.text = "开启应用列表权限"
noDataContainer.reuseNoneDataDescTv.text = "及时获悉游戏最新的更新消息"
noDataContainer.reuseResetLoadTv.text = "去开启"
noDataContainer.reuseResetLoadTv.setOnClickListener {
PermissionHelper.requestGetInstalledAppsListPermission(
requireActivity(),
false,
object : EmptyCallback {
override fun onCallback() {
updateNoDataView()
PackageRepository.initData()
}
})
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(requireActivity()) { isGranted ->
if (isGranted) {
updateNoDataView()
}
}
}
} else {
noDataContainer.reuseNoneDataIv.visibility = View.VISIBLE

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@ -17,8 +18,14 @@ data class CommonCollectionEntity(
@SerializedName("vertical_line")
val verticalLine: String = "", // 竖排时才有数据,代表竖排行数控制
@SerializedName("common_collection_content")
val collectionList: MutableList<CommonCollectionContentEntity> = mutableListOf()
val collectionList: MutableList<CommonCollectionContentEntity> = mutableListOf(),
@SerializedName("common_collection_recommend_cards")
private val _commonCollectionRecommendCards: List<CustomPageData.RecommendCard>? = null
) {
val commonCollectionRecommendCards: List<CustomPageData.RecommendCard>
get() = _commonCollectionRecommendCards ?: emptyList()
val layoutChinese: String
get() = when (layout) {
0 -> "轮播banner"
@ -30,6 +37,10 @@ data class CommonCollectionEntity(
6 -> "双列竖式卡片"
7 -> "竖式图文列表"
8 -> "横排图文列表"
9 -> "内容标签泳道"
10 -> "通知栏目"
11 -> "公告横幅"
12 -> "推荐卡片"
else -> ""
}
}

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
import android.graphics.Color
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.entity.Time
import com.google.gson.annotations.SerializedName
@ -22,5 +23,87 @@ data class GameNavigationEntity(
var hintStartTime: Long = 0,
@SerializedName("hint_end_time")
var hintEndTime: Long = 0,
var time: Time? = null
)
var time: Time? = null,
@SerializedName("entry_name_status")
private val _entryNameStatus: String? = null,
@SerializedName("guide")
private val _guide: Guide? = null
) {
val isShowEntryName: Boolean
get() = ENTRY_NAME_STATUS_HIDE != _entryNameStatus
val isShowBubble: Boolean
get() = _guide != null
val guide: Guide
get() = _guide ?: Guide()
data class Guide(
@SerializedName("text")
private val _text: String? = null,
@SerializedName("color")
private val _color: String? = null
) {
val text: String
get() = _text ?: ""
val color: String
get() = _color ?: ""
/**
* 文字颜色 不透明度为 70%
* 十六进制: B2
* 十进制: 178
*/
val textColorInt: Int
get() = parseColorWithAlpha(TEXT_ALPHA, color)
/**
* 边框颜色 不透明度为 10%
* 十六进制: 4D
* 十进制: 77
*/
val borderColorInt: Int
get() = parseColorWithAlpha(BORDER_ALPHA, color)
/**
* 背景颜色 不透明度为 30%
* 十六进制: 1A
* 十进制: 26
*/
val backgroundColorInt: Int
get() = parseColorWithAlpha(BACKGROUND_ALPHA, color)
private fun parseColorWithAlpha(alpha: Int, color: String): Int {
val colorInt = try {
Color.parseColor(color)
} catch (e: IllegalArgumentException) {
// 解析失败,默认使用红色
Color.RED
}
val hsv = FloatArray(3)
Color.colorToHSV(colorInt, hsv)
return Color.HSVToColor(alpha, hsv)
}
companion object {
private const val COLOR_BLUE = "blue"
private const val COLOR_PURPLE = "purple"
private const val COLOR_RED = "red"
private const val COLOR_ORANGE = "orange"
private const val COLOR_YELLOW = "yellow"
private const val COLOR_GREEN = "green"
private const val TEXT_ALPHA = 178
private const val BORDER_ALPHA = 77
private const val BACKGROUND_ALPHA = 26
}
}
companion object {
private const val ENTRY_NAME_STATUS_HIDE = "hide"
}
}

View File

@ -20,7 +20,8 @@ data class HomeRecommend(
private val _image: String? = null,
@SerializedName("link_community")
private val community: CommunityEntity? = null,
@SerializedName("guide")
private val _guide: Guide? = null,
// 绑定的曝光实体
var exposureEvent: ExposureEvent? = null,
) {
@ -28,6 +29,12 @@ data class HomeRecommend(
val image: String
get() = _image ?: ""
val isShowGuide: Boolean
get() = _guide != null
val guide: Guide
get() = _guide ?: Guide()
fun transformLinkEntity(): LinkEntity {
return LinkEntity(
name = name,
@ -38,4 +45,12 @@ data class HomeRecommend(
community = community
)
}
data class Guide(
@SerializedName("text")
private val _text: String? = null
) {
val text: String
get() = _text ?: ""
}
}

View File

@ -36,7 +36,7 @@ data class HomeSubSlide(
return if (linkType.isNotEmpty()) {
LinkEntity(link = linkId, type = linkType, text = linkText, community = community)
} else {
LinkEntity(link = cardId, type = cardType, linkText = cardText)
LinkEntity(link = cardId, type = cardType, text = cardText)
}
}
}
@ -44,9 +44,12 @@ data class HomeSubSlide(
data class CardData(
var games: List<GameEntity> = arrayListOf(),
@SerializedName("game_total")
val gameTotal: GameTotal = GameTotal(),
private val _gameTotal: GameTotal? = null,
val stamp: String = ""
)
) {
val gameTotal: GameTotal
get() = _gameTotal ?: GameTotal()
}
data class GameTotal(
val vote: Int = 0,

View File

@ -11,6 +11,12 @@ class NewApiSettingsEntity(
var startup: StartupAdEntity? = null,//启动文案广告
@SerializedName("user_interested_game")
var userInterestedGame: Boolean = false, //偏好设置状态开关
@SerializedName("installed_compliance_switch")
var installedComplianceSwitch: Boolean? = false, //安装合规开关
@SerializedName("listen_switch")
var isPackageObserveEnable: Boolean = false, // 安装包监听开关
@SerializedName("listen_str")
var packageObserveActions: PackageObserveActions? = null, // 安装包监听的三个 action
var install: Install, // 安装相关的
@SerializedName("game_shield_contents")
var gameShieldContents: List<String>? = listOf(),//游戏屏蔽内容
@ -46,4 +52,13 @@ class NewApiSettingsEntity(
val type: String,
val link: LinkEntity
)
class PackageObserveActions(
@SerializedName("ADD")
val add: String,
@SerializedName("REM")
val rem: String,
@SerializedName("REP")
val rep: String
)
}

View File

@ -0,0 +1,5 @@
package com.gh.gamecenter.entity
class WhitePackageListEntity {
var data: HashSet<String>? = null
}

View File

@ -10,6 +10,9 @@ import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 论坛详情
*/
class ForumDetailActivity : BaseActivity() {
private var mContainerFragment: Fragment? = null

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.EntranceConsts.IS_DETAIL_PAGE
import com.gh.gamecenter.video.detail.HomeVideoFragment
/**
* 社区首页
*/
class CommunityActivity : BaseActivity() {
override fun getLayoutId(): Int = R.layout.activity_community

View File

@ -17,11 +17,9 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager.widget.ViewPager
import com.gh.common.browse.BrowseTimer
import com.gh.common.browse.withLifecycle
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.TrackableDialog
import com.gh.gamecenter.common.base.adapter.FragmentAdapter
@ -74,7 +72,6 @@ class CommunityHomeFragment : LazyFragment() {
private var mBottomTabId = ""
private val browseTimer = BrowseTimer()
.withLifecycle(this)
.withResult {
SensorsBridge.trackCommunityBrowsingDuration(it / 1000.0)
}
@ -202,13 +199,14 @@ class CommunityHomeFragment : LazyFragment() {
mBottomTabId = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_ID, "") ?: ""
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
browseTimer.start()
} else {
browseTimer.stop()
}
override fun onResume() {
super.onResume()
browseTimer.start()
}
override fun onPause() {
super.onPause()
browseTimer.stop()
}
override fun onSaveInstanceState(outState: Bundle) {

View File

@ -9,6 +9,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 关注论坛/热门论坛/综合论坛
*/
class ForumListActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -12,6 +12,9 @@ import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.entity.ApplyModeratorStatusEntity
/**
* 版主申请
*/
class ApplyModeratorActivity : ToolBarActivity() {
companion object {
fun getIntent(context: Context, bbsId: String, status: ApplyModeratorStatusEntity): Intent {

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 版主列表
*/
class ModeratorListActivity : ToolBarActivity() {
companion object {

View File

@ -20,6 +20,9 @@ import com.gh.gamecenter.forum.detail.ForumDetailFragment
import com.gh.gamecenter.search.SearchDefaultFragment
import com.lightgame.utils.Util_System_Keyboard
/**
* 论坛搜索
*/
class ForumOrUserSearchActivity : SearchActivity() {
private var mBbsId = ""

View File

@ -9,6 +9,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 通用内容合集详情
*/
class CommonCollectionDetailActivity : ToolBarActivity() {
override fun provideNormalIntent(): Intent {

View File

@ -9,6 +9,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 旧 通用内容合集详情
*/
class CustomCommonCollectionDetailActivity : ToolBarActivity() {
override fun provideNormalIntent(): Intent {

View File

@ -9,10 +9,7 @@ import com.gh.common.exposure.IExposable
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailOneItemViewHolder
import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailTwoItemHorizontalViewHolder
import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailTwoItemViewHolder
import com.gh.gamecenter.adapter.viewholder.CommonCollectionImageTextItemViewHolder
import com.gh.gamecenter.adapter.viewholder.*
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.exposure.ExposureSource
@ -21,11 +18,13 @@ import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.entity.CommonCollectionContentEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.game.data.CommonContentCollectionDetailItem
import com.gh.gamecenter.game.data.CommonContentCollectionDetailRecommendCardItem
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD
class CustomCommonCollectionDetailAdapter(
context: Context,
@ -35,13 +34,13 @@ class CustomCommonCollectionDetailAdapter(
val mTabIndex: Int,
val mEntrance: String,
private val mBasicExposureSourceList: List<ExposureSource>?
) : ListAdapter<CommonCollectionContentEntity>(context), IExposable {
) : ListAdapter<CommonContentCollectionDetailItem>(context), IExposable {
private val mExposureEventSparseArray = SparseArray<ExposureEvent>()
override fun areItemsTheSame(
oldItem: CommonCollectionContentEntity?,
newItem: CommonCollectionContentEntity?
oldItem: CommonContentCollectionDetailItem?,
newItem: CommonContentCollectionDetailItem?
): Boolean {
return oldItem == newItem
}
@ -50,12 +49,19 @@ class CustomCommonCollectionDetailAdapter(
return if (viewType == ItemViewType.ITEM_BODY) {
when (collectionStyle) {
"1-1" -> CommonCollectionDetailOneItemViewHolder(parent.toBinding())
"1-2" -> if (mViewModel.getLayout() == COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
|| mViewModel.getLayout() == COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER
) {
CommonCollectionDetailTwoItemHorizontalViewHolder(parent.toBinding())
} else {
CommonCollectionDetailTwoItemViewHolder(parent.toBinding())
"1-2" -> when (mViewModel.getLayout()) {
COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER,
COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER -> {
CommonCollectionDetailTwoItemHorizontalViewHolder(parent.toBinding())
}
COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD -> {
CustomCollectionDetailRecommendCardViewHolder(parent.toBinding())
}
else -> {
CommonCollectionDetailTwoItemViewHolder(parent.toBinding())
}
}
else -> CommonCollectionImageTextItemViewHolder(parent.toBinding())
@ -79,7 +85,7 @@ class CustomCommonCollectionDetailAdapter(
}
val contentEntity = mEntityList[position]
val linkEntity = mEntityList[position].linkEntity
val linkEntity = contentEntity.link
val listener: (v: View) -> Unit = {
DirectUtils.directToLinkPage(
@ -189,6 +195,15 @@ class CustomCommonCollectionDetailAdapter(
root.setOnClickListener(listener)
}
}
is CustomCollectionDetailRecommendCardViewHolder-> {
if (contentEntity is CommonContentCollectionDetailRecommendCardItem) {
val recommendCard = contentEntity.data
holder.bind(recommendCard)
holder.itemView.setOnClickListener(listener)
}
}
}
}

View File

@ -5,8 +5,11 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.entity.CommonCollectionContentEntity
import com.gh.gamecenter.entity.CommonCollectionEntity
import com.gh.gamecenter.game.data.CommonContentCollectionDetailItem
import com.gh.gamecenter.game.data.CommonContentCollectionDetailOldItem
import com.gh.gamecenter.game.data.CommonContentCollectionDetailRecommendCardItem
import com.gh.gamecenter.home.custom.model.CustomPageItem
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Observable
@ -15,16 +18,16 @@ class CustomCommonCollectionDetailViewModel(
application: Application,
private val mCollectionId: String,
cachedLayout: Int,
) : ListViewModel<CommonCollectionContentEntity, CommonCollectionContentEntity>(application) {
) : ListViewModel<CommonContentCollectionDetailItem, CommonContentCollectionDetailItem>(application) {
var finalLayout = cachedLayout
val commonCollectionLiveData = MutableLiveData<CommonCollectionEntity>()
fun getLayout() : Int {
fun getLayout(): Int {
return finalLayout
}
override fun provideDataObservable(page: Int): Observable<MutableList<CommonCollectionContentEntity>>? {
override fun provideDataObservable(page: Int): Observable<List<CommonContentCollectionDetailItem>>? {
return if (page == 1) {
RetrofitManager.getInstance().api
.getCommonCollectionDetail(mCollectionId)
@ -33,11 +36,40 @@ class CustomCommonCollectionDetailViewModel(
finalLayout = it.layout
}
commonCollectionLiveData.postValue(it)
it.collectionList
if (it.layout == CustomPageItem.COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD) {
it.commonCollectionRecommendCards
.map {
CommonContentCollectionDetailRecommendCardItem(it)
}
} else {
it.collectionList.map {
CommonContentCollectionDetailOldItem(it)
}
}
}
} else {
RetrofitManager.getInstance().api
.getCommonCollectionDetail(mCollectionId, page)
if (finalLayout == CustomPageItem.COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD) {
RetrofitManager.getInstance().api
.getCommonCollectionDetailWithRecommenCards(mCollectionId, page)
.map {
it
.map { entity ->
CommonContentCollectionDetailRecommendCardItem(entity)
}
.toMutableList()
}
} else {
RetrofitManager.getInstance().api
.getCommonCollectionDetail(mCollectionId, page)
.map {
it
.map { entity ->
CommonContentCollectionDetailOldItem(entity)
}
.toMutableList()
}
}
}
}

View File

@ -0,0 +1,49 @@
package com.gh.gamecenter.game.data
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.entity.CommonCollectionContentEntity
import com.gh.gamecenter.home.custom.model.CustomPageData
abstract class CommonContentCollectionDetailItem {
abstract val title: String
abstract val image: String
abstract val addedContent1: String
abstract val addedContent2: String
abstract val link: LinkEntity
}
data class CommonContentCollectionDetailOldItem(
val data: CommonCollectionContentEntity
) : CommonContentCollectionDetailItem() {
override val title: String
get() = data.title
override val image: String
get() = data.image
override val addedContent1: String
get() = data.addedContent1 ?: ""
override val addedContent2: String
get() = data.addedContent2 ?: ""
override val link: LinkEntity
get() = data.linkEntity
}
data class CommonContentCollectionDetailRecommendCardItem(
val data: CustomPageData.RecommendCard
) : CommonContentCollectionDetailItem() {
override val title: String
get() = data.title
override val image: String
get() = data.image
override val addedContent1: String
get() = data.addedContent
override val addedContent2: String
get() = ""
override val link: LinkEntity
get() = LinkEntity(link = data.linkId, type = data.linkType, linkText = data.linkText)
}

View File

@ -15,13 +15,15 @@ import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.subjectTypeToComponentStyle
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity
class GameHorizontalAdapter(
context: Context,
private var mSubjectEntity: SubjectEntity,
private var type: GameHorizontalListType = GameHorizontalListType.SubjectHorizontalType
private var type: GameHorizontalListType = GameHorizontalListType.SubjectHorizontalType,
private val trackColumnClick: Boolean = true
) : BaseRecyclerAdapter<GameHorizontalItemViewHolder>(context) {
var gameName = ""
@ -55,7 +57,7 @@ class GameHorizontalAdapter(
val size = mSubjectEntity.data!!.size - getIndex()
return if (type == GameHorizontalListType.GameDetailHorizontalType) {
size
} else if (type == GameHorizontalListType.QGameSubjectHorizontalType){
} else if (type == GameHorizontalListType.QGameSubjectHorizontalType) {
mSubjectEntity.data!!.size
} else {
when {
@ -109,8 +111,8 @@ class GameHorizontalAdapter(
DataCollectionUtils.uploadClick(mContext, path, "游戏详情", gameEntity.name)
NewLogUtils.logGameDetailPopularClick(gameName, gameId, "game", gameEntity.name ?: "")
SensorsBridge.trackGameDetailPagePopularClick(
gameId = gameName,
gameName = gameId,
gameId = gameId,
gameName = gameName,
pageName = GlobalActivityManager.getCurrentPageEntity().pageName,
pageId = GlobalActivityManager.getCurrentPageEntity().pageId,
pageBusinessId = GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
@ -123,14 +125,15 @@ class GameHorizontalAdapter(
clickGameName = gameEntity.name ?: "",
clickGameId = gameEntity.id
)
if (!gameEntity.isQQMiniGame()) {
if (!gameEntity.isQQMiniGame() && trackColumnClick) {
SensorsBridge.trackColumnClick(
location = "游戏详情",
gameName = gameName,
gameId = gameId,
gameColumnName = mSubjectEntity.name ?: "",
gameColumnId = mSubjectEntity.id ?: "",
text = "游戏"
text = "游戏",
columnPattern = subjectTypeToComponentStyle[mSubjectEntity.type] ?: ""
)
}
}

View File

@ -7,6 +7,9 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 选择游戏-添加游戏
*/
class AddGamesActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -7,6 +7,9 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 选择游戏
*/
class ChooseGamesActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -10,6 +10,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.common.exposure.ExposureSource
/**
* 游戏单详情
*/
class GameCollectionDetailActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -798,6 +798,8 @@ class GameCollectionDetailFragment :
}
}, 2000)
}
mListViewModel.refreshPackageStatus()
}
override fun onPause() {

View File

@ -10,6 +10,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.ErrorHelper
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.Constants
@ -64,6 +65,8 @@ open class GameCollectionDetailViewModel(
var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
var isPostFirstOver = false
private var packageNameSet = hashSetOf<String>()
@SuppressLint("CheckResult")
fun getGameCollectionDetail() {
mApi.getGameCollectionDetail(gameCollectionId)
@ -128,10 +131,17 @@ open class GameCollectionDetailViewModel(
add(mResultLiveData.value!![i])
}
} else {
packageNameSet = hashSetOf()
games?.forEach {
it.isAdData = adIconActive
add(CommentItemData(game = it))
it.getApk().forEach { apk ->
packageNameSet.add(apk.packageName)
}
}
refreshPackageStatus()
}
}
@ -158,6 +168,12 @@ open class GameCollectionDetailViewModel(
override fun getHandleTopCommentCondition(index: Int) =
!isHandleTopComment && gameCollectionDetail != null && topCommentId.isNotBlank() && index == 0
fun refreshPackageStatus() {
if (packageNameSet.isNotEmpty()) {
PackageHelper.refreshWrongInstallStatus(packageNameSet)
}
}
fun followingCommand(userId: String, isFollow: Boolean) {
val observable = if (isFollow) {
RetrofitManager.getInstance().api.postFollowing(userId)

View File

@ -9,6 +9,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.entity.GamesCollectionDetailEntity
/**
* 游戏单详情-封面页
*/
class GameCollectionPosterActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -4,6 +4,9 @@ import android.os.Bundle
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
/**
* 游戏单热榜
*/
class GameCollectionHotListActivity : BaseActivity() {
override fun getLayoutId(): Int {
return R.layout.activity_amway

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.entity.GameCollectionListEntity
/**
* 游戏单合集详情
*/
class GameCollectionListDetailActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -7,6 +7,9 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 我的游戏单
*/
class MyGameCollectionActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -37,6 +37,9 @@ import com.zhihu.matisse.internal.utils.PathUtils
import org.greenrobot.eventbus.EventBus
import org.json.JSONObject
/**
* 创建/编辑游戏单
*/
class GameCollectionEditActivity : ToolBarActivity() {
private lateinit var mMenuPost: MenuItem

View File

@ -5,6 +5,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.core.utils.DisplayUtils
/**
* 游戏单广场
*/
class GameCollectionSquareActivity : BaseActivity() {
override fun getLayoutId(): Int {
return R.layout.activity_amway

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.entity.TagInfoEntity
/**
* 游戏单选择标签
*/
class GameCollectionTagSelectActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -2399,6 +2399,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
DownloadManager.getInstance().addObserver(dataWatcher)
controlInstallHint()
mViewModel.refreshWrongInstallStatus()
}
override fun onFragmentPause() {

View File

@ -14,8 +14,8 @@ import com.gh.common.history.HistoryHelper
import com.gh.common.util.CheckLoginUtils
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.common.util.LibaoUtils
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.livedata.NonStickyMutableLiveData
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
@ -184,6 +184,7 @@ class GameDetailViewModel(
}
}
refreshWrongInstallStatus()
filterGameTags(data)
filterBlockedContent(data)
replaceWithMirrorInfoIfNeeded(data)
@ -256,6 +257,14 @@ class GameDetailViewModel(
}
}
fun refreshWrongInstallStatus() {
val packageNameSet = hashSetOf<String>()
game?.getApk()?.forEach {
packageNameSet.add(it.packageName)
}
PackageHelper.refreshWrongInstallStatus(packageNameSet)
}
private fun replaceWithMirrorInfoIfNeeded(data: NewGameDetailEntity) {
// 获取镜像相关数据,不存在时不替换
val mirrorData = getMirrorData(data) ?: return

View File

@ -302,7 +302,7 @@ class DescAdapter(
galleryRv.layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
subjectAdapter =
GameHorizontalAdapter(mContext, subjectEntity, GameHorizontalListType.GameDetailHorizontalType)
GameHorizontalAdapter(mContext, subjectEntity, GameHorizontalListType.GameDetailHorizontalType, false)
subjectAdapter.gameName = mGameName
subjectAdapter.game = mViewModel.game
subjectAdapter.gameId = mViewModel.gameId ?: ""

View File

@ -35,6 +35,9 @@ import org.greenrobot.eventbus.ThreadMode
import java.text.SimpleDateFormat
import java.util.*
/**
* 开服日历表
*/
class ServersCalendarActivity : ToolBarActivity() {
private lateinit var mBinding: ActivityServersCalendarBinding
private lateinit var mViewModel: ServersCalendarViewModel

View File

@ -129,7 +129,7 @@ class ServersCalendarDetailNoDataDialog : BottomSheetDialogFragment() {
HelpAndFeedbackBridge.startSuggestionActivity(
it.context,
SuggestType.GAME,
"service"
null
)
}

View File

@ -8,6 +8,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 开服订阅
*/
class ServersCalendarManagementActivity : BaseActivity_TabLayout() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -9,6 +9,9 @@ import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.feature.entity.GameEntity
/**
* 历史版本
*/
class HistoryApkListActivity : ToolBarActivity() {
companion object {

View File

@ -11,6 +11,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
/**
* 我的游戏评论
*/
@Deprecated("已废弃")
class MyRatingActivity : ToolBarActivity() {
companion object {

View File

@ -45,6 +45,9 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.abs
/**
* 评价详情
*/
@Route(path = RouteConsts.activity.ratingReplyActivity)
class RatingReplyActivity : ListActivity<RatingReplyEntity, RatingReplyViewModel>(),
KeyboardHeightObserver {

View File

@ -50,6 +50,9 @@ import okhttp3.RequestBody
import org.json.JSONObject
import retrofit2.HttpException
/**
* 评论游戏/修改游戏评论
*/
class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver {
private var mPostDialog: WaitingDialogFragment? = null

View File

@ -19,6 +19,9 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Single
/**
* 评论修改历史
*/
class CommentLogsActivity : ListActivity<RatingComment, NormalListViewModel<RatingComment>>() {
private var mAdapter: CommentLogsAdapter? = null

View File

@ -9,6 +9,9 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
/**
* 浏览记录
*/
class HistoryActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -23,6 +23,8 @@ class BannerInRecyclerController(
private var isParentScrolling = false
private var isDestroyed = false
private val onScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
isParentScrolling = newState != RecyclerView.SCROLL_STATE_IDLE
@ -37,6 +39,7 @@ class BannerInRecyclerController(
fun onViewAttachedToWindow(parent: RecyclerView?) {
isAttachToWindow = true
parent?.addOnScrollListener(onScrollListener)
start()
}
fun onViewDetachedFromWindow(parent: RecyclerView?) {
@ -46,7 +49,7 @@ class BannerInRecyclerController(
}
fun start() {
if (isActive && !isParentScrolling) {
if (isActive && !isParentScrolling && !isDestroyed) {
handler.removeCallbacksAndMessages(null)
nextToPage()
}
@ -56,7 +59,7 @@ class BannerInRecyclerController(
handler.removeCallbacksAndMessages(null)
}
private fun destroy() {
fun destroy() {
handler.removeCallbacksAndMessages(null)
}
@ -73,6 +76,7 @@ class BannerInRecyclerController(
}
override fun onDestroy(owner: LifecycleOwner) {
isDestroyed = true
destroy()
}

View File

@ -5,6 +5,7 @@ import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import com.gh.common.exposure.ExposureListener
@ -184,6 +185,10 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
}
with(viewModel) {
customPageData.observe(viewLifecycleOwner, Observer {
setNavigationTitle(it.title)
})
dataList.observe(viewLifecycleOwner) {
adapter.submitList(it)
}

View File

@ -483,6 +483,9 @@ class CustomPageViewModel(
}
}
val shareHiddenNotifications: LiveData<HashMap<String, MutableSet<String>>>
get() = repository.hiddenNotifications
private fun getPositionAndPackageMap(list: List<CustomPageItem>): HashMap<String, Int> {
val hashMap = hashMapOf<String, Int>()
list.forEach { custom ->
@ -608,10 +611,8 @@ class CustomPageViewModel(
private val _userDestination = MutableLiveData<Event<Triple<String, String, String>>>()
val userDestination: LiveData<Event<Triple<String, String, String>>> = _userDestination
override fun navigateUserHomePage(item: CustomPageItem, userId: String) {
//todo 待定
val entrance = ""
val path = ""
when {
item is CustomSubjectCollectionItem -> pageTracker.trackGameListCollectionClickWithUser(item, userId)
}
@ -634,7 +635,12 @@ class CustomPageViewModel(
private val _linkDestination = MutableLiveData<Event<Pair<LinkEntity, ExposureEvent?>>>()
val linkDestination: LiveData<Event<Pair<LinkEntity, ExposureEvent?>>> = _linkDestination
override fun navigateToLinkPage(item: CustomPageItem, link: LinkEntity, text: String, exposureEvent: ExposureEvent?) {
override fun navigateToLinkPage(
item: CustomPageItem,
link: LinkEntity,
text: String,
exposureEvent: ExposureEvent?
) {
_linkDestination.value = Event(Pair(link, exposureEvent))
}
@ -650,7 +656,8 @@ class CustomPageViewModel(
_badgeWallDestination.value = Event(comment)
}
private val _gameDetailDestinationOnAmway = MutableLiveData<Event<Triple<CustomPageTrackData, String, ExposureEvent?>>>()
private val _gameDetailDestinationOnAmway =
MutableLiveData<Event<Triple<CustomPageTrackData, String, ExposureEvent?>>>()
val gameDetailDestinationOnAmway: LiveData<Event<Triple<CustomPageTrackData, String, ExposureEvent?>>> =
_gameDetailDestinationOnAmway
@ -707,6 +714,10 @@ class CustomPageViewModel(
_gameListSquareDestination.value = Event(item)
}
fun hideNotificationItem(id: String, itemId: String) {
repository.hideNotificationItem(id, itemId)
}
private fun Disposable.addDisposable() {
compositeDisposable.add(this)
}

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