Compare commits

..

396 Commits

Author SHA1 Message Date
94ffe5a86f chore: 版本更新至 5.30.6 2023-09-20 11:03:34 +08:00
c3ddd28bad Merge branch 'pack/v5.29.2-932/remove_storage_permission_and_change_to_v5.30.4-954_rebased' into 'release'
feat: 合规代码合并 https://jira.shanqu.cc/browse/GHZS-3510

See merge request halo/android/assistant-android!1364
2023-09-20 11:01:41 +08:00
eab8bc846c feat: 合规代码合并 https://jira.shanqu.cc/browse/GHZS-3510 2023-09-20 11:01:41 +08:00
3d322b29c1 Merge branch 'hotfix/v5.30.3-953/GHZS-3484' into 'release'
修复普通微信登录也会触发 QQ 小游戏的微信登录异常 toast 问题

See merge request halo/android/assistant-android!1359
2023-09-18 09:34:12 +08:00
dcfc2f44cb fix: 微信登录提示问题 https://jira.shanqu.cc/browse/GHZS-3484 2023-09-18 09:34:12 +08:00
3afae78477 Merge branch 'hotfix/GHZS-3479' into 'release'
fix:【光环助手】通用内容合集首页显示问题 https://jira.shanqu.cc/browse/GHZS-3479

See merge request halo/android/assistant-android!1355
2023-09-14 16:26:20 +08:00
b03df595bc fix:【光环助手】通用内容合集首页显示问题 https://jira.shanqu.cc/browse/GHZS-3479 2023-09-14 16:15:52 +08:00
1c35982db0 Merge branch 'feature-GHZS-qq-game-crash' into 'release'
fix: 修复QQ小游戏调用stopAllMiniApp方法Context为空导致的崩溃问题

See merge request halo/android/assistant-android!1343
2023-09-12 13:46:54 +08:00
52f71dc79e fix: 修复QQ小游戏调用stopAllMiniApp方法Context为空导致的崩溃问题 2023-09-12 13:46:53 +08:00
a88500576f Merge branch 'hotfix/home_game_collection_refresh' into 'release'
fix: 修复首页/版块在特定情况下显示空白的问题

See merge request halo/android/assistant-android!1341
2023-09-11 17:45:05 +08:00
058eaf0a4a fix: 修复首页/版块在特定情况下显示空白的问题 2023-09-11 17:10:40 +08:00
71318fa9ef chore: 版本更新至 5.30.3 2023-09-05 10:03:01 +08:00
05b4896d6e Merge branch 'feature-GHZS-sentry-327680' into 'release'
fix: 修复QQ小游戏Activity未校验导致的BUG

See merge request halo/android/assistant-android!1319
2023-09-05 10:02:07 +08:00
7f40e45ef2 fix: 修复QQ小游戏Activity未校验导致的BUG 2023-09-05 10:02:07 +08:00
412ea87668 Merge branch 'hotfix/v5.30.2-952/sql_crashes' into 'release'
fix: 捕抓卸载畅玩游戏时的数据库闪退问题...

See merge request halo/android/assistant-android!1315
2023-09-04 11:23:33 +08:00
dc40f81ff2 fix: 捕抓卸载畅玩游戏时的数据库闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/299251/events/0dd11c01f5a5465face2b6849e5cffc4/?project=22 2023-09-04 11:15:14 +08:00
d593c54262 Merge branch 'hotfix/v5.30.2-952/number-format-issue' into 'release'
fix: 修复在部分语言设备上解压 XAPK 文件时的闪退问题...

See merge request halo/android/assistant-android!1309
2023-09-01 11:18:29 +08:00
b1e5d48098 fix: 修复在部分语言设备上解压 XAPK 文件时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/318692/?project=22&query=NumberFormatException&statsPeriod=14d 2023-09-01 11:10:21 +08:00
77ee092b5b chore: 版本更新至 5.30.2 2023-08-31 16:58:17 +08:00
c65147e309 Merge branch 'hotfix/v5.30.1-951/ad-sdk-init-issue' into 'release'
fix: 修复开屏广告有机率因为初始化问题导致无法显示的问题

See merge request halo/android/assistant-android!1307
2023-08-31 16:02:13 +08:00
1ff2bb0bcc fix: 修复开屏广告有机率因为初始化问题导致无法显示的问题 2023-08-31 15:45:46 +08:00
89ecf09b55 Merge branch 'hotfix/v5.30.1-951/gson-culprit' into 'release'
fix: 捕抓 gson toList 方法在部分设备上异常闪退的问题

See merge request halo/android/assistant-android!1304
2023-08-31 10:19:34 +08:00
2cfb227c22 fix: 捕抓 gson toList 方法在部分设备上异常闪退的问题 2023-08-31 10:18:02 +08:00
f34adc8e6d chore: 版本更新至 5.30.1 2023-08-30 17:39:45 +08:00
8606c8f87a Merge branch 'feature-GHZS-sentry-327130' into 'release'
Fix Sentry327130 QQ小游戏生命周期回调异常处理

See merge request halo/android/assistant-android!1301
2023-08-30 17:22:18 +08:00
caf2dbacf9 Fix Sentry327130 QQ小游戏生命周期回调异常处理 2023-08-30 17:22:18 +08:00
9587336b31 Merge branch 'fix/vgame_ui_issue' into 'release'
fix: 修复畅玩首页最近在玩区域的更多按钮被隐藏的问题

See merge request halo/android/assistant-android!1299
2023-08-30 15:23:31 +08:00
e1c2b2027a fix: 修复畅玩首页最近在玩区域的更多按钮被隐藏的问题 2023-08-30 15:22:39 +08:00
c5ff26c879 Merge branch 'fix/crashes' into 'release'
修复Sentry闪退问题

See merge request halo/android/assistant-android!1298
2023-08-30 15:10:57 +08:00
9690a695d4 fix: Sentry327122 https://sentry.shanqu.cc/organizations/lightgame/issues/327122/ 2023-08-30 15:06:59 +08:00
78e9c43f24 fix: Sentry323027 https://sentry.shanqu.cc/organizations/lightgame/issues/323027/ 2023-08-30 15:06:59 +08:00
7cfa26ff02 Merge branch 'build/build_issue' into 'dev'
build: 将 QQ 小游戏的类添加到移除日志输出白名单,避免无法编译

See merge request halo/android/assistant-android!1292
2023-08-29 11:55:24 +08:00
a7335d21c5 build: 将 QQ 小游戏的类添加到移除日志输出白名单,避免无法编译 2023-08-29 11:54:43 +08:00
0fd84f8b44 Merge branch 'fix/csj-privacy-issue' into 'dev'
fix: 处理穿山甲 SDK 的自动初始化问题,穿山甲 SDK 区分测试和正式 ID

See merge request halo/android/assistant-android!1288
2023-08-28 09:51:41 +08:00
43bcf78dea Merge branch 'fix/GHZS-3317' into 'dev'
fix: 【光环助手】插件通知业务:已通知的消息图片不展示以及批量回复“未回复”用户报错(1) https://jira.shanqu.cc/browse/GHZS-3317

See merge request halo/android/assistant-android!1289
2023-08-28 09:51:33 +08:00
fb44391500 fix: 处理穿山甲 SDK 的自动初始化问题,穿山甲 SDK 区分测试和正式 ID 2023-08-28 09:44:20 +08:00
4c4de337cd fix: 【光环助手】插件通知业务:已通知的消息图片不展示以及批量回复“未回复”用户报错(1) https://jira.shanqu.cc/browse/GHZS-3317 2023-08-28 09:41:45 +08:00
625e448928 Merge branch 'fix/qGame_culprit' into 'dev'
fix: 修复专题详情默认为 QQ 小游戏的问题

See merge request halo/android/assistant-android!1286
2023-08-25 16:04:53 +08:00
2bfefc5082 fix: 修复专题详情默认为 QQ 小游戏的问题 2023-08-25 16:00:17 +08:00
1538d77960 Merge branch 'feature-GHZS-3273' into 'dev'
feat: 【光环助手】同步正式问题—QQ小游戏SDK https://jira.shanqu.cc/browse/GHZS-3273

See merge request halo/android/assistant-android!1284
2023-08-24 17:41:27 +08:00
9f77e70c16 feat: 【光环助手】同步正式问题—QQ小游戏SDK https://jira.shanqu.cc/browse/GHZS-3273 2023-08-24 17:41:27 +08:00
630f78e62d Merge branch 'feature-sentry-318553' into 'dev'
fix: Sentry318553

See merge request halo/android/assistant-android!1279
2023-08-18 16:55:52 +08:00
dc7b103cbc fix: Sentry318553 2023-08-18 16:55:52 +08:00
d30f51123d Merge branch 'feature-GHZS-2966-new' into 'dev'
feat: QQ小游戏SDK接入—客户端 https://jira.shanqu.cc/browse/GHZS-2966

See merge request halo/android/assistant-android!1278
2023-08-18 15:23:19 +08:00
00f625c350 feat: QQ小游戏SDK接入—客户端 https://jira.shanqu.cc/browse/GHZS-2966 2023-08-18 15:23:19 +08:00
95f63bd4f2 Merge branch 'feat/GHZS-3252' into 'dev'
feat: 已安装列表权限-合规整改 https://jira.shanqu.cc/browse/GHZS-3249

See merge request halo/android/assistant-android!1276
2023-08-17 16:53:41 +08:00
07a1b2a63b feat: 已安装列表权限-合规整改 https://jira.shanqu.cc/browse/GHZS-3249 2023-08-17 16:29:29 +08:00
6a36874ef8 Merge branch 'fix/GHZS-3242' into 'dev'
fix: 订阅&推送体系优化-消息中心优化—0816测试-客户端(1) https://jira.shanqu.cc/browse/GHZS-3242

See merge request halo/android/assistant-android!1271
2023-08-16 18:02:13 +08:00
285e0caafe fix: 订阅&推送体系优化-消息中心优化—0816测试-客户端(1) https://jira.shanqu.cc/browse/GHZS-3242 2023-08-16 17:51:09 +08:00
0e0c6c48af Merge branch 'fix/GHZS-3242' into 'dev'
fix: 订阅&推送体系优化-消息中心优化—0816测试-客户端(2) https://jira.shanqu.cc/browse/GHZS-3242

See merge request halo/android/assistant-android!1269
2023-08-16 17:30:07 +08:00
38c02380ad fix: 订阅&推送体系优化-消息中心优化—0816测试-客户端(2) https://jira.shanqu.cc/browse/GHZS-3242 2023-08-16 16:24:16 +08:00
bf5608492d Merge branch 'fix/GHZS-3217' into 'dev'
fix: 搜索结果列表跳转开服表问题 https://jira.shanqu.cc/browse/GHZS-3217

See merge request halo/android/assistant-android!1267
2023-08-16 15:42:55 +08:00
267f03fd42 fix: 搜索结果列表跳转开服表问题 https://jira.shanqu.cc/browse/GHZS-3217 2023-08-16 15:23:53 +08:00
d39a62d4e0 Merge branch 'fix/home_game_library_download_hint' into 'dev'
fix: 修复添加游戏下载时游戏库下载按钮没有提示的问题

See merge request halo/android/assistant-android!1264
2023-08-16 13:44:21 +08:00
5d02c40227 fix: 修复添加游戏下载时游戏库下载按钮没有提示的问题 2023-08-16 11:53:51 +08:00
910d1eb6b7 Merge branch 'fix/GHZS-3218' into 'dev'
fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218

See merge request halo/android/assistant-android!1263
2023-08-16 11:51:18 +08:00
755a2a0633 fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218 2023-08-16 11:28:13 +08:00
1a33e24a85 Merge branch 'fix/GHZS-3218' into 'dev'
fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218

See merge request halo/android/assistant-android!1261
2023-08-15 17:39:26 +08:00
9a9c219082 fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218 2023-08-15 17:36:37 +08:00
3e9c3027f2 Merge branch 'fix/GHZS-3218' into 'dev'
fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218

See merge request halo/android/assistant-android!1260
2023-08-15 15:17:35 +08:00
c895965822 fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218 2023-08-15 15:16:16 +08:00
8dff7f3e69 Merge branch 'fix/multiprocess_init_ad_error' into 'dev'
fix: 修复部分广告 SDK 相关的问题

See merge request halo/android/assistant-android!1251
2023-08-15 15:06:02 +08:00
5abb229fcc fix: 修复因接口返回速度不够快时可能导致首页弹窗无法正常弹出的问题 2023-08-15 15:02:29 +08:00
d0b6d4ae5c Merge branch 'fix/GHZS-3221' into 'dev'
fix: 消息中心优化测试:游戏动态更新,但消息中心入口的红点未作提醒 https://jira.shanqu.cc/browse/GHZS-3221

See merge request halo/android/assistant-android!1258
2023-08-15 09:45:06 +08:00
772a21210d fix: 消息中心优化埋点测试:发现从消息中心到游戏详情下载埋点事件的来源属性为空 https://jira.shanqu.cc/browse/GHZS-3225 2023-08-14 16:46:57 +08:00
b81df5b2ad fix: 修复消息会话列表动图图标圆角裁切不生效的问题 2023-08-14 15:21:22 +08:00
07c44ef6a1 fix: 消息中心优化测试:游戏动态更新,但消息中心入口的红点未作提醒 https://jira.shanqu.cc/browse/GHZS-3221 2023-08-14 15:07:28 +08:00
6aa1a0a00e Merge branch 'fix/GHZS-3223' into 'dev'
fix: 消息中心优化埋点测试:message_inform_message_click的会话类型埋点错误 https://jira.shanqu.cc/browse/GHZS-3223

See merge request halo/android/assistant-android!1257
2023-08-14 13:47:47 +08:00
c6890cee19 fix: 消息中心优化埋点测试:message_inform_message_click的会话类型埋点错误 https://jira.shanqu.cc/browse/GHZS-3223 2023-08-14 13:45:46 +08:00
f83a4035c3 Merge branch 'fix/GHZS-3218' into 'dev'
fix: 订阅&推送体系优化-消息中心优化—0811UI测试(3) https://jira.shanqu.cc/browse/GHZS-3213

See merge request halo/android/assistant-android!1256
2023-08-14 09:56:38 +08:00
5fc03780a9 fix: 订阅&推送体系优化-消息中心优化—0811UI测试(3) https://jira.shanqu.cc/browse/GHZS-3213
fix: 消息中心优化测试:消息中心入口的红点的显示样式异常 https://jira.shanqu.cc/browse/GHZS-3218
2023-08-14 09:55:01 +08:00
ac7828c9f2 Merge branch 'fix/GHZS-3215' into 'dev'
fix: 【光环助手】首页下拉推送相关问题(2) https://jira.shanqu.cc/browse/GHZS-3215

See merge request halo/android/assistant-android!1255
2023-08-11 17:18:12 +08:00
270a02366d fix: 【光环助手】首页下拉推送相关问题(2) https://jira.shanqu.cc/browse/GHZS-3215 2023-08-11 17:14:20 +08:00
25d96aba67 Merge branch 'fix/GHZS-2953' into 'dev'
fix: 消息中心优化测试:消息中心入口的未读与消息列表不一致 https://jira.shanqu.cc/browse/GHZS-3208

See merge request halo/android/assistant-android!1254
2023-08-11 16:17:55 +08:00
f6558e1e13 fix: 订阅&推送体系优化-消息中心优化—0811UI测试 https://jira.shanqu.cc/browse/GHZS-3213 2023-08-11 16:10:51 +08:00
7784cecdbc fix: 消息中心优化测试:测试提问帖邀请消息,发现能收到消息,但会话消息列表没有消息 https://jira.shanqu.cc/browse/GHZS-3205 2023-08-11 15:46:42 +08:00
ad3301e0a8 fix: 订阅&推送体系优化-消息中心优化—0811UI测试 https://jira.shanqu.cc/browse/GHZS-3213 2023-08-11 14:54:05 +08:00
8f2ee5d323 fix: 消息中心优化测试:消息中心入口的未读与消息列表不一致 https://jira.shanqu.cc/browse/GHZS-3208
fix: 消息中心优化测试:会话消息设置免打扰或取消免打扰时,页面没有立即响应 https://jira.shanqu.cc/browse/GHZS-3209
2023-08-11 14:38:51 +08:00
9a999eefb7 Merge branch 'fix/GHZS-2953' into 'dev'
fix: 消息中心优化测试:会话消息列表未做已读规则 https://jira.shanqu.cc/browse/GHZS-3200

See merge request halo/android/assistant-android!1253
2023-08-11 11:16:07 +08:00
cdb274229b fix: 消息中心优化测试:会话消息列表未做已读规则 https://jira.shanqu.cc/browse/GHZS-3200
fix: 消息中心优化测试:消息中心入口的红点提醒,无法被消除 https://jira.shanqu.cc/browse/GHZS-3202
fix: 消息中心优化:消息中心入口的未读提醒,冷启动时没有响应,要切换页面才有 https://jira.shanqu.cc/browse/GHZS-3203
2023-08-11 11:10:59 +08:00
b20a3717e1 Merge branch 'fix/GHZS-3183' into 'dev'
fix: 补充消息中心模块混淆规则

See merge request halo/android/assistant-android!1252
2023-08-10 16:48:49 +08:00
3ef8dea4d2 fix: 补充消息中心模块混淆规则 2023-08-10 16:33:46 +08:00
17ee9752d3 fix: 避免多进程初始化广告 SDK 2023-08-10 11:18:10 +08:00
a5992750ed Merge branch 'fix/update_gid' into 'dev'
fix: 更新 gid 版本,避免闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/313421/?project=22

See merge request halo/android/assistant-android!1249
2023-08-10 09:25:38 +08:00
8b76b72222 fix: 更新 gid 版本,避免闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/313421/?project=22 2023-08-10 09:25:04 +08:00
ad6b7228cf Merge branch 'feat/GHZS-3035' into 'dev'
feat: 推广打包功能相关优化 https://jira.shanqu.cc/browse/GHZS-3035

See merge request halo/android/assistant-android!1247
2023-08-09 14:04:24 +08:00
9a0873cf67 feat: 推广打包功能相关优化 https://jira.shanqu.cc/browse/GHZS-3035 2023-08-09 13:50:34 +08:00
6cf461dbf7 Merge remote-tracking branch 'origin/release' into dev 2023-08-09 09:59:32 +08:00
f33595c4c4 Merge branch 'fix/pack_parse_issue' into 'release'
fix: 更新打包解析字段

See merge request halo/android/assistant-android!1245
2023-08-08 17:36:31 +08:00
f6f2db4b6f fix: 更新打包解析字段 2023-08-08 17:35:44 +08:00
68252a4375 Merge remote-tracking branch 'origin/release' into dev 2023-08-08 16:21:10 +08:00
c57a9f44a2 Merge branch 'feat/GHZS-3039' into 'release'
feat: 快手可选是否使用默认渠道 SDK https://jira.shanqu.cc/browse/GHZS-3039

See merge request halo/android/assistant-android!1244
2023-08-08 16:10:48 +08:00
2fb90cb5d4 feat: 快手可选是否使用默认渠道 SDK https://jira.shanqu.cc/browse/GHZS-3039 2023-08-08 16:02:14 +08:00
9925022660 Merge branch 'feature/GHZS-2992' into 'dev'
feat: 订阅&推送体系优化-消息中心优化—客户端 https://jira.shanqu.cc/browse/GHZS-2992

See merge request halo/android/assistant-android!1243
2023-08-08 14:56:32 +08:00
5972b8b4bf feat: 订阅&推送体系优化-消息中心优化—客户端 https://jira.shanqu.cc/browse/GHZS-2992 2023-08-08 14:03:32 +08:00
f31507ae9f Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/search/SearchGameResultViewModel.kt
#	dependencies.gradle
2023-08-08 10:03:10 +08:00
ab984d133a Merge branch 'fix/GHZS-3126' into 'release'
fix: 视频帖播放问题 https://jira.shanqu.cc/browse/GHZS-3126

See merge request halo/android/assistant-android!1241
2023-08-07 13:54:21 +08:00
7440998d5f fix: 视频帖播放问题 https://jira.shanqu.cc/browse/GHZS-3126 2023-08-07 13:45:21 +08:00
1e6351a11c Merge branch 'fix/GHZS-3141' into 'release'
fix: 【光环助手】首页下拉推送未自动弹出问题 https://jira.shanqu.cc/browse/GHZS-3141

See merge request halo/android/assistant-android!1240
2023-08-07 10:47:42 +08:00
78d9bde4c7 fix: 【光环助手】首页下拉推送未自动弹出问题 https://jira.shanqu.cc/browse/GHZS-3141 2023-08-07 09:49:28 +08:00
dec546238e Merge branch 'fix/GHZS-3129' into 'dev'
fix: 修复游戏下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-3129

See merge request halo/android/assistant-android!1239
2023-08-04 16:51:44 +08:00
5715d36ad1 fix: 修复游戏下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-3129 2023-08-04 16:40:58 +08:00
351e1d2eba Merge branch 'fix/home_game_collection' into 'release'
fix: 修复删除下载任务时首页游戏单下载按钮没有更新的问题

See merge request halo/android/assistant-android!1238
2023-08-04 10:35:32 +08:00
0a067eb9dd fix: 修复删除下载任务时首页游戏单下载按钮没有更新的问题 2023-08-04 10:33:26 +08:00
c62021ee64 Merge branch 'fix/home_game_collection' into 'dev'
fix: 修复删除下载任务时首页游戏单下载按钮没有更新的问题

See merge request halo/android/assistant-android!1237
2023-08-04 10:29:59 +08:00
7bab11d2a1 fix: 修复删除下载任务时首页游戏单下载按钮没有更新的问题 2023-08-04 10:09:33 +08:00
5bb2451750 Merge branch 'fix/ad_culprit' into 'dev'
fix: 修复开屏广告在部分数据为空时候的显示问题

See merge request halo/android/assistant-android!1236
2023-08-03 17:55:03 +08:00
ef0341ad6d fix: 修复开屏广告在部分数据为空时候的显示问题 2023-08-03 17:50:51 +08:00
a97a0d64a4 Merge branch 'hotfix/v5.29.2-932/GHZS-3122' into 'release'
fix: 修复搜索专题的超出搜索结构数量后的排序问题 https://jira.shanqu.cc/browse/GHZS-3122

See merge request halo/android/assistant-android!1234
2023-08-03 11:54:52 +08:00
627190ddb7 fix: 修复搜索专题的超出搜索结构数量后的排序问题 https://jira.shanqu.cc/browse/GHZS-3122 2023-08-03 11:51:14 +08:00
f1139add2a chore: 版本更新至 5.29.2 2023-08-03 11:03:45 +08:00
ba59291932 Merge branch 'feature-fix-xapk-installer-crash' into 'release'
Fix 修复Sentry上XApk相关的一些BUG

See merge request halo/android/assistant-android!1232
2023-08-03 10:44:42 +08:00
d3a8bafe8b Fix 修复Sentry上XApk相关的一些BUG 2023-08-03 10:44:42 +08:00
4cfc98ec5a Merge branch 'hotfix/v5.29.1-931/vdownload_crash' into 'release'
fix: 修复删除下载内容时 apkEntity 为空导致的空指针闪退...

See merge request halo/android/assistant-android!1233
2023-08-03 10:36:29 +08:00
86b7924a55 fix: 修复删除下载内容时 apkEntity 为空导致的空指针闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/319106/?project=22&query=dist%3A931+level%3Afatal&sort=freq&statsPeriod=14d 2023-08-03 10:32:56 +08:00
f645964bdf Merge branch 'fix/GHZS-3115' into 'dev'
fix: 新增广告位管理功能—0802优化(1,3,5)  https://jira.shanqu.cc/browse/GHZS-3115

See merge request halo/android/assistant-android!1231
2023-08-03 09:27:24 +08:00
e420b261bb fix: 新增广告位管理功能—0802优化(1,3,5) https://jira.shanqu.cc/browse/GHZS-3115 2023-08-03 09:22:48 +08:00
1781f4c665 Merge branch 'fix/cloud_archive_sync_issue' into 'dev'
feat: 补上遗漏的跨光环和畅玩组件间的云存档下载数据同步功能 https://jira.shanqu.cc/browse/GHZS-2886

See merge request halo/android/assistant-android!1230
2023-08-02 16:33:56 +08:00
ee79ed528b feat: 补上遗漏的跨光环和畅玩组件间的云存档下载数据同步功能 https://jira.shanqu.cc/browse/GHZS-2886 2023-08-02 15:47:19 +08:00
fc9137a48d Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-08-02 11:21:14 +08:00
37a6dae3b5 Merge branch 'hotfix/v5.29.1-931/GHZS-3094' into 'release'
fix: 游戏专题-换一批加载问题 https://jira.shanqu.cc/browse/GHZS-3094

See merge request halo/android/assistant-android!1229
2023-08-01 11:33:01 +08:00
4cbd4fe629 fix: 游戏专题-换一批加载问题 https://jira.shanqu.cc/browse/GHZS-3094 2023-08-01 11:28:24 +08:00
44df5dc061 Merge branch 'hotfix/v5.29.1-931/db_crash' into 'release'
fix: 修复多进程初始化下载数据库出现的闪退问题...

See merge request halo/android/assistant-android!1228
2023-07-31 14:50:05 +08:00
9f144a638b fix: 尝试修复畅玩数据库 observeForever 导致的数据错乱和闪退问题 2023-07-31 14:34:45 +08:00
18276c5941 fix: 修复多进程初始化下载数据库出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/295121/events/7dc71a556b3242ab94054454e99a92a3/?project=22 2023-07-31 10:28:15 +08:00
385d197e31 chore: 版本更新至 5.29.1 2023-07-31 09:50:14 +08:00
2dceaeec3e Merge remote-tracking branch 'origin/dev' into dev-5.30.0
# Conflicts:
#	app/build.gradle
2023-07-31 09:36:08 +08:00
f59bc42539 Merge branch 'fix/GHZS-3051' into 'dev-5.30.0'
fix: 游戏搜索-热门标签 补充相关曝光数据—0728测试(0729测试) https://jira.shanqu.cc/browse/GHZS-3051

See merge request halo/android/assistant-android!1227
2023-07-31 09:28:26 +08:00
5b7c98224c fix: 游戏搜索-热门标签 补充相关曝光数据—0728测试(0729测试) https://jira.shanqu.cc/browse/GHZS-3051 2023-07-31 09:21:45 +08:00
2542311341 Merge branch 'fix/sentry_log' into 'dev'
fix: 移除部分 sentry 的测试用 log

See merge request halo/android/assistant-android!1226
2023-07-28 18:07:45 +08:00
f4d001a821 fix: 移除部分 sentry 的测试用 log 2023-07-28 17:44:03 +08:00
2710c03112 Merge branch 'fix/GHZS-3051' into 'dev-5.30.0'
fix: 游戏搜索-热门标签 补充相关曝光数据—0728测试 https://jira.shanqu.cc/browse/GHZS-3051

See merge request halo/android/assistant-android!1225
2023-07-28 16:33:05 +08:00
3341d55f5a fix: 游戏搜索-热门标签 补充相关曝光数据—0728测试 https://jira.shanqu.cc/browse/GHZS-3051 2023-07-28 16:23:12 +08:00
bbca9c17e7 Merge branch 'feat/GHZS-3039' into 'dev'
feat: 推广打包功能相关优化 https://jira.shanqu.cc/browse/GHZS-3039

See merge request halo/android/assistant-android!1224
2023-07-28 15:46:28 +08:00
d84cca5ab9 feat: 推广打包功能相关优化 https://jira.shanqu.cc/browse/GHZS-3039 2023-07-28 15:39:06 +08:00
99d1185333 Merge branch 'feat/GHZS-3054' into 'dev'
feat: 助手V5.29剥离广告SDK https://jira.shanqu.cc/browse/GHZS-3054

See merge request halo/android/assistant-android!1223
2023-07-28 13:57:24 +08:00
9f6611f877 feat: 助手V5.29剥离广告SDK https://jira.shanqu.cc/browse/GHZS-3054 2023-07-28 13:56:30 +08:00
f81d315800 Merge branch 'feat/GHZS-2989' into 'dev-5.30.0'
feat: 右下悬浮窗新增埋点 https://jira.shanqu.cc/browse/GHZS-2989

See merge request halo/android/assistant-android!1222
2023-07-28 11:55:12 +08:00
33f5badfd9 feat: 右下悬浮窗新增埋点 https://jira.shanqu.cc/browse/GHZS-2989 2023-07-28 11:47:01 +08:00
0407244cca Merge branch 'feat/GHZS-2919' into 'dev-5.30.0'
新增广告位管理功能

See merge request halo/android/assistant-android!1221
2023-07-28 11:30:52 +08:00
64449ec38b feat: 新增广告位管理功能 https://jira.shanqu.cc/browse/GHZS-2919 2023-07-28 10:28:49 +08:00
fb937e8ced feat: 完成穿山甲广告SDK接入 https://jira.shanqu.cc/browse/GHZS-2940 2023-07-28 10:16:52 +08:00
96f9e8aceb Merge remote-tracking branch 'origin/dev' into dev-5.30.0
# Conflicts:
#	app/src/main/java/com/gh/common/xapk/XapkInstaller.kt
#	app/src/main/res/values/strings.xml
#	module_common/src/main/java/com/gh/gamecenter/common/utils/DialogHelper.kt
#	module_common/src/main/java/com/gh/gamecenter/common/utils/MiuiUtils.java
#	module_common/src/main/java/com/gh/gamecenter/common/utils/SystemUtils.kt
2023-07-28 10:11:25 +08:00
be294fbba5 Merge branch 'fix/home_game_tab' into 'dev-5.30.0'
fix: 修复游戏库最后一个Tab选中时Tab被切图遮挡的问题

See merge request halo/android/assistant-android!1220
2023-07-27 15:30:36 +08:00
aabc676f94 fix: 修复游戏库最后一个Tab选中时Tab被切图遮挡的问题 2023-07-27 15:26:26 +08:00
24e6f93eae Merge branch 'fix/search_paging_error' into 'dev'
fix: 修复搜索结果的分页问题

See merge request halo/android/assistant-android!1219
2023-07-26 17:13:42 +08:00
9a75e242e6 fix: 修复搜索结果的分页问题 2023-07-26 17:04:07 +08:00
4c867390c2 Merge branch 'feature/GHZS-2972' into 'dev-5.30.0'
feat: 组件化消息中心相关功能 https://jira.shanqu.cc/browse/GHZS-2972

See merge request halo/android/assistant-android!1218
2023-07-24 17:49:02 +08:00
f9c6bb1e56 feat: 组件化消息中心相关功能 https://jira.shanqu.cc/browse/GHZS-2972 2023-07-24 17:49:02 +08:00
3a15f9af33 Merge branch 'feature-GHZS-3018' into 'dev'
fix: MIUI优化关闭提示弹窗—0720测试 https://jira.shanqu.cc/browse/GHZS-3001

See merge request halo/android/assistant-android!1217
2023-07-24 11:55:52 +08:00
6920d682b2 fix: MIUI优化关闭提示弹窗—0720测试 https://jira.shanqu.cc/browse/GHZS-3001 2023-07-24 11:55:52 +08:00
b0493502e4 Merge branch 'feature-dev-cherry-pick-GHZS-2901' into 'dev'
feat: MIUI优化关闭提示弹窗—客户端 https://jira.shanqu.cc/browse/GHZS-2901

See merge request halo/android/assistant-android!1216
2023-07-24 11:39:55 +08:00
723202d4ce feat: MIUI优化关闭提示弹窗—客户端 https://jira.shanqu.cc/browse/GHZS-2901 2023-07-24 11:36:49 +08:00
33ed2796c8 Merge remote-tracking branch 'origin/dev' into dev-5.30.0 2023-07-24 10:48:52 +08:00
6e0628b478 Merge remote-tracking branch 'origin/release' into dev 2023-07-24 10:42:53 +08:00
7f14555886 Merge branch 'hotfix/v5.28.2-912/crashes' into 'release'
修复 5.28.2 的部分线上闪退

See merge request halo/android/assistant-android!1215
2023-07-24 10:41:52 +08:00
c2477d2a3f fix: 捕抓畅玩游戏创建快捷方式时的闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/300166/?project=22&query=dist%3A912+level%3Afatal&statsPeriod=14d 2023-07-24 10:24:51 +08:00
8ff4945cfa fix: 修复曝光上报时的空指针问题 https://sentry.shanqu.cc/organizations/lightgame/issues/301370/events/4fed437358844787bb532a12283205b6/?project=22 2023-07-24 10:15:21 +08:00
fcc65fdbfe fix: 修复上层下载持有错误下载状态时,暂停任务导致的空指针闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/304224/?project=22 2023-07-24 10:05:52 +08:00
d4b0ecce98 fix: 修复下载其它内容时偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/314990/?project=22 2023-07-24 09:44:52 +08:00
c4fb785e55 Merge branch 'fix/channel_issue' into 'dev-5.30.0'
fix: 修复渠道更换的保存问题

See merge request halo/android/assistant-android!1214
2023-07-21 18:07:38 +08:00
848ca0b5c6 Merge branch 'fix/pkg_issue' into 'dev'
fix: 修复特殊打包选择首页 tab 异常的问题

See merge request halo/android/assistant-android!1213
2023-07-21 17:58:40 +08:00
8d5e6c8940 fix: 修复渠道更换的保存问题 2023-07-21 17:51:51 +08:00
4f0c81420e fix: 修复特殊打包选择首页 tab 异常的问题 2023-07-21 17:38:32 +08:00
0c437d32bd Merge branch 'feat/GHZS-2910' into 'dev'
feat: 关于我们页面新增安装包隐藏信息提示 https://jira.shanqu.cc/browse/GHZS-2910

See merge request halo/android/assistant-android!1212
2023-07-21 14:31:53 +08:00
25d9771a3c feat: 关于我们页面新增安装包隐藏信息提示 https://jira.shanqu.cc/browse/GHZS-2910 2023-07-21 14:01:44 +08:00
668b54ac6d Merge branch 'feature-GHZS-2987' into 'dev'
fix: 【光环助手】同步正式环境问题-插件化安装弹窗 https://jira.shanqu.cc/browse/GHZS-2987

See merge request halo/android/assistant-android!1211
2023-07-21 11:40:53 +08:00
92b0f8fe73 fix: 【光环助手】同步正式环境问题-插件化安装弹窗 https://jira.shanqu.cc/browse/GHZS-2987 2023-07-21 11:39:07 +08:00
f258b71648 Merge branch 'feature-GHZS-2884' into 'dev-5.30.0'
feat: 游戏下载新增跳转第三方落地页—客户端 https://jira.shanqu.cc/browse/GHZS-2884

See merge request halo/android/assistant-android!1210
2023-07-21 09:36:35 +08:00
f3679aa041 feat: 游戏下载新增跳转第三方落地页—客户端 https://jira.shanqu.cc/browse/GHZS-2884 2023-07-21 09:23:51 +08:00
3b02c9df23 Merge branch 'feature/GHZS-2978' into 'dev-5.30.0'
feat: 游戏搜索-热门标签 补充相关曝光数据—客户端 https://jira.shanqu.cc/browse/GHZS-2978

See merge request halo/android/assistant-android!1209
2023-07-20 17:17:36 +08:00
1034254613 feat: 游戏搜索-热门标签 补充相关曝光数据—客户端 https://jira.shanqu.cc/browse/GHZS-2978 2023-07-20 17:14:52 +08:00
bc3e92c4a1 Merge branch 'feature/GHZS-2912' into 'dev-5.30.0'
feat: 游戏库增加顶部tab栏—客户端 https://jira.shanqu.cc/browse/GHZS-2912

See merge request halo/android/assistant-android!1208
2023-07-20 09:47:18 +08:00
c7dabaa37b Merge branch 'dev-5.30.0' into feature/GHZS-2912
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt
2023-07-20 09:40:21 +08:00
69866eaf91 Merge remote-tracking branch 'origin/dev' into dev-5.30.0 2023-07-19 19:26:05 +08:00
f689dfce07 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-07-19 19:22:43 +08:00
5a8f1d663d feat: 游戏库增加顶部tab栏—客户端 https://jira.shanqu.cc/browse/GHZS-2912 2023-07-19 14:46:19 +08:00
42d5d46e53 chore: 版本更新至 5.28.2 2023-07-18 16:13:09 +08:00
cdccc35703 Merge branch 'feature-GHZS-2946' into 'release'
fix: 修复线上闪退问题 https://jira.shanqu.cc/browse/GHZS-2946

See merge request halo/android/assistant-android!1207
2023-07-18 16:08:44 +08:00
d3e2fea019 fix: 修复线上闪退问题 https://jira.shanqu.cc/browse/GHZS-2946 2023-07-18 16:08:44 +08:00
f343841233 Merge branch 'fix/GHZS-2948' into 'release'
fix: 修复线上闪退问题 https://jira.shanqu.cc/browse/GHZS-2948

See merge request halo/android/assistant-android!1206
2023-07-18 14:58:47 +08:00
f62083eff2 fix: 修复线上闪退问题 https://jira.shanqu.cc/browse/GHZS-2948 2023-07-18 14:58:47 +08:00
8594e998c2 Merge branch 'fix/vspace_dialog_dismiss_issue' into 'release'
fix: 修复畅玩弹窗在组件安装完成以后的 dismiss 问题

See merge request halo/android/assistant-android!1205
2023-07-17 17:54:15 +08:00
6865706b0f fix: 修复畅玩弹窗在组件安装完成以后的 dismiss 问题 2023-07-17 17:50:23 +08:00
bfb8b46ce8 Merge branch 'fix/GHZS-2941' into 'dev'
fix:【光环助手】畅玩助手神策数据流程优化 https://jira.shanqu.cc/browse/GHZS-2941

See merge request halo/android/assistant-android!1204
2023-07-17 17:34:40 +08:00
b6d8ca4d84 Merge branch 'feat/GHZS-2959' into 'release'
feat: 神策渠道调整 https://jira.shanqu.cc/browse/GHZS-2959

See merge request halo/android/assistant-android!1203
2023-07-17 16:14:05 +08:00
455e1f0432 feat: 神策渠道调整 https://jira.shanqu.cc/browse/GHZS-2959 2023-07-17 16:12:29 +08:00
ba27c09096 fix:【光环助手】畅玩助手神策数据流程优化 https://jira.shanqu.cc/browse/GHZS-2941 2023-07-17 15:03:16 +08:00
15276cc4b3 Merge branch 'hotfix/v5.28.1-911/crashes' into 'release'
修复部分线上闪退

See merge request halo/android/assistant-android!1202
2023-07-17 11:53:17 +08:00
130a7cdf2a fix: 修复因为混淆造成的下载数据恢复闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/281841/?project=22 2023-07-17 11:08:11 +08:00
164ec0c368 fix: 捕抓首页 tab 的 roundToInt 闪退异常 2023-07-17 11:07:11 +08:00
2be72776ce Merge branch 'feature-GHZS-2901' into 'dev-5.30.0'
feat: MIUI优化关闭提示弹窗—客户端 https://jira.shanqu.cc/browse/GHZS-2901

See merge request halo/android/assistant-android!1201
2023-07-17 09:51:44 +08:00
d92f6ff164 feat: MIUI优化关闭提示弹窗—客户端 https://jira.shanqu.cc/browse/GHZS-2901 2023-07-17 09:46:55 +08:00
756bc66f26 Merge branch 'fix/GHZS-2945' into 'dev'
fix:【光环助手】内容导航栏图标闪烁 https://jira.shanqu.cc/browse/GHZS-2945

See merge request halo/android/assistant-android!1200
2023-07-17 09:45:10 +08:00
e589bce5c6 fix:【光环助手】内容导航栏图标闪烁 https://jira.shanqu.cc/browse/GHZS-2945 2023-07-17 09:36:28 +08:00
991bd22511 Merge branch 'fix/sensors_log' into 'release'
fix: 修复畅玩助手下载弹窗错误上报安装点击事件的问题

See merge request halo/android/assistant-android!1199
2023-07-14 17:05:55 +08:00
df1ab5221d fix: 修复畅玩助手下载弹窗错误上报安装点击事件的问题 2023-07-14 16:41:51 +08:00
9aaeee9b3d Merge remote-tracking branch 'origin/dev' into dev-5.30.0 2023-07-14 10:01:59 +08:00
70916fd0f7 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/home/gamecollection/carousel/HomeGameCollectionCarouselAdapter.kt
#	dependencies.gradle
2023-07-14 09:58:36 +08:00
226d6c4f2c chore: 版本更新至 5.28.1 2023-07-13 17:25:06 +08:00
896adc9d36 Merge branch 'feature-data-watcher-patch' into 'release'
fix: Sentry312134...

See merge request halo/android/assistant-android!1198
2023-07-13 15:35:48 +08:00
0e33abebdd fix: Sentry312134... 2023-07-13 15:35:48 +08:00
b4e94eeabb Merge branch 'feature-GHZS-2855' into 'dev-5.30.0'
feat: 优化内部测试包的渠道切换功能 https://jira.shanqu.cc/browse/GHZS-2855

See merge request halo/android/assistant-android!1197
2023-07-12 16:04:48 +08:00
6f86dd7eef feat: 优化内部测试包的渠道切换功能 https://jira.shanqu.cc/browse/GHZS-2855 2023-07-12 15:58:33 +08:00
c8ed126605 Merge branch 'fix/GHZS-2926' into 'release'
fix:【光环助手】游戏单封面图显示问题 https://jira.shanqu.cc/browse/GHZS-2926

See merge request halo/android/assistant-android!1196
2023-07-12 14:48:17 +08:00
b510a329b6 fix:【光环助手】游戏单封面图显示问题 https://jira.shanqu.cc/browse/GHZS-2926 2023-07-12 14:36:38 +08:00
04d001a055 Merge branch 'feature/GHZS-2806' into 'dev-5.30.0'
feat: 插件管理功能优化-新增插件发布上架通知提醒—客户端 https://jira.shanqu.cc/browse/GHZS-2806

See merge request halo/android/assistant-android!1194
2023-07-11 16:07:15 +08:00
2de1ba4e1d Merge branch 'fix/GHZS-2907' into 'release'
fix: 神策埋点—07/10测试 (3) https://jira.shanqu.cc/browse/GHZS-2907

See merge request halo/android/assistant-android!1195
2023-07-11 15:37:47 +08:00
e4a0f0e68b fix: 神策埋点—07/10测试 (3) https://jira.shanqu.cc/browse/GHZS-2907 2023-07-11 15:31:44 +08:00
f10b08e152 feat: 插件管理功能优化-新增插件发布上架通知提醒—客户端 https://jira.shanqu.cc/browse/GHZS-2806 2023-07-11 14:33:04 +08:00
c064f9d3a6 Merge branch 'feat/core_event_with_toast' into 'release'
fix: 特殊包上报比例为 1 时关键行为进行 toast 提示(方便测试)

See merge request halo/android/assistant-android!1190
2023-07-11 13:52:00 +08:00
759401d9ae Merge branch 'fix/CWZS-91' into 'release'
fix: 推送更新测试问题—测试问题07/06 https://jira.shanqu.cc/browse/CWZS-91

See merge request halo/android/assistant-android!1191
2023-07-11 13:51:53 +08:00
e56209d15e fix: 处理弹窗 dismiss 问题 2023-07-11 13:38:59 +08:00
c466ff1f21 fix: 处理弹窗 dismiss 问题 2023-07-11 11:51:41 +08:00
e09cf299f0 Merge branch 'feature-GHZS-2771-patch-3' into 'release'
fix: 支持xapk格式的apks文件解压-0706测试

See merge request halo/android/assistant-android!1193
2023-07-11 10:40:24 +08:00
25352ba609 fix: 支持xapk格式的apks文件解压-0706测试 2023-07-11 10:40:24 +08:00
3cd065cb6e fix: 处理弹窗 dismiss 问题 2023-07-10 16:21:01 +08:00
5a483bb5db Merge branch 'fix/GHZS-2887' into 'dev'
fix: 游戏单功能优化-游戏单合集-前端部分—0709测试-客户端 https://jira.shanqu.cc/browse/GHZS-2887

See merge request halo/android/assistant-android!1192
2023-07-10 15:55:07 +08:00
3b380c6fe3 fix: 游戏单功能优化-游戏单合集-前端部分—0709测试-客户端 https://jira.shanqu.cc/browse/GHZS-2887 2023-07-10 14:25:14 +08:00
919a98ffe6 fix: 处理弹窗 dismiss 问题 2023-07-10 11:26:22 +08:00
eff84218a8 fix: 特殊包上报比例为 1 时关键行为进行 toast 提示(方便测试) 2023-07-07 11:32:44 +08:00
7c9c363422 fix: 推送更新测试问题—测试问题07/06 https://jira.shanqu.cc/browse/CWZS-91 2023-07-07 10:04:41 +08:00
add6448f44 Merge branch 'fix/GHZS-2848' into 'dev'
fix: 游戏单功能优化-游戏单合集-前端部分—0704测试-客户端(0706测试1、3) https://jira.shanqu.cc/browse/GHZS-2848

See merge request halo/android/assistant-android!1188
2023-07-06 15:49:58 +08:00
efccfaaa7f fix: 游戏单功能优化-游戏单合集-前端部分—0704测试-客户端(0706测试1、3) https://jira.shanqu.cc/browse/GHZS-2848 2023-07-06 15:33:01 +08:00
a61057ae10 Merge branch 'fix/download_issue' into 'dev'
fix: 移除部分在 DownloadObserver/DownloadDataHelper 进行的数据库操作

See merge request halo/android/assistant-android!1187
2023-07-06 15:17:27 +08:00
9472cafe48 fix: 移除部分在 DownloadObserver 进行的数据库操作 2023-07-06 14:37:00 +08:00
be83e1a2b4 Merge branch 'fix/GHZS-2870' into 'dev'
fix: 相关曝光数据埋点补充—0705测试 https://jira.shanqu.cc/browse/GHZS-2870

See merge request halo/android/assistant-android!1186
2023-07-06 11:08:09 +08:00
e48d7745b4 fix: 相关曝光数据埋点补充—0705测试 https://jira.shanqu.cc/browse/GHZS-2870 2023-07-06 10:59:50 +08:00
8b1a38214c Merge branch 'feature-GHZS-2771-patch-2' into 'release'
feat: 支持xapk格式的apks文件解压—0705测试

See merge request halo/android/assistant-android!1185
2023-07-06 09:47:32 +08:00
2acde0af00 feat: 支持xapk格式的apks文件解压—0705测试 2023-07-06 09:47:32 +08:00
daab20424e Merge branch 'fix/GHZS-2848' into 'dev'
fix: 游戏单功能优化-游戏单合集-前端部分—0704测试-客户端 https://jira.shanqu.cc/browse/GHZS-2848

See merge request halo/android/assistant-android!1184
2023-07-05 16:55:40 +08:00
63f2adade2 fix: 游戏单功能优化-游戏单合集-前端部分—0704测试-客户端 https://jira.shanqu.cc/browse/GHZS-2848 2023-07-05 15:39:04 +08:00
201c1207f9 Merge branch 'feature-GHZS-2771-patch-1' into 'release'
feat: 支持xapk格式的apks文件解压—0704测试

See merge request halo/android/assistant-android!1183
2023-07-05 14:24:55 +08:00
75d86b5a91 feat: 支持xapk格式的apks文件解压—0704测试 2023-07-05 14:24:55 +08:00
f30d647936 Merge branch 'feat/enable_log_in_internal_build' into 'dev'
feat: 邮件包保留日志输出,方便无编译条件时简单调试

See merge request halo/android/assistant-android!1182
2023-07-05 10:50:06 +08:00
c7dd449899 feat: 邮件包保留日志输出,方便无编译条件时简单调试 2023-07-05 10:13:09 +08:00
56c8885030 chore: 版本更新至 5.30.0 2023-07-05 09:56:12 +08:00
0e9f7feff9 Merge branch 'feature/CWZS-80' into 'dev-5.29.0'
feat: 新增谷歌框架版本管理 https://jira.shanqu.cc/browse/CWZS-81

See merge request halo/android/assistant-android!1181
2023-07-04 17:45:56 +08:00
3697cd720e feat: 新增谷歌框架版本管理 https://jira.shanqu.cc/browse/CWZS-81 2023-07-04 17:38:55 +08:00
07a3c06804 Merge branch 'feature/GHZS-2738' into 'dev-5.29.0'
feat: 相关曝光数据埋点补充 https://jira.shanqu.cc/browse/GHZS-2738

See merge request halo/android/assistant-android!1180
2023-07-04 16:13:09 +08:00
2fce492689 feat: 相关曝光数据埋点补充 https://jira.shanqu.cc/browse/GHZS-2738 2023-07-04 16:13:09 +08:00
d87d12e1ec fix: 合并冲突 2023-07-04 14:58:57 +08:00
a595730c50 Merge remote-tracking branch 'origin/dev' into dev-5.29.0
# Conflicts:
#	libraries/LGLibrary
2023-07-04 14:45:40 +08:00
7976355e34 Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1178
2023-07-04 14:41:38 +08:00
a9097793ac Merge branch 'feature-forum-tag-icon-not-display' into 'release'
fix: 修复社区-推荐列表项论坛入口图标不显示以及点击无反应的问题

See merge request halo/android/assistant-android!1177
2023-07-04 13:38:53 +08:00
86e4ddd3f7 fix: 修复社区-推荐列表项论坛入口图标不显示以及点击无反应的问题 2023-07-04 12:45:53 +08:00
b9abf2009d Merge branch 'fix/GHZS-2838' into 'dev-5.29.0'
fix: 游戏单功能优化-游戏单合集-前端部分—0703UI优化(2、6) https://jira.shanqu.cc/browse/GHZS-2838

See merge request halo/android/assistant-android!1176
2023-07-04 11:55:37 +08:00
a7dfd6c16c fix: 游戏单功能优化-游戏单合集-前端部分—0703UI优化(2、6) https://jira.shanqu.cc/browse/GHZS-2838 2023-07-04 11:51:05 +08:00
07dcb4aca2 Merge branch 'fix/web_share_info' into 'dev-5.29.0'
fix: 修复网页分享时分享回调类型为与需求对应不上的问题

See merge request halo/android/assistant-android!1175
2023-07-04 11:09:45 +08:00
48123ff991 fix: 修复网页分享时分享回调类型为与需求对应不上的问题 2023-07-04 11:08:56 +08:00
8312d8e5fe Merge branch 'feature-GHZS-2771-patch' into 'dev'
feat:支持xapk格式的apks文件解压—0620测试 https://jira.shanqu.cc/browse/GHZS-2771

See merge request halo/android/assistant-android!1174
2023-07-04 10:34:40 +08:00
98b4901d55 feat:支持xapk格式的apks文件解压—0620测试 https://jira.shanqu.cc/browse/GHZS-2771 2023-07-04 10:34:40 +08:00
a6a411f2e3 Merge branch 'fix/GHZS-2838' into 'dev-5.29.0'
fix: 游戏单功能优化-游戏单合集-前端部分—0703UI优化 https://jira.shanqu.cc/browse/GHZS-2838

See merge request halo/android/assistant-android!1172
2023-07-03 17:48:47 +08:00
59976dcccd fix: 游戏单功能优化-游戏单合集-前端部分—0703UI优化 https://jira.shanqu.cc/browse/GHZS-2838 2023-07-03 17:47:18 +08:00
e22a3ddcdb Merge branch 'fix/web_share_info' into 'dev-5.29.0'
feat: JS 分享结果回调添加分享类型

See merge request halo/android/assistant-android!1173
2023-07-03 17:41:50 +08:00
ecfd133ce2 feat: JS 分享结果回调添加分享类型 2023-07-03 17:36:37 +08:00
d13ef56eb8 Merge branch 'fix/GHZS-2831' into 'dev-5.29.0'
fix: 游戏单功能优化-游戏单合集-前端部分—0630测试-客户端 https://jira.shanqu.cc/browse/GHZS-2831

See merge request halo/android/assistant-android!1171
2023-07-03 13:36:19 +08:00
66f2d1df99 fix: 游戏单功能优化-游戏单合集-前端部分—0630测试-客户端 https://jira.shanqu.cc/browse/GHZS-2831 2023-07-03 11:38:09 +08:00
8555673d71 Merge branch 'feat/GHZS-2797' into 'dev'
feat: 推广打包配置项增加关键行为上报 https://jira.shanqu.cc/browse/GHZS-2797

See merge request halo/android/assistant-android!1170
2023-06-30 17:43:55 +08:00
cfe4c243e6 feat: 推广打包配置项增加关键行为上报 https://jira.shanqu.cc/browse/GHZS-2797 2023-06-30 17:30:18 +08:00
c999ddf914 Merge branch 'fix/GHZS-2818' into 'dev'
fix: 【光环助手】神策埋点问题(1) https://jira.shanqu.cc/browse/GHZS-2818

See merge request halo/android/assistant-android!1169
2023-06-30 17:03:53 +08:00
f9004bf884 fix: 【光环助手】神策埋点问题(1) https://jira.shanqu.cc/browse/GHZS-2818 2023-06-30 16:50:29 +08:00
7794ef4acf fix: 【光环助手】神策埋点问题(1) https://jira.shanqu.cc/browse/GHZS-2818 2023-06-30 16:05:51 +08:00
1ef9c1fc23 Merge branch 'fix/vgame_download_flicker' into 'dev'
fix: 修复列表下载畅玩游戏时下载按钮闪烁并频繁切换状态的问题

See merge request halo/android/assistant-android!1166
2023-06-30 15:48:54 +08:00
1b1b753feb Merge remote-tracking branch 'origin/dev' into dev-5.29.0 2023-06-30 14:40:29 +08:00
2561767b9a Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/download/DownloadManager.java
#	dependencies.gradle
#	module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java
2023-06-30 14:34:01 +08:00
8bda0e178e Merge branch 'fix/GHZS-2818' into 'dev'
fix: 【光环助手】神策埋点问题(1) https://jira.shanqu.cc/browse/GHZS-2818

See merge request halo/android/assistant-android!1167
2023-06-30 14:10:27 +08:00
f634d60605 Merge remote-tracking branch 'origin/dev' into dev-5.29.0 2023-06-30 13:52:06 +08:00
1dcc7654e8 Merge branch 'fix/wrong_game_category' into 'dev'
fix: 更正游戏类型在 downloadEntity 的记录

See merge request halo/android/assistant-android!1168
2023-06-30 11:54:34 +08:00
3579b9d808 fix: 更正游戏类型在 downloadEntity 的记录 2023-06-30 11:51:38 +08:00
c74663c082 fix: 【光环助手】神策埋点问题(1) https://jira.shanqu.cc/browse/GHZS-2818 2023-06-30 11:35:36 +08:00
848d352c60 fix: 【光环助手】神策埋点问题(1) https://jira.shanqu.cc/browse/GHZS-2818 2023-06-30 10:20:53 +08:00
5176766b29 fix: 修复列表下载畅玩游戏时下载按钮闪烁并频繁切换状态的问题 2023-06-30 10:10:47 +08:00
0a90a7ddd9 Merge branch 'feature/GHZS-2748' into 'dev-5.29.0'
feat: 游戏单活动:游戏单狂欢季—客户端-埋点 https://jira.shanqu.cc/browse/GHZS-2748

See merge request halo/android/assistant-android!1165
2023-06-29 17:47:32 +08:00
27ca5073d7 feat: 游戏单活动:游戏单狂欢季—客户端-埋点 https://jira.shanqu.cc/browse/GHZS-2748 2023-06-29 17:39:04 +08:00
e3eb8178a3 fix: merge conflict 2023-06-29 14:52:21 +08:00
10104812d6 Merge remote-tracking branch 'origin/dev' into dev-5.29.0 2023-06-29 14:29:23 +08:00
12cb9a4883 Merge branch 'fix/CWZS-86' into 'dev'
fix: 修复推送更新测试问题 https://jira.shanqu.cc/browse/CWZS-86

See merge request halo/android/assistant-android!1164
2023-06-29 14:08:18 +08:00
a30cc8c273 fix: 修复推送更新测试问题 https://jira.shanqu.cc/browse/CWZS-86 2023-06-29 13:55:19 +08:00
0f0620586b Merge branch 'fix/GHZS-2516' into 'dev'
fix: 【光环助手】神策首次事件取值的相关排查 (修复用户首次启动退出后再次热启动时用户第一次打开的标记仍为true的问题)...

See merge request halo/android/assistant-android!1163
2023-06-28 15:20:24 +08:00
b9e86dd67a fix: 【光环助手】神策首次事件取值的相关排查 (修复用户首次启动退出后再次热启动时用户第一次打开的标记仍为true的问题) https://jira.shanqu.cc/browse/GHZS-2516 2023-06-28 14:47:07 +08:00
9ce793d47e Merge branch 'fix/GHZS-2561' into 'dev'
fix:【光环助手】动态设置-公告文章支持通用链接(修改接口字段的处理方式)https://jira.shanqu.cc/browse/GHZS-2561

See merge request halo/android/assistant-android!1162
2023-06-28 11:31:37 +08:00
43cb18d6e0 fix:【光环助手】动态设置-公告文章支持通用链接(修改接口字段的处理方式)https://jira.shanqu.cc/browse/GHZS-2561 2023-06-28 11:26:42 +08:00
1e87610899 Merge branch 'feature/GHZS-2481' into 'dev-5.29.0'
feat: 游戏单功能优化-游戏单合集-前端部分—客户端 https://jira.shanqu.cc/browse/GHZS-2481

See merge request halo/android/assistant-android!1158
2023-06-28 10:50:33 +08:00
d04d486425 feat: 游戏单功能优化-游戏单合集-前端部分—客户端 https://jira.shanqu.cc/browse/GHZS-2481 2023-06-28 10:50:33 +08:00
843aa4d1c8 Merge branch 'fix/format_check_crash' into 'dev'
fix: 处理 XAPK 类型检测闪退问题

See merge request halo/android/assistant-android!1161
2023-06-27 18:15:41 +08:00
1745ac91b7 fix: 处理 XAPK 类型检测闪退问题 2023-06-27 16:43:36 +08:00
20bc4a0dc8 Merge branch 'fix/direct_to_gamedetail_without_entrance_issue' into 'dev'
fix: 修复部分位置跳转游戏详情丢失 entrance 字段信息的问题

See merge request halo/android/assistant-android!1160
2023-06-27 15:20:48 +08:00
1105f1b92a feat: 测试包默认开启畅玩功能 2023-06-27 15:20:34 +08:00
53f00f00d3 fix: 修复部分位置跳转游戏详情丢失 entrance 字段信息的问题 2023-06-27 15:12:29 +08:00
b66827e216 Merge branch 'feature/GHZS-2800' into 'dev-5.29.0'
feat: 帖子发布按钮展示优化—客户端 https://jira.shanqu.cc/browse/GHZS-2800

See merge request halo/android/assistant-android!1159
2023-06-27 13:52:39 +08:00
485c34d402 feat: 帖子发布按钮展示优化—客户端 https://jira.shanqu.cc/browse/GHZS-2800 2023-06-27 13:49:42 +08:00
330bcd72d7 Merge branch 'fix/concurrent_crash' into 'dev'
fix: 处理部分下载相关的 concurrent 闪退

See merge request halo/android/assistant-android!1157
2023-06-26 17:20:41 +08:00
b04231772b fix: 处理部分下载相关的 concurrent 闪退 2023-06-26 17:10:13 +08:00
ec1bbdc7d5 Merge branch 'feature-GHZS-2771' into 'dev'
feat:支持xapk格式的apks文件解压—0620测试 https://jira.shanqu.cc/browse/GHZS-2771

See merge request halo/android/assistant-android!1155
2023-06-26 16:48:30 +08:00
c685a02653 feat:支持xapk格式的apks文件解压—0620测试 https://jira.shanqu.cc/browse/GHZS-2771 2023-06-26 16:48:30 +08:00
6594bf14df Revert "Revert "Merge branch 'fix/sqlite_full_crash' into 'dev'""
This reverts commit 043f3c5d17.
2023-06-21 15:22:09 +08:00
5a4f19dd8a Merge branch 'feature-GHZS-2730' into 'dev-5.29.0'
feat:插件化安装弹窗优化—客户端 https://jira.shanqu.cc/browse/GHZS-2730

See merge request halo/android/assistant-android!1154
2023-06-21 15:05:39 +08:00
b54be8cb79 feat:插件化安装弹窗优化—客户端 https://jira.shanqu.cc/browse/GHZS-2730 2023-06-21 14:59:11 +08:00
655380d547 Merge branch 'hotfix/v5.27.1-891/cloud_archive_manager_crash' into 'release'
fix: 修复云存档管理页面点击下载按钮偶发的闪退问题...

See merge request halo/android/assistant-android!1153
2023-06-21 11:48:12 +08:00
da3948228f chore: 版本更新至 5.27.2 2023-06-21 11:39:33 +08:00
5c03119c32 fix: 修复云存档管理页面点击下载按钮偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/289025/events/ba71db5b3538491fa2096ecf33fdfcf8/?project=22 2023-06-21 11:38:53 +08:00
2a496b680b Merge branch 'hotfix/v5.27.1-891/emulator_oaid_crash' into 'release'
fix: 修复模拟器上 OAID SDK 闪退的问题,在所有 postInit 操作前初始化 sentry

See merge request halo/android/assistant-android!1152
2023-06-21 11:26:36 +08:00
db535cf281 fix: 修复模拟器上 OAID SDK 闪退的问题,在所有 postInit 操作前初始化 sentry 2023-06-21 11:20:25 +08:00
c199582efc Merge branch 'hotfix/v5.27.1-891/emulator_oaid_crash' into 'release'
fix: 修复模拟器上 OAID SDK 闪退的问题

See merge request halo/android/assistant-android!1151
2023-06-21 11:02:06 +08:00
b53677a118 fix: 修复模拟器上 OAID SDK 闪退的问题 2023-06-21 10:56:24 +08:00
76ba3a5938 Merge branch 'feature-GHZS-2731' into 'dev-5.29.0'
feat:视频播放组件优化—客户端 https://jira.shanqu.cc/browse/GHZS-2731

See merge request halo/android/assistant-android!1150
2023-06-21 09:27:46 +08:00
db596a6c75 feat:视频播放组件优化—客户端 https://jira.shanqu.cc/browse/GHZS-2731 2023-06-20 18:40:31 +08:00
043f3c5d17 Revert "Merge branch 'fix/sqlite_full_crash' into 'dev'"
This reverts merge request !1147
2023-06-20 18:00:56 +08:00
68006dda38 Merge branch 'feature-GHZS-2754' into 'release'
fix:尝试修复部分线上闪退 https://jira.shanqu.cc/browse/GHZS-2754

See merge request halo/android/assistant-android!1149
2023-06-20 17:24:57 +08:00
b5cab193be fix:尝试修复部分线上闪退 https://jira.shanqu.cc/browse/GHZS-2754 2023-06-20 17:24:57 +08:00
6f2692296c Merge branch 'fix/sqlite_full_crash' into 'dev'
fix: 处理存储空间满了后的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/197777/?project=22&query=assigned%3Ame+status%3Aunresolved&sort=user&statsPeriod=14d

See merge request halo/android/assistant-android!1147
2023-06-20 17:16:25 +08:00
0bb7a53046 Merge branch 'fix/game_collection_hot_list' into 'dev'
fix: 修复游戏单热榜的游戏单宽度不能自适应的问题

See merge request halo/android/assistant-android!1146
2023-06-20 15:51:08 +08:00
25fe362912 fix: 修复游戏单热榜的游戏单宽度不能自适应的问题 2023-06-20 15:49:33 +08:00
6749d94c34 fix: 处理存储空间满了后的闪退问题 2023-06-20 15:25:54 +08:00
51f5ea1cd9 Merge branch 'fix/CWZS-85' into 'dev'
fix: 畅玩助手组件下载链接失效问题 https://jira.shanqu.cc/browse/CWZS-85

See merge request halo/android/assistant-android!1145
2023-06-20 14:08:55 +08:00
50a6d5e204 fix: 畅玩助手组件下载链接失效问题 https://jira.shanqu.cc/browse/CWZS-85 2023-06-20 14:02:33 +08:00
044e5646ec Merge branch 'fix/GHZS-2641' into 'dev'
fix: 游戏单功能优化-游戏单广场—0606测试 (修复正式包刷新轮换失效的问题) https://jira.shanqu.cc/browse/GHZS-2641

See merge request halo/android/assistant-android!1144
2023-06-20 11:23:35 +08:00
0ebf3d191d fix: 游戏单功能优化-游戏单广场—0606测试 (修复正式包刷新轮换失效的问题) https://jira.shanqu.cc/browse/GHZS-2641 2023-06-20 11:05:49 +08:00
bb81d91fd5 Merge branch 'release' of git.shanqu.cc:halo/android/assistant-android into release 2023-06-20 10:32:53 +08:00
7442da80e0 Merge branch 'fix/GHZS-2753' into 'dev'
fix: 尝试修复部分线上闪退 https://jira.shanqu.cc/browse/GHZS-2753

See merge request halo/android/assistant-android!1142
2023-06-19 17:00:54 +08:00
96c28907ec Merge branch 'feature-GHZS-2758' into 'dev'
fix:支持xapk格式的apks文件解压—0619测试 https://jira.shanqu.cc/browse/GHZS-2758

See merge request halo/android/assistant-android!1143
2023-06-19 16:52:03 +08:00
e9e7c2043e fix:支持xapk格式的apks文件解压—0619测试 https://jira.shanqu.cc/browse/GHZS-2758 2023-06-19 16:52:03 +08:00
eb5c55f046 ci: 处理特殊打包的编译问题 2023-06-19 16:32:29 +08:00
8f2a1ecaa1 fix: 尝试修复部分线上闪退 https://jira.shanqu.cc/browse/GHZS-2753 2023-06-19 16:31:49 +08:00
8dbe9c5772 Merge branch 'fix/border_color' into 'dev'
fix: 修改玩家创作榜用户头像边框深色模式颜色

See merge request halo/android/assistant-android!1141
2023-06-19 14:14:09 +08:00
6c911e09d3 fix: 修改玩家创作榜用户头像边框深色模式颜色 2023-06-19 14:13:26 +08:00
df557099ec Merge branch 'fix/GHZS-2717' into 'dev'
fix: 搭建评论数据面板—0615测试(修复部分上报位置遗漏问题) https://jira.shanqu.cc/browse/GHZS-2717

See merge request halo/android/assistant-android!1140
2023-06-19 14:09:40 +08:00
fedc91d37e fix: 搭建评论数据面板—0615测试(修复部分上报位置遗漏问题) https://jira.shanqu.cc/browse/GHZS-2717 2023-06-19 13:57:13 +08:00
27484a8306 Merge branch 'fix/GHZS-2752' into 'dev'
fix: 游戏单功能优化-游戏单热榜-前端部分—0619UI优化 https://jira.shanqu.cc/browse/GHZS-2752

See merge request halo/android/assistant-android!1139
2023-06-19 10:36:22 +08:00
42193d222a fix: 游戏单功能优化-游戏单热榜-前端部分—0619UI优化 https://jira.shanqu.cc/browse/GHZS-2752 2023-06-19 10:34:40 +08:00
0a433566b1 chore: 版本更新至 5.29.0 2023-06-19 10:01:48 +08:00
ff02ccd839 Merge remote-tracking branch 'origin/dev' into dev-5.28.0 2023-06-19 09:51:15 +08:00
d1cc0853d4 Merge branch 'fix/vgame_backup_issue' into 'dev-5.28.0'
fix: 修复部分设备卸载重装后无法恢复畅玩历史数据的问题

See merge request halo/android/assistant-android!1138
2023-06-19 09:40:46 +08:00
51eb814a42 fix: 修复部分设备卸载重装后无法恢复畅玩历史数据的问题 2023-06-16 18:04:30 +08:00
6534c17cc0 Merge branch 'fix/GHZS-2641' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0606测试(修复筛选游戏单标签时请求接口缺少参数的问题) https://jira.shanqu.cc/browse/GHZS-2641

See merge request halo/android/assistant-android!1137
2023-06-16 16:57:54 +08:00
749a76a09e fix: 游戏单功能优化-游戏单广场—0606测试(修复筛选游戏单标签时请求接口缺少参数的问题) https://jira.shanqu.cc/browse/GHZS-2641 2023-06-16 14:53:04 +08:00
0f59f79495 Merge branch 'fix/GHZS-2744' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单热榜-前端部分—0616UI测试 https://jira.shanqu.cc/browse/GHZS-2744

See merge request halo/android/assistant-android!1136
2023-06-16 14:50:31 +08:00
af66a967b5 fix: 游戏单功能优化-游戏单热榜-前端部分—0616UI测试 https://jira.shanqu.cc/browse/GHZS-2744 2023-06-16 14:39:30 +08:00
9a9095bcf0 Merge branch 'feature-GHZS-2456-patch' into 'dev-5.28.0'
feat:补充支持xapk格式的apks一些需求 https://jira.shanqu.cc/browse/GHZS-2456

See merge request halo/android/assistant-android!1133
2023-06-16 13:51:35 +08:00
225f2becf3 feat:补充支持xapk格式的apks一些需求 https://jira.shanqu.cc/browse/GHZS-2456 2023-06-16 13:51:35 +08:00
a502fb64cb Merge branch 'fix/GHZS-2714' into 'dev-5.28.0'
feat: 启动事件埋点补充—0615测试(处理部分游戏类型为空情况) https://jira.shanqu.cc/browse/GHZS-2714

See merge request halo/android/assistant-android!1130
2023-06-16 10:26:41 +08:00
724fe8142c feat: 启动事件埋点补充—0615测试(处理部分游戏类型为空情况,但还需接口返回) https://jira.shanqu.cc/browse/GHZS-2714 2023-06-16 10:16:37 +08:00
dee5a0822d Merge branch 'fix/GHZS-2689' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0614测试 (0615测试) https://jira.shanqu.cc/browse/GHZS-2689

See merge request halo/android/assistant-android!1128
2023-06-16 09:51:43 +08:00
e826346ca9 Merge branch 'fix/GHZS-2685' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单热榜-前端部分—0614测试-客户端 (0615测试) https://jira.shanqu.cc/browse/GHZS-2685

See merge request halo/android/assistant-android!1129
2023-06-16 09:51:35 +08:00
06b43cde77 fix: 游戏单功能优化-游戏单广场—0614测试 (0615测试) https://jira.shanqu.cc/browse/GHZS-2689 2023-06-16 09:45:35 +08:00
ae5edad87b fix: 游戏单功能优化-游戏单热榜-前端部分—0614测试-客户端 (0615测试) https://jira.shanqu.cc/browse/GHZS-2685 2023-06-16 09:35:28 +08:00
c8916f5f33 Merge branch 'fix/GHZS-2641' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0606测试 https://jira.shanqu.cc/browse/GHZS-2641

See merge request halo/android/assistant-android!1127
2023-06-15 18:10:53 +08:00
04cca95435 Merge branch 'feature-update-lgl-library' into 'dev-5.28.0'
feat:更新LGLibrary指向

See merge request halo/android/assistant-android!1126
2023-06-15 17:52:55 +08:00
1bd3d8b044 feat:更新LGLibrary指向 2023-06-15 17:52:19 +08:00
4e79466cca fix: 游戏单功能优化-游戏单广场—0606测试 https://jira.shanqu.cc/browse/GHZS-2641 2023-06-15 17:40:20 +08:00
88093d0a8e Merge branch 'feature-GHZS-2456' into 'dev-5.28.0'
feat:支持xapk格式的apks文件解压—客户端 https://jira.shanqu.cc/browse/GHZS-2456

See merge request halo/android/assistant-android!1124
2023-06-15 17:06:10 +08:00
26adcc48f8 feat:支持xapk格式的apks文件解压—客户端 https://jira.shanqu.cc/browse/GHZS-2456 2023-06-15 17:06:10 +08:00
e94e86d901 Merge branch 'fix/GHZS-2472' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单热榜-前端部分—0614测试-客户端 https://jira.shanqu.cc/browse/GHZS-2685

See merge request halo/android/assistant-android!1125
2023-06-15 15:45:46 +08:00
73355a4103 fix: 游戏单功能优化-游戏单热榜-前端部分—0614测试-客户端 https://jira.shanqu.cc/browse/GHZS-2685
fix: 游戏单功能优化-游戏单热榜-前端部分—0614UI测试 https://jira.shanqu.cc/browse/GHZS-2686
2023-06-15 15:33:21 +08:00
794377fdad fix: 游戏单功能优化-游戏单广场—0614测试 https://jira.shanqu.cc/browse/GHZS-2689 2023-06-15 14:31:33 +08:00
1bff098369 Merge branch 'feat/GHZS-2603' into 'dev-5.28.0'
fix: 修复曝光 id 的传递问题 https://jira.shanqu.cc/browse/GHZS-2603

See merge request halo/android/assistant-android!1123
2023-06-15 13:54:11 +08:00
45c7638dee fix: 修复曝光 id 的传递问题 https://jira.shanqu.cc/browse/GHZS-2603 2023-06-15 13:52:30 +08:00
4c57092300 Merge branch 'feat/GHZS-2622' into 'dev-5.28.0'
feat: 启动事件埋点补充 https://jira.shanqu.cc/browse/GHZS-2622

See merge request halo/android/assistant-android!1121
2023-06-15 13:47:59 +08:00
1ddf9a667e feat: 启动事件埋点补充 https://jira.shanqu.cc/browse/GHZS-2622 2023-06-15 10:42:08 +08:00
84972e7ba7 Merge branch 'fix/GHZS-2687' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0614UI优化 https://jira.shanqu.cc/browse/GHZS-2687

See merge request halo/android/assistant-android!1120
2023-06-14 15:00:41 +08:00
03692ad753 fix: 游戏单功能优化-游戏单广场—0614UI优化 https://jira.shanqu.cc/browse/GHZS-2687 2023-06-14 14:59:12 +08:00
bb138fa25f Merge branch 'fix/GHZS-2669' into 'dev-5.28.0'
fix: 多渠道多版本配置-搜索管理功能优化—0612测试-客户端 https://jira.shanqu.cc/browse/GHZS-2669

See merge request halo/android/assistant-android!1118
2023-06-14 14:33:41 +08:00
c5024e670a Merge branch 'fix/GHZS-2674' into 'dev-5.28.0'
fix: 【光环助手】求版本下载跳转问题 https://jira.shanqu.cc/browse/GHZS-2674

See merge request halo/android/assistant-android!1117
2023-06-14 14:33:29 +08:00
fe5c92e988 fix: 【光环助手】求版本下载跳转问题 https://jira.shanqu.cc/browse/GHZS-2674 2023-06-14 14:22:48 +08:00
9b31bf4164 fix: 多渠道多版本配置-搜索管理功能优化—0612测试-客户端 https://jira.shanqu.cc/browse/GHZS-2669 2023-06-14 11:37:25 +08:00
c670ab722f Merge branch 'fix/GHZS-2658' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0609测试 https://jira.shanqu.cc/browse/GHZS-2658

See merge request halo/android/assistant-android!1115
2023-06-13 15:14:39 +08:00
fd4f3c25e7 fix: 游戏单功能优化-游戏单广场—0609测试 https://jira.shanqu.cc/browse/GHZS-2658 2023-06-13 15:09:46 +08:00
a14ea3708a Merge branch 'fix/GHZS-2658' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0609测试 https://jira.shanqu.cc/browse/GHZS-2658

See merge request halo/android/assistant-android!1114
2023-06-13 14:57:25 +08:00
c003240f16 Merge branch 'fix/GHZS-2576' into 'dev-5.28.0'
fix: 修复游戏详情页在正式环境下的闪退问题

See merge request halo/android/assistant-android!1113
2023-06-13 14:57:18 +08:00
891e3d93fb fix: 游戏单功能优化-游戏单广场—0609测试 https://jira.shanqu.cc/browse/GHZS-2658 2023-06-13 14:48:31 +08:00
af5ec74b9e Merge branch 'feat/GHZS-2644' into 'dev-5.28.0'
feat: 搭建评论数据面板(补充埋点) https://jira.shanqu.cc/browse/GHZS-2644

See merge request halo/android/assistant-android!1112
2023-06-13 13:39:57 +08:00
d2c4483455 feat: 搭建评论数据面板(补充埋点) https://jira.shanqu.cc/browse/GHZS-2644 2023-06-13 11:47:21 +08:00
3a156aa8c1 fix: 修复游戏详情页在正式环境下的闪退问题 2023-06-13 11:03:23 +08:00
60bd3ee9b2 Merge branch 'feature/GHZS-2485' into 'dev-5.28.0'
feat: 游戏单功能优化-游戏单热榜-前端部分—客户端 https://jira.shanqu.cc/browse/GHZS-2485

See merge request halo/android/assistant-android!1111
2023-06-13 10:53:34 +08:00
dacda1a858 feat: 游戏单功能优化-游戏单热榜-前端部分—客户端 https://jira.shanqu.cc/browse/GHZS-2485 2023-06-13 10:53:34 +08:00
265b5f6b57 Merge branch 'feat/GHZS-2502' into 'dev-5.28.0'
feat: 我的光环在设备无网络时的功能版块优化 https://jira.shanqu.cc/browse/GHZS-2502

See merge request halo/android/assistant-android!1109
2023-06-12 10:30:56 +08:00
b4bd6f250b feat: 我的光环在设备无网络时的功能版块优化 https://jira.shanqu.cc/browse/GHZS-2502 2023-06-12 10:25:35 +08:00
0f3ae5f085 Merge branch 'fix/GHZS-2656' into 'dev-5.28.0'
fix: 游戏单功能优化-游戏单广场—0609UI测试 https://jira.shanqu.cc/browse/GHZS-2656

See merge request halo/android/assistant-android!1108
2023-06-09 17:03:43 +08:00
3ab6cc202e fix: 游戏单功能优化-游戏单广场—0609UI测试 https://jira.shanqu.cc/browse/GHZS-2656 2023-06-09 17:03:05 +08:00
7a154bc130 Merge branch 'feature/GHZS-2576' into 'dev-5.28.0'
feat: 动态设置-公告文章支持通用链接—客户端 https://jira.shanqu.cc/browse/GHZS-2576

See merge request halo/android/assistant-android!1106
2023-06-09 15:35:07 +08:00
7cd6f2b0f4 feat: 动态设置-公告文章支持通用链接—客户端 https://jira.shanqu.cc/browse/GHZS-2576 2023-06-09 14:20:13 +08:00
8db2519f61 Merge branch 'feature-GHZS-2590' into 'dev-5.28.0'
feat:帖子更多操作图标UI样式替换—客户端 https://jira.shanqu.cc/browse/GHZS-2590

See merge request halo/android/assistant-android!1102
2023-06-08 16:57:35 +08:00
6b2902a73b feat:帖子更多操作图标UI样式替换—客户端 https://jira.shanqu.cc/browse/GHZS-2590 2023-06-08 16:53:19 +08:00
df7618bbda Merge branch 'feature-GHZS-2626' into 'dev-5.28.0'
feat:【光环助手】视频帖详情页UI展示问题 https://jira.shanqu.cc/browse/GHZS-2626

See merge request halo/android/assistant-android!1100
2023-06-08 15:44:12 +08:00
246983a097 feat:【光环助手】视频帖详情页UI展示问题 https://jira.shanqu.cc/browse/GHZS-2626 2023-06-08 15:42:01 +08:00
ca6146ad9a Merge branch 'feature-GHZS-2649' into 'dev-5.28.0'
feat:【光环助手】游戏礼包相关bug https://jira.shanqu.cc/browse/GHZS-2649

See merge request halo/android/assistant-android!1097
2023-06-08 11:03:06 +08:00
c647320abc feat:【光环助手】游戏礼包相关bug https://jira.shanqu.cc/browse/GHZS-2649 2023-06-08 10:59:07 +08:00
afd738454e Merge branch 'feat/GHZS-2645' into 'dev-5.28.0'
feat: 新增畅玩32位游戏类型 https://jira.shanqu.cc/browse/GHZS-2637

See merge request halo/android/assistant-android!1093
2023-06-07 14:04:40 +08:00
134cb327ec feat: 新增畅玩32位游戏类型 https://jira.shanqu.cc/browse/GHZS-2637 2023-06-07 14:01:57 +08:00
f50ce741ae Merge branch 'dev' into 'dev-5.28.0'
Dev

See merge request halo/android/assistant-android!1092
2023-06-07 11:51:27 +08:00
4547ba969e Merge branch 'dev' into 'dev-5.28.0'
Dev

See merge request halo/android/assistant-android!1087
2023-06-06 16:53:05 +08:00
0a4af78ac8 Merge branch 'dev' into 'dev-5.28.0'
合并 dev 变更

See merge request halo/android/assistant-android!1084
2023-06-06 14:36:18 +08:00
d38e1d1637 Merge branch 'feature/GHZS-2476' into 'dev-5.28.0'
feat: 游戏单功能优化-游戏单广场—客户端 https://jira.shanqu.cc/browse/GHZS-2476

See merge request halo/android/assistant-android!1076
2023-06-05 17:07:28 +08:00
0d3456cf97 feat: 游戏单功能优化-游戏单广场—客户端 https://jira.shanqu.cc/browse/GHZS-2476 2023-06-05 17:00:56 +08:00
f56529aa5b chore: 版本更新至 5.28.0 2023-05-31 11:49:46 +08:00
819 changed files with 24565 additions and 5331 deletions

View File

@ -71,8 +71,8 @@ android_build:
exit_codes: 137
only:
- dev
- dev-5.26.0
- dev-5.27.0
- dev-5.29.0
- dev-5.30.0
# 代码检查
sonarqube_analysis:
@ -103,8 +103,8 @@ sonarqube_analysis:
exit_codes: 137
only:
- dev
- dev-5.26.0
- dev-5.27.0
- dev-5.29.0
- dev-5.30.0
## 发送简易检测结果报告
send_sonar_report:
@ -122,8 +122,8 @@ send_sonar_report:
exit_codes: 137
only:
- dev
- dev-5.26.0
- dev-5.27.0
- dev-5.29.0
- dev-5.30.0
oss-upload&send-email:
tags:
@ -155,5 +155,5 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail.py
only:
- dev
- dev-5.26.0
- dev-5.27.0
- dev-5.29.0
- dev-5.30.0

View File

@ -11,7 +11,11 @@ android {
String CONFIG_ID = ""
String FIRST_LAUNCH = ""
int ACTIVATE_REPORTING_RATIO = 0
String SDK_VERSION = ""
String SDK_APP_ID = ""
String SDK_APP_NAME = ""
boolean USE_DEFAULT_CHANNEL_SDK = true
int ACTIVATE_REPORTING_RATIO = 100
buildFeatures {
viewBinding true
@ -71,9 +75,20 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
String CORE_EVENT_GAME_CATEGORY = ""
// 推广用的关键事件游戏类型
buildConfigField "String", "CORE_EVENT_GAME_CATEGORY", "\"${CORE_EVENT_GAME_CATEGORY}\""
// 推广用的配置 id
buildConfigField "String", "CONFIG_ID", "\"${CONFIG_ID}\""
// 推广用的 SDK 版本 (仅记录使用)
buildConfigField "String", "SDK_VERSION", "\"${SDK_VERSION}\""
buildConfigField "String", "SDK_APP_ID", "\"${SDK_APP_ID}\""
buildConfigField "String", "SDK_APP_NAME", "\"${SDK_APP_NAME}\""
buildConfigField "boolean", "USE_DEFAULT_CHANNEL_SDK", "${USE_DEFAULT_CHANNEL_SDK}"
// 首次启动的跳转配置
buildConfigField "String", "FIRST_LAUNCH", "\"${FIRST_LAUNCH}\""
@ -173,6 +188,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${DEV_VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${DEV_QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "CSJ_APPID", "\"${DEV_CSJ_APPID}\""
}
// publish 发布时候使用的 flavor接口仅包含正式环境
@ -184,6 +200,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
tea {
@ -194,6 +211,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
}
@ -201,17 +219,12 @@ android {
kuaishou {
dimension "env"
String KUAI_SHOU_APP_ID = ""
String KUAI_SHOU_APP_NAME = ""
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "KUAI_SHOU_APP_ID", "\"${KUAI_SHOU_APP_ID}\""
buildConfigField "String", "KUAI_SHOU_APP_NAME", "\"${KUAI_SHOU_APP_NAME}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
gdt {
@ -222,6 +235,7 @@ android {
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
}
}
}
@ -329,11 +343,19 @@ dependencies {
implementation(project(':module_sensors_data')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_message')) {
exclude group: 'androidx.swiperefreshlayout'
}
// implementation(project(':feature:vpn'))
implementation(project(':feature:pkg'))
implementation(project(':feature:oaid'))
implementation(project(':feature:floating-window'))
implementation(project(':feature:beizi_startup_ad'))
implementation(project(':feature:csj_ad'))
// implementation(project(':feature:beizi_startup_ad'))
implementation(project(':feature:xapk-installer'))
implementation(project(':feature:qq_game')) {
exclude group: 'androidx.swiperefreshlayout'
}
}
File propFile = file('sign.properties')

View File

@ -20,12 +20,13 @@
-keep class com.gh.gamecenter.db.info.* {*;}
-keep class com.gh.gamecenter.entity.** {<fields>;}
-keep class com.gh.gamecenter.qa.entity.** {<fields>;}
-keep class com.gh.download.DownloadDataSimpleEntity {<fields>;}
-keep class com.gh.gamecenter.floatingwindow.FloatingWindowEntity {<fields>;}
-keep class com.gh.gamecenter.BR
-keep class com.gh.gamecenter.retrofit.* {*;}
-keep class com.gh.gamecenter.eventbus.* {*;}
-keep class com.gh.gamecenter.home.gamecollection.GameCollectionStackLayout {*;}
-keep class com.gh.gamecenter.home.gamecollection.GameCollectionStackAnimation {*;}
-keep class com.gh.gamecenter.home.gamecollection.carousel.GameCollectionStackLayout {*;}
-keep class com.gh.gamecenter.home.gamecollection.carousel.GameCollectionStackAnimation {*;}
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {

View File

@ -33,4 +33,8 @@ class FlavorProviderImp : IFlavorProvider {
override fun logEvent(content: String) {
// do nothing
}
override fun logCoreEvent() {
// do nothing
}
}

View File

@ -42,6 +42,10 @@ class FlavorProviderImp : IFlavorProvider {
GdtHelper.logAction(content)
}
override fun logCoreEvent() {
// do nothing
}
companion object {
private const val GDT_DEFAULT_CHANNEL = "GDT_GHZS_01"
}

Binary file not shown.

View File

@ -5,8 +5,8 @@ import com.kwai.monitor.log.TurboAgent
import com.kwai.monitor.log.TurboConfig
object KuaishouHelper {
private val mAppId by lazy { BuildConfig.KUAI_SHOU_APP_ID.ifEmpty { "81537" } }
private val mAppName by lazy { BuildConfig.KUAI_SHOU_APP_NAME.ifEmpty { "guanghuanzhushou_1" } }
private val mAppId by lazy { BuildConfig.SDK_APP_ID.ifEmpty { "81537" } }
private val mAppName by lazy { BuildConfig.SDK_APP_NAME.ifEmpty { "guanghuanzhushou_1" } }
@JvmStatic
fun init(context: Context, channel: String) {

View File

@ -3,12 +3,16 @@ package com.gh.gamecenter.provider
import android.app.Activity
import android.app.Application
import android.text.TextUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.KuaishouHelper
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.halo.assistant.HaloApp
import com.kwai.monitor.payload.TurboHelper
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {
@ -31,7 +35,11 @@ class FlavorProviderImp : IFlavorProvider {
}
override fun getChannelStr(application: Application): String {
var channel = TurboHelper.getChannel(application)
var channel = if (BuildConfig.USE_DEFAULT_CHANNEL_SDK) {
ChannelReaderUtil.getChannel(application)
} else {
TurboHelper.getChannel(application)
}
if (channel == null || TextUtils.isEmpty(channel.trim())) {
channel = KUAISHOU_CHANNEL
}
@ -42,6 +50,15 @@ class FlavorProviderImp : IFlavorProvider {
KuaishouHelper.onEvent(content)
}
override fun logCoreEvent() {
logEvent("EVENT_KEY_PATH_OPTIMIZATION")
if (BuildConfig.ACTIVATE_REPORTING_RATIO == 1) {
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast("关键行为 EVENT_KEY_PATH_OPTIMIZATION")
}, 500)
}
}
companion object {
private const val KUAISHOU_CHANNEL = "KS-GHZS-01"
}

Binary file not shown.

View File

@ -77,7 +77,12 @@
androidx.compose.animation.core,
androidx.constraintlayout.compose,
androidx.compose.ui.test.manifest,
androidx.compose.ui.tooling.preview" />
com.bytedance.sdk.openadsdk,
androidx.compose.ui.tooling.preview,
com.tencent.qqmini,
com.tencent.qqmini.minigame.external,
com.tencent.qqmini.minigame.opensdk,
com.tencent.qqmini.union.ad" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -106,8 +111,8 @@
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:largeHeap="true"
android:resizeableActivity="true"
android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
tools:replace="android:name,android:allowBackup"
tools:targetApi="n">
@ -297,10 +302,6 @@
android:name="com.gh.gamecenter.CollectionActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.MessageActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.UserInfoEditActivity"
android:screenOrientation="portrait"
@ -314,26 +315,10 @@
android:name="com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.ConcernInfoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.InfoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.MessageKeFuActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.MessageInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.MessageVoteActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.questions.invite.QuestionsInviteActivity"
android:screenOrientation="portrait" />
@ -756,6 +741,22 @@
android:name=".servers.gametest2.GameServerTestV2Activity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qgame.QGameHomeWrapperActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qgame.QGameSearchActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qgame.QGameSubjectActivity"
android:screenOrientation="portrait" />
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
@ -826,6 +827,11 @@
</intent-filter>
</receiver>
<activity
android:name="com.gh.common.xapk.XapkInstallReceiver"
android:theme="@style/Theme.Transparent"
android:exported="false" />
<receiver
android:name="com.gh.gamecenter.receiver.ActivitySkipReceiver"
android:exported="true">
@ -834,39 +840,6 @@
</intent-filter>
</receiver>
<!-- 梦工厂配置 开始 -->
<!--<meta-data
android:name="MGC_APPID"
android:value="1001276" />
<provider
android:name="com.leto.game.base.provider.LetoFileProvider"
android:authorities="${applicationId}.leto.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/leto_file_path"
tools:replace="android:resource" />
</provider>-->
<!-- 梦工厂配置 结束 -->
<!-- 穿山甲配置 开始 -->
<!--<provider
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<provider
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:exported="false" />-->
<!-- 穿山甲配置 结束 -->
</application>
</manifest>

View File

@ -0,0 +1 @@
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":144,"h":144,"nm":"icon_change","ddd":0,"assets":[{"id":"comp_0","nm":"icon_change_detail","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"stroke1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[37.04,52.994,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.533,-0.143],[0.143,-0.533],[1.487,-1.304],[1.961,-0.258],[1.774,0.875],[0.709,0.661],[0,0],[0,0.445],[0,0],[-0.276,0],[0,0],[-0.013,0],[0,0],[0.315,-0.315],[0,0],[-0.682,-0.336],[-1.569,0.207],[-1.19,1.043],[-0.41,1.528]],"o":[[0.533,0.143],[-0.512,1.91],[-1.487,1.304],[-1.961,0.258],[-0.879,-0.433],[0,0],[-0.315,0.315],[0,0],[0,-0.276],[0,0],[0.013,0],[0,0],[0.445,0],[0,0],[0.555,0.508],[1.419,0.7],[1.569,-0.207],[1.19,-1.043],[0.143,-0.533]],"v":[[8.605,-4.301],[9.312,-3.076],[6.247,1.854],[0.958,4.25],[-4.77,3.304],[-7.163,1.652],[-8.493,2.982],[-9.347,2.628],[-9.347,-1.665],[-8.847,-2.165],[-8.161,-2.165],[-8.122,-2.165],[-4.554,-2.165],[-4.2,-1.311],[-5.748,0.237],[-3.885,1.51],[0.697,2.267],[4.928,0.35],[7.381,-3.594]],"c":true},"ix":2},"nm":"stroke1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.8,1,0.6],"ix":9}},"s":{"a":0,"k":[-5.347,-4.665],"ix":5},"e":{"a":0,"k":[8.653,-4.665],"ix":6},"t":1,"nm":"color1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"stroke1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"stroke2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34.96,19.006,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.961,0.258],[-1.774,-0.875],[-0.709,-0.661],[0,0],[0,-0.445],[0,0],[0.276,0],[0,0],[0.012,0],[0,0],[-0.315,0.315],[0,0],[0.682,0.336],[1.569,-0.207],[1.19,-1.043],[0.41,-1.528],[0.533,0.143],[-0.143,0.533],[-1.487,1.304]],"o":[[1.961,-0.258],[0.879,0.433],[0,0],[0.315,-0.315],[0,0],[0,0.276],[0,0],[-0.012,0],[0,0],[-0.445,0],[0,0],[-0.555,-0.508],[-1.419,-0.7],[-1.569,0.207],[-1.19,1.043],[-0.143,0.533],[-0.533,-0.143],[0.512,-1.91],[1.487,-1.304]],"v":[[-0.958,-4.25],[4.77,-3.304],[7.163,-1.652],[8.493,-2.982],[9.347,-2.628],[9.347,1.665],[8.847,2.165],[8.16,2.165],[8.123,2.165],[4.554,2.165],[4.2,1.311],[5.748,-0.237],[3.885,-1.51],[-0.697,-2.267],[-4.928,-0.35],[-7.381,3.594],[-8.605,4.301],[-9.312,3.076],[-6.247,-1.854]],"c":true},"ix":2},"nm":"stroke2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.8,1,0.6],"ix":9}},"s":{"a":0,"k":[5.347,4.665],"ix":5},"e":{"a":0,"k":[-8.653,4.665],"ix":6},"t":1,"nm":"color2","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"stroke2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"icon_change_detail","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[72,72,0],"ix":2,"l":2},"a":{"a":0,"k":[36,36,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":72,"h":72,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1 @@
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":72,"h":72,"nm":"icon_title_change","ddd":0,"assets":[{"id":"comp_0","nm":"arrow","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"arrow_e_dark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.25,30,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.701,0.456],[-1.627,-0.674],[-0.705,-0.667],[0,0],[-0.552,0],[0,-0.552],[0,0],[0.552,0],[0,0],[0.012,0],[0,0],[0,0.552],[-0.552,0],[0,0],[0.615,0.255],[1.276,-0.342],[0.804,-1.048],[0,-1.321],[-0.804,-1.048],[-1.276,-0.342],[-1.22,0.505],[-0.66,1.144],[-0.478,-0.276],[0.276,-0.478],[1.627,-0.674],[1.701,0.456],[1.072,1.397],[0,1.761],[-1.072,1.397]],"o":[[1.701,-0.456],[0.909,0.376],[0,0],[0,-0.552],[0.552,0],[0,0],[0,0.552],[0,0],[-0.012,0],[0,0],[-0.552,0],[0,-0.552],[0,0],[-0.493,-0.435],[-1.22,-0.505],[-1.276,0.342],[-0.804,1.048],[0,1.321],[0.804,1.048],[1.276,0.342],[1.22,-0.505],[0.276,-0.478],[0.478,0.276],[-0.881,1.525],[-1.627,0.674],[-1.701,-0.456],[-1.072,-1.397],[0,-1.761],[1.072,-1.397]],"v":[[-1.821,-7.727],[3.311,-7.391],[5.75,-5.809],[5.75,-6.5],[6.75,-7.5],[7.75,-6.5],[7.75,-3.5],[6.75,-2.5],[6.331,-2.5],[6.295,-2.5],[3.75,-2.5],[2.75,-3.5],[3.75,-4.5],[4.219,-4.5],[2.546,-5.543],[-1.303,-5.796],[-4.51,-3.653],[-5.75,0],[-4.51,3.653],[-1.303,5.796],[2.546,5.543],[5.446,3],[6.812,2.634],[7.178,4],[3.311,7.391],[-1.821,7.727],[-6.097,4.87],[-7.75,0],[-6.097,-4.87]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.158117651939,0.532358944416,0.878431379795,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"arrow_e_dark","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"arrow","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[36,36,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":60,"h":60,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1 @@
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":72,"h":72,"nm":"icon_title_change","ddd":0,"assets":[{"id":"comp_0","nm":"arrow","fr":60,"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"arrow_e_light","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.25,30,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.701,0.456],[-1.627,-0.674],[-0.705,-0.667],[0,0],[-0.552,0],[0,-0.552],[0,0],[0.552,0],[0,0],[0.012,0],[0,0],[0,0.552],[-0.552,0],[0,0],[0.615,0.255],[1.276,-0.342],[0.804,-1.048],[0,-1.321],[-0.804,-1.048],[-1.276,-0.342],[-1.22,0.505],[-0.66,1.144],[-0.478,-0.276],[0.276,-0.478],[1.627,-0.674],[1.701,0.456],[1.072,1.397],[0,1.761],[-1.072,1.397]],"o":[[1.701,-0.456],[0.909,0.376],[0,0],[0,-0.552],[0.552,0],[0,0],[0,0.552],[0,0],[-0.012,0],[0,0],[-0.552,0],[0,-0.552],[0,0],[-0.493,-0.435],[-1.22,-0.505],[-1.276,0.342],[-0.804,1.048],[0,1.321],[0.804,1.048],[1.276,0.342],[1.22,-0.505],[0.276,-0.478],[0.478,0.276],[-0.881,1.525],[-1.627,0.674],[-1.701,-0.456],[-1.072,-1.397],[0,-1.761],[1.072,-1.397]],"v":[[-1.821,-7.727],[3.311,-7.391],[5.75,-5.809],[5.75,-6.5],[6.75,-7.5],[7.75,-6.5],[7.75,-3.5],[6.75,-2.5],[6.331,-2.5],[6.295,-2.5],[3.75,-2.5],[2.75,-3.5],[3.75,-4.5],[4.219,-4.5],[2.546,-5.543],[-1.303,-5.796],[-4.51,-3.653],[-5.75,0],[-4.51,3.653],[-1.303,5.796],[2.546,5.543],[5.446,3],[6.812,2.634],[7.178,4],[3.311,7.391],[-1.821,7.727],[-6.097,4.87],[-7.75,0],[-6.097,-4.87]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141176477075,0.588235318661,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"arrow_e_light","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"arrow","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[36,36,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":60,"h":60,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1,430 @@
package com.gh.ad
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.launcher.ARouter
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.provider.IBeiziAdProvider
import com.gh.gamecenter.core.provider.ICsjAdProvider
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils.getToday
import com.gh.gamecenter.entity.AdConfig
import com.gh.gamecenter.entity.StartupAdEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
/**
* 广告实现代理类
*
* 由它来分发功能实现到具体的实现
*
* 以最复杂的开屏广告为例有三种实现1. 自有的广告实现 2. 穿山甲的开屏广告实现 3. Beizi 的开屏广告实现)
*
* 由于两个广告 SDK 有可能在一次启动中都被使用,所以会根据获取到的广告配置 config 来决定是否需要出是很好两个 SDK
*/
object AdDelegateHelper {
private var mCsjAdImpl: ICsjAdProvider? = null
private var mBeiziAdImpl: IBeiziAdProvider? = null
private var mAdConfigList: ArrayList<AdConfig>? = null
private var mSplashAd: AdConfig? = null
private var mDownloadManagerAd: AdConfig? = null
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
private var mVGameLaunchAd: AdConfig? = null
private const val AD_SDK_CSJ = "穿山甲"
private const val AD_SDK_BEIZI = "倍孜"
private const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
private const val KEY_CACHE_CONFIG = "cache_config" // 放在 SP 里的广告缓存(避免接口加载问题)
private val mAdConfigSp: SharedPreferences by lazy {
HaloApp.getInstance().getSharedPreferences("AdConfig", Context.MODE_PRIVATE)
}
fun initAdSdk(context: Context) {
// 初始化 Beizi
if (mBeiziAdImpl == null) {
mBeiziAdImpl =
ARouter.getInstance().build(RouteConsts.provider.beiziAd).navigation() as? IBeiziAdProvider
mBeiziAdImpl?.initSDK(context)
}
// 初始化穿山甲
if (mCsjAdImpl == null) {
mCsjAdImpl =
ARouter.getInstance().build(RouteConsts.provider.csjAd).navigation() as? ICsjAdProvider
mCsjAdImpl?.initSDK(context, BuildConfig.CSJ_APPID, HaloApp.getInstance().oaid)
// 监听亮色/暗色模式切换
DarkModeUtils.registerModeChangeListener {
val topActivity = CurrentActivityHolder.getCurrentActivity() ?: return@registerModeChangeListener
updateThemeStatus(context, DarkModeUtils.isDarkModeOn(topActivity))
}
}
}
/**
* 请求接口获取广告相关配置
*/
@SuppressLint("CheckResult")
fun requestAdConfig(isFromRetry: Boolean) {
// mAdConfigList 不为空不需要重试
if (isFromRetry && mAdConfigList != null) {
return
}
RetrofitManager.getInstance()
.newApi
.adConfig
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<List<AdConfig>>() {
override fun onSuccess(data: List<AdConfig>) {
handleAdConfig(data)
// 缓存数据到 SP 供接口请求失败用
SPUtils.setString(mAdConfigSp, KEY_CACHE_CONFIG, data.toJson())
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
// 若接口请求失败时,从 SP 里获取上次缓存的数据
val cachedConfig: List<AdConfig>? = SPUtils.getString(mAdConfigSp, KEY_CACHE_CONFIG).toObject()
if (cachedConfig != null) {
handleAdConfig(cachedConfig)
}
}
})
}
/**
* 获取搜索页的广告列表
*/
fun getGameSearchAdList(): ArrayList<AdConfig> {
return mGameSearchAdList
}
/**
* 获取下载管理页的广告
*/
fun getDownloadManagerAd(): AdConfig? {
return mDownloadManagerAd
}
/**
* 处理广告配置
*/
fun handleAdConfig(configList: List<AdConfig>) {
for (config in configList) {
// 处理返回的数据
when (config.location) {
"halo_launch" -> mSplashAd = config
"download_manager" -> mDownloadManagerAd = config
"game_search" -> config.let { mGameSearchAdList.add(it) }
"helper_launch" -> mVGameLaunchAd = config
}
}
}
/**
* 是否需要显示开屏广告
*/
fun shouldShowStartUpAd(): Boolean {
return mSplashAd != null
}
/**
* 更新主题样式
*/
private fun updateThemeStatus(context: Context, isDarkMode: Boolean) {
mCsjAdImpl?.updateThemeStatus(context, isDarkMode)
}
/**
* 请求开屏广告
*/
@JvmStatic
fun requestSplashAd(
activity: Activity,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
) {
if (mSplashAd != null) {
if (mSplashAd!!.displayRule.adSource == AD_TYPE_SDK) {
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
if (isSuccess) {
hideCallback.invoke()
} else {
if (mSplashAd?.displayRule?.onFailedAction == "show") {
sdkStartAdContainer.visibility = View.GONE
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
} else {
hideCallback.invoke()
}
}
}
// 第三方广告的数据为空,按加载失败处理
if (mSplashAd?.thirdPartyAd == null) {
sdkSplashCallback.invoke(false)
return
}
if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
sdkStartAdContainer.visibility = View.VISIBLE
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, sdkSplashCallback)
} else if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
sdkStartAdContainer.visibility = View.VISIBLE
requestCsjSplashAd(
activity,
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
sdkStartAdContainer,
sdkSplashCallback
)
}
} else {
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
}
}
}
/**
* 获取穿山甲的开屏广告
*/
private fun requestCsjSplashAd(
activity: Activity,
slotId: String,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mCsjAdImpl == null) {
callback.invoke(false)
} else {
mCsjAdImpl?.requestSplashAd(
activity,
slotId,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
callback,
)
}
}
/**
* 获取 Beizi 的开屏广告
*/
private fun requestBeiziSplashAd(
startAdContainer: View,
adsFl: FrameLayout,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mBeiziAdImpl == null) {
callback.invoke(false)
} else {
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, callback)
}
}
/**
* 显示自有的开屏广告
*/
private fun requestStandardSplashAd(
splashAd: StartupAdEntity?,
startAdContainer: ViewGroup,
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
) {
if (splashAd == null) {
hideCallback.invoke()
return
}
if (!TextUtils.isEmpty(splashAd.img)) {
val showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "") ?: ""
when (splashAd.rule) {
"each" -> showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
"once" -> if (TextUtils.isEmpty(showedTodayTimestamp)
|| !showedTodayTimestamp.contains(splashAd.id)
) {
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
} else {
hideCallback.invoke()
}
"everyday" -> {
val today = getToday()
if (TextUtils.isEmpty(showedTodayTimestamp)
|| !showedTodayTimestamp.contains(today)
|| !showedTodayTimestamp.contains(splashAd.id)
) {
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
} else {
hideCallback.invoke()
}
}
else -> hideCallback.invoke()
}
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, splashAd.id + getToday())
} else {
hideCallback.invoke()
}
}
private fun showStandardSplashAd(
ad: StartupAdEntity,
startAdContainer: ViewGroup,
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
) {
val jumpBtn: View = startAdContainer.findViewById(R.id.jumpBtn)
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
startAdContainer.visibility = View.VISIBLE
jumpDetailBtn.text = ad.desc
jumpDetailBtn.setDrawableEnd(
AppCompatResources.getDrawable(
startAdContainer.context,
R.drawable.ic_startup_ad_arrow
), null, null
)
ImageUtils.display(adImage, ad.img)
startAdContainer.setOnClickListener {
// 拦截点击事件传递
}
jumpBtn.setOnClickListener {
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
val linkEntity = ad.jump
logOpenScreenAdSkip(
ad.id,
(if (linkEntity.text != null) linkEntity.text else "")!!,
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
}
val sources: MutableList<ExposureSource> = ArrayList()
sources.add(ExposureSource("开屏广告", ad.id))
val event = createEvent(null, sources, null, ExposureType.EXPOSURE)
ExposureManager.log(event)
if (ad.button) {
jumpDetailBtn.setOnClickListener { v: View ->
directToLinkPage(v.context, ad.jump, "(启动广告)", "", event)
v.postDelayed({
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
}, 1000)
}
jumpDetailBtn.visibility = View.VISIBLE
LogUtils.logStartAd("watch_start_ads", ad)
} else {
LogUtils.logStartAd("start_ads", ad)
}
handler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
}
/**
* 获取信息流广告
*/
fun requestFlowAd(
fragment: Fragment,
slotId: String,
adContainerView: ViewGroup,
expressViewWidth: Float,
callback: (isSuccess: Boolean) -> Unit,
) {
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, callback)
}
/**
* 获取 Banner 广告
*/
fun requestBannerAd(
fragment: Fragment,
containerView: ViewGroup,
ad: AdConfig.ThirdPartyAd,
expressViewWidthInDp: Float,
callback: (isSuccess: Boolean) -> Unit
) {
val slotId = ad.slotId
val displayRatio: Float = if (ad.displaySize.isEmpty()) {
2F
} else {
val array = ad.displaySize.split("*")
if (array.size == 2) {
array[0].toFloat() / array[1].toFloat()
} else {
2F
}
}
val expressViewHeightInDp = expressViewWidthInDp / displayRatio
mCsjAdImpl?.requestBannerAd(
fragment,
containerView,
slotId,
expressViewWidthInDp,
expressViewHeightInDp,
callback
)
}
/**
* 取消开屏广告
*/
fun cancelSplashAd(context: Context) {
mBeiziAdImpl?.cancelSplashAd(context)
mCsjAdImpl?.cancelSplashAd(context)
}
}

View File

@ -1,18 +1,20 @@
package com.gh.base
import android.graphics.Typeface
import android.os.Bundle
import android.text.TextUtils
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.gh.download.DownloadManager
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils.getBoolean
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
@ -58,6 +60,7 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
}
val downloadMenuView = mActionMenuView.menu.findItem(R.id.menu_download).actionView
mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, "fonts/d_din_bold_only_number.ttf")
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
@ -74,19 +77,27 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
if (mDownloadCountHint == null) return
val count = DownloadManager.getInstance().getDownloadOrUpdateCount(updateList)
if (count != null) {
mDownloadCountHint!!.visibility = View.VISIBLE
mDownloadCountHint!!.text = count
val params = mDownloadCountHint!!.layoutParams
if (TextUtils.isEmpty(count)) {
params.width = DisplayUtils.dip2px(6f)
params.height = DisplayUtils.dip2px(6f)
} else {
params.width = DisplayUtils.dip2px(12f)
params.height = DisplayUtils.dip2px(12f)
}
mDownloadCountHint!!.layoutParams = params
mDownloadCountHint?.visibility = View.VISIBLE
mDownloadCountHint?.text = count
val params = mDownloadCountHint?.layoutParams
params?.width = if (count.isEmpty()) 6F.dip2px() else ConstraintLayout.LayoutParams.WRAP_CONTENT
params?.height = if (count.isEmpty()) 6F.dip2px() else 14F.dip2px()
(params as? ViewGroup.MarginLayoutParams)?.setMargins(
0,
if (count.isEmpty()) 0 else (-4F).dip2px(),
if (count.isEmpty()) (-4F).dip2px() else (-8F).dip2px(),
0
)
mDownloadCountHint?.setPadding(
if (count.isEmpty()) 0 else 4F.dip2px(),
0,
if (count.isEmpty()) 0 else 4F.dip2px(),
0
)
mDownloadCountHint?.minWidth = if (count.isEmpty()) 0 else 14F.dip2px()
mDownloadCountHint?.layoutParams = params
} else {
mDownloadCountHint!!.visibility = View.GONE
mDownloadCountHint?.visibility = View.GONE
}
}

View File

@ -5,6 +5,7 @@ import android.app.Application
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.util.FloatingBackViewManager
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.SingletonWebActivity
import com.gh.gamecenter.SkipActivity
@ -61,6 +62,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
) {
VHelper.showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity)
}
XapkInstaller.updateCurrentInstallStatus()
}
override fun onActivityPaused(activity: Activity) {

View File

@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.*
import com.gh.common.util.LogUtils
import com.gh.download.DownloadManager
@ -37,6 +38,8 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.Badge
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.login.user.LoginTag
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
@ -65,12 +68,14 @@ class DefaultJsApi(
val entrance: String = "",
private var mFragment: Fragment? = null,
private var mBbsId: String? = "",
private var mOriginUrl: String?= "",
) {
private var mLoginHandler: CompletionHandler<Any>? = null
private var mDownloadWatcher: DataWatcher? = null // 下载观察者
private var mDownloadUrlSet: HashSet<String>? = null // 下载的 url 集合
private var mDownloadHandler: CompletionHandler<Any>? = null // 下载信息回调
private var mExposureEvent: ExposureEvent? = null // 活动曝光实体
init {
if (mFragment != null) {
@ -213,7 +218,7 @@ class DefaultJsApi(
VHelper.launch(context, packageName)
}
} else {
PackageUtils.launchApplicationByPackageName(context, packageName)
PackageLauncher.launchApp(context, packageName = packageName)
}
}
}
@ -624,6 +629,33 @@ class DefaultJsApi(
}
}
@JavascriptInterface
fun logExposure(event: Any) {
val simpleExposureEvent = event.toString().toObject() ?: SimpleExposureEvent()
if (simpleExposureEvent.id.isNotEmpty()) {
val sourceKey = if (mOriginUrl?.contains(Constants.URL_QUERY_FROM_FLOATING_WINDOW) == true) {
"落地页"
} else {
"游戏活动"
}
val exposureSource = ExposureSource(sourceKey, "${simpleExposureEvent.title}+${simpleExposureEvent.id}")
mExposureEvent = ExposureEvent.createEvent(
gameEntity = null,
source = arrayListOf(exposureSource),
)
ExposureManager.log(mExposureEvent!!)
ExposureManager.commitSavedExposureEvents(true)
}
}
/**
* 获取 ExposureEvent可能为空
*/
fun getExposureEvent(): ExposureEvent? {
return mExposureEvent
}
private fun autoUnregisterDownloadObserverIfNeeded(fragment: Fragment?) {
fragment?.parentFragmentManager?.registerFragmentLifecycleCallbacks(
object : FragmentManager.FragmentLifecycleCallbacks() {
@ -676,6 +708,9 @@ class DefaultJsApi(
@Keep
internal class TextShareEvent(var text: String = "", var type: String = "")
@Keep
internal class SimpleExposureEvent(var title: String = "", var id: String = "")
@Keep
internal class InviteFriendsEvent(
var type: String = "",

View File

@ -36,6 +36,7 @@ import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity
@ -51,14 +52,21 @@ object DefaultUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
return interceptUrl(context, url, entrance, false)
return interceptUrl(context, url, null, entrance, false)
}
/**
* 检查并拦截部分内部处理的 url
* @param traceEvent 供一些页面用于登记曝光来源的实体
* @param bringAppToFront 是否需要在不匹配 host 的时候把 APP 调回到前台 (如微信调起)
*
* @return 是否已拦截处理
*/
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String, bringAppToFront: Boolean = false): Boolean {
fun interceptUrl(context: Context, url: String,
traceEvent: ExposureEvent? = null,
entrance: String,
bringAppToFront: Boolean = false): Boolean {
val uri = Uri.parse(url)
if ("ghzhushou" == uri.scheme) {
Utils.log("url = $url")
@ -82,6 +90,7 @@ object DefaultUrlHandler {
id = id,
tab = uri.getQueryParameter("to"),
autoDownload = uri.getQueryParameter("auto_download") == "true",
traceEvent = traceEvent,
entrance = entrance
)
@ -90,6 +99,7 @@ object DefaultUrlHandler {
id,
uri.getQueryParameter("name"),
false,
null,
entrance
)
@ -467,7 +477,7 @@ object DefaultUrlHandler {
}
EntranceConsts.HOST_GAME_COLLECTION_DETAIL -> {
DirectUtils.directToGameCollectionDetail(context, id, entrance)
DirectUtils.directToGameCollectionDetail(context, id, entrance, traceEvent = traceEvent)
}
EntranceConsts.HOST_GAME_COLLECTION_SQUARE -> {

View File

@ -20,7 +20,7 @@ object FixedRateJobHelper {
private const val CHECKER_PERIOD: Long = 15 * 1000L
private const val TIME_PERIOD: Long = 10 * 60 * 1000L
private const val LOGHUB_PERIOD: Long = 2 * 60 * 1000L
private const val EXPOSURE_PERIOD: Long = 5 * 60 * 1000L
private const val EXPOSURE_PERIOD: Long = 1 * 60 * 1000L
private const val REGION_SETTING_PERIOD: Long = 60 * 1000L
private const val VIDEO_RECORD_PERIOD: Long = 60 * 1000L
@ -84,11 +84,6 @@ object FixedRateJobHelper {
VideoRecordUtils.commitVideoRecord()
}
// 获取启动广告 (第一次不需要获取)
if (elapsedTime % STARTUP_AD == 0L && mExecuteCount != 0) {
AdHelper.getSettingAdCache()
}
mExecuteCount++
}
}

View File

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

View File

@ -0,0 +1,23 @@
package com.gh.common.chain
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.feature.entity.GameEntity
class LandPageAddressHandler : ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
if (gameEntity.isLandPageAddressDialog()) {
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
} else {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {
processEndCallback?.invoke(null)
}
}
}
}

View File

@ -7,7 +7,15 @@ import com.gh.gamecenter.feature.entity.GameEntity
class OverseaDownloadHandler : ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {
if (gameEntity.isOverseaAddressDialog()) {
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {// 跳转海外下载地址弹窗
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {
processEndCallback?.invoke(null)
}
}
} else {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {

View File

@ -0,0 +1,27 @@
package com.gh.common.chain
import android.content.Context
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.feature.entity.GameEntity
class UnsupportedFeatureHandler : ChainHandler() {
override fun handleRequest(
context: Context, gameEntity: GameEntity
) {
if (shouldShowUnsupportedFeatureDialog()) {
DialogHelper.showUnsupportedFeatureDialog(context)
} else {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {
processEndCallback?.invoke(null)
}
}
}
/**
* TODO 检查某个版本是否支持指定的功能
*/
private fun shouldShowUnsupportedFeatureDialog(): Boolean = false
}

View File

@ -205,9 +205,6 @@ public class Config {
// 加载完设置后刷新下
PackageHelper.initList();
// 初始化畅玩相关的东西
VHelper.init(HaloApp.getInstance());
}
@Nullable
@ -308,6 +305,26 @@ public class Config {
return mVSetting;
}
/**
* 请求网络数据,尝试刷新畅玩相关配置
*/
@SuppressLint("CheckResult")
public static void refreshVSettingEntity() {
RetrofitManager.getInstance()
.getVApi().getSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<VSetting>() {
@Override
public void onSuccess(VSetting data) {
mVSetting = data;
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
VHelper.init(HaloApp.getInstance());
}
});
}
@Nullable
public static GameGuidePopupEntity getGameGuidePopupEntity() {
return mGameGuidePopupEntity;
@ -385,16 +402,7 @@ public class Config {
}
});
RetrofitManager.getInstance()
.getVApi().getSettings(BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.subscribe(new BiResponse<VSetting>() {
@Override
public void onSuccess(VSetting data) {
mVSetting = data;
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
}
});
refreshVSettingEntity();
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
@ -451,7 +459,6 @@ public class Config {
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
DarkModeUtils.INSTANCE.initDarkMode();
}
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
}
});

View File

@ -1,5 +1,6 @@
package com.gh.common.databind;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
@ -27,8 +28,10 @@ import com.gh.common.chain.CheckDownloadHandler;
import com.gh.common.chain.CheckStoragePermissionHandler;
import com.gh.common.chain.DownloadDialogHelperHandler;
import com.gh.common.chain.GamePermissionHandler;
import com.gh.common.chain.LandPageAddressHandler;
import com.gh.common.chain.OverseaDownloadHandler;
import com.gh.common.chain.PackageCheckHandler;
import com.gh.common.chain.UnsupportedFeatureHandler;
import com.gh.common.chain.ValidateVSpaceHandler;
import com.gh.common.chain.VersionNumberHandler;
import com.gh.common.constant.Config;
@ -45,10 +48,12 @@ import com.gh.common.util.GameViewUtils;
import com.gh.common.util.LogUtils;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageLauncher;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.ReservationHelper;
import com.gh.download.DownloadManager;
import com.gh.download.dialog.DownloadDialog;
import com.gh.download.server.BrowserInstallHelper;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
@ -63,6 +68,7 @@ import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.NumberUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
@ -398,6 +404,7 @@ public class BindingAdapters {
}
ChainBuilder builder = new ChainBuilder();
builder.addHandler(new UnsupportedFeatureHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CheckStoragePermissionHandler());
builder.addHandler(new ValidateVSpaceHandler());
@ -406,11 +413,12 @@ public class BindingAdapters {
builder.addHandler(new DownloadDialogHelperHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
builder.addHandler(new LandPageAddressHandler());
builder.addHandler(new OverseaDownloadHandler());
builder.addHandler(new CheckDownloadHandler());
builder.setProcessEndCallback(o -> {
download(progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
download(v.getContext(), progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
return null;
});
final ChainHandler chainHandler = builder.buildHandlerChain();
@ -419,6 +427,7 @@ public class BindingAdapters {
}
} else {
ChainBuilder builder = new ChainBuilder();
builder.addHandler(new UnsupportedFeatureHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CertificationHandler());
builder.addHandler(new VersionNumberHandler());
@ -447,7 +456,7 @@ public class BindingAdapters {
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
download(progressBar, gameEntity, traceEvent, false, entrance, location);
download(v.getContext(), progressBar, gameEntity, traceEvent, false, entrance, location);
return;
}
@ -457,11 +466,11 @@ public class BindingAdapters {
}
if (gameEntity.isVGame()) {
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity);
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity, null);
return;
}
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
PackageLauncher.launchApp(v.getContext(), gameEntity, gameEntity.getApk().get(0).getPackageName());
} else {
DownloadDialog.showDownloadDialog(
v.getContext(),
@ -477,7 +486,7 @@ public class BindingAdapters {
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
if (gameEntity.isVGame()) {
VHelper.installOrLaunch(v.getContext(), gameEntity);
VHelper.installOrLaunch(v.getContext(), gameEntity, null);
return;
}
@ -673,12 +682,16 @@ public class BindingAdapters {
// 开始下载
private static void download(DownloadButton progressBar,
private static void download(Context context,
DownloadButton progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
boolean isSubscribe,
String entrance,
String location) {
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
}
String str = progressBar.getText().toString();
String method;
if (str.contains("更新")) {

View File

@ -4,6 +4,8 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.LayoutManager
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.gh.gamecenter.feature.exposure.ExposureEvent
import io.reactivex.functions.Consumer
@ -18,7 +20,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
Consumer(Throwable::printStackTrace)
)
}
var layoutManager: LinearLayoutManager? = null
var layoutManager: LayoutManager? = null
var visibleState: ExposureThrottleBus.VisibleState? = null
init {
@ -47,12 +49,28 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (layoutManager == null) layoutManager = recyclerView.layoutManager as LinearLayoutManager
layoutManager = recyclerView.layoutManager
layoutManager?.run {
visibleState =
ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
throttleBus.postVisibleState(visibleState!!)
if (layoutManager != null) {
if (layoutManager is LinearLayoutManager) {
(layoutManager as LinearLayoutManager).run {
visibleState =
ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
throttleBus.postVisibleState(visibleState!!)
}
} else if (layoutManager is StaggeredGridLayoutManager) {
(recyclerView.layoutManager as StaggeredGridLayoutManager).run {
val firstVisibleItemArray = IntArray(2)
val lastVisibleItemArray = IntArray(2)
findFirstVisibleItemPositions(firstVisibleItemArray)
findLastVisibleItemPositions(lastVisibleItemArray)
visibleState =
ExposureThrottleBus.VisibleState(firstVisibleItemArray.first(), lastVisibleItemArray.first())
throttleBus.postVisibleState(visibleState!!)
}
}
}
}

View File

@ -47,7 +47,7 @@ object ExposureManager {
fun log(eventList: List<ExposureEvent>) {
AppExecutor.logExecutor.execute {
for (event in eventList) {
if (!exposureCache.contains(event.id)) {
if (event != null && !exposureCache.contains(event.id)) {
exposureSet.add(event)
exposureCache.add(event.id)
} else {

View File

@ -48,6 +48,7 @@ object ExposureUtils {
}
if (!TextUtils.isEmpty(entity.id)) {
ExposureManager.log(exposureEvent)
ExposureManager.commitSavedExposureEvents(forcedUpload = true)
}
return exposureEvent
}

View File

@ -10,6 +10,7 @@ import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.NewsEntity
import com.gh.gamecenter.feature.entity.User
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
import com.gh.gamecenter.qa.entity.ArticleDetailEntity

View File

@ -2,6 +2,7 @@ package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IAppProvider
@ -18,6 +19,10 @@ class AppProviderImpl : IAppProvider {
return HaloApp.getInstance().getString(R.string.app_name)
}
override fun getAppVersion(): String {
return BuildConfig.VERSION_NAME
}
override fun getGid(): String {
return HaloApp.getInstance().gid ?: ""
}
@ -70,6 +75,10 @@ class AppProviderImpl : IAppProvider {
return HaloApp.getInstance().flavorProvider
}
override fun getFlavor(): String {
return BuildConfig.FLAVOR
}
override fun getIsBrandNewInstall(): Boolean {
return HaloApp.getInstance().isBrandNewInstall
}

View File

@ -1,6 +1,7 @@
package com.gh.common.provider
import android.content.Context
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
@ -24,6 +25,14 @@ class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
BindingAdapters.setGameTags(layout, gameEntity)
}
override fun setMessageUnread(view: TextView, unreadCount: Int) {
BindingAdapters.setMessageUnread(view, unreadCount)
}
override fun setGame(view: View, gameEntity: GameEntity) {
BindingAdapters.setGame(view, gameEntity)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -0,0 +1,22 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import android.os.Parcelable
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.CommentDetailActivity
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.ICommentDetailProvider
import com.gh.gamecenter.feature.entity.MessageEntity
@Route(path = RouteConsts.provider.commentDetail, name = "CommentDetailActivity暴露服务")
class CommentDetailProviderImpl : ICommentDetailProvider {
override fun getIntent(context: Context, commentId: String?, message: Parcelable): Intent {
return CommentDetailActivity.getIntent(context, commentId, message as MessageEntity.Article)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,18 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.ICommentManagerProvider
import com.gh.gamecenter.manager.CommentManager
@Route(path = RouteConsts.provider.commentManager, name = "CommentManager暴露服务")
class CommentManagerProviderImpl : ICommentManagerProvider {
override fun addUrl(ids: String) {
CommentManager.getInstance().addUrl(ids)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,23 @@
package com.gh.common.provider
import android.content.Context
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.CommentUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.ICommentUtilsProvider
@Route(path = RouteConsts.provider.commentUtils, name = "CommentUtils暴露服务")
class CommentUtilsProviderImpl : ICommentUtilsProvider {
override fun setCommentTime(textView: TextView, time: Long) {
CommentUtils.setCommentTime(textView, time)
}
override fun getCommentTime(timestamp: Long): String {
return CommentUtils.getCommentTime(timestamp)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,26 @@
package com.gh.common.provider
import android.content.Context
import android.widget.LinearLayout
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.ConcernContentUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IConcernContentUtilsProvider
@Route(path = RouteConsts.provider.concernContentUtils, name = "ConcernContentUtils暴露服务")
class ConcernContentUtilsProviderImpl : IConcernContentUtilsProvider {
override fun addContentPic(
context: Context,
linearLayout: LinearLayout,
list: List<String>,
entrance: String,
width: Int
) {
ConcernContentUtils.addContentPic(context, linearLayout, list, entrance, width)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,20 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.ConcernActivity
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IConcernProvider
@Route(path = RouteConsts.provider.concernActivity, name = "ConcernActivity暴露服务")
class ConcernProviderImpl : IConcernProvider {
override fun getIntent(context: Context, entrance: String): Intent {
return ConcernActivity.getIntent(context, entrance)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,19 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.constant.Config
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.feature.provider.IConfigSettingProvider
@Route(path = RouteConsts.provider.configSetting, name = "Config.getSettings暴露服务")
class ConfigSettingProviderImpl : IConfigSettingProvider {
override fun getSettings(): SettingsEntity? {
return Config.getSettings()
}
override fun init(context: Context?) {
// do nothing
}
}

View File

@ -0,0 +1,22 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.DataCollectionUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.IDataCollectionProvider
@Route(path = RouteConsts.provider.dataCollection, name = "DataCollectionUtils暴露服务")
class DataCollectionProviderImpl : IDataCollectionProvider {
override fun uploadClick(context: Context, vararg args: String) {
DataCollectionUtils.uploadClick(context, *args)
}
override fun uploadConcern(context: Context, vararg args: String) {
DataCollectionUtils.uploadConcern(context, *args)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

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

View File

@ -69,6 +69,56 @@ class DirectProviderImpl : IDirectProvider {
return DirectUtils.directToQqGroup(context, groupNumber)
}
override fun directToHomeActivity(context: Context, userId: String?, entrance: String?, path: String?) {
DirectUtils.directToHomeActivity(context, userId, entrance, path)
}
override fun directToAnswerDetail(context: Context, id: String, entrance: String?, path: String?) {
DirectUtils.directToAnswerDetail(context, id, entrance, path)
}
override fun directToCommunityArticle(
context: Context,
articleId: String?,
communityId: String?,
entrance: String?,
path: String?
) {
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path)
}
override fun directToVideoDetail(context: Context, videoId: String, entrance: String?, path: String?) {
DirectUtils.directToVideoDetail(context, videoId, entrance, path)
}
override fun directToAmway(context: Context, fixedTopAmwayCommentId: String?, entrance: String?, path: String?) {
DirectUtils.directToAmway(context, fixedTopAmwayCommentId, entrance, path)
}
override fun directToOrderCenter(context: Context) {
DirectUtils.directToOrderCenter(context)
}
override fun directToOrderDetail(context: Context, orderId: String) {
DirectUtils.directToOrderDetail(context, orderId)
}
override fun directToEnergyRecord(context: Context, position: Int) {
DirectUtils.directToEnergyRecord(context, position)
}
override fun directToMyPrizePage(context: Context) {
DirectUtils.directToMyPrizePage(context)
}
override fun directToWinOrderDetail(context: Context, orderId: String, activityId: String) {
DirectUtils.directToWinOrderDetail(context, orderId, activityId)
}
override fun directToQGame(context: Context) {
return DirectUtils.directToQGameHome(context)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -0,0 +1,119 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.provider.IDownloadButtonClickedProvider
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.packagehelper.PackageRepository
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
@Route(path = RouteConsts.provider.downloadButtonClickedHandler, name = "DownloadButton点击事件暴露服务")
class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
override fun onClicked(downloadButton: DownloadButton) {
var gameId = ""
var gameName = ""
var gameCategory = ""
var gameTypeInChinese = ""
var downloadStatus = ""
var downloadStatusInChinese = ""
var gameSchemaType = ""
var packageName = ""
val boundedObject = downloadButton.getObject()
Utils.log("DownloadButtonClickedProviderImpl", "$downloadButton onClicked ${boundedObject?.javaClass}")
if (boundedObject != null) {
when (boundedObject) {
is GameEntity -> {
gameId = boundedObject.id
gameName = boundedObject.name ?: ""
gameCategory = boundedObject.category ?: ""
downloadStatus = if (boundedObject.isVGame()) {
"畅玩"
} else if (boundedObject.downloadStatus == "demo") {
"试玩"
} else {
"下载"
}
gameTypeInChinese = boundedObject.categoryChinese
downloadStatusInChinese = boundedObject.downloadStatusChinese
gameSchemaType = boundedObject.gameBitChinese
packageName = boundedObject.getUniquePackageName() ?: ""
}
is GameUpdateEntity -> {
gameId = boundedObject.id
gameName = boundedObject.name ?: ""
// 下载管理-更新页面,把下载状态都置为下载
downloadStatus = "下载"
gameTypeInChinese = boundedObject.categoryChinese
downloadStatusInChinese = boundedObject.downloadStatusChinese
packageName = boundedObject.packageName
}
is DownloadEntity -> {
gameId = boundedObject.gameId
gameName = boundedObject.name ?: ""
gameCategory = boundedObject.getGameCategory()
downloadStatus = if (boundedObject.isVGame()) "畅玩" else "下载"
packageName = boundedObject.packageName
}
}
// 上报 UI 状态为启动的点击事件 (样式为启动,或者文案包含启动都算能启动)
if (downloadButton.buttonStyle == DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
|| downloadButton.text.contains("启动")) {
// boundedObject 里找不到游戏类型时,尝试从已安装列表中获取
if (gameCategory.isEmpty() && packageName.isNotEmpty()) {
gameCategory = PackageRepository.gameInstalled.find { it.packageName == packageName }?.category ?: ""
}
NewFlatLogUtils.logGameLaunchButtonClicked(
gameId = gameId,
gameName = gameName,
location = downloadButton.getWidgetBusinessName(),
gameCategory = gameCategory,
downloadStatus = downloadStatus
)
}
// 预约状态不上报
if (downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVABLE
&& downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVED
) {
// 上报神策点击事件
SensorsBridge.trackEvent(
"DownLoadbuttonClick",
"game_id", gameId,
"game_name", gameName,
"game_type", gameTypeInChinese,
"download_status", downloadStatusInChinese,
"button_name", downloadButton.text,
"game_schema_type", gameSchemaType,
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
}
}
override fun init(context: Context?) {
// do nothing
}
}

View File

@ -0,0 +1,24 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.IGameCollectionDetailProvider
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
@Route(path = RouteConsts.provider.gameCollectionDetail, name = "GameCollectionDetailActivity暴露服务")
class GameCollectionDetailProviderImpl : IGameCollectionDetailProvider {
override fun getIntent(context: Context, gameCollectionId: String, isFromSquare: Boolean): Intent {
return GameCollectionDetailActivity.getIntent(context, gameCollectionId, isFromSquare)
}
override fun getSpecifiedCommentIntent(context: Context, gameCollectionId: String, topCommentId: String): Intent {
return GameCollectionDetailActivity.getSpecifiedCommentIntent(context, gameCollectionId, topCommentId)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -10,6 +10,15 @@ import com.gh.gamecenter.feature.provider.IGameDetailProvider
@Route(path = RouteConsts.provider.gameDetail, name = "GameDetailActivity暴露服务")
class GameDetailProviderImpl : IGameDetailProvider {
override fun startGameDetailActivity(
context: Context,
gameEntity: GameEntity?,
entrance: String,
traceEvent: ExposureEvent?
) {
GameDetailActivity.startGameDetailActivity(context, gameEntity, entrance, traceEvent)
}
override fun startGameDetailActivity(
context: Context,
gameId: String,
@ -18,6 +27,7 @@ class GameDetailProviderImpl : IGameDetailProvider {
) {
GameDetailActivity.startGameDetailActivity(context, gameId, entrance, traceEvent)
}
override fun startGameDetailActivity(
context: Context,
gameEntity: GameEntity?,
@ -40,6 +50,30 @@ class GameDetailProviderImpl : IGameDetailProvider {
)
}
override fun startGameDetailActivity(
context: Context,
gameId: String,
entrance: String?,
defaultTab: Int,
isSkipGameComment: Boolean,
scrollToLibao: Boolean,
openVideoStreaming: Boolean,
openPlatformWindow: Boolean,
traceEvent: ExposureEvent?
) {
GameDetailActivity.startGameDetailActivity(
context,
gameId,
entrance,
defaultTab,
isSkipGameComment,
scrollToLibao,
openVideoStreaming,
openPlatformWindow,
traceEvent
)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -0,0 +1,18 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.GameTrendsHelper
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IGameTrendsHelperProvider
@Route(path = RouteConsts.provider.gameTrendsHelper, name = "GameTrendsHelper暴露服务")
class GameTrendsHelperProviderImpl : IGameTrendsHelperProvider {
override fun updateReadPostTime() {
GameTrendsHelper.updateReadPostTime()
}
override fun init(context: Context?) {
// do nothing
}
}

View File

@ -0,0 +1,27 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.LibaoUtils
import com.gh.common.util.LibaoUtils.PostLibaoListener
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.ILibaoUtilsProvider
@Route(path = RouteConsts.provider.libaoUtils, name = "LibaoUtils暴露服务")
class LibaoUtilsProviderImpl : ILibaoUtilsProvider {
override fun getLibaoStatus(ids: String, successCallback: ((Any?) -> Unit)?, failureCallback: (() -> Unit)?) {
LibaoUtils.getLibaoStatus(ids, object : PostLibaoListener {
override fun postSucceed(response: Any?) {
successCallback?.invoke(response)
}
override fun postFailed(error: Throwable?) {
failureCallback?.invoke()
}
})
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -4,6 +4,7 @@ import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
@ -62,6 +63,16 @@ class LinkDirectUtilsProviderImpl : ILinkDirectUtilsProvider {
DirectUtils.directToSuggestion(context, type, hiddenHint)
}
override fun directToCommunityColumn(
context: Context,
community: CommunityEntity?,
subjectId: String,
entrance: String?,
path: String?
) {
DirectUtils.directToCommunityColumn(context, community, subjectId, entrance, path)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -0,0 +1,31 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.MessageDetailActivity
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.entity.ConcernEntity
import com.gh.gamecenter.feature.provider.IMessageDetailProvider
@Route(path = RouteConsts.provider.messageDetail, name = "MessageDetailActivity暴露服务")
class MessageDetailProviderImpl : IMessageDetailProvider {
override fun getIntentById(
context: Context,
newsId: String,
commentNum: Int,
openSoftInput: Boolean,
entrance: String
): Intent {
return MessageDetailActivity.getIntentById(context, newsId, commentNum, openSoftInput, entrance)
}
override fun getIntentByEntity(context: Context, concernEntity: ConcernEntity, entrance: String): Intent? {
return MessageDetailActivity.getIntentByEntity(context, concernEntity, entrance)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -1,9 +1,13 @@
package com.gh.common.provider
import android.content.Context
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IMessageUnreadRepositoryProvider
import com.gh.gamecenter.feature.entity.MessageUnreadCount
import com.gh.gamecenter.feature.entity.MessageUnreadEntity
import com.gh.gamecenter.feature.provider.IMessageUnreadRepositoryProvider
import com.gh.gamecenter.message.MessageUnreadRepository
@Route(path = RouteConsts.provider.messageUnreadRepository, name = "MessageUnreadRepository暴露服务")
@ -13,6 +17,22 @@ class MessageUnreadRepositoryProviderImpl : IMessageUnreadRepositoryProvider {
MessageUnreadRepository.loadMessageUnreadData()
}
override fun loadMessageUnreadTotal(isRecordData: Boolean) {
MessageUnreadRepository.loadMessageUnreadTotal(isRecordData)
}
override fun getUnreadLiveData(): MediatorLiveData<MessageUnreadEntity> {
return MessageUnreadRepository.unreadLiveData
}
override fun getZixunConcernLiveData(): MutableLiveData<Boolean> {
return MessageUnreadRepository.zixunConcern
}
override fun getMessageUnreadCountLiveData(): MutableLiveData<MessageUnreadCount?> {
return MessageUnreadRepository.messageUnreadCountLiveData
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -0,0 +1,83 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.INewCommentDetailProvider
import com.gh.gamecenter.qa.comment.NewCommentDetailActivity
@Route(path = RouteConsts.provider.newCommentDetail, name = "NewCommentDetailActivity暴露服务")
class NewCommentDetailProviderImpl : INewCommentDetailProvider {
override fun getAnswerCommentIntent(
context: Context,
commentId: String,
questionId: String,
topCommentId: String,
entrance: String,
path: String
): Intent {
return NewCommentDetailActivity.getAnswerCommentIntent(
context,
commentId,
questionId,
topCommentId,
entrance,
path
)
}
override fun getArticleCommentIntent(
context: Context,
commentId: String,
communityId: String,
articleId: String,
topCommentId: String,
entrance: String,
path: String
): Intent {
return NewCommentDetailActivity.getArticleCommentIntent(
context,
commentId,
communityId,
articleId,
topCommentId,
entrance,
path
)
}
override fun getVideoCommentIntent(
context: Context,
commentId: String,
videoId: String,
topCommentId: String,
entrance: String,
path: String
): Intent {
return NewCommentDetailActivity.getVideoCommentIntent(context, commentId, videoId, topCommentId, entrance, path)
}
override fun getGameCollectionCommentIntent(
context: Context,
commentId: String,
gameCollectionId: String,
topCommentId: String,
entrance: String,
path: String
): Intent {
return NewCommentDetailActivity.getGameCollectionCommentIntent(
context,
commentId,
gameCollectionId,
topCommentId,
entrance,
path
)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -33,6 +33,18 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
return PackageUtils.getSideLoadedInfo()
}
override fun isSignedByGh(context: Context, packageName: String): Boolean {
return PackageUtils.isSignedByGh(context, packageName)
}
override fun getInstalledTime(context: Context, packageName: String): Long {
return PackageUtils.getInstalledTime(context, packageName)
}
override fun getVersionNameByPackageName(packageName: String): String {
return PackageUtils.getVersionNameByPackageName(packageName) ?: ""
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -3,7 +3,8 @@ package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IPackagesManagerProvider
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.feature.provider.IPackagesManagerProvider
import com.gh.gamecenter.manager.PackagesManager
@Route(path = RouteConsts.provider.packagesManager, name = "PackagesManager暴露服务")
@ -12,6 +13,10 @@ class PackagesManagerProviderImpl: IPackagesManagerProvider {
return PackagesManager.isCanPluggable(gameId, packageName)
}
override fun getFilterSameApkInstalledList(): ArrayList<GameInstall> {
return PackagesManager.getFilterSameApkInstalledList()
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -30,6 +30,10 @@ class RegionSettingHelperProviderImpl : IRegionSettingHelperProvider {
return RegionSettingHelper.getIpInfo()
}
override fun shouldThisGameBeFiltered(gameId: String?): Boolean {
return RegionSettingHelper.shouldThisGameBeFiltered(gameId)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -0,0 +1,19 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.ShareCardPicActivity
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.entity.ConcernEntity
import com.gh.gamecenter.feature.provider.IShareCardPicProvider
@Route(path = RouteConsts.provider.shareCardPicActivity, name = "ShareCardPicActivity暴露服务")
class ShareCardPicProviderImpl : IShareCardPicProvider {
override fun startShareCardPicActivity(context: Context, concernEntity: ConcernEntity, entrance: String) {
ShareCardPicActivity.startShareCardPicActivity(context, concernEntity, entrance)
}
override fun init(context: Context?) {
// do nothing
}
}

View File

@ -0,0 +1,20 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.ShareCardActivity
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.entity.ConcernEntity
import com.gh.gamecenter.feature.provider.IShareCardProvider
@Route(path = RouteConsts.provider.shareCardActivity, name = "ShareCardActivity暴露服务")
class ShareCardProviderImpl : IShareCardProvider {
override fun getIntent(context: Context, concernEntity: ConcernEntity, shareContent: String): Intent {
return ShareCardActivity.getIntent(context, concernEntity, shareContent)
}
override fun init(context: Context?) {
// do nothing
}
}

View File

@ -0,0 +1,20 @@
package com.gh.common.provider
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.ISimpleAnswerDetailProvider
import com.gh.gamecenter.qa.answer.detail.SimpleAnswerDetailActivity
@Route(path = RouteConsts.provider.simpleAnswerDetail, name = "SimpleAnswerDetailActivity暴露服务")
class SimpleAnswerDetailProviderImpl : ISimpleAnswerDetailProvider {
override fun getIntent(context: Context, answerId: String, entrance: String, path: String): Intent {
return SimpleAnswerDetailActivity.getIntent(context, answerId, entrance, path)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,24 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.feature.provider.ISubjectProvider
import com.gh.gamecenter.subject.SubjectActivity
@Route(path = RouteConsts.provider.subject, name = "SubjectActivity暴露服务")
class SubjectProviderImpl : ISubjectProvider {
override fun startSubjectActivity(
context: Context,
id: String?,
name: String?,
isOrder: Boolean,
entrance: String?
) {
SubjectActivity.startSubjectActivity(context, id, name, isOrder, null, entrance)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -9,7 +9,7 @@ import com.gh.gamecenter.manager.UpdateManager
@Route(path = RouteConsts.provider.updateManager, name = "UpdateManager暴露服务")
class UpdateManagerProviderImpl: IUpdateManagerProvider {
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler) {
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler?) {
UpdateManager.getInstance(context).checkUpdate(isAutoCheck, handler)
}

View File

@ -0,0 +1,22 @@
package com.gh.common.provider
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IVisitManagerProvider
import com.gh.gamecenter.manager.VisitManager
@Route(path = RouteConsts.provider.visitManager, name = "VisitManager暴露服务")
class VisitManagerProviderImpl : IVisitManagerProvider {
override fun updateOkhttpCache(context: Context, newsId: String) {
VisitManager.updateOkhttpCache(context, newsId)
}
override fun addUrl(ids: String) {
VisitManager.getInstance().addUrl(ids)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -35,6 +35,16 @@ class WebProviderImpl : IWebProvider {
return WebActivity.getQAIntent(context, url, title, isWebPageHandleBackPressed, qaType)
}
override fun getIntentByNews(
context: Context?,
concernLink: String?,
concernGameName: String,
concernId: String?,
entrance: String?
): Intent {
return WebActivity.getIntentByNews(context, concernLink, concernGameName, concernId, entrance)
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -19,44 +19,11 @@ object AdHelper {
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
const val LOCATION_SIMULATOR_GAME = "simulator_game"
@JvmStatic
fun getStartUpAd(): StartupAdEntity? {
return Config.getNewApiSettingsEntity()?.startAd
}
@JvmStatic
fun getStartUp(): StartupAdEntity? {
return Config.getNewApiSettingsEntity()?.startup
}
@JvmStatic
fun prefetchStartUpAd(settingsEntity: NewApiSettingsEntity) {
if (settingsEntity.startAd != null && !settingsEntity.startAd?.img.isNullOrEmpty()) {
val screenWidth = DisplayUtils.getScreenWidth()
val transformedUrl = ImageUtils.getTransformedUrl(settingsEntity.startAd?.img, screenWidth) ?: return
ImageUtils.prefetchToDiskCache(transformedUrl)
}
}
fun getSettingAdCache() {
RetrofitManager.getInstance().newApi
.getSettingAdCache(HaloApp.getInstance().channel)
.compose(observableToMain())
.subscribe(object : Response<NewApiSettingsEntity>() {
override fun onResponse(response: NewApiSettingsEntity?) {
super.onResponse(response)
val settings = Config.getNewApiSettingsEntity()
if (settings != null) {
settings.startAd = response?.startAd
Config.updateNewApiSettings(settings)
if (response != null) {
prefetchStartUpAd(response)
}
}
}
})
}
fun getAd(location: String): SettingsEntity.AD? {
val adList = Config.getSettings()?.adList ?: return null

View File

@ -13,7 +13,7 @@ import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.utils.ifLogin
import com.gh.gamecenter.common.utils.showAutoOrientation
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.feature.entity.CommentEntity
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener

View File

@ -29,7 +29,7 @@ import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.NumberUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.feature.entity.CommentEntity;
import com.gh.gamecenter.feature.entity.MeEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.login.user.UserManager;

View File

@ -57,8 +57,7 @@ public class DataUtils {
return;
}
// 初始化 Sentry 约占用 90ms这里切换到子线程初始化
AppExecutor.getIoExecutor().execute(() -> initSentry(context, channel));
initSentry(context, channel);
}
private static void initSentry(Context context, String channel) {

View File

@ -24,6 +24,8 @@ import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import java.util.Objects;
/**
* Created by khy on 27/06/17.
* 详情下载工具类
@ -42,9 +44,7 @@ public class DetailDownloadUtils {
viewHolder.mMultiVersionDownloadTv.setVisibility(View.GONE);
}
if (viewHolder.gameEntity != null
&& Config.isShowDownload(viewHolder.gameEntity.getId())
&& !"光环助手".equals(viewHolder.gameEntity.getName())) {
if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) && !"光环助手".equals(viewHolder.gameEntity.getName())) {
viewHolder.downloadBottom.setVisibility(View.VISIBLE);
} else {
viewHolder.downloadBottom.setVisibility(View.GONE);
@ -233,6 +233,13 @@ public class DetailDownloadUtils {
DownloadEntity downloadEntity = viewHolder.downloadEntity;
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
if (XapkUnzipStatus.SUCCESS.name().equals(xapkStatus) && XapkInstaller.INSTANCE.isInstalling(downloadEntity.getPath())) {
viewHolder.mDownloadPb.setText("游戏安装中");
viewHolder.mDownloadPb.setProgress(100);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
return;
}
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
viewHolder.mDownloadPb.setText("游戏解压中 " + percent + "%");
@ -286,7 +293,7 @@ public class DetailDownloadUtils {
viewHolder.mDownloadPb.setText(R.string.launch);
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
} else {
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) {
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
} else {
viewHolder.mDownloadPb.setText(R.string.install);
@ -307,13 +314,12 @@ public class DetailDownloadUtils {
}
}
} else {
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) {
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
} else {
viewHolder.mDownloadPb.setText(R.string.install);
}
if (downloadEntity.isPluggable()
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_PLUGIN);
} else {
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);

View File

@ -71,8 +71,8 @@ import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.SpanBuilder;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.DialogAddressConfirmationBinding;
import com.gh.gamecenter.databinding.DialogBindPhoneBinding;
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
import com.gh.gamecenter.databinding.DialogPackageParseErrorBinding;
import com.gh.gamecenter.databinding.DialogRelievePhoneBinding;
import com.gh.gamecenter.databinding.DialogReportReasonBinding;
@ -732,40 +732,65 @@ public class DialogUtils {
public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
context = checkDialogContext(context);
if (gameEntity.getOverseasAddressDialog() == null
|| gameEntity.getApk().size() == 0
|| !gameEntity.getOverseasAddressDialog().isEnable()) {
listener.onConfirm();
} else {
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
View contentView = binding.getRoot();
View contentView = binding.getRoot();
binding.gameIcon.displayGameIcon(gameEntity);
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
binding.gameIcon.displayGameIcon(gameEntity);
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
}
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
binding.downloadBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
});
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
}
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
binding.downloadBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
});
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
// 跳转第三方落地页下载弹窗
public static void showLandPageAddressDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
View contentView = binding.getRoot();
binding.gameIcon.displayGameIcon(gameEntity);
binding.gameNameTv.setText(context.getString(R.string.dialog_land_page_address_hint, gameEntity.getName()));
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
binding.urlTv.setText(gameEntity.getLandPageAddressDialog().getLink());
binding.downloadBtn.setText(context.getString(R.string.dialog_land_page_address_confirm));
binding.downloadBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
});
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
public static void showGameH5DownloadDialog(Context context, GameEntity gameEntity, RegionSetting.GameH5Download gameH5Download) {
@ -773,7 +798,7 @@ public class DialogUtils {
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
View contentView = binding.getRoot();
@ -1293,11 +1318,13 @@ public class DialogUtils {
return dialog;
}
public static void showReserveSuccess2WechatBindDialog(Context context, ConfirmListener confirmListener, CancelListener cancelListener) {
public static void showReserveOrVoteSuccess2WechatBindDialog(Context context, Boolean isReserve, ConfirmListener confirmListener, CancelListener cancelListener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
DialogWechatReserveSuccessBinding binding = DialogWechatReserveSuccessBinding.inflate(LayoutInflater.from(context));
binding.titleIv.setImageResource(isReserve ? R.drawable.bg_reserve_success : R.drawable.bg_vote_success);
binding.contentTv.setText(isReserve ? "游戏上线时,您将在消息中心收到通知。为了避免错过通知,建议您开启微信公众号提醒": "版本上线时,您将在消息中心收到通知。为了避免错过通知,亦建议您开启微信公众号提醒");
binding.closeBtn.setOnClickListener(v -> {
cancelListener.onCancel();
dialog.dismiss();
@ -1318,13 +1345,13 @@ public class DialogUtils {
}
}
public static void showReserveSuccessDialog(Context context) {
public static void showReserveOrVoteSuccessDialog(Context context, Boolean isReserve) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
DialogAlertDefaultBinding binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(context));
binding.titleTv.setText("游戏预约成功");
binding.contentTv.setText("游戏上线时,您将在消息中心和微信公众号收到通知,不会错过任何预约的游戏");
binding.titleTv.setText(isReserve ? "游戏预约成功" : "版本投票成功");
binding.contentTv.setText(isReserve ? "游戏上线时,您将在消息中心和微信公众号收到通知,不会错过任何预约的游戏" : "版本上线时,您将在消息中心和微信公众号收到通知,不会错过任何投票的版本");
binding.confirmTv.setText("我知道了");
binding.centerDivider.setVisibility(View.GONE);
binding.cancelTv.setVisibility(View.GONE);

View File

@ -1,5 +1,6 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
@ -9,6 +10,7 @@ import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.common.constant.Config
import com.gh.common.exposure.ExposureManager.log
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
@ -28,9 +30,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.EntranceConsts.*
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.*
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.provider.IQGameProvider
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.discovery.DiscoveryActivity
@ -39,10 +41,12 @@ import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.entity.GameDetailServer
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.LibaoEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.provider.IConcernInfoProvider
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.forum.home.CommunityHomeFragment
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
@ -51,6 +55,7 @@ import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActi
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity
import com.gh.gamecenter.game.upload.GameSubmissionActivity
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
@ -67,6 +72,9 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
import com.gh.gamecenter.qgame.QGameHomeWrapperActivity
import com.gh.gamecenter.qgame.QGameSearchActivity
import com.gh.gamecenter.qgame.QGameViewModel
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.servers.GameServerTestActivity
import com.gh.gamecenter.servers.GameServersActivity
@ -97,53 +105,6 @@ import kotlin.math.roundToInt
*/
object DirectUtils {
/**
* 跳转到特定页面,根据 [type] 决定跳转页面,[path] 为跳转前的页面名称
*/
@JvmStatic
fun directToSpecificPage(
context: Context,
type: String,
link: String,
text: String? = "",
entrance: String? = null,
path: String? = null
) {
when (type) {
HOST_ARTICLE -> directToArticle(context, id = link, entrance = entrance)
HOST_GAME -> directToGameDetail(context, id = link, entrance = entrance)
HOST_GAME_DOWNLOAD -> directToGameDetail(context, id = link, entrance = entrance, autoDownload = true)
HOST_COLUMN -> directToSubject(context, id = link, subjectName = text, entrance = entrance)
HOST_QUESTION -> directToQuestionDetail(context, id = link, entrance = entrance, path = path)
HOST_ANSWER -> directToAnswerDetail(context, id = link, entrance = entrance, path = path)
HOST_WEB -> directToWebView(context, url = link, entrance = entrance)
HOST_DOWNLOAD -> directToDownloadManagerAndStartDownload(
context,
gameId = link,
packageName = text,
entrance = entrance
)
HOST_UPDATE -> directToDownloadManagerAndStartUpdate(
context,
gameId = link,
packageName = text,
entrance = entrance
)
HOST_LIBAO -> directToGiftDetail(context, giftId = link, entrance = entrance)
HOST_COMMUNITY -> directToCommunity(context, CommunityEntity(link, text!!))
}
}
@JvmStatic
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
directToLinkPage(context, linkEntity, entrance, path, null)
@ -219,8 +180,9 @@ object DirectUtils {
)
} else {
directToGameDetail(
context, linkEntity.link
?: "", BaseActivity.mergeEntranceAndPath(entrance, path)
context,
linkEntity.link ?: "",
entrance = BaseActivity.mergeEntranceAndPath(entrance, path)
)
}
}
@ -258,7 +220,7 @@ object DirectUtils {
path
)
"web", "inurl", "web链接" -> {
HOST_WEB, HOST_WEB_INURL, HOST_WEB_AL -> {
when {
linkEntity.link!!.contains("v.douyin") && PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme") -> {
directDouyin(context, "1402577827140941")
@ -316,7 +278,7 @@ object DirectUtils {
)
}
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance, "", exposureEvent)
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path, exposureEvent)
@ -338,7 +300,7 @@ object DirectUtils {
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, false, "", entrance)
"qa", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa_collection", "Q&A合集" -> directToQaCollection(
context, linkEntity.text
@ -410,7 +372,7 @@ object DirectUtils {
"column_test" -> context.startActivity(
GameServerTestActivity.getIntent(
context, linkEntity.link
?: "", linkEntity.text ?: "", entrance
?: "", linkEntity.text ?: "", entrance, exposureEvent
)
)
@ -438,13 +400,13 @@ object DirectUtils {
//"h5_game_center" -> directLetoGameCenter(context)
"game_list" -> directToGameCollectionSquare(context, entrance, "", "", "")
"game_list" -> directToGameCollectionSquare(context, entrance, traceEvent = exposureEvent)
"game_list_detail" -> directToGameCollectionDetail(
context,
linkEntity.link ?: "",
entrance,
exposureEvent = exposureEvent
traceEvent = exposureEvent
)
"explore_column", "game_explore" -> context.startActivity(
@ -463,6 +425,8 @@ object DirectUtils {
)
)
"qq_mini_game_column" -> directToQGameHome(context)
"" -> {
// do nothing
}
@ -513,7 +477,8 @@ object DirectUtils {
id: String,
position: Int = -1,
entrance: String,
columnName: String = ""
columnName: String = "",
exposureEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
val bundle = Bundle()
@ -522,6 +487,9 @@ object DirectUtils {
bundle.putString(KEY_COLLECTION_ID, id)
bundle.putString(KEY_COLUMNNAME, columnName)
bundle.putInt(KEY_POSITION, position)
if (exposureEvent != null) {
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST ,ArrayList(exposureEvent.source))
}
jumpActivity(context, bundle)
}
@ -748,11 +716,12 @@ object DirectUtils {
id: String,
subjectName: String? = "",
entrance: String? = null,
exposureEvent: ExposureEvent? = null
exposureEvent: ExposureEvent? = null,
isQQMiniGame: Boolean = false,
) {
if (id.isEmpty()) return
val bundle = Bundle()
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false)
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, isQQMiniGame = isQQMiniGame)
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, SubjectActivity::class.java.name)
bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData)
@ -1864,8 +1833,11 @@ object DirectUtils {
* 跳转到游戏动态,请不要随意修改方法名
*/
@JvmStatic
fun directToConcernInfo(context: Context) {
context.startActivity(ConcernInfoActivity.getIntent(context));
fun directToConcernInfo(context: Context, entrance: String) {
context.startActivity(
(ARouter.getInstance().build(RouteConsts.provider.concernInfo)
.navigation() as? IConcernInfoProvider)?.getIntent(context, entrance)
)
}
/**
@ -1877,14 +1849,36 @@ object DirectUtils {
entrance: String = "",
forumName: String = "",
gameCollectionTitle: String = "",
gameCollectionId: String = ""
gameCollectionId: String = "",
collectionName: String = "",
collectionId: String = "",
traceEvent: ExposureEvent? = null
) {
val bundle = Bundle()
val exposureSourceList = traceEvent?.source
bundle.putString(KEY_TO, GameCollectionSquareActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_FORUM_NAME, forumName)
bundle.putString(KEY_GAME_COLLECTION_TITLE, gameCollectionTitle)
bundle.putString(KEY_GAME_COLLECTION_ID, gameCollectionId)
bundle.putString(KEY_COLLECTION_ID, collectionId)
bundle.putString(KEY_COLLECTION_NAME, collectionName)
if (exposureSourceList is ArrayList) {
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
} else if (exposureSourceList != null) {
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureSourceList))
}
jumpActivity(context, bundle)
}
/**
* 跳转至游戏单热榜
*/
@JvmStatic
fun directToGameCollectionHotList(context: Context, entrance: String = "") {
val bundle = Bundle()
bundle.putString(KEY_TO, GameCollectionHotListActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
jumpActivity(context, bundle)
}
@ -1897,15 +1891,20 @@ object DirectUtils {
id: String,
entrance: String? = null,
path: String? = null,
exposureEvent: ExposureEvent? = null
traceEvent: ExposureEvent? = null,
) {
if (id.isEmpty()) return
val bundle = Bundle()
val exposureSourceList = traceEvent?.source
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, GameCollectionDetailActivity::class.java.name)
bundle.putString(KEY_GAME_COLLECTION_ID, id)
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
if (exposureSourceList is ArrayList) {
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
} else if (exposureSourceList != null) {
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureSourceList))
}
jumpActivity(context, bundle)
}
@ -2030,4 +2029,71 @@ object DirectUtils {
platform = platform
)
}
@JvmStatic
fun directToQGameHome(context: Context) {
context.startActivity(QGameHomeWrapperActivity.getIntent(context))
}
@JvmStatic
fun directToQGameSearch(
context: Context,
hint: String,
sourceEntrance: String
) {
context.startActivity(QGameSearchActivity.getIntent(context, hint, sourceEntrance))
}
@SuppressLint("CheckResult")
@JvmStatic
fun directToQGameById(
activity: Activity,
qqGameId: String
) {
if (activity !is AppCompatActivity || activity.supportFragmentManager.isDestroyed) {
ToastUtils.toast("启动QQ小游戏失败请稍后再试")
return
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
ToastUtils.toast("该游戏仅支持安卓5.0及以上设备")
return
}
CheckLoginUtils.checkLogin(
activity, null, true, "QQ小游戏-秒开"
) {
val userToken = UserManager.getInstance().token
val userId = UserManager.getInstance().userId
val userName = UserManager.getInstance().userInfoEntity?.name ?: "unknown"
val qGameProvider = ARouter
.getInstance()
.build(RouteConsts.provider.qGame)
.navigation() as IQGameProvider<*>
qGameProvider.setLoginInfo(activity, userId, userName, userToken)
qGameProvider.launchGame(activity, qqGameId) { _, _ ->
RetrofitManager
.getInstance()
.newApi
.postQGamePlay(qqGameId, userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
QGameViewModel.notifyQGameSubjectUpdate() // 通知QQ小游戏首页列表刷新
},
{}
) // 秒玩记录上报
}
}
}
@JvmStatic
fun directToMessageCenter(defaultTabIndex: Int) {
ARouter.getInstance().build(RouteConsts.activity.messageWrapperActivity)
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
.navigation()
}
}

View File

@ -1,5 +1,6 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
import android.os.Message
import android.text.TextUtils
@ -7,6 +8,7 @@ import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.collection.ArrayMap
import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.common.chain.*
import com.gh.common.constant.Config
import com.gh.common.dialog.DeviceRemindDialog
@ -18,9 +20,11 @@ import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkInstaller.cancelUnzipTask
import com.gh.common.xapk.XapkInstaller.isInstalling
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
@ -28,15 +32,20 @@ import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.callback.CancelListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.provider.IQGameProvider
import com.gh.gamecenter.core.utils.*
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.feature.view.DownloadButton
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadConfig
@ -163,6 +172,8 @@ object DownloadItemUtils {
briefStyle: String? = null,
isShowRecommendStar: Boolean = false
) {
holder.gameDownloadBtn.putObject(gameEntity)
// 显示预约
if (gameEntity.isReservable) {
holder.multiVersionDownloadTv?.visibility = View.GONE
@ -233,6 +244,24 @@ object DownloadItemUtils {
}
return
}
if (gameEntity.isQQMiniGame()) {
val isQQMiniGameOffShelve = gameEntity.qqMiniGameAppStatus == 1 // QQ小游戏是否下架
if (isQQMiniGameOffShelve) {
downloadBtn.apply {
isClickable = false
text = context.getString(R.string.off_shelve)
buttonStyle = DownloadButton.ButtonStyle.NONE
}
} else {
downloadBtn.apply {
isClickable = true
setBackgroundResource(R.drawable.download_button_normal_style)
setTextColor(R.color.white.toColor(context))
text = context.getString(R.string.quick_play)
}
}
return
}
if (gameEntity.getApk().isEmpty() || gameEntity.downloadOffStatus != null) {
val h5LinkEntity = gameEntity.h5Link
val offStatus = gameEntity.downloadOffStatus
@ -263,20 +292,14 @@ object DownloadItemUtils {
}
}
} else if (gameEntity.getApk().size == 1) {
// 优先从下载管理获取 downloadEntity
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在代表游戏已下载并成功安装
if (downloadEntity == null && gameEntity.isVGame()) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
}
if (downloadEntity == null) {
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
val apkEntity = gameEntity.getApk()[0]
if (entryMap.isNotEmpty()) {
downloadEntity = entryMap[apkEntity.getPlatform()]
}
}
if (downloadEntity != null) {
downloadBtn.apply {
when (downloadEntity.status) {
@ -297,6 +320,25 @@ object DownloadItemUtils {
DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
}
} else {
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {
progress = 100
setText(R.string.installing)
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
return
}
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
val percent = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_PERCENT]
progress = (java.lang.Float.valueOf(percent) * 10).toInt()
text = "$percent%"
buttonStyle = DownloadButton.ButtonStyle.XAPK_UNZIPPING
return
} else if (XapkUnzipStatus.FAILURE.name == xapkStatus) {
setText(R.string.install)
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
return
}
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
setText(R.string.install)
}
@ -307,6 +349,7 @@ object DownloadItemUtils {
DownloadButton.ButtonStyle.NORMAL
}
}
DownloadStatus.pause,
DownloadStatus.timeout,
DownloadStatus.neterror,
@ -317,9 +360,11 @@ object DownloadItemUtils {
buttonStyle = DownloadButton.ButtonStyle.NORMAL
setText(R.string.resume)
}
DownloadStatus.cancel -> {
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
}
else -> {
// do nothing
}
@ -341,15 +386,7 @@ object DownloadItemUtils {
briefStyle: String?,
isShowRecommendStar: Boolean = false
) {
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
val apkEntity = gameEntity.getApk()[0]
var downloadEntity: DownloadEntity? = null
if (entryMap.isNotEmpty()) {
downloadEntity = entryMap[apkEntity.getPlatform()]
}
if (downloadEntity == null) {
downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
}
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity != null) {
if (downloadEntity.isSimulatorGame()) {
if (downloadEntity.status != DownloadStatus.done) {
@ -396,7 +433,7 @@ object DownloadItemUtils {
}
// 更改进度条和提示文本的状态
fun changeStatus(
private fun changeStatus(
context: Context,
holder: GameViewHolder,
downloadEntity: DownloadEntity,
@ -421,6 +458,7 @@ object DownloadItemUtils {
holder.gameDownloadBtn.text = downloadEntity.percent.toString() + "%"
}
}
DownloadStatus.waiting -> {
if (isMultiVersion) {
holder.gameDownloadTips?.visibility = View.VISIBLE
@ -429,6 +467,7 @@ object DownloadItemUtils {
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.WAITING
holder.gameDownloadBtn.text = context.getString(R.string.waiting)
}
DownloadStatus.pause,
DownloadStatus.timeout,
DownloadStatus.neterror,
@ -443,6 +482,7 @@ object DownloadItemUtils {
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
holder.gameDownloadBtn.text = context.getString(R.string.resume)
}
DownloadStatus.done -> {
if (isMultiVersion) {
holder.gameDownloadTips?.visibility = View.VISIBLE
@ -462,6 +502,7 @@ object DownloadItemUtils {
holder.gameDownloadBtn.progress = 1000
holder.gameDownloadBtn.setText(R.string.hundred_percent)
}
else -> {
holder.gameDownloadTips?.visibility = View.GONE
}
@ -592,13 +633,15 @@ object DownloadItemUtils {
refreshCallback: EmptyCallback?,
allStateClickCallback: EmptyCallback?
) {
// 为 downloadButton 添加游戏实体,供点击的时候上报用
downloadBtn.putObject(gameEntity)
val gamePermissionDialogFragment = (context as AppCompatActivity).supportFragmentManager.findFragmentByTag(
GamePermissionDialogFragment::class.java.name
) as GamePermissionDialogFragment?
gamePermissionDialogFragment?.dismissAllowingStateLoss()
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
DialogHelper.showDialog(
context,
"提示",
@ -618,7 +661,6 @@ object DownloadItemUtils {
if (gameEntity.isSpecialDownload()) {
val info = RegionSettingHelper.getGameSpecialDownloadInfo(gameEntity.id) ?: return
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
DialogHelper.showDialog(
context,
"提示",
@ -659,14 +701,12 @@ object DownloadItemUtils {
ReservationHelper.reserve(
context,
gameEntity.id,
gameEntity.name ?: "",
object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
})
gameEntity.name ?: ""
) {
LogUtils.logReservation(gameEntity, traceEvent)
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
}
}
} else {
@ -708,16 +748,22 @@ object DownloadItemUtils {
val gameH5Download = RegionSettingHelper.getGameH5DownloadByGameId(gameEntity.id)
if (gameH5Download != null) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
DialogUtils.showGameH5DownloadDialog(context, gameEntity, gameH5Download)
}
return
}
if (gameEntity.isQQMiniGame()) {
downloadBtn.setOnClickListener {
NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name)
GlobalActivityManager.currentActivity?.let { activity ->
DirectUtils.directToQGameById(activity, gameEntity.qqMiniGameAppId)
}
}
return
}
if (gameEntity.getApk().size == 0 && gameEntity.h5Link != null) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
allStateClickCallback?.onCallback()
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.name)
val linkEntity = gameEntity.h5Link
val isPlay = "play" == linkEntity!!.type // 是否为开始玩
if (isPlay) {
@ -734,7 +780,6 @@ object DownloadItemUtils {
}
} else if (gameEntity.getApk().size == 1) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
val clickRunnable = EmptyCallback {
allStateClickCallback?.onCallback()
clickCallback?.onCallback()
@ -795,6 +840,7 @@ object DownloadItemUtils {
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
if (str == context.getString(R.string.download)) {
ChainBuilder().apply {
addHandler(UnsupportedFeatureHandler())
addHandler(UpdateNewSimulatorHandler())
addHandler(GamePermissionHandler())
addHandler(BrowserInstallHandler())
@ -802,6 +848,7 @@ object DownloadItemUtils {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(OverseaDownloadHandler())
addHandler(LandPageAddressHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback {
@ -812,6 +859,7 @@ object DownloadItemUtils {
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str == context.getString(R.string.attempt)) {
ChainBuilder().apply {
addHandler(UnsupportedFeatureHandler())
addHandler(UpdateNewSimulatorHandler())
addHandler(GamePermissionHandler())
addHandler(BrowserInstallHandler())
@ -819,6 +867,7 @@ object DownloadItemUtils {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
addHandler(CheckDownloadHandler())
}
@ -830,11 +879,13 @@ object DownloadItemUtils {
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str == context.getString(R.string.smooth)) {
ChainBuilder().apply {
addHandler(UnsupportedFeatureHandler())
addHandler(GamePermissionHandler())
addHandler(PackageCheckHandler())
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
addHandler(CheckStoragePermissionHandler())
addHandler(ValidateVSpaceHandler())
@ -846,9 +897,6 @@ object DownloadItemUtils {
.buildHandlerChain()
?.handleRequest(context, gameEntity)
} else if (str.contains("")) {
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "插件化", gameEntity.name)
}
if (gameEntity.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
@ -913,42 +961,48 @@ object DownloadItemUtils {
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
return
}
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
}
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
} else if (str == context.getString(R.string.update)) {
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.name)
}
if (gameEntity.isVGame()) {
VHelper.updateOrReDownload(gameEntity)
return
}
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback {
override fun onCallback() {
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name
) { isSubscribe: Boolean ->
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
ChainBuilder()
.apply {
addHandler(LandPageAddressHandler())
}.setProcessEndCallback {
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name
) { isSubscribe: Boolean ->
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
}
}
}
})
.buildHandlerChain()
?.handleRequest(context, gameEntity)
} else {
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
if (downloadEntity == null && gameEntity.getApk().size == 1) {
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
val apkEntity = gameEntity.getApk()[0]
if (entryMap.isNotEmpty()) {
downloadEntity = entryMap[apkEntity.getPlatform()]
}
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在代表游戏已下载并成功安装
if (downloadEntity == null && gameEntity.isVGame()) {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
}
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
if (downloadEntity == null) {
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
}
if (downloadEntity != null) {
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {// 安装过程中避免重复点击
return
}
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
cancelUnzipTask(downloadEntity)
return
@ -957,9 +1011,11 @@ object DownloadItemUtils {
context.getString(R.string.resume) -> {
DownloadManager.getInstance().resume(downloadEntity, true)
}
context.getString(R.string.waiting) -> {
Utils.toast(context, "最多只能同时下载三个任务,请稍等")
}
else -> {
DownloadManager.getInstance().pause(downloadEntity.url)
}
@ -980,7 +1036,7 @@ object DownloadItemUtils {
) {
if (gameEntity.getApk().isEmpty()) return
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size)
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(
context,
@ -991,7 +1047,13 @@ object DownloadItemUtils {
isSubscribe,
traceEvent
)
Utils.toast(context, gameEntity.name + "已加入下载队列")
ToastUtils.toast(gameEntity.name + "已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
if (downloadBtn is DownloadButton) {
downloadBtn.text = "0%"
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
@ -1012,10 +1074,16 @@ object DownloadItemUtils {
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size)
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
Utils.toast(context, gameEntity.name + "已加入下载队列")
ToastUtils.toast(gameEntity.name + "已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
if (downloadBtn is DownloadButton) {
downloadBtn.setText(R.string.downloading)
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN
@ -1045,9 +1113,11 @@ object DownloadItemUtils {
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
PackageUtils.isCanPluggable(apkEntity) -> {
DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
}
else -> {
PackageInstaller.install(context, downloadEntity)
}
@ -1066,23 +1136,4 @@ object DownloadItemUtils {
) {
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
}
private fun logDownloadButtonClick(gameEntity: GameEntity, downloadBtn: View) {
val buttonName = if (downloadBtn is DownloadButton) downloadBtn.text else ""
SensorsBridge.trackEvent(
"DownLoadbuttonClick",
"game_id", gameEntity.id,
"game_name", gameEntity.name ?: "",
"game_type", gameEntity.categoryChinese,
"download_status", gameEntity.downloadStatusChinese,
"button_name", buttonName,
"game_schema_type", gameEntity.gameBitChinese,
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
}

View File

@ -16,7 +16,6 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBShowDialog
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.eventbus.EBDownloadStatus
@ -24,18 +23,13 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.pkg.PkgHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.*
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import org.greenrobot.eventbus.EventBus
import org.json.JSONObject
object DownloadObserver {
@ -45,7 +39,10 @@ object DownloadObserver {
// TODO 修复因为更改内存对象造成的双重下载完成事件问题,具体触发代码见 DownloadDao.updateSnapshotList
private var mDoneDebouncePair: Pair<String, Long>? = null
private const val TEA_EVENT_DOWNLOAD_COMPLETE = "game_addiction"
private const val TAG = "DownloadObserver"
private const val CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED = "CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED"
private val mRetryableHashMap = hashMapOf<String, Boolean>()
// 如果在WIFI状态下,下载自动暂停,则再重试一遍
@JvmStatic
@ -76,28 +73,34 @@ object DownloadObserver {
val currentActivity = AppManager.getInstance().currentActivity() ?: return
DialogHelper.showDialog(currentActivity, "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
HelpAndFeedbackBridge.startSuggestionActivity(
currentActivity,
SuggestType.gameQuestion, "notfound",
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
SimpleGameEntity(gameId, downloadEntity.name, "")
)
}, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
DialogHelper.showDialog(
currentActivity,
"下载失败",
"下载链接已失效,建议提交反馈",
"立即反馈",
"取消",
{
HelpAndFeedbackBridge.startSuggestionActivity(
currentActivity,
SuggestType.gameQuestion, "notfound",
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
SimpleGameEntity(gameId, downloadEntity.name, "")
)
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
return
} else if (DownloadStatus.neterror == downloadEntity.status
|| DownloadStatus.timeout == downloadEntity.status
|| DownloadStatus.diskioerror == downloadEntity.status
|| DownloadStatus.diskisfull == downloadEntity.status) {
if (downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD].isNullOrEmpty()
|| DownloadStatus.diskisfull == downloadEntity.status
) {
if (mRetryableHashMap[downloadEntity.url] == true
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
) {
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = downloadEntity.progress.toString()
downloadManager.updateDownloadEntity(downloadEntity)
downloadManager.resumeDownload(downloadEntity.url)
debugOnly {
Utils.log("DownloadObserver", "下载重试->" + downloadEntity.toJson())
}
mRetryableHashMap[downloadEntity.url] = false
Utils.log(TAG, "下载重试->" + downloadEntity.toJson())
} else {
if (DownloadStatus.diskisfull == downloadEntity.status) {
ToastUtils.toast("磁盘已满,请清理空间后重试下载")
@ -108,13 +111,10 @@ object DownloadObserver {
}
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
debugOnly {
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
}
Utils.log(TAG, "下载自动暂停->" + downloadEntity.toJson())
}
} else if (DownloadStatus.redirected == downloadEntity.status) {
debugOnly { Utils.log("重定向完毕") }
Utils.log(TAG, "重定向完毕")
DownloadDataHelper.uploadRedirectEvent(downloadEntity)
} else if (DownloadStatus.unqualified == downloadEntity.status) {
// 未成年
@ -159,40 +159,35 @@ object DownloadObserver {
if (DownloadStatus.done == downloadEntity.status) {
if (mDoneDebouncePair?.first != downloadEntity.url) {
mDoneDebouncePair = Pair(downloadEntity.url, System.currentTimeMillis())
performDownloadCompleteAction(downloadEntity, gameId, downloadManager)
performDownloadCompleteAction(downloadEntity, downloadManager)
} else {
if (mDoneDebouncePair?.second == 0L
|| System.currentTimeMillis() - (mDoneDebouncePair?.second ?: 0) > 500
) {
performDownloadCompleteAction(downloadEntity, gameId, downloadManager)
performDownloadCompleteAction(downloadEntity, downloadManager)
}
}
}
if (downloadEntity.status == DownloadStatus.done) {
mRetryableHashMap.remove(downloadEntity.url)
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
}
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
if (downloadEntity.status == DownloadStatus.downloading &&
downloadEntity.progress.toString() != downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD]
) {
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = ""
downloadManager.updateDownloadEntity(downloadEntity)
if (downloadEntity.status == DownloadStatus.downloading) {
mRetryableHashMap[downloadEntity.url] = true
}
}
}
// 添加观察者
DownloadManager.getInstance().addObserver(dataWatcher)
}
private fun performDownloadCompleteAction(
downloadEntity: DownloadEntity,
gameId: String,
downloadManager: DownloadManager
) {
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
@ -210,10 +205,7 @@ object DownloadObserver {
} else {
statDoneEvent(downloadEntity)
if (!SPUtils.getBoolean(TEA_EVENT_DOWNLOAD_COMPLETE)) {
HaloApp.getInstance().flavorProvider.logEvent(TEA_EVENT_DOWNLOAD_COMPLETE)
SPUtils.setBoolean(TEA_EVENT_DOWNLOAD_COMPLETE, true)
}
logCoreEventIfNeeded(downloadEntity.getGameCategory())
GameActivityDownloadHelper.clear()
@ -226,13 +218,16 @@ object DownloadObserver {
EventBus.getDefault().post(
EBShowDialog(
BaseActivity.PLUGGABLE,
downloadEntity.path
downloadEntity.path,
downloadEntity.pluginDesc
)
)
downloadEntity.isPlugin -> Utils.toast(
mApplication,
downloadEntity.name + " - " + platform + " - 下载完成"
)
else -> {
if (!downloadEntity.isVGame()) {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
@ -250,15 +245,10 @@ object DownloadObserver {
val gameName = downloadEntity.getMetaExtra(Constants.GAME_NAME)
if (simulatorJson.isEmpty()) return
var simulator = GsonUtils.fromJson(simulatorJson, SimulatorEntity::class.java)
val isInstalled = PackageUtils.isInstalledFromAllPackage(
HaloApp.getInstance().application,
simulator.apk?.packageName
)
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
val isInstalledOldSimulator =
SimulatorGameManager.isOldSimulatorInstalled(HaloApp.getInstance().application)
// if (!isInstalled && !isInstalledNewSimulator) {
val currentActivity = AppManager.getInstance().currentActivity()
?: return
val newSimulator = Config.getNewSimulatorEntitySetting()
@ -269,7 +259,6 @@ object DownloadObserver {
currentActivity, simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, downloadEntity.gameId, gameName, null
)
// }
SimulatorGameManager.recordDownloadSimulatorGame(downloadEntity.gameId, simulator.type)
SimulatorGameManager.postPlayedGame(downloadEntity.gameId, downloadEntity.packageName)
} else {
@ -296,7 +285,8 @@ object DownloadObserver {
EventBus.getDefault().post(
EBShowDialog(
BaseActivity.PLUGGABLE,
downloadEntity.path
downloadEntity.path,
downloadEntity.pluginDesc
)
)
} else {
@ -392,7 +382,7 @@ object DownloadObserver {
"DownloadProcessFinish",
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_TYPE] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
"page_name", getCurrentPageEntity().pageName,
"page_id", getCurrentPageEntity().pageId,
@ -409,11 +399,6 @@ object DownloadObserver {
var elapsedTime = elapsedTimeString.toLong()
if (elapsedTime == 0L) {
elapsedTime = 1L
SentryHelper.onEvent(
"DOWNLOAD_ELAPSED_TIME",
"elapsedTime is zero",
downloadEntity.gameId + ":" + downloadEntity.size
)
}
downloadSpeed = downloadEntity.size / elapsedTime
}
@ -452,4 +437,21 @@ object DownloadObserver {
DataLogUtils.uploadHijack(mApplication, downloadEntity)
}
/**
* 根据预设的游戏类型上报关键事件(下载完成事件)
*/
private fun logCoreEventIfNeeded(gameCategory: String) {
val category = PkgHelper.getCoreEventGameCategory()
val categoryMatched = if (category == "standard" || category.isNullOrEmpty()) {
true
} else {
gameCategory == category
}
if (!SPUtils.getBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED) && categoryMatched) {
HaloApp.getInstance().flavorProvider.logCoreEvent()
SPUtils.setBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED, true)
}
}
}

View File

@ -15,6 +15,7 @@ import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.constant.Constants
@ -26,6 +27,7 @@ import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MtaHelper
@ -183,6 +185,12 @@ object GameActivityDownloadHelper {
str != context.getString(R.string.launch)
) {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
} else {
when {
str == context.getString(R.string.download) || str == context.getString(R.string.attempt) -> {
@ -205,6 +213,12 @@ object GameActivityDownloadHelper {
}
else -> {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
}
}
}
@ -348,7 +362,7 @@ object GameActivityDownloadHelper {
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
}
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
}
// 处理更新状态
@ -424,6 +438,12 @@ object GameActivityDownloadHelper {
), entrance, location, isSubscribe, traceEvent
)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
} else {
ToastUtils.toast(msg)
}
@ -443,6 +463,12 @@ object GameActivityDownloadHelper {
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
} else {
ToastUtils.toast(msg)
}
@ -463,7 +489,7 @@ object GameActivityDownloadHelper {
gameEntity.getEntryMap().remove(apkEntity.getPlatform())
}
PackageUtils.isCanPluggable(apkEntity) -> {
DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
}
else -> {
PackageInstaller.install(context, downloadEntity)
@ -483,6 +509,12 @@ object GameActivityDownloadHelper {
) {
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
val toast = context.getString(R.string.unsupported_browser_install_hint)
AppExecutor.uiExecutor.executeWithDelay({
ToastUtils.toast(toast)
}, 1000)
}
}
@SuppressLint("CheckResult")

View File

@ -0,0 +1,18 @@
package com.gh.common.util
import com.gh.gamecenter.db.GameTrendsDao
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.message.MessageUnreadRepository
import com.halo.assistant.HaloApp
object GameTrendsHelper {
private val mGameTrendsDao = GameTrendsDao(HaloApp.getInstance().application)
fun updateReadPostTime() {
mGameTrendsDao.findGameTrendsInfo(UserManager.getInstance().userId)?.let { trendsInfo ->
trendsInfo.readPostTime = System.currentTimeMillis()
mGameTrendsDao.add(trendsInfo)
MessageUnreadRepository.loadMessageUnreadTotal(true)
}
}
}

View File

@ -8,6 +8,7 @@ import androidx.annotation.WorkerThread;
import com.gh.common.constant.Config;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
@ -180,7 +181,8 @@ public class GameUtils {
if (gameEntity.isVGame()) {
return context.getString(R.string.smooth);
} else {
if ("smooth".equals(gameEntity.getDownloadStatus())) {
if (Constants.V_GAME.equals(gameEntity.getDownloadStatus())
|| Constants.V_GAME_32.equals(gameEntity.getDownloadStatus())) {
GameEntity.GameCategory gameCategory = gameEntity.getGameCategory();
if (gameCategory.equals(GameEntity.GameCategory.ONLINE_GAME)
|| gameCategory.equals(GameEntity.GameCategory.INTERNATIONAL_ONLINE_GAME)) {

View File

@ -22,8 +22,8 @@ import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.entity.LibaoEntity;
import com.gh.gamecenter.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.LibaoEntity;
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.MeEntity;
import com.gh.gamecenter.common.entity.NotificationUgc;
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
@ -46,7 +46,6 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -786,7 +785,7 @@ public class LibaoUtils {
, "关闭", "启动游戏"
, () -> {
if (LibaoUtils.isAppInstalled(context, libaoEntity.getPackageName())) {
PackageUtils.launchApplicationByPackageName(context, libaoEntity.getPackageName());
PackageLauncher.launchApp(context, null, libaoEntity.getPackageName());
} else {
Utils.toast(context, "请安装游戏:" + libaoEntity.getGame().getName()
+ PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform()) + "");

View File

@ -986,7 +986,7 @@ public class LogUtils {
LoghubUtils.log(object, LOG_STORE_EVENT, false);
}
public static void logHomeTopTabClick(String tabName, String linkType, String linkTitle, String linkId, int sequence) {
public static void logHomeTopTabClick(String tabName, String linkType, String linkTitle, String linkId, int sequence, String entrance) {
JSONObject object = new JSONObject();
try {
object.put(KEY_EVENT, "top_tab_click");
@ -995,6 +995,7 @@ public class LogUtils {
object.put("link_id", linkId);
object.put("link_text", linkTitle);
object.put("sequence", sequence);
object.put("entrance", entrance);
object.put(KEY_META, getMetaObject());
object.put(KEY_TIMESTAMP, System.currentTimeMillis() / 1000);
} catch (JSONException e) {

View File

@ -23,6 +23,9 @@ object NewFlatLogUtils {
private const val KEY_TEXT = "text"
private const val KEY_BUTTON_TYPE = "button_type"
private const val KEY_BBS_ID = "bbs_id"
private const val KEY_GAME_CATEGORY = "game_category"
private const val KEY_DOWNLOAD_STATE = "download_state"
private const val KEY_LOCATION = "location"
private const val EVENT_LOGIN_FROM_GHZS_SHOW = "halo_fun_login_from_ghzs_show"
private const val EVENT_LOGIN_FROM_GHZS_CLICK = "halo_fun_login_from_ghzs_click"
@ -118,7 +121,7 @@ object NewFlatLogUtils {
fun logHaloFunGameDetailJumpClick(downloadStatus: String, gameId: String) {
val json = json {
KEY_EVENT to "halo_fun_game_detail_jump_click"
"download_state" to downloadStatus
KEY_DOWNLOAD_STATE to downloadStatus
KEY_GAME_ID to gameId
parseAndPutMeta().invoke(this)
}
@ -684,7 +687,7 @@ object NewFlatLogUtils {
val json = json {
KEY_EVENT to "halo_self_publish_content"
"tab_name" to tabName
"location" to location
KEY_LOCATION to location
parseAndPutMeta().invoke(this)
}
log(json)
@ -1052,10 +1055,11 @@ object NewFlatLogUtils {
}
//游戏单广场浏览时长
fun logGameCollectSquareStayTime(interval: Long) {
fun logGameCollectSquareStayTime(interval: Long, source: String) {
val json = json {
KEY_EVENT to "game_collect_square_stay_time"
"interval" to interval
"source" to source
parseAndPutMeta().invoke(this)
}
log(json)
@ -1479,7 +1483,7 @@ object NewFlatLogUtils {
) {
val json = json {
KEY_EVENT to "game_detail_comment_tab_game_comment_click"
"location" to location
KEY_LOCATION to location
"tag" to tag
"filter_tag_name" to filter
"button" to button
@ -1521,7 +1525,7 @@ object NewFlatLogUtils {
) {
val json = json {
KEY_EVENT to "game_detail_comment_tab_game_comment_detail_click"
"location" to location
KEY_LOCATION to location
"tag" to tag
"filter_tag_name" to filter
"button" to button
@ -1623,7 +1627,7 @@ object NewFlatLogUtils {
val json = json {
"event" to "game_test_detail_game_category_click"
"tab_name" to tabName
"game_category" to gameCategory
KEY_GAME_CATEGORY to gameCategory
"game_test_start_type" to gameTestStartType
parseAndPutMeta().invoke(this)
}
@ -1658,7 +1662,7 @@ object NewFlatLogUtils {
val json = json {
"event" to "game_test_home_more_click"
"text" to text //右上角文案,包括:全部、更多
"location" to location //新游开测所处位置,包括:首页、版块
KEY_LOCATION to location //新游开测所处位置,包括:首页、版块
"block_id" to blockId //新游开测所处位置为“版块”上报版块ID
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
"link_type" to linkType //右上角文案为“更多”时的链接类型
@ -1685,7 +1689,7 @@ object NewFlatLogUtils {
) {
val json = json {
"event" to "game_test_home_recommend_tag_click"
"location" to location //新游开测所处位置,包括:首页、版块
KEY_LOCATION to location //新游开测所处位置,包括:首页、版块
"block_id" to blockId //新游开测所处位置为“版块”上报版块ID
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
"tag_id" to tagId //点击推荐标签的ID
@ -1733,7 +1737,7 @@ object NewFlatLogUtils {
) {
val json = json {
"event" to "game_test_home_view"
"location" to location //新游开测所处位置,包括:首页、版块
KEY_LOCATION to location //新游开测所处位置,包括:首页、版块
"block_id" to blockId //新游开测所处位置为“版块”上报版块ID
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
"interval" to interval //内容在屏幕可见范围完整展示的时长
@ -1988,7 +1992,7 @@ object NewFlatLogUtils {
"type" to homeSubSlide.cardType
"text" to homeSubSlide.cardText
"count_num" to countNum
"location" to location
KEY_LOCATION to location
"link_type" to homeSubSlide.linkType
"link_id" to homeSubSlide.linkId
"link_text" to homeSubSlide.linkText
@ -2185,4 +2189,225 @@ object NewFlatLogUtils {
}
log(json, "event", false)
}
// 游戏单广场刷新
@JvmStatic
fun logGameCollectionSquareFlush(action: String, countNum: Int) {
val json = json {
KEY_EVENT to "game_list_square_flush"
"action" to action
"count_num" to countNum
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏详情点击公告文章
@JvmStatic
fun logGameDetailNoticeClick(gameId: String, gameName: String, linkId: String, linkType: String, linkText: String) {
val json = json {
KEY_EVENT to "game_detail_notice_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"link_id" to linkId
"link_type" to linkType
"link_text" to linkText
parseAndPutMeta().invoke(this)
}
log(json)
}
// 启动游戏(UI被点击)
fun logGameLaunchButtonClicked(
gameId: String,
gameName: String,
location: String,
gameCategory: String,
downloadStatus: String
) {
val json = json {
KEY_EVENT to "game_launch_button_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
KEY_LOCATION to location
KEY_GAME_CATEGORY to gameCategory
KEY_DOWNLOAD_STATE to downloadStatus
parseAndPutMeta().invoke(this)
}
log(json)
}
// 启动游戏(具体实现逻辑)
fun logGameLaunch(
gameId: String,
gameName: String,
gameCategory: String,
downloadStatus: String
) {
val json = json {
KEY_EVENT to "game_launch"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
KEY_GAME_CATEGORY to gameCategory
KEY_DOWNLOAD_STATE to downloadStatus
parseAndPutMeta().invoke(this)
}
log(json)
}
// 进入游戏单热榜
@JvmStatic
fun logGameCollectionHotListEnter(entrance: String) {
val json = json {
KEY_EVENT to "game_list_hot_rank_enter"
"entrance" to entrance
parseAndPutMeta().invoke(this)
}
log(json)
}
// 离开游戏单热榜
@JvmStatic
fun logGameCollectionHotListExit(interval: Long, tabName: String) {
val json = json {
KEY_EVENT to "game_list_hot_rank_exit"
"interval" to interval
"tab_name" to tabName
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏热榜点击tab
@JvmStatic
fun logGameCollectionHotListTabClick(tabName: String, collectionId: String, collectionName: String) {
val json = json {
KEY_EVENT to "game_hot_rank_tab_click"
"tab_name" to tabName
"game_list_collection_id" to collectionId
"game_list_collection_name" to collectionName
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏热榜tab浏览
@JvmStatic
fun logGameCollectionHotListTabView(interval: Int, tabName: String, collectionId: String, collectionName: String) {
val json = json {
KEY_EVENT to "game_hot_rank_tab_view"
"interval" to interval
"tab_name" to tabName
"game_list_collection_id" to collectionId
"game_list_collection_name" to collectionName
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏单热榜点击
@JvmStatic
fun logGameCollectionHotListClick(tabName: String, collectionId: String, collectionName: String, text: String) {
val json = json {
KEY_EVENT to "game_list_hot_rank_click"
"tab_name" to tabName
"game_list_collection_id" to collectionId
"game_list_collection_name" to collectionName
"text" to text
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏单合集点击
fun logGameListCollectionClick(
source: String,
blockName: String,
blockId: String,
collectionName: String,
collectionId: String,
text: String
) {
val json = json {
KEY_EVENT to "game_list_collection_click"
"source" to source
"block_name" to blockName
"block_id" to blockId
"game_list_collection_id" to collectionId
"game_list_collection_name" to collectionName
"text" to text
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏详情-求加速点击事件
fun logGameDetailClickForAccelerate(gameId: String, gameName: String) {
val json = json {
KEY_EVENT to "game_detail_click_for_accelerate"
"game_name" to gameName
"game_id" to gameId
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏详情-求版本投票事件
fun logGameDetailClickForVersionVote(gameId: String, gameName: String, button: String) {
val json = json {
KEY_EVENT to "game_detail_click_for_version_vote"
"game_name" to gameName
"game_id" to gameId
"button" to button
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏详情-求版本取消投票事件
fun logGameDetailCancelForVersionVote(gameId: String, gameName: String, button: String) {
val json = json {
KEY_EVENT to "game_detail_cancel_for_version_vote"
"game_name" to gameName
"game_id" to gameId
"button" to button
parseAndPutMeta().invoke(this)
}
log(json)
}
// 消息中心-插件版本提醒弹窗点击事件
@JvmStatic
fun logMessageInformClickPluginVersion(gameId: String, gameName: String) {
val json = json {
KEY_EVENT to "message_inform_click_plugin_version"
"game_name" to gameName
"game_id" to gameId
parseAndPutMeta().invoke(this)
}
log(json)
}
// 游戏动态关注列表取消关注事件 / 游戏动态关注列表查看详情事件
@JvmStatic
fun logGameActivityConcern(event: String, gameId: String, gameName: String?) {
val json = json {
KEY_EVENT to event
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json)
}
@JvmStatic
fun logQGameClick(qqGameId: String, qqGameName: String?) {
val json = json {
KEY_EVENT to "qq_game_click"
"qq_game_id" to qqGameId
"qq_game_name" to qqGameName ?: ""
parseAndPutMeta().invoke(this)
}
log(json)
}
}

View File

@ -1657,13 +1657,22 @@ object NewLogUtils {
}
//进入游戏单广场
fun logEnterGameCollectionSquare(entrance: String, forumName: String = "", title: String = "", id: String = "") {
fun logEnterGameCollectionSquare(
entrance: String,
forumName: String = "",
gameCollectionTitle: String = "",
gameCollectionId: String = "",
collectionName: String = "",
collectionId: String = ""
) {
val json = json {
KEY_EVENT to "enter_game_collect_square"
KEY_ENTRANCE to entrance
"forum_name" to forumName
"game_collect_title" to title
"game_collect_id" to id
"game_collect_title" to gameCollectionTitle
"game_collect_id" to gameCollectionId
"game_list_collection_name" to collectionName
"game_list_collection_id" to collectionId
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
parseAndPutMeta().invoke(this)
}
@ -1671,9 +1680,10 @@ object NewLogUtils {
}
//进入选择标签
fun logEnterGameCollectionTag() {
fun logEnterGameCollectionTag(source: String) {
val json = json {
KEY_EVENT to "enter_game_collect_tag_location"
"source" to source
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
parseAndPutMeta().invoke(this)
}
@ -1681,11 +1691,12 @@ object NewLogUtils {
}
//筛选游戏单标签
fun logFilterGameCollectionTag(tagCategory: String, tagName: String) {
fun logFilterGameCollectionTag(tagCategory: String, tagName: String, source: String) {
val json = json {
KEY_EVENT to "filter_game_collect_tag"
"filter_tag_category" to tagCategory
"filter_tag_name" to tagName
"source" to source
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
parseAndPutMeta().invoke(this)
}
@ -1693,9 +1704,10 @@ object NewLogUtils {
}
//点击安利墙卡片
fun logClickGameCollectionAmway() {
fun logClickGameCollectionAmway(tabName: String) {
val json = json {
KEY_EVENT to "click_game_collect_recommend_card"
"tab_name" to tabName
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
parseAndPutMeta().invoke(this)
}

View File

@ -1,6 +1,7 @@
package com.gh.common.util
import android.app.Activity
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.net.Uri
@ -9,6 +10,7 @@ import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.gh.common.dialog.InstallPermissionDialogFragment
import com.gh.common.xapk.XapkInstallReceiver
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.BuildConfig
@ -118,7 +120,7 @@ object PackageInstaller {
}
} else {
if (isPluggin) {
DialogHelper.showPluginDialog(context) {
DialogHelper.showPluginDialog(context, downloadEntity?.pluginDesc) {
uninstall(context, pkgPath)
}
} else {
@ -142,6 +144,32 @@ object PackageInstaller {
context.startActivity(installIntent)
}
fun installMultiple(
context: Context,
pkgPath: String,
sessionId: Int = -1
) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return
}
val installer = context.packageManager.packageInstaller
val session = installer.openSession(sessionId)
// 监听安装回调的组件可以是Activity、Service或者是BroadcastReceiver
val intent = Intent(context, XapkInstallReceiver::class.java)
.also {
it.putExtra(XapkInstallReceiver.KEY_PACKAGE_PATH, pkgPath)
}
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
} else {
PendingIntent.FLAG_CANCEL_CURRENT
}
val pendingIntent = PendingIntent.getActivity(context, sessionId, intent, flags)
// 提交数据流并执行安装
session.commit(pendingIntent.intentSender)
}
/**
* 获取启动安装意图
*
@ -216,7 +244,8 @@ object PackageInstaller {
}
private fun getFileSuffixByFormat(format: String?): String {
return if (format == XapkInstaller.XAPK_EXTENSION_NAME) {
return if (format == Constants.XAPK_FORMAT
|| format == Constants.XAPK_APKS_FORMAT) {
XapkInstaller.XAPK_EXTENSION_NAME
} else {
"apk"

View File

@ -0,0 +1,54 @@
package com.gh.common.util
import android.content.Context
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.packagehelper.PackageRepository
object PackageLauncher {
/*
* 启动应用
*/
@JvmStatic
fun launchApp(
context: Context,
gameEntity: GameEntity? = null,
packageName: String?
) {
if (packageName.isNullOrEmpty()) {
ToastUtils.toast("启动失败")
return
}
// 获取 GameInstall 实体,用于记录启动日志用
val gameInstall = if (gameEntity != null) {
GameInstall.transformGameInstall(gameEntity, packageName)
} else {
PackageRepository.gameInstalled.find { it.packageName == packageName }
}
if (gameInstall != null) {
NewFlatLogUtils.logGameLaunch(
gameId = gameInstall.id ?: "unknown",
gameName = gameInstall.name ?: "unknown",
gameCategory = gameInstall.category ?: "unknown",
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
)
}
try {
val intent = context.applicationContext.packageManager.getLaunchIntentForPackage(packageName)
if (intent != null) {
context.startActivity(intent)
} else {
ToastUtils.toast("启动失败")
}
} catch (e: Exception) {
ToastUtils.toast( "启动失败")
}
}
}

View File

@ -7,12 +7,14 @@ 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,6 +31,7 @@ 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;
@ -74,6 +77,9 @@ public class PackageUtils {
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,
@ -137,6 +143,9 @@ public class PackageUtils {
updateEntity.setSignature(apkEntity.getSignature());
updateEntity.setCategory(gameEntity.getCategory());
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
if (gameEntity.isLandPageAddressDialog()) {
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
}
updateList.add(updateEntity);
}
}
@ -211,6 +220,9 @@ public class PackageUtils {
updateEntity.setSignature(apkEntity.getSignature());
updateEntity.setCategory(gameEntity.getCategory());
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
if (gameEntity.isLandPageAddressDialog()) {
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
}
updateList.add(updateEntity);
}
}
@ -746,9 +758,11 @@ public class PackageUtils {
}
/*
/**
* 启动应用
* 请使用 PackageLauncher.launchApp()
*/
@Deprecated
public static void launchApplicationByPackageName(Context context, String packageName) {
try {
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
@ -958,18 +972,78 @@ public class PackageUtils {
return new ArrayList<>(mInstalledPackageList);
}
Utils.log(TAG, "调用系统 API 获取新的已安装应用列表");
// 是否需要调用系统 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<>();
}
mLastInstalledPackageListTime = System.currentTimeMillis();
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
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);

View File

@ -7,7 +7,7 @@ import android.text.TextUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.feature.entity.CommentEntity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.utils.Utils;
import com.walkud.rom.checker.RomIdentifier;

View File

@ -66,7 +66,7 @@ object RealNameHelper {
"game_name",
downloadEntity.name ?: "",
"game_type",
downloadEntity.meta[Constants.GAME_TYPE] ?: ""
downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: ""
)
val contentText = if (downloadEntity.status == DownloadStatus.done) {

View File

@ -95,21 +95,19 @@ object ReservationHelper {
NewLogUtils.logReserveGameSuccess(wechatConfig)
if (bind && follow && notice) {
NewLogUtils.logReserveWechatSuccessPopShow()
DialogUtils.showReserveSuccessDialog(context)
DialogUtils.showReserveOrVoteSuccessDialog(context, true)
} else {
NewLogUtils.logReserveWechatRemindPopShow(wechatConfig)
SensorsBridge.trackEvent("AppointmenWechatRemindDialogShow")
DialogUtils.showReserveSuccess2WechatBindDialog(context, object : ConfirmListener {
override fun onConfirm() {
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
context.startActivity(WebActivity.getBindWechatIntent(context))
SensorsBridge.trackEvent(
"AppointmenWechatRemindConfigPageShow",
"source_entrance",
"设置微信提醒弹窗"
)
}
DialogUtils.showReserveOrVoteSuccess2WechatBindDialog(context, true, {
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
context.startActivity(WebActivity.getBindWechatIntent(context))
SensorsBridge.trackEvent(
"AppointmenWechatRemindConfigPageShow",
"source_entrance",
"设置微信提醒弹窗"
)
}, object : CancelListener {
override fun onCancel() {
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "关闭弹窗")

View File

@ -0,0 +1,64 @@
package com.gh.common.xapk
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInstaller
import android.os.Build
import android.os.Bundle
import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class XapkInstallReceiver : Activity() {
companion object {
const val KEY_PACKAGE_PATH = "package_path"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
overridePendingTransition(0, 0)
handleIntent(this, intent)
}
private fun handleIntent(context: Context, intent: Intent) {
when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
val installIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
if (installIntent != null) {
try {
context.startActivity(installIntent)
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION)
} catch (e: Exception) {
// OPPO低版本会出现CONFIRM_PERMISSIONS的权限异常这个问题无解直接取消安装
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
}
finish()
}
}
PackageInstaller.STATUS_FAILURE,
PackageInstaller.STATUS_FAILURE_ABORTED,
PackageInstaller.STATUS_FAILURE_BLOCKED,
PackageInstaller.STATUS_FAILURE_CONFLICT,
PackageInstaller.STATUS_FAILURE_INCOMPATIBLE,
PackageInstaller.STATUS_FAILURE_INVALID,
PackageInstaller.STATUS_FAILURE_STORAGE -> {
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
finish()
}
else -> {
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS)
finish()
}
}
}
private fun updatePendingSessionInfoStatus(intent: Intent, status: Int) {
val installPackagePath = intent.getStringExtra(KEY_PACKAGE_PATH)
if (!installPackagePath.isNullOrEmpty()) {
val pendingSessionInfo = XapkInstaller.getPendingSessionInfo(installPackagePath)
pendingSessionInfo?.updateStatus(status)
}
}
}

View File

@ -2,20 +2,34 @@ package com.gh.common.xapk
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import com.gh.common.constant.Config
import com.gh.common.util.*
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.utils.debugOnly
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.xapk.XApkUnZipper
import com.gh.gamecenter.xapk.core.XApkFile
import com.gh.gamecenter.xapk.core.XApkUnZipCallback
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
import com.gh.gamecenter.xapk.io.NonSplitApksOutput
import com.gh.gamecenter.xapk.io.OBBFileOutput
import com.gh.gamecenter.xapk.io.SplitApksOutput
import com.gh.gamecenter.xapk.io.XApkFileOutput
import com.gh.gamecenter.xapk.pi.IPackageInstaller
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import java.text.DecimalFormat
import java.io.File
import java.util.*
/**
@ -28,7 +42,8 @@ import java.util.*
* apk文件这解压的gh-files文件夹中
*/
@SuppressLint("StaticFieldLeak")
object XapkInstaller : IXapkUnzipListener {
object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
private const val XAPK_PACKAGE_PATH_TAG = "xapk_package_path"
const val XAPK_EXTENSION_NAME = "xapk"
@ -40,10 +55,19 @@ object XapkInstaller : IXapkUnzipListener {
const val XAPK_DATA_EXTENSION_NAME = "obb"
const val PACKAGE_EXTENSION_NAME = "apk"
private const val GUIDE_TYPE_MIUI_OPTIMIZATION = "miui_optimization"
private const val MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE = "MIUI优化关闭提示弹窗"
private var mContext = HaloApp.getInstance().application.applicationContext
// 是否需要开启特定线程处理
private val mXapkUnzipThreadMap = Collections.synchronizedMap(HashMap<String, XapkUnzipThread>())
private val mXApkUnZipper = XApkUnZipper(this)
.also {
it.registerCallback(this)
}
private val mDownloadEntityMap = Collections.synchronizedMap(HashMap<String, DownloadEntity>())
private val mPendingSessionInfoMap = HashMap<String, XapkPendingSessionInfo>()
// 按并行解压
@JvmStatic
@ -52,6 +76,38 @@ object XapkInstaller : IXapkUnzipListener {
val filePath = downloadEntity.path
if (XAPK_EXTENSION_NAME == filePath.getExtension()) {
if (MiuiUtils.isMiui() && !MiuiUtils.isMiuiOptimizationDisabled() && downloadEntity.format == Constants.XAPK_APKS_FORMAT) {// 小米手机开启miui以后需要引导用户关闭miui优化
DialogHelper.showMiuiOptimizationWarning(
context,
onHintClick = {
val guides = Config.getNewApiSettingsEntity()?.install
val miuiOptimizationGuide = guides?.guides?.findLast {
it.type == GUIDE_TYPE_MIUI_OPTIMIZATION
}
if (miuiOptimizationGuide != null) {
DirectUtils.directToLinkPage(
context,
miuiOptimizationGuide.link,
MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE,
""
)
}
},
onConfirmClick = {
if (SystemUtils.isDevelopmentSettingsEnabled(context)) {
context.startActivity(
Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
it.dismiss()
} else {
ToastUtils.showToast(context.getString(R.string.miui_open_adb_hint))
}
}
)
return
}
unzipXapkFile(downloadEntity)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
@ -63,122 +119,234 @@ object XapkInstaller : IXapkUnzipListener {
}
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
if (mXapkUnzipThreadMap[downloadEntity.path] == null) {
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压开始")
val xapkUnzipThread = XapkUnzipThread(downloadEntity, this)
xapkUnzipThread.start()
mXapkUnzipThreadMap[downloadEntity.path] = xapkUnzipThread
} else {
debugOnly {
Utils.log("unzip", "重复解压,该文件解压已在队列中")
}
}
mXApkUnZipper.unzip(
XApkUnZipEntry(
downloadEntity.path,
File(downloadEntity.path)
)
)
mDownloadEntityMap[downloadEntity.path] = downloadEntity
}
override fun onProgress(downloadEntity: DownloadEntity, unzipPath: String, unzipSize: Long, unzipProgress: Long) {
AppExecutor.uiExecutor.execute {
val df = DecimalFormat("#.0")
var percent = 0.0
tryCatchInRelease {
percent = df.format((unzipProgress / unzipSize.toFloat()) * 100).toDouble()
}
downloadEntity.meta[XAPK_UNZIP_PERCENT] = percent.toString()
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
@JvmStatic
fun cancelUnzipTask(downloadEntity: DownloadEntity) {
mXApkUnZipper.cancel(downloadEntity.path)
}
override fun onProgress(apk: XApkFile, progress: Float) {
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
downloadEntity.meta[XAPK_UNZIP_PERCENT] = String.format(Locale.CHINA, "%.2f", progress * 100)
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
AppExecutor.ioExecutor.execute {
NDataChanger.notifyDataChanged(downloadEntity)
}
debugOnly {
Utils.log("unzip", "onProgress->" + (unzipProgress / unzipSize.toFloat()))
Utils.log("unzip", "onProgress->$progress")
}
}
override fun onNext(downloadEntity: DownloadEntity, unzipPath: String) {
if (PACKAGE_EXTENSION_NAME == unzipPath.getExtension()) {
downloadEntity.meta[XAPK_PACKAGE_PATH_TAG] = unzipPath
override fun onSuccess(apk: XApkFile, installer: IPackageInstaller) {
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
AppExecutor.ioExecutor.execute {
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
}
debugOnly {
Utils.log("unzip", "onNext->$unzipPath")
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
}
installer.install(mContext)
}
/**
* 取消解压回调
*
* 取消后的表现与下载完成一致
*/
override fun onCancel(downloadEntity: DownloadEntity) {
mXapkUnzipThreadMap.remove(downloadEntity.path)
override fun onError(apk: XApkFile, exception: Throwable) {
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
AppExecutor.uiExecutor.execute {
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
}
}
override fun onFailure(downloadEntity: DownloadEntity, exception: Exception) {
mXapkUnzipThreadMap.remove(downloadEntity.path)
AppExecutor.uiExecutor.execute {
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
AppExecutor.ioExecutor.execute {
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
}
// 仅官网渠道上报 XAPK 异常信息
if (HaloApp.getInstance().channel == "GH_206") {
SentryHelper.onEvent(
"XAPK_UNZIP_ERROR",
"gameName", downloadEntity.name,
"errorDigest", exception.localizedMessage
)
}
// 仅官网渠道上报 XAPK 异常信息
if (HaloApp.getInstance().channel == "GH_206") {
SentryHelper.onEvent(
"XAPK_UNZIP_ERROR",
"gameName", downloadEntity.name,
"errorDigest", exception.localizedMessage
)
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
}
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
debugOnly {
Utils.log("unzip", "onFailure->$exception")
}
}
override fun onSuccess(downloadEntity: DownloadEntity) {
mXapkUnzipThreadMap.remove(downloadEntity.path)
AppExecutor.uiExecutor.execute {
val pkgPath = downloadEntity.meta[XAPK_PACKAGE_PATH_TAG]
if (pkgPath == null) {
Utils.toast(mContext, "下载出错,请重新下载!")
return@execute
}
PackageInstaller.install(mContext, downloadEntity.isPlugin, pkgPath, downloadEntity)
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
override fun onCancel(apk: XApkFile) {
val downloadEntity = mDownloadEntityMap.remove(apk.file.path) ?: return
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
AppExecutor.ioExecutor.execute {
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
}
}
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
override fun onNext(apk: XApkFile, fileName: String) {
debugOnly {
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
Utils.log("unzip", "onNext->$fileName")
}
}
@JvmStatic
fun cancelUnzipTask(downloadEntity: DownloadEntity) {
val xapkUnzipThread = mXapkUnzipThreadMap[downloadEntity.path]
if (xapkUnzipThread != null) {
xapkUnzipThread.canceled = true
fun getPendingSessionInfo(packagePath: String): XapkPendingSessionInfo? = mPendingSessionInfoMap[packagePath]
fun isInstalling(packagePath: String): Boolean = mPendingSessionInfoMap.containsKey(packagePath)
/**
* 通知XAPK安装完成
*/
fun onInstalled(packagePath: String) {
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
mPendingSessionInfoMap.remove(packagePath)
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.INSTALLED.name
AppExecutor.ioExecutor.execute {
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装成功")
}
}
fun onInstallCanceled(packagePath: String) {
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
mPendingSessionInfoMap.remove(packagePath)
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
AppExecutor.ioExecutor.execute {
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装取消")
}
}
/**
* 更新当前XAPK安装状态, 主要针对以下出现安装结果回调异常的情况:
* 1. 用户触碰安装弹窗(原生Android系统)区域外导致安装取消
*/
fun updateCurrentInstallStatus() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || mPendingSessionInfoMap.isEmpty()) {
return
}
val updateList = mutableListOf<XapkPendingSessionInfo>()
for (pendingSessionInfoEntry in mPendingSessionInfoMap) {
val pendingSessionInfo = pendingSessionInfoEntry.value
if (pendingSessionInfo.getStatus() == XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION) {// 用户触摸安装弹窗外部区域取消安装后,更新安装状态
val installer = mContext.packageManager.packageInstaller
val sessionId = pendingSessionInfo.sessionId
if (sessionId != -1) {
val sessionInfo = installer.getSessionInfo(sessionId)
// 表示用户点击了安装弹窗外部区域
if (sessionInfo == null) {
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
} else if (sessionInfo.progress <= 0.8F) {
AppExecutor.ioExecutor.execute {
try {
installer.abandonSession(sessionInfo.sessionId)
} catch (_: Exception) {
// 有概率抛SecurityException这里只要直接catch不做处理即可
}
}
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
}
}
}
val installStatus = pendingSessionInfo.getStatus()
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED
|| installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS
) {
updateList.add(pendingSessionInfo)
}
}
for (pendingSessionInfo in updateList) {
val downloadEntity = mDownloadEntityMap[pendingSessionInfo.path] ?: continue
val installStatus = pendingSessionInfo.getStatus()
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS) {
onInstalled(downloadEntity.path)
} else if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED) {
onInstallCanceled(downloadEntity.path)
}
}
}
override fun onCreateOBBOutput(apk: XApkFile): XApkFileOutput<Unit> {
return OBBFileOutput()
}
override fun onCreateApkOutput(apk: XApkFile): XApkFileOutput<IPackageInstaller> {
val isMultiApks = apk.manifest.isMultiApks
return if (isMultiApks) {
SplitApksOutput(mContext.applicationContext) {
SplitApksInstaller(apk, it)
}
} else {
onCancel(downloadEntity) // 刷新页面
NonSplitApksOutput {
NonSplitApkInstaller(apk, it)
}
}
}
private class SplitApksInstaller(
private val xApkFile: XApkFile,
private val sessionId: Int,
) : IPackageInstaller {
override fun install(context: Context) {
val applicationContext = context.applicationContext
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
mPendingSessionInfoMap[downloadEntity.path] = XapkPendingSessionInfo(downloadEntity.path, sessionId)
AppExecutor.ioExecutor.execute {// 有可能卡顿造成anr
PackageInstaller.installMultiple(applicationContext, downloadEntity.path, sessionId)
NDataChanger.notifyDataChanged(downloadEntity)
}
}
}
private class NonSplitApkInstaller(
private val xApkFile: XApkFile,
private val file: File
) : IPackageInstaller {
override fun install(context: Context) {
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
PackageInstaller.install(
context,
downloadEntity.isPlugin,
file.absolutePath,
downloadEntity
)
}
}
}
@ -187,5 +355,6 @@ enum class XapkUnzipStatus(status: String) {
UNZIPPING("unzipping"),
SUCCESS("success"),
CANCEL("cancel"),
INSTALLED("installed"),
FAILURE("failure");
}

View File

@ -0,0 +1,21 @@
package com.gh.common.xapk
class XapkPendingSessionInfo(
val path: String,
val sessionId: Int = -1
) {
companion object {
const val STATUS_INIT = -1
const val STATUS_PENDING_USER_ACTION = 0
const val STATUS_INSTALL_SUCCESS = 1
const val STATUS_INSTALL_CANCELED = 2
}
private var status = STATUS_INIT
internal fun updateStatus(status: Int) {
this.status = status
}
fun getStatus(): Int = status
}

View File

@ -23,9 +23,6 @@ import org.json.JSONObject
object DownloadDataHelper {
private const val TAG = "DownloadDataHelper"
private const val DOWNLOAD_SPEED_TIME = "download_speed_time"
private const val DOWNLOAD_SPEED_SIZE = "download_speed_size"
const val DOWNLOAD_RESUME_WAY = "download_resume_way"
const val DOWNLOAD_RESUME_MANUAL = "manual"
const val DOWNLOAD_RESUME_AUTO = "auto"
@ -34,8 +31,6 @@ object DownloadDataHelper {
const val DOWNLOAD_CANCEL_MANUAL = "manual"
const val DOWNLOAD_CANCEL_AUTO = "auto"
const val DOWNLOAD_FIRST_START = "download_first_start"
const val DOWNLOAD_THREAD_SIZE = "download_thread_size" // 线程数量0为传统单线程模式; 1为多线程的单线程; >1为多线程的实际线程数量
private val mDownloadSpeedMap = HashMap<String, MutableList<Long>>()
@ -128,7 +123,7 @@ object DownloadDataHelper {
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
jsonObject.put("payload", payloadObject)
} catch (e: Exception) {
e.printStackTrace()
@ -140,26 +135,28 @@ object DownloadDataHelper {
@JvmStatic
fun uploadDownloadEvent(downloadEntity: DownloadEntity) {
val downloadSimpleEntity = DownloadDataSimpleHelper.getDownloadDataSimpleEntity(downloadEntity.url)
if (downloadEntity.status != DownloadStatus.downloading) {
uploadDownloadStatusEvent(downloadEntity)
}
if (downloadEntity.status == DownloadStatus.downloading) {
val startupTime = downloadEntity.meta[DownloadEntity.DOWNLOAD_STARTUP_TIME_KEY]
val startupTime =
downloadSimpleEntity?.downloadStartUpTime
if (startupTime != null) {
uploadDownloadStartupTimeEvent(downloadEntity, startupTime.toInt())
downloadEntity.meta.remove(DownloadEntity.DOWNLOAD_STARTUP_TIME_KEY)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
uploadDownloadStartupTimeEvent(downloadEntity, startupTime)
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadStartUpTime = null)
}
}
if (downloadEntity.status == DownloadStatus.downloading || downloadEntity.status == DownloadStatus.done) {
val time = downloadEntity.meta[DOWNLOAD_SPEED_TIME]
val size = downloadEntity.meta[DOWNLOAD_SPEED_SIZE]
val time = downloadSimpleEntity?.downloadSpeedTime
val size = downloadSimpleEntity?.downloadSpeedSize
if (downloadEntity.speed == 0L || time == null || size == null) {
downloadEntity.meta[DOWNLOAD_SPEED_TIME] = System.currentTimeMillis().toString()
downloadEntity.meta[DOWNLOAD_SPEED_SIZE] = downloadEntity.progress.toString()
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
val currentTime = System.currentTimeMillis()
val currentProgress = downloadEntity.progress
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadSpeedTime = currentTime, downloadSpeedSize = currentProgress)
} else {
val offset = System.currentTimeMillis() - time.toLong()
if (offset > 5000) {
@ -180,15 +177,15 @@ object DownloadDataHelper {
}
}
}
downloadEntity.meta[DOWNLOAD_SPEED_TIME] = System.currentTimeMillis().toString()
downloadEntity.meta[DOWNLOAD_SPEED_SIZE] = downloadEntity.progress.toString()
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
val currentTime = System.currentTimeMillis()
val currentProgress = downloadEntity.progress
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadSpeedTime = currentTime, downloadSpeedSize = currentProgress)
}
}
}
}
private fun uploadDownloadStartupTimeEvent(downloadEntity: DownloadEntity, startupTime: Int) {
private fun uploadDownloadStartupTimeEvent(downloadEntity: DownloadEntity, startupTime: Long) {
val jsonObject = JSONObject()
try {
@ -214,7 +211,7 @@ object DownloadDataHelper {
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("launch_ms", startupTime)
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
if (parallel != null) {
payloadObject.put("parallel", parallel)
}
@ -264,23 +261,16 @@ object DownloadDataHelper {
// 下载时间统计时间为零时,手动改成 1000ms如果文件大小大于 50M 时上报 sentry
if (elapsedTime == 0L) {
elapsedTime = 1000L
if (sizeInMB > 50) {
SentryHelper.onEvent(
"DOWNLOAD_ELAPSED_TIME",
"elapsedTime is zero",
downloadEntity.gameId + ":" + sizeInMB
)
}
}
val speed = downloadEntity.size / elapsedTime
payloadObject.put("speed", speed)
}
} else {
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
}
payloadObject.put("completed_size", downloadEntity.progress / 1024 / 1024)
if (downloadEntity.status == DownloadStatus.resume) {
if (downloadEntity.meta[DOWNLOAD_FIRST_START] == "YES") {
if (DownloadDataSimpleHelper.getDownloadDataSimpleEntity(downloadEntity.url)?.isFirstTimeDownload == true) {
payloadObject.put("is_first_start", true)
} else {
payloadObject.put("is_first_start", false)
@ -288,8 +278,7 @@ object DownloadDataHelper {
}
if (downloadEntity.status == DownloadStatus.resume || downloadEntity.status == DownloadStatus.add) {
downloadEntity.meta[DOWNLOAD_FIRST_START] = "NO"
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
DownloadDataSimpleHelper.updateDownloadSimpleEntityFirstTimeDownload(downloadEntity.url, false)
}
jsonObject.put("payload", payloadObject)
} catch (e: Exception) {
@ -329,7 +318,7 @@ object DownloadDataHelper {
if (parallel != null) {
payloadObject.put("parallel", parallel)
}
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
jsonObject.put("payload", payloadObject)
} catch (e: Exception) {
e.printStackTrace()
@ -342,7 +331,7 @@ object DownloadDataHelper {
/**
* 分片检测下载进度,每隔15秒内记录一次,60秒上传一次
*
* 请见:https://gitlab.ghzs.com/stats/stats-issues/-/issues/188#note_66919
* 请见:https://git.shanqu.cc/stats/stats-issues/-/issues/188#note_66919
*/
fun uploadDownloadHeartbeat(upload: Boolean) {
val allDownloadEntity = DownloadManager.getInstance().allDownloadEntity
@ -352,7 +341,8 @@ object DownloadDataHelper {
* 在后台唤醒的情况下 下载状态可能无法修正
* see [DownloadManager.initDownloadService]
*/
if (downloadEntity.status == DownloadStatus.downloading && NDataChanger.downloadingTasks[downloadEntity.url] != null) {
if (downloadEntity.status == DownloadStatus.downloading
&& NDataChanger.downloadingTaskUrlSet.contains(downloadEntity.url)) {
var sheet = mDownloadHeartbeatSheet[downloadEntity.url]
if (sheet == null) {
sheet = JSONObject()

View File

@ -0,0 +1,60 @@
package com.gh.download
import android.content.Context
import android.content.SharedPreferences
import com.gh.gamecenter.common.HaloApp
import com.gh.gamecenter.common.utils.toJsonIgnoredNull
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.core.utils.SPUtils
/**
* 用来简单保存/获取下载时一些额外信息的辅助类,避免下载时反复修改原始下载实体的糟糕操作
* 使用 SP 来实现,只适用于相对较为低频的调用
*/
object DownloadDataSimpleHelper {
private val mSp: SharedPreferences by lazy {
HaloApp.getInstance().getSharedPreferences("DownloadDataSimpleDao", Context.MODE_PRIVATE)
}
fun getDownloadDataSimpleEntity(url: String): DownloadDataSimpleEntity? {
return mSp.getString(url, "")?.toObject()
}
fun updateDownloadDataSimpleEntity(
url: String,
downloadStartUpTime: Long? = null,
downloadSpeedTime: Long? = null,
downloadSpeedSize: Long? = null,
) {
val entity = getDownloadDataSimpleEntity(url) ?: DownloadDataSimpleEntity()
entity.downloadStartUpTime = downloadStartUpTime
entity.downloadSpeedTime = downloadSpeedTime
entity.downloadSpeedSize = downloadSpeedSize
SPUtils.setString(mSp, url, entity.toJsonIgnoredNull())
}
fun updateDownloadSimpleEntityFirstTimeDownload(url: String, isFirstTimeDownload: Boolean) {
val entity = getDownloadDataSimpleEntity(url) ?: DownloadDataSimpleEntity()
entity.isFirstTimeDownload = isFirstTimeDownload
SPUtils.setString(mSp, url, entity.toJsonIgnoredNull())
}
fun removeDownloadSimpleEntity(url: String) {
SPUtils.remove(mSp, url)
}
}
class DownloadDataSimpleEntity(
var downloadStartUpTime: Long? = null,
var downloadSpeedTime: Long? = null,
var downloadSpeedSize: Long? = null,
var isFirstTimeDownload: Boolean? = true
)

View File

@ -61,7 +61,6 @@ import com.lightgame.download.DownloadDao;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.DownloadStatusListener;
import com.lightgame.download.DownloadTask;
import com.lightgame.download.FileUtils;
import com.lightgame.download.HttpDnsManager;
import com.lightgame.utils.Utils;
@ -284,6 +283,7 @@ public class DownloadManager implements DownloadStatusListener {
String path;
String downloadId = PackageInstaller.createDownloadId(gameEntity.getName());
String gameCategory = gameEntity.getCategory();
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
path = SimulatorGameManager.getPathByType(gameEntity.getSimulatorType()) + "/" + gameEntity.getName() + "." + apkEntity.getFormat();
@ -309,6 +309,7 @@ public class DownloadManager implements DownloadStatusListener {
downloadEntity.setUrl(apkEntity.getUrl());
downloadEntity.setName(gameEntity.getName());
downloadEntity.setPath(path);
downloadEntity.setPluginDesc(gameEntity.getPluginDesc());
downloadEntity.setETag(apkEntity.getEtag());
downloadEntity.setIcon(gameEntity.getIcon());
downloadEntity.setPlatform(apkEntity.getPlatform());
@ -316,6 +317,7 @@ public class DownloadManager implements DownloadStatusListener {
downloadEntity.setGameId(gameEntity.getId());
downloadEntity.setEntrance(entrance);
downloadEntity.setLocation(location);
downloadEntity.setFormat(apkEntity.getFormat());
downloadEntity.setVersionName(apkEntity.getVersion());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, apkEntity.getMd5());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_ID, downloadId);
@ -323,9 +325,11 @@ public class DownloadManager implements DownloadStatusListener {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_PLATFORM_RECOMMEND, apkEntity.getRecommend() != null ? "true" : "false");
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_NAME, gameEntity.getName());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_TYPE, gameEntity.getCategoryChinese());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_CATEGORY_IN_CHINESE, gameEntity.getCategoryChinese());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.AD_ICON_ACTIVE, String.valueOf(gameEntity.getAdIconActive()));
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_AD_DATA, String.valueOf(gameEntity.isAdData()));
ExtensionsKt.putGameCategory(downloadEntity, gameCategory != null ? gameCategory : "");
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_SIZE, apkEntity.getSize());
if (gameEntity.getIconFloat() != null) {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT, gameEntity.getIconFloat().getUpperLeftText());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR, gameEntity.getIconFloat().getUpperLeftColor());
@ -545,7 +549,7 @@ public class DownloadManager implements DownloadStatusListener {
* 任务是否已经下载中
*/
public boolean isTaskDownloading(String url) {
if (NDataChanger.INSTANCE.getDownloadingTasks().get(url) != null) {
if (NDataChanger.INSTANCE.getDownloadingTaskUrlSet().contains(url)) {
Utils.log(DownloadManager.class.getSimpleName(), url + "正在下载!");
return true;
}
@ -830,6 +834,7 @@ public class DownloadManager implements DownloadStatusListener {
*/
public void cancel(String url, boolean isDeleteFile, boolean automatic, boolean cancelSilently) {
DownloadEntity entry = mDownloadDao.getSnapshot(url);
DownloadDataSimpleHelper.INSTANCE.removeDownloadSimpleEntity(url);
if (entry != null) {
AppExecutor.getIoExecutor().execute(() -> {
NDownloadBridge.INSTANCE.cancel(url);
@ -867,12 +872,8 @@ public class DownloadManager implements DownloadStatusListener {
private void cancelAndNotify(DownloadEntity entry, boolean cancelSilently) {
mDownloadDao.removeErrorMessage(entry.getUrl());
DownloadTask task = NDataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl());
if (task != null) {
task.cancel();
// 改任务队列的状态
NDataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl());
}
// 改任务队列的状态
NDataChanger.INSTANCE.getDownloadingTaskUrlSet().remove(entry.getUrl());
NDataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
if (!cancelSilently) {
NDataChanger.INSTANCE.notifyDataChanged(entry);
@ -886,8 +887,10 @@ public class DownloadManager implements DownloadStatusListener {
* 暂停所有正在下载的任务
*/
public void pauseAll() {
for (DownloadEntity entity : NDataChanger.INSTANCE.getDownloadEntries().values()) {
pause(entity.getUrl());
synchronized (NDataChanger.INSTANCE.getDownloadEntries()) {
for (DownloadEntity entity : NDataChanger.INSTANCE.getDownloadEntries().values()) {
pause(entity.getUrl());
}
}
Utils.log(DownloadManager.class.getSimpleName(), "pause all");
}
@ -913,10 +916,10 @@ public class DownloadManager implements DownloadStatusListener {
* 3.检查是否显示下载通知栏
*/
public void initDownloadService() {
final List<String> urlList = new ArrayList<>(NDataChanger.INSTANCE.getDownloadingTasks().keySet());
final Set<String> urlSet = NDataChanger.INSTANCE.getDownloadingTaskUrlSet();
for (DownloadEntity downloadEntity : getAllDownloadEntity()) {
if (!urlList.contains(downloadEntity.getUrl()) &&
(downloadEntity.getStatus().equals(DownloadStatus.downloading)
if (!urlSet.contains(downloadEntity.getUrl())
&& (downloadEntity.getStatus().equals(DownloadStatus.downloading)
|| downloadEntity.getStatus().equals(DownloadStatus.waiting))) {
downloadEntity.setStatus(DownloadStatus.subscribe);
mDownloadDao.newOrUpdate(downloadEntity);
@ -994,8 +997,11 @@ public class DownloadManager implements DownloadStatusListener {
}
if (status == DownloadStatus.add || status == DownloadStatus.subscribe) {
if (downloadEntity.getMeta().get(DownloadDataHelper.DOWNLOAD_FIRST_START) == null) {
downloadEntity.getMeta().put(DownloadDataHelper.DOWNLOAD_FIRST_START, "YES");
DownloadDataSimpleEntity simpleEntity =
DownloadDataSimpleHelper.INSTANCE.getDownloadDataSimpleEntity(downloadEntity.getUrl());
if (simpleEntity == null || simpleEntity.isFirstTimeDownload() == null) {
DownloadDataSimpleHelper.INSTANCE.updateDownloadSimpleEntityFirstTimeDownload(downloadEntity.getUrl(), true);
}
}
@ -1235,7 +1241,10 @@ public class DownloadManager implements DownloadStatusListener {
/**
* 更新数据库中的下载实体
*
* @deprecated 随意更新数据库可能会出现意想不到的情况,建议不要随意调用
*/
@Deprecated()
public void updateDownloadEntity(DownloadEntity downloadEntity) {
mDownloadDao.update(downloadEntity, false);
}

View File

@ -2,10 +2,11 @@ package com.gh.download
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.common.util.ConcernUtils
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.loghub.LoghubUtils
@ -110,6 +111,10 @@ object PackageObserver {
runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) }
}
if (mDownloadEntity.format == Constants.XAPK_FORMAT) {
XapkInstaller.onInstalled(mDownloadEntity.path)
}
DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false)
if (SPUtils.getBoolean(Constants.SP_CONCERN_GAME, true)) { //设置页面控制是否安装后自动关注

View File

@ -178,9 +178,18 @@ class DownloadDialog : BaseDraggableDialogFragment() {
for (i in 0 until it.itemCount) {
val apkEntity = itemList[i].normal ?: continue
val apkCollection = apkEntity.apkCollection
if (apkCollection != null && apkCollection.name == mPlatformName) {
scrollAndDownload(recyclerView, false, i)
break
if (apkCollection != null) {
if (apkCollection.name == mPlatformName) {
scrollAndDownload(recyclerView, false, i)
break
} else {
apkCollection.saveApkEntity?.forEach { entity ->
if (entity.getPlatformName() == mPlatformName || entity.packageName == mPackageName) {
scrollAndDownload(recyclerView, false, i)
}
}
break
}
}
if (apkEntity.getPlatformName() == mPlatformName || apkEntity.packageName == mPackageName) {
scrollAndDownload(recyclerView, true, i)

View File

@ -10,12 +10,9 @@ import com.gh.common.constant.Config
import com.gh.common.dialog.CertificationDialog
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.common.dialog.PackageCheckDialogFragment
import com.gh.common.util.*
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.DownloadDialogHelper
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.DownloadManagerActivity
@ -244,7 +241,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_下载"
}
DownloadDialogItemStatus.LAUNCH -> {
PackageUtils.launchApplicationByPackageName(it.context, apkEntity.packageName)
PackageLauncher.launchApp(it.context, gameEntity, apkEntity.packageName)
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_启动"
}
@ -282,7 +279,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
DownloadManager.getInstance().cancel(apkEntity.url)
} else {
if (PackageUtils.isCanPluggable(apkEntity)) {
DialogHelper.showPluginDialog(it.context) {
DialogHelper.showPluginDialog(it.context, gameEntity.pluginDesc) {
PackageInstaller.uninstall(it.context, downloadEntity.path)
}
} else {
@ -352,54 +349,46 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
if (msg.isNullOrEmpty()) {
BrowserInstallHelper.showBrowserInstallHintDialog(
context,
gameEntity.isVGame(),
object : EmptyCallback {
override fun onCallback() {
DownloadDialogHelper.findAvailableDialogAndShow(
gameEntity.isVGame() || gameEntity.isSplitXApk()
) {
DownloadDialogHelper.findAvailableDialogAndShow(
context,
gameEntity,
apkEntity
) {
PackageCheckDialogFragment.show(
context as AppCompatActivity,
gameEntity
) {
CertificationDialog.showCertificationDialog(
context,
gameEntity,
apkEntity,
object : EmptyCallback {
override fun onCallback() {
PackageCheckDialogFragment.show(
context as AppCompatActivity,
gameEntity,
object : ConfirmListener {
override fun onConfirm() {
CertificationDialog.showCertificationDialog(
context,
gameEntity,
object : ConfirmListener {
override fun onConfirm() {
DialogUtils.checkDownload(
context,
apkEntity.size,
gameEntity.id,
gameEntity.name
) { isSubscribe ->
DownloadManager.createDownload(
context,
apkEntity,
gameEntity,
downloadMethod,
entrance,
location,
isSubscribe, traceEvent
)
gameEntity
) {
DialogUtils.checkDownload(
context,
apkEntity.size,
gameEntity.id,
gameEntity.name
) { isSubscribe ->
DownloadManager.createDownload(
context,
apkEntity,
gameEntity,
downloadMethod,
entrance,
location,
isSubscribe, traceEvent
)
DeviceRemindDialog.showDeviceRemindDialog(
context,
gameEntity
)
}
}
})
}
})
}
})
DeviceRemindDialog.showDeviceRemindDialog(
context,
gameEntity
)
}
}
}
})
}
}
} else {
Utils.toast(context, msg)
}

View File

@ -17,6 +17,7 @@ import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.JsonObject
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
@ -93,6 +94,10 @@ object BrowserInstallHelper {
return false
}
@JvmStatic
fun shouldAutoSwitchAssistantInstall(gameEntity: GameEntity): Boolean =
isUseBrowserToInstallEnabled() && shouldUseBrowserToInstall() && gameEntity.isSplitXApk()
/**
* 是否显示使用浏览器来安装弹窗
*/
@ -144,7 +149,8 @@ object BrowserInstallHelper {
val manufacturer = Build.MANUFACTURER.toUpperCase(Locale.CHINA)
var contentText = "当前安装方式为助手安装,如果出现游戏无法安装的问题,可选择切换安装方式为“浏览器安装”"
if (manufacturer == "OPPO" || manufacturer == "VIVO") {
contentText = "当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”"
contentText =
"当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”"
}
DialogHelper.showDialog(

View File

@ -55,23 +55,21 @@ object DownloadMessageHandler : InnerDownloadListener {
* @param status 下载状态
*/
override fun onStatusChanged(id: String, status: DownloadStatus) {
val entity = findEntity(id)
val entity = findEntity(id) ?: return
if (entity != null) {
entity.status = status
entity.status = status
if (status == DownloadStatus.COMPLETED) {
SimpleDownloadManager.resumeQueuedTask()
}
if (status == DownloadStatus.COMPLETED) {
SimpleDownloadManager.resumeQueuedTask()
}
ExecutorProvider.getInstance().backgroundExecutor.execute {
updateDownloadToDatabase(entity)
updateDownloadList()
}
ExecutorProvider.getInstance().backgroundExecutor.execute {
updateDownloadToDatabase(entity)
updateDownloadList()
}
for (listener in mGlobalStatusChangedListenerList) {
listener.invoke(entity!!, status)
listener.invoke(entity, status)
}
val listenerList = mListenerMap[id] ?: return
@ -165,7 +163,7 @@ object DownloadMessageHandler : InnerDownloadListener {
* @param error 错误类型
* @param exception 包裹错误的 Exception
*/
override fun onError(id: String, error: DownloadError?, exception: Exception) {
override fun onError(id: String, error: DownloadError?, exception: Exception?) {
error ?: return
when (error) {

View File

@ -7,14 +7,21 @@ import com.gh.base.DownloadToolbarActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.game.GameFragment
class BlockActivity : DownloadToolbarActivity() {
companion object {
fun getIntent(context: Context, blockData: SubjectRecommendEntity, entrance: String): Intent {
fun getIntent(context: Context,
blockData: SubjectRecommendEntity,
exposureSourceList: ArrayList<ExposureSource>? = null,
entrance: String): Intent {
val args = Bundle()
args.putParcelable(EntranceConsts.KEY_BLOCK_DATA, blockData)
if (exposureSourceList != null) {
args.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
}
args.putString(EntranceConsts.KEY_ENTRANCE, entrance)
return getTargetIntent(context, BlockActivity::class.java, GameFragment::class.java, args)
}

View File

@ -10,7 +10,7 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.entity.MessageEntity;
import com.gh.gamecenter.feature.entity.MessageEntity;
import com.gh.gamecenter.qa.comment.CommentActivity;
import com.gh.gamecenter.qa.comment.NewCommentConversationFragment;
import com.halo.assistant.fragment.comment.CommentDetailFragment;

View File

@ -1,32 +0,0 @@
package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.info.ConcernFragment;
/**
* Created by khy on 10/04/18.
*/
public class ConcernInfoActivity extends ToolBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
}
public static Intent getIntent(Context context) {
return getTargetIntent(context, ConcernInfoActivity.class, ConcernFragment.class);
}
@Override
protected void onDarkModeChanged() {
super.onDarkModeChanged();
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
}
}

View File

@ -34,6 +34,7 @@ import androidx.transition.*
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import com.alibaba.android.arouter.facade.annotation.Route
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipeline
@ -41,6 +42,7 @@ import com.facebook.imagepipeline.request.ImageRequest
import com.gh.common.constant.Config
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
@ -71,6 +73,7 @@ import kotlin.math.roundToInt
* @author 黄壮华
*
*/
@Route(path = RouteConsts.activity.imageViewerActivity)
class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
private var mScale = 0F
@ -150,8 +153,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
mUrlList = ArrayList()
mUrlList?.add(base64Image)
} else {
mUrlList = it.getStringArrayList(KEY_URL_LIST) ?: arrayListOf()
mInitialPosition = it.getInt(KEY_CURRENT, 0)
mUrlList = it.getStringArrayList(EntranceConsts.KEY_URL_LIST) ?: arrayListOf()
mInitialPosition = it.getInt(EntranceConsts.KEY_CURRENT, 0)
}
mShowSaveBtn = it.getBoolean(KEY_SHOW_SAVE)
mUseEnterAndExitAnimation = it.getBoolean(KEY_USE_ENTER_AND_EXIT_ANIMATION)
@ -930,8 +933,6 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
var base64Image: String = ""
private const val KEY_BASE64 = "base64"
private const val KEY_URL_LIST = "urls"
private const val KEY_CURRENT = "current"
private const val KEY_SHOW_SAVE = "showSave"
private const val KEY_USE_ENTER_AND_EXIT_ANIMATION = "use_enter_and_exit_animation"
private const val KEY_IS_FROM_IMAGE_CONTAINER_VIEW = "is_from_image_container_view"
@ -995,8 +996,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
isFromICV: Boolean = false
): Intent {
val intent = Intent(context, ImageViewerActivity::class.java)
intent.putExtra(KEY_URL_LIST, list)
intent.putExtra(KEY_CURRENT, position)
intent.putExtra(EntranceConsts.KEY_URL_LIST, list)
intent.putExtra(EntranceConsts.KEY_CURRENT, position)
intent.putExtra(KEY_SHOW_SAVE, isShowSaveBtn)
intent.putExtra(AnswerEntity::class.java.name, answerEntity)
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)

View File

@ -18,9 +18,11 @@ import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.ethanhua.skeleton.Skeleton;
import com.ethanhua.skeleton.ViewSkeletonScreen;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DetailDownloadUtils;
@ -38,8 +40,8 @@ import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.view.VerticalItemDecoration;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.entity.LibaoEntity;
import com.gh.gamecenter.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.LibaoEntity;
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.MeEntity;
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
@ -70,6 +72,7 @@ import retrofit2.HttpException;
/**
* Created by khy on 2016/12/13.
*/
@Route(path = RouteConsts.activity.libaoDetailActivity)
public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailAdapter.OnCodeScrollListener,
OnRequestCallBackListener {

View File

@ -21,7 +21,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
@ -33,6 +32,7 @@ import android.text.Html;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
@ -43,9 +43,8 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import com.alibaba.android.arouter.launcher.ARouter;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.DefaultUrlHandler;
import com.gh.ad.AdDelegateHelper;
import com.gh.common.constant.Config;
import com.gh.common.exposure.ExposureManager;
import com.gh.common.filter.RegionSettingHelper;
@ -77,7 +76,6 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.constant.CommonConsts;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.entity.NotificationUgc;
import com.gh.gamecenter.common.entity.SuggestType;
@ -92,7 +90,6 @@ import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NotificationHelper;
import com.gh.gamecenter.common.utils.ShareUtils;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.provider.IStartUpAdProvider;
import com.gh.gamecenter.core.utils.ClassUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
@ -102,8 +99,6 @@ import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.download.DownloadFragment;
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
import com.gh.gamecenter.entity.StartupAdEntity;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.feature.entity.GameEntity;
@ -141,22 +136,16 @@ import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -174,7 +163,7 @@ public class MainActivity extends BaseActivity {
public static final String SWITCH_TO_COMMUNITY = "switch_to_community";
public static final String SWITCH_TO_VIDEO = "switch_to_video";
public static final String SHOW_AD = "show_ad";
private static final int COUNTDOWN_AD = 100;
public static final int COUNTDOWN_AD = 100;
private static final int COUNTDOWN_MAX_COUNT = 3;
private int countdownCount = 0;
@ -190,15 +179,12 @@ public class MainActivity extends BaseActivity {
public static boolean isNewFirstLaunch;
private final Handler handler = new Handler();
public boolean showAd = false; // 是否显示广告
private IStartUpAdProvider mStartUpAdProvider;
private boolean mShouldShowAd = false; // 是否显示广告
@Override
protected void onCreate(Bundle savedInstanceState) {
showAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
mShouldShowAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
HaloApp.getInstance().initFresco();
HaloApp.getInstance().isAlreadyUpAndRunning = true;
super.onCreate(savedInstanceState);
@ -231,7 +217,6 @@ public class MainActivity extends BaseActivity {
}
}
}, 2000L);
getPluginUpdate();
sp.edit().putBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), false).apply();
// 记录曾安装过的版本 + 渠道
@ -285,8 +270,6 @@ public class MainActivity extends BaseActivity {
}
}
// checkTinkerPath(); // 看情况是否需要显示补丁弹窗
// 必须放在这里,否则会导致获取 baseActivity 不是本应用包名
DownloadManager.getInstance().initDownloadService();
@ -303,22 +286,23 @@ public class MainActivity extends BaseActivity {
doSkip();
}
// debug 模式下的快速跳转页面
if (BuildConfig.DEBUG) {
handler.postDelayed(() -> {
EntranceUtils.jumpShortcut(this);
}, 500);
handler.postDelayed(() -> EntranceUtils.jumpShortcut(this), 500);
}
if (showAd) {
observeStartUp();
if (mShouldShowAd) {
showAd();
} else {
hideStartUp();
hideStartUpAd();
hideTextAd();
hideSplashAd();
}
// 默认配置为空时重试
if (Config.getSettings() == null) {
Config.getGhzsSettings();
} else if (Config.getVSettingEntity() == null) {
Config.refreshVSettingEntity();
}
// 耗时操作
@ -474,7 +458,7 @@ public class MainActivity extends BaseActivity {
protected void onDestroy() {
super.onDestroy();
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
handler.removeCallbacksAndMessages(null);
releaseExoSourceCache();
@ -498,87 +482,58 @@ public class MainActivity extends BaseActivity {
}
}
private void observeStartUp() {
if (!showAd) {
hideStartUp();
hideStartUpAd();
/**
* 显示广告 (包括文本广告和开屏广告)
*/
private void showAd() {
if (!mShouldShowAd) {
hideTextAd();
hideSplashAd();
return;
}
final StartupAdEntity startUp = AdHelper.getStartUp();
if (startUp != null) {
showStartUp(startUp);
final StartupAdEntity textAd = AdHelper.getStartUp();
if (textAd != null) {
showTextAd(textAd);
AppExecutor.getUiExecutor().executeWithDelay(() -> {
hideStartUp();
initStartUpAd();
hideTextAd();
showSplashAd();
}, 2000);
} else {
initStartUpAd();
showSplashAd();
}
}
private void initStartUpAd() {
mStartUpAdProvider = (IStartUpAdProvider) ARouter.getInstance().build(RouteConsts.provider.adSdk).navigation();
if (mStartUpAdProvider != null && mStartUpAdProvider.shouldEnableSDK(HaloApp.getInstance().getChannel())) {
initSDKStartUpAd();
} else {
observeStartUpAd();
}
}
/**
* 显示开屏广告
*/
private void showSplashAd() {
if (AdDelegateHelper.INSTANCE.shouldShowStartUpAd()) {
ViewGroup startAdContainer = findViewById(R.id.startAdContainer);
ViewGroup sdkStartAdContainer = findViewById(R.id.sdkStartAdContainer);
FrameLayout adsFl = findViewById(R.id.adsFl);
private void observeStartUpAd() {
final StartupAdEntity startUpAd = AdHelper.getStartUpAd();
int screenWidthInPx = DisplayUtils.getScreenWidth(this);
int screenHeightInPx = DisplayUtils.getScreenHeight(this) + DisplayUtils.getStatusBarHeight(this.getResources());
float screenWidthInDp = DisplayUtils.px2dip(this, screenWidthInPx);
float screenHeightInDp = DisplayUtils.px2dip(this, screenHeightInPx);
if (startUpAd != null && !TextUtils.isEmpty(startUpAd.getImg())) {
// 根据接口返回的广告时间,判断该图片广告是否还有必要显示
boolean isAdValid = false;
if (startUpAd.getTime() != null) {
long currentTimeInSecond = System.currentTimeMillis() / 1000;
if (currentTimeInSecond > startUpAd.getTime().getStart()
&& currentTimeInSecond < startUpAd.getTime().getEnd()) {
isAdValid = true;
}
} else {
// 接口没有返回开始和结束时间时,默认有效
isAdValid = true;
}
// 图片广告无效,跳过
if (!isAdValid) {
hideStartUpAd();
return;
}
final String showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "");
final String rule = startUpAd.getRule();
switch (rule) {
case "each":
showStartUpAd(startUpAd);
break;
case "once":
if (TextUtils.isEmpty(showedTodayTimestamp)
|| !showedTodayTimestamp.contains(startUpAd.getId())) {
showStartUpAd(startUpAd);
} else {
hideStartUpAd();
AdDelegateHelper.requestSplashAd(
this,
screenWidthInPx,
screenHeightInPx,
screenWidthInDp,
screenHeightInDp,
startAdContainer,
sdkStartAdContainer,
adsFl,
(BaseHandler) mBaseHandler,
() -> {
hideSplashAd();
return null;
}
break;
case "everyday":
final String today = TimeUtils.getToday();
if (TextUtils.isEmpty(showedTodayTimestamp)
|| !showedTodayTimestamp.contains(today)
|| !showedTodayTimestamp.contains(startUpAd.getId())) {
showStartUpAd(startUpAd);
} else {
hideStartUpAd();
}
break;
default:
hideStartUpAd();
break;
}
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, startUpAd.getId() + TimeUtils.getToday());
);
} else {
hideStartUpAd();
hideSplashAd();
}
}
@ -590,14 +545,17 @@ public class MainActivity extends BaseActivity {
TextView jumpBtn = findViewById(R.id.jumpBtn);
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - countdownCount));
if (COUNTDOWN_MAX_COUNT < countdownCount) {
hideStartUpAd();
hideSplashAd();
} else {
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
}
}
}
private void hideStartUp() {
/**
* 隐藏开屏文案
*/
private void hideTextAd() {
View maskContainer = findViewById(R.id.maskContainer);
if (maskContainer != null) {
maskContainer.setVisibility(View.GONE);
@ -605,8 +563,11 @@ public class MainActivity extends BaseActivity {
}
}
private void hideStartUpAd() {
showAd = false;
/**
* 隐藏开屏广告
*/
private void hideSplashAd() {
mShouldShowAd = false;
getIntent().putExtra(SHOW_AD, false);
View startAdContainer = findViewById(R.id.startAdContainer);
if (startAdContainer != null) {
@ -617,7 +578,7 @@ public class MainActivity extends BaseActivity {
if (startSdkAdContainer != null) {
startSdkAdContainer.setVisibility(View.GONE);
ExtensionsKt.removeFromParent(startSdkAdContainer);
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
}
checkDialog();
}
@ -633,62 +594,10 @@ public class MainActivity extends BaseActivity {
});
}
private void showStartUpAd(StartupAdEntity ad) {
View startAdContainer = findViewById(R.id.startAdContainer);
View jumpBtn = findViewById(R.id.jumpBtn);
TextView jumpDetailBtn = findViewById(R.id.jumpDetailBtn);
SimpleDraweeView adImage = findViewById(R.id.adImage);
startAdContainer.setVisibility(View.VISIBLE);
jumpDetailBtn.setText(ad.getDesc());
ExtensionsKt.setDrawableEnd(jumpDetailBtn, AppCompatResources.getDrawable(this, R.drawable.ic_startup_ad_arrow), null, null);
ImageUtils.display(adImage, ad.getImg());
startAdContainer.setOnClickListener(v -> {
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
});
jumpBtn.setOnClickListener(v -> {
mBaseHandler.removeMessages(COUNTDOWN_AD);
hideStartUpAd();
LinkEntity linkEntity = ad.getJump();
NewFlatLogUtils.logOpenScreenAdSkip(
ad.getId(),
linkEntity.getText() != null ? linkEntity.getText() : "",
linkEntity.getType() != null ? linkEntity.getType() : "",
linkEntity.getLink() != null ? linkEntity.getLink() : ""
);
});
List<ExposureSource> sources = new ArrayList<>();
sources.add(new ExposureSource("开屏广告", ad.getId()));
final ExposureEvent event = ExposureEvent.createEvent(null, sources, null, ExposureType.EXPOSURE);
ExposureManager.INSTANCE.log(event);
if (ad.getButton()) {
jumpDetailBtn.setOnClickListener(v -> {
DirectUtils.directToLinkPage(this, ad.getJump(), "(启动广告)", "", event);
v.postDelayed(() -> {
mBaseHandler.removeMessages(COUNTDOWN_AD);
hideStartUpAd();
}, 1000);
});
jumpDetailBtn.setVisibility(View.VISIBLE);
LogUtils.logStartAd("watch_start_ads", ad);
} else {
LogUtils.logStartAd("start_ads", ad);
}
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
}
private void initSDKStartUpAd() {
View startAdContainer = findViewById(R.id.sdkStartAdContainer);
startAdContainer.setVisibility(View.VISIBLE);
FrameLayout adsFl = findViewById(R.id.adsFl);
if (mStartUpAdProvider != null) {
mStartUpAdProvider.initStartUpAd(startAdContainer, adsFl, showAd, () -> {
hideStartUpAd();
return null;
});
}
}
private void showStartUp(StartupAdEntity ad) {
/**
* 显示文本广告
*/
private void showTextAd(StartupAdEntity ad) {
TextView adContentTv = findViewById(R.id.adContentTv);
View containerView = findViewById(R.id.maskContainer);
containerView.setVisibility(View.VISIBLE);
@ -696,7 +605,7 @@ public class MainActivity extends BaseActivity {
containerView.setElevation(500F);
}
containerView.setOnClickListener(v -> {
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
// 拦截点击事件,避免传递到下面的页面
});
adContentTv.setText(ad.getDesc());
adContentTv.setVisibility(View.VISIBLE);
@ -746,7 +655,6 @@ public class MainActivity extends BaseActivity {
} else {
Intent skipIntent = new Intent(MainActivity.this, clazz);
skipIntent.putExtras(bundle);
// startActivity(skipIntent);
AvoidOnResultManager.Companion.getInstance(this)
.startForResult(skipIntent, (resultCode, data) -> {
Bundle nextToBundle = getIntent().getBundleExtra(KEY_NEXT_TO);
@ -803,6 +711,15 @@ public class MainActivity extends BaseActivity {
ToastUtils.showToast("游戏启动失败,请联系客服反馈相关信息");
return;
}
VHelper.INSTANCE.logLaunchButtonClicked(
gamePackageName,
null,
null,
null,
"桌面快捷图标"
);
ToastUtils.showToast("游戏启动中,请稍后~");
handler.postDelayed(() -> {
VHelper.postOnInitialized(() -> {
@ -859,7 +776,7 @@ public class MainActivity extends BaseActivity {
@Override
public Boolean invoke(Integer code) {
if (code == 404001) {
if (showAd) {
if (mShouldShowAd) {
AppExecutor.getUiExecutor().executeWithDelay(() -> {
toast("抱歉,暂未找到相关内容");
}, 1000);
@ -970,7 +887,7 @@ public class MainActivity extends BaseActivity {
@Override
protected int getLayoutId() {
if (showAd) {
if (mShouldShowAd) {
return R.layout.activity_main;
} else {
return R.layout.layout_wrapper_activity;
@ -993,77 +910,14 @@ public class MainActivity extends BaseActivity {
}
}
// 获取META-INF中的plugin_update 文件判断是否从游戏插件中下载的app是则获取游戏id启动游戏更新下载该游戏
private void getPluginUpdate() {
AppExecutor.getIoExecutor().execute(() -> {
ApplicationInfo appinfo = getApplicationInfo();
String sourceDir = appinfo.sourceDir;
ZipFile zipfile = null;
try {
zipfile = new ZipFile(sourceDir);
Enumeration<?> entries = zipfile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
if (entryName.contains("gh_assist")) {
String packageName = entryName.substring(entryName.lastIndexOf("_") + 1);
startActivity(DownloadManagerActivity.getDownloadMangerIntent(MainActivity.this,
packageName, DownloadFragment.INDEX_UPDATE, "(游戏插件)"));
break;
} else if (entryName.contains("halo_skip.json")) {
InputStream in = zipfile.getInputStream(entry);
if (in != null) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
InnerMetaInfoEntity info = GsonUtils.getGson().fromJson(reader, InnerMetaInfoEntity.class);
if (info != null) {
if (EntranceConsts.HOST_COMMUNITY.equals(info.getType())) {
runOnUiThread(() -> mMainWrapperFragment.setCurrentItem(MainWrapperFragment.INDEX_BBS));
} else {
DirectUtils.directToSpecificPage(this,
info.getType(),
info.getLink(),
info.getText(),
EntranceConsts.KEY_PLUGIN,
"特定包启动跳转");
}
}
}
} else if (entryName.contains("halo_skip.dat")) {
InputStream in = zipfile.getInputStream(entry);
if (in != null) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String content = "";
for (String line; (line = reader.readLine()) != null; content += line) ;
if (!TextUtils.isEmpty(content)) {
DefaultUrlHandler.interceptUrl(this, content, "(特定包启动跳转)");
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
// 连接上网络事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBNetworkState busNetworkState) {
if (busNetworkState.isNetworkConnected()) {
if (Config.getSettings() == null) {
Config.getGhzsSettings();
} else if (Config.getVSettingEntity() == null) {
Config.refreshVSettingEntity();
}
mPackageViewModel.checkData();

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