Compare commits

..

367 Commits

Author SHA1 Message Date
49a610deee feat: 动态java方法注册 2023-10-11 19:41:28 +08:00
61f43d53b2 feat: 文章详情WebView预加载 2023-10-11 15:52:35 +08:00
0dcf5d2097 Merge branch 'fix/GHZS-3596' into 'dev'
fix: 【光环助手】APP内图片显示问题 https://jira.shanqu.cc/browse/GHZS-3596

See merge request halo/android/assistant-android!1375
2023-10-09 15:08:09 +08:00
32e584c04c Merge remote-tracking branch 'origin/dev' into dev-5.32.0
# Conflicts:
#	dependencies.gradle
2023-10-09 10:45:04 +08:00
f726a4629f chore: 版本更新至 5.31.1 2023-10-09 10:40:01 +08:00
fbe29d82be fix: 【光环助手】APP内图片显示问题 https://jira.shanqu.cc/browse/GHZS-3596 2023-10-08 16:54:13 +08:00
a6c2254db3 Merge branch 'fix/GHZS-3600' into 'dev'
fix: 光环助手使用微信登录问题 https://jira.shanqu.cc/browse/GHZS-3600

See merge request halo/android/assistant-android!1374
2023-10-08 16:16:21 +08:00
3d4977dc87 Merge branch 'feature-GHZS-3462' into 'dev-5.32.0'
feat: 帖子加载问题优化—客户端 https://jira.shanqu.cc/browse/GHZS-3462

See merge request halo/android/assistant-android!1373
2023-10-08 16:14:05 +08:00
4d0fda6157 feat: 帖子加载问题优化—客户端 https://jira.shanqu.cc/browse/GHZS-3462 2023-10-08 16:14:05 +08:00
34fb8ccf93 fix: 光环助手使用微信登录问题 https://jira.shanqu.cc/browse/GHZS-3600 2023-10-08 16:07:48 +08:00
49b9c3a135 Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1372
2023-10-08 09:23:54 +08:00
bc04dcc94b Merge branch 'feature-article-detail-comment-no-data' into 'dev'
feat: 文章详情评论列表缺省图修改

See merge request halo/android/assistant-android!1371
2023-10-08 09:16:48 +08:00
eb0bba47f9 feat: 文章详情评论列表缺省图修改 2023-10-08 09:16:48 +08:00
9ba4e9c2cf Merge branch 'fix/GHZS-3532' into 'dev'
fix:【光环助手】同步正式环境问题-帮助视频问题 https://jira.shanqu.cc/browse/GHZS-3532

See merge request halo/android/assistant-android!1370
2023-10-07 14:06:48 +08:00
3a69bb4452 fix:【光环助手】同步正式环境问题-帮助视频问题 https://jira.shanqu.cc/browse/GHZS-3532 2023-10-07 14:06:48 +08:00
0581ebf409 Merge branch 'hotfix/v5.30.6-956/vivo_culprit' into 'release'
fix: 特殊处理 vivo 设备获取已安装列表权限的异常问题

See merge request halo/android/assistant-android!1369
2023-09-27 15:11:30 +08:00
44607a9039 fix: 特殊处理 vivo 设备获取已安装列表权限的异常问题 2023-09-27 15:06:23 +08:00
00db8c00c6 Merge branch 'feature-GHZS-3528' into 'dev'
fix 【光环助手】同步正式环境问题—帖子详情页相关问题 https://jira.shanqu.cc/browse/GHZS-3528

See merge request halo/android/assistant-android!1367
2023-09-26 11:14:31 +08:00
c64713117e fix 【光环助手】同步正式环境问题—帖子详情页相关问题 https://jira.shanqu.cc/browse/GHZS-3528 2023-09-26 11:14:31 +08:00
28e28d0775 feat: 畅玩游戏启动中转页面内容调整—客户端 https://jira.shanqu.cc/browse/CWZS-101 2023-09-26 09:33:09 +08:00
6f53a67554 feat: 畅玩游戏启动中转页面内容调整—客户端 https://jira.shanqu.cc/browse/CWZS-101 2023-09-26 09:33:09 +08:00
f2b965b447 Merge branch 'fix/GHZS-3513' into 'dev'
fix:【光环助手】同步正式环境问题-新游开测相关 https://jira.shanqu.cc/browse/GHZS-3513

See merge request halo/android/assistant-android!1365
2023-09-21 10:18:58 +08:00
0ae4f745ee fix:【光环助手】同步正式环境问题-新游开测相关 https://jira.shanqu.cc/browse/GHZS-3513 2023-09-21 10:10:05 +08:00
bcfd9cdfef Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-09-20 16:32:53 +08:00
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
05268442f8 Merge branch 'fix/GHZS-3500' into 'dev-5.32.0'
fix: 求版本下载跳转问题 https://jira.shanqu.cc/browse/GHZS-2674

See merge request halo/android/assistant-android!1362
2023-09-20 10:42:45 +08:00
55521e6f29 fix: 求版本下载跳转问题 https://jira.shanqu.cc/browse/GHZS-2674 2023-09-20 10:42:45 +08:00
db5b09cc11 Merge branch 'feature-GHZS-3493' into 'dev-5.32.0'
fix: 插件求版本相关优化—0915测试 https://jira.shanqu.cc/browse/GHZS-3493

See merge request halo/android/assistant-android!1361
2023-09-19 10:51:12 +08:00
b0922b4c29 fix: 插件求版本相关优化—0915测试 https://jira.shanqu.cc/browse/GHZS-3493 2023-09-19 10:51:12 +08:00
455ed32ac6 Merge branch 'hotfix/v5.30.3-953/GHZS-3484' into 'dev'
修复普通微信登录也会触发 QQ 小游戏的微信登录异常 toast 问题

See merge request halo/android/assistant-android!1360
2023-09-18 09:39:47 +08:00
fd92979481 fix: 微信登录提示问题 https://jira.shanqu.cc/browse/GHZS-3484 2023-09-18 09:39:47 +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
b809ae6687 Merge branch 'fix/GHZS-3452' into 'dev-5.32.0'
fix: 开发者中心及其配套优化—0912测试(2) https://jira.shanqu.cc/browse/GHZS-3452

See merge request halo/android/assistant-android!1358
2023-09-15 09:42:17 +08:00
c575e589ae fix: 开发者中心及其配套优化—0912测试(2) https://jira.shanqu.cc/browse/GHZS-3452 2023-09-15 09:30:57 +08:00
2af47af681 Merge branch 'feat/GHZS-3437' into 'dev-5.32.0'
feat: 游戏下载增加文件格式 https://jira.shanqu.cc/browse/GHZS-3437

See merge request halo/android/assistant-android!1354
2023-09-14 17:12:49 +08:00
b1228bdd2a feat: 游戏下载增加文件格式 https://jira.shanqu.cc/browse/GHZS-3437 2023-09-14 17:12:49 +08:00
4008c7fa4d Merge branch 'feature-GHZS-3424-patch-2' into 'dev'
fix: 神策数据埋点第二期-0914测试...

See merge request halo/android/assistant-android!1357
2023-09-14 17:08:30 +08:00
f2d714280b fix: 神策数据埋点第二期-0914测试... 2023-09-14 17:08:30 +08:00
6862609bba Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1356
2023-09-14 16:31:22 +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
c6f0825fb5 Merge branch 'feature-GHZS-3432-patch-1' into 'dev'
fix: 神策数据埋点第二期—0912测试...

See merge request halo/android/assistant-android!1353
2023-09-14 09:08:08 +08:00
cbc2902613 fix: 神策数据埋点第二期—0912测试... 2023-09-14 09:08:08 +08:00
db725a417d Merge branch 'chen/202309/fix-upload-archive-crash' into 'dev'
存档上传bug

See merge request halo/android/assistant-android!1352
2023-09-13 12:09:08 +08:00
4270924d0f fix:登陆光环账号,然后断网,在光环助手游戏详情页上传存档,有的手机是上传存档弹窗一闪而过没有任何提示,有的手机是弹窗一闪而过后提示‘当前页面未捕获的异常....’ 2023-09-13 11:58:57 +08:00
69fc206377 Merge branch 'feature-GHZs-3038-patch' into 'dev'
fix: 帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038

See merge request halo/android/assistant-android!1350
2023-09-13 11:07:47 +08:00
8468ec45c2 fix: 帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038 2023-09-13 11:07:47 +08:00
256a4c2b0a Merge branch 'feature-GHZS-3424-patch' into 'dev'
feat: 【光环助手】帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038

See merge request halo/android/assistant-android!1349
2023-09-12 17:37:46 +08:00
7d01e47c26 feat: 【光环助手】帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038 2023-09-12 17:37:46 +08:00
5814f468b3 Merge branch 'feature-GHZS-3432-patch' into 'dev'
fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432

See merge request halo/android/assistant-android!1348
2023-09-12 16:24:01 +08:00
a5730e0ffd fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432 2023-09-12 16:24:00 +08:00
0dfd87db25 Merge branch 'feature-GHZS-3420' into 'dev'
fix: 帖子详情页UI优化—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3420

See merge request halo/android/assistant-android!1347
2023-09-12 14:49:18 +08:00
31aa16f155 fix: 帖子详情页UI优化—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3420 2023-09-12 14:49:18 +08:00
b22c6b9a5b Merge branch 'feature-GHZS-3432' into 'dev'
fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432

See merge request halo/android/assistant-android!1344
2023-09-12 14:46:11 +08:00
ffae0d1b1d Merge branch 'dev' into 'dev-5.32.0'
Dev

See merge request halo/android/assistant-android!1346
2023-09-12 13:59:06 +08:00
5d8a31c725 Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1345
2023-09-12 13:58:25 +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
f1c0155379 fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432 2023-09-12 11:38:30 +08:00
19dc23d98a Merge branch 'fix/GHZS-3434' into 'dev'
fix: 首页推荐入口数据上报问题 https://jira.shanqu.cc/browse/GHZS-3434

See merge request halo/android/assistant-android!1342
2023-09-12 11:00:30 +08:00
69c82ec0e6 fix: 首页推荐入口数据上报问题 https://jira.shanqu.cc/browse/GHZS-3434 2023-09-12 11:00:29 +08:00
b1a9d96c3b Merge branch 'fix/GHZS-3426' into 'dev'
fix: 神策数据埋点第二期—0907测试(1)(0911测试) https://jira.shanqu.cc/browse/GHZS-3426

See merge request halo/android/assistant-android!1340
2023-09-11 17:45:22 +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
1b326a0515 fix: 神策数据埋点第二期—0907测试(1)(0911测试) https://jira.shanqu.cc/browse/GHZS-3426 2023-09-11 15:44:02 +08:00
3fc1fd821a Merge branch 'feature/GHZS-3408' into 'dev-5.32.0'
feat: 开发者中心及配套优化—客户端 https://jira.shanqu.cc/browse/GHZS-3408

See merge request halo/android/assistant-android!1339
2023-09-11 09:55:00 +08:00
b3af44cc4c feat: 开发者中心及配套优化—客户端 https://jira.shanqu.cc/browse/GHZS-3408 2023-09-11 09:49:25 +08:00
44c1711be7 Merge branch 'fix/GHZS-3426' into 'dev'
fix: 神策数据埋点第二期—0907测试(1) https://jira.shanqu.cc/browse/GHZS-3426

See merge request halo/android/assistant-android!1338
2023-09-08 16:19:21 +08:00
c616df87ea fix: 神策数据埋点第二期—0907测试(1) https://jira.shanqu.cc/browse/GHZS-3426 2023-09-08 16:11:02 +08:00
dd7072eea4 Merge branch 'feature-GHZS-3412' into 'dev-5.32.0'
feat: 插件求版本相关优化—0905测试 https://jira.shanqu.cc/browse/GHZS-3412

See merge request halo/android/assistant-android!1337
2023-09-08 15:55:50 +08:00
4ee463f03e feat: 插件求版本相关优化—0905测试 https://jira.shanqu.cc/browse/GHZS-3412 2023-09-08 15:55:49 +08:00
d3dc31eeaf Update README.md 2023-09-08 15:27:26 +08:00
08b364a626 Merge branch 'fix/GHZS-3421' into 'dev'
fix: 右下悬浮窗优化-新增悬浮窗展开交互—0907测试(补充) https://jira.shanqu.cc/browse/GHZS-3421

See merge request halo/android/assistant-android!1336
2023-09-08 14:59:40 +08:00
9e6d1e5fbd fix: 右下悬浮窗优化-新增悬浮窗展开交互—0907测试(补充) https://jira.shanqu.cc/browse/GHZS-3421 2023-09-08 14:59:40 +08:00
75a21ee04e Merge branch 'feature-GHZS-3424' into 'dev'
feat: 帖子详情页UI优化—0907UI测试 https://jira.shanqu.cc/browse/GHZS-3424

See merge request halo/android/assistant-android!1335
2023-09-08 13:59:49 +08:00
27d13d4ce9 feat: 帖子详情页UI优化—0907UI测试 https://jira.shanqu.cc/browse/GHZS-3424 2023-09-08 13:59:49 +08:00
16526ddfbd Merge branch 'feature/GHZS-3346' into 'dev-5.32.0'
feat: 插件管理功能优化(第2期)—客户端 https://jira.shanqu.cc/browse/GHZS-3346

See merge request halo/android/assistant-android!1334
2023-09-08 11:20:21 +08:00
d6e676300e feat: 插件管理功能优化(第2期)—客户端 https://jira.shanqu.cc/browse/GHZS-3346 2023-09-08 11:15:30 +08:00
7852972e01 feat: 插件管理功能优化(第2期)—客户端 https://jira.shanqu.cc/browse/GHZS-3346 2023-09-08 11:15:22 +08:00
6ff76ea1ed Merge branch 'fix/help_video' into 'dev'
修复帮助视频相关问题

See merge request halo/android/assistant-android!1333
2023-09-07 18:05:18 +08:00
39d51ceeb3 fix: 处理帮助视频全屏播放时全面屏手势与进度条冲突导致无法拖动进度条的问题 2023-09-07 17:49:54 +08:00
00fc6e447c fix: 修复帮助视频上报埋点数据异常的问题 2023-09-07 16:23:22 +08:00
76fff608ed Merge branch 'fix/GHZS-3421' into 'dev'
fix: 右下悬浮窗优化-新增悬浮窗展开交互—0907测试 https://jira.shanqu.cc/browse/GHZS-3421

See merge request halo/android/assistant-android!1332
2023-09-07 11:03:51 +08:00
460409ac30 fix: 右下悬浮窗优化-新增悬浮窗展开交互—0907测试 https://jira.shanqu.cc/browse/GHZS-3421 2023-09-07 10:57:45 +08:00
80403e1684 Merge remote-tracking branch 'origin/dev' into dev-5.32.0 2023-09-07 10:30:53 +08:00
ef32fd946b Merge branch 'feature-GHZS-3373-patch-1' into 'dev'
feat: 帖子详情页UI优化—0901UI测试-客户端 https://jira.shanqu.cc/browse/GHZS-3373

See merge request halo/android/assistant-android!1331
2023-09-07 09:50:49 +08:00
23d57c8bbd feat: 帖子详情页UI优化—0901UI测试-客户端 https://jira.shanqu.cc/browse/GHZS-3373 2023-09-07 09:50:49 +08:00
c46b93769d Merge branch 'fix/GHZS-3415' into 'dev'
fix: 意见反馈页面改版—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3415

See merge request halo/android/assistant-android!1330
2023-09-06 17:52:07 +08:00
2305229919 fix: 意见反馈页面改版—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3415 2023-09-06 17:48:39 +08:00
0e9453b1b2 Merge branch 'fix/floating_window_api_crash' into 'dev'
fix: 修复右下悬浮窗接口结构未同步造成的闪退

See merge request halo/android/assistant-android!1329
2023-09-06 16:58:32 +08:00
420290bc87 fix: 修复右下悬浮窗接口结构未同步造成的闪退 2023-09-06 16:55:43 +08:00
91be2cea1d Merge branch 'fix/GHZS-3415' into 'dev'
fix: 意见反馈页面改版—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3415

See merge request halo/android/assistant-android!1328
2023-09-06 15:52:13 +08:00
4dc3a8edc3 fix: 意见反馈页面改版—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3415 2023-09-06 15:27:43 +08:00
5ba9c74583 Merge branch 'feature-GHZS-3373' into 'dev'
feat: 帖子详情页UI优化—0901UI测试-Web前端 https://jira.shanqu.cc/browse/GHZS-3374

See merge request halo/android/assistant-android!1326
2023-09-06 11:38:43 +08:00
a694e401d3 feat: 帖子详情页UI优化—0901UI测试-Web前端 https://jira.shanqu.cc/browse/GHZS-3374 2023-09-06 11:38:43 +08:00
a6cb0b9fa0 Merge branch 'fix/feedback' into 'dev'
fix: 修改意见反馈页面文案

See merge request halo/android/assistant-android!1327
2023-09-06 11:34:26 +08:00
9b599fd28d fix: 修改意见反馈页面文案 2023-09-06 11:33:10 +08:00
f04fecc11e Merge branch 'feature-GHZS-3373' into 'dev'
feat: 帖子详情页UI优化—0901UI测试-客户端 https://jira.shanqu.cc/browse/GHZS-3373

See merge request halo/android/assistant-android!1323
2023-09-06 10:05:54 +08:00
471e28099b Merge branch 'fix/GHZS-3371' into 'dev'
fix: 意见反馈页面改版—0901UI测试(4) https://jira.shanqu.cc/browse/GHZS-3371

See merge request halo/android/assistant-android!1325
2023-09-05 17:31:44 +08:00
5a3031ae87 fix: 意见反馈页面改版—0901UI测试(4) https://jira.shanqu.cc/browse/GHZS-3371 2023-09-05 17:30:30 +08:00
1421f27bd3 Merge branch 'fix/GHZS-3371' into 'dev'
fix: 意见反馈页面改版—0901UI测试(2) https://jira.shanqu.cc/browse/GHZS-3371

See merge request halo/android/assistant-android!1324
2023-09-05 16:12:51 +08:00
e9e152eeee fix: 意见反馈页面改版—0901UI测试(2) https://jira.shanqu.cc/browse/GHZS-3371 2023-09-05 16:01:31 +08:00
aae6904e4b feat: 帖子详情页UI优化—0901UI测试-客户端 https://jira.shanqu.cc/browse/GHZS-3373 2023-09-05 16:00:36 +08:00
db7fbe057e Merge remote-tracking branch 'origin/dev' into dev-5.32.0 2023-09-05 14:35:39 +08:00
042508e8e6 Merge branch 'release' into dev
# Conflicts:
#	dependencies.gradle
2023-09-05 14:35:09 +08:00
af5736f54d Merge branch 'fix/GHZS-3371' into 'dev'
fix: 意见反馈页面改版—0901UI测试(1-2) https://jira.shanqu.cc/browse/GHZS-3371

See merge request halo/android/assistant-android!1322
2023-09-05 14:21:11 +08:00
56816fa682 fix: 意见反馈页面改版—0901UI测试(1-2) https://jira.shanqu.cc/browse/GHZS-3371 2023-09-05 14:17:47 +08:00
05e0609f94 Merge branch 'fix/GHZS-3382' into 'dev'
fix: 帮助与反馈页面改版—0904测试 https://jira.shanqu.cc/browse/GHZS-3382

See merge request halo/android/assistant-android!1320
2023-09-05 14:05:25 +08:00
7a080851ae Merge branch 'feature-GHZS-3276-patch-2' into 'dev'
feat: 游戏详情-开服日历表-反馈优化—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3276

See merge request halo/android/assistant-android!1321
2023-09-05 13:56:46 +08:00
e1ce989d43 feat: 游戏详情-开服日历表-反馈优化—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3276 2023-09-05 13:56:46 +08:00
6e00a0c2a6 fix: 帮助与反馈页面改版—0904测试 https://jira.shanqu.cc/browse/GHZS-3382 2023-09-05 10:19:58 +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
2928c59b87 Merge branch 'fix/help_and_feedback_help_video' into 'dev'
fix: 修复帮助视频轮播显示问题

See merge request halo/android/assistant-android!1318
2023-09-04 17:58:39 +08:00
ceb2442f3f fix: 修复帮助视频轮播显示问题 2023-09-04 17:56:43 +08:00
cec684c325 Merge branch 'fix/GHZS-3361' into 'dev'
fix: 帮助与反馈页面改版—0831测试(特殊处理【与我相关】接口内容) https://jira.shanqu.cc/browse/GHZS-3361

See merge request halo/android/assistant-android!1317
2023-09-04 16:23:31 +08:00
b5e4bf772b fix: 帮助与反馈页面改版—0901UI测试(8) https://jira.shanqu.cc/browse/GHZS-3370 2023-09-04 15:08:11 +08:00
9f3fe9e30d fix: 帮助与反馈页面改版—0831测试(特殊处理【与我相关】接口内容) https://jira.shanqu.cc/browse/GHZS-3361 2023-09-04 14:53:54 +08:00
c7174bbaec Merge branch 'fix/help_and_feedback_swipe_refresh' into 'dev'
fix: 修复帮助与反馈页面左右滑动会触发下拉刷新的问题

See merge request halo/android/assistant-android!1316
2023-09-04 11:53:42 +08:00
de013e0129 fix: 修复帮助与反馈页面左右滑动会触发下拉刷新的问题 2023-09-04 11:51:30 +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
25c849ccad Merge branch 'fix/GHZS-3371' into 'dev'
fix: 意见反馈页面改版—UI测试 https://jira.shanqu.cc/browse/GHZS-3371

See merge request halo/android/assistant-android!1314
2023-09-04 10:26:54 +08:00
927c846bcb Merge branch 'fix/GHZS-3361' into 'dev'
fix: 帮助与反馈页面改版—0831测试 https://jira.shanqu.cc/browse/GHZS-3361

See merge request halo/android/assistant-android!1313
2023-09-04 10:26:40 +08:00
fcd13ba8b0 fix: 意见反馈页面改版—UI测试 https://jira.shanqu.cc/browse/GHZS-3371 2023-09-04 10:23:48 +08:00
bccd161762 Merge branch 'feature-GHZS-3276-patch-1' into 'dev'
feat: 【光环助手】游戏详情-开服日历表-反馈优化 https://jira.shanqu.cc/browse/GHZS-3049

See merge request halo/android/assistant-android!1312
2023-09-04 10:05:55 +08:00
776dfddc34 feat: 【光环助手】游戏详情-开服日历表-反馈优化 https://jira.shanqu.cc/browse/GHZS-3049 2023-09-04 10:05:55 +08:00
b31b529ca7 Merge branch 'feature-GHZS-3367' into 'dev'
feat: 帖子详情页UI优化—0831测试 https://jira.shanqu.cc/browse/GHZS-3367

See merge request halo/android/assistant-android!1311
2023-09-04 09:40:19 +08:00
1cc2f5387a feat: 帖子详情页UI优化—0831测试 https://jira.shanqu.cc/browse/GHZS-3367 2023-09-02 21:38:19 +08:00
5c79a01cc6 fix: 帮助与反馈页面改版—UI测试 https://jira.shanqu.cc/browse/GHZS-3370 2023-09-01 18:01:06 +08:00
1e3704c1ed fix: 帮助与反馈页面改版—0831测试 https://jira.shanqu.cc/browse/GHZS-3361 2023-09-01 14:17:17 +08:00
41340f7333 Merge branch 'feature-GHZS-3295' into 'dev-5.32.0'
feat: 插件求版本相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3295

See merge request halo/android/assistant-android!1310
2023-09-01 11:45:18 +08:00
e73fc09d9b feat: 插件求版本相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3295 2023-09-01 11:35:50 +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
f9d652d629 Merge branch 'fix/floating_window_issue' into 'dev'
fix: 修复右下悬浮窗及启动弹窗的一些显示问题

See merge request halo/android/assistant-android!1308
2023-08-31 17:05:54 +08:00
77ee092b5b chore: 版本更新至 5.30.2 2023-08-31 16:58:17 +08:00
0a61d29f37 fix: 修复右下悬浮窗及启动弹窗的一些显示问题 2023-08-31 16:50:14 +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
f8ce9ffc90 Merge branch 'fix/GHZS-3358' into 'dev'
fix: 意见反馈页面改版-0830测试 https://jira.shanqu.cc/browse/GHZS-3358

See merge request halo/android/assistant-android!1306
2023-08-31 10:59:25 +08:00
42366a8591 fix: 意见反馈页面改版-0830测试 https://jira.shanqu.cc/browse/GHZS-3358 2023-08-31 10:53:52 +08:00
5dbf29a09d Merge branch 'feature-GHZS-3276-patch' into 'dev'
feat: 游戏详情-开服日历表-反馈优化—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3276

See merge request halo/android/assistant-android!1305
2023-08-31 10:53:41 +08:00
9621a62ed6 feat: 游戏详情-开服日历表-反馈优化—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3276 2023-08-31 10:37:27 +08:00
07f320db27 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-08-31 10:20:25 +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
285ec88d01 Merge branch 'feature-GHZS-3168' into 'dev'
feat: 帖子详情页UI优化—客户端 https://jira.shanqu.cc/browse/GHZS-3168

See merge request halo/android/assistant-android!1303
2023-08-31 09:26:01 +08:00
1f86e7b32d feat: 帖子详情页UI优化—客户端 https://jira.shanqu.cc/browse/GHZS-3168 2023-08-30 18:00:09 +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
df6c87eed2 Merge branch 'fix/GHZS-3064' into 'dev'
fix: 修复帮助与反馈页面帮助视频轮播与下拉刷新的滑动冲突

See merge request halo/android/assistant-android!1302
2023-08-30 17:08:00 +08:00
2894a964ea fix: 修复帮助与反馈页面帮助视频轮播与下拉刷新的滑动冲突 2023-08-30 17:06:35 +08:00
421baf2889 Merge branch 'fix/GHZS-3315' into 'dev'
fix: 重构首页弹窗类功能的显示(调整通知权限弹窗的回调)

See merge request halo/android/assistant-android!1300
2023-08-30 15:32:46 +08:00
040901f9df fix: 重构首页弹窗类功能的显示(调整通知权限弹窗的回调) 2023-08-30 15:28:24 +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
2d9af85b62 Merge branch 'fix/home_game_collection_carousel_crash' into 'dev'
fix: 修复首页游戏单轮播数组越界闪退

See merge request halo/android/assistant-android!1297
2023-08-30 14:36:12 +08:00
35c71c70c9 fix: 修复首页游戏单轮播数组越界闪退 2023-08-30 14:23:47 +08:00
70e63ed8e3 Merge branch 'fix/GHZS-3286' into 'dev-5.32.0'
fix: 单机插件更新跳转—客户端 https://jira.shanqu.cc/browse/GHZS-3286

See merge request halo/android/assistant-android!1296
2023-08-30 11:32:38 +08:00
b7a36074ed fix: 单机插件更新跳转—客户端 https://jira.shanqu.cc/browse/GHZS-3286 2023-08-30 11:08:31 +08:00
0cb7e4c9a1 Merge branch 'fix/window_animation' into 'dev'
fix: 优化右下悬浮窗的隐藏动画

See merge request halo/android/assistant-android!1295
2023-08-30 10:55:50 +08:00
152b9add80 fix: 优化右下悬浮窗的隐藏动画 2023-08-30 10:52:22 +08:00
ab27ca5256 Merge branch 'fix/compose_setting' into 'dev'
fix: 修复compose设置模块编译问题

See merge request halo/android/assistant-android!1294
2023-08-29 17:35:37 +08:00
90545415ae fix: 修复compose设置模块编译问题 2023-08-29 17:31:55 +08:00
8018517207 Merge branch 'feature/GHZS-3172' into 'dev'
feat: 神策数据埋点第二期(1)—客户端 https://jira.shanqu.cc/browse/GHZS-3172

See merge request halo/android/assistant-android!1293
2023-08-29 15:40:15 +08:00
c79128d6f4 feat: 神策数据埋点第二期(1)—客户端 https://jira.shanqu.cc/browse/GHZS-3172 2023-08-29 15:40:15 +08:00
141d179a64 chore: 版本个更新至 5.32.0 2023-08-29 14:12:07 +08:00
0a9471fc2e Merge remote-tracking branch 'origin/dev' into dev-5.31.0 2023-08-29 14:06:47 +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
ce3d594a4e Merge branch 'feat/GHZS-3182' into 'dev-5.31.0'
feat: 神策数据埋点第二期(3) https://jira.shanqu.cc/browse/GHZS-3182

See merge request halo/android/assistant-android!1291
2023-08-29 10:50:58 +08:00
553f84daa1 feat: 神策数据埋点第二期(3) https://jira.shanqu.cc/browse/GHZS-3182 2023-08-29 10:35:40 +08:00
70f782cb5c Merge branch 'fix/GHZS-3325' into 'dev-5.31.0'
fix: 右下悬浮窗优化-0828测试 https://jira.shanqu.cc/browse/GHZS-3325

See merge request halo/android/assistant-android!1290
2023-08-29 10:25:53 +08:00
28725ae76f fix: 右下悬浮窗优化-0828测试 https://jira.shanqu.cc/browse/GHZS-3325 2023-08-29 10:17:38 +08:00
b0972f1a80 Merge branch 'feature/GHZS-3064' into 'dev-5.31.0'
帮助与反馈页面改版&意见反馈页面改版

See merge request halo/android/assistant-android!1283
2023-08-28 14:06:09 +08:00
585660e52d 帮助与反馈页面改版&意见反馈页面改版 2023-08-28 14:06:09 +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
20998852b6 fix: 处理合并冲突 2023-08-25 16:57:53 +08:00
929a2c4d29 Merge remote-tracking branch 'origin/dev' into dev-5.31.0
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java
#	app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt
2023-08-25 16:38:27 +08:00
f0fd323107 Merge branch 'fix/floating_window_animation' into 'dev-5.31.0'
fix: 修复右下悬浮窗展开和收起的动画显示问题

See merge request halo/android/assistant-android!1287
2023-08-25 16:34:50 +08:00
00892e831a fix: 修复右下悬浮窗展开和收起的动画显示问题 2023-08-25 16:34:15 +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
a55fcdcb28 Merge branch 'feat/GHZS-3081' into 'dev-5.31.0'
feat: 右下悬浮窗优化-新增悬浮窗展开交互 https://jira.shanqu.cc/browse/GHZS-3081

See merge request halo/android/assistant-android!1285
2023-08-24 18:03:20 +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
548a34c66d feat: 右下悬浮窗优化-新增悬浮窗展开交互 https://jira.shanqu.cc/browse/GHZS-3081 2023-08-24 17:28:36 +08:00
55f51284c8 Merge branch 'feature-GHZS-3255' into 'dev-5.31.0'
feat: 插件化相关弹窗埋点补充—0817测试 https://jira.shanqu.cc/browse/GHZS-3255

See merge request halo/android/assistant-android!1282
2023-08-24 15:06:07 +08:00
079dac80f8 feat: 插件化相关弹窗埋点补充—0817测试 https://jira.shanqu.cc/browse/GHZS-3255 2023-08-24 15:06:07 +08:00
b33fee6ec0 Merge branch 'feature-GHZS-3276' into 'dev-5.31.0'
feat: 游戏详情-开服日历表-反馈优化—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3276

See merge request halo/android/assistant-android!1281
2023-08-24 09:55:43 +08:00
2c1fdae6c7 feat: 游戏详情-开服日历表-反馈优化—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3276 2023-08-24 09:55:43 +08:00
6a935b18e8 Merge branch 'fix/GHZS-3274' into 'dev-5.31.0'
fix: 新游开测相关功能优化(第二期)—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3274

See merge request halo/android/assistant-android!1280
2023-08-22 15:40:13 +08:00
91c363fb55 fix: 新游开测相关功能优化(第二期)—0822UI测试 https://jira.shanqu.cc/browse/GHZS-3274 2023-08-22 15:38:46 +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
e1a65c5fce Merge branch 'fix/GHZS-3248' into 'dev-5.31.0'
fix: 新游开测相关功能优化(第二期)—0817测试 https://jira.shanqu.cc/browse/GHZS-3248

See merge request halo/android/assistant-android!1277
2023-08-17 16:39:02 +08:00
9fd6ce4e74 fix: 新游开测相关功能优化(第二期)—0817测试 https://jira.shanqu.cc/browse/GHZS-3248 2023-08-17 16:37:33 +08:00
46df9cdccc Merge branch 'fix/GHZS-3248' into 'dev-5.31.0'
fix: 新游开测相关功能优化(第二期)—0817测试 https://jira.shanqu.cc/browse/GHZS-3248

See merge request halo/android/assistant-android!1275
2023-08-17 16:34:37 +08:00
339665f90f fix: 新游开测相关功能优化(第二期)—0817测试 https://jira.shanqu.cc/browse/GHZS-3248 2023-08-17 16:29:33 +08:00
07a1b2a63b feat: 已安装列表权限-合规整改 https://jira.shanqu.cc/browse/GHZS-3249 2023-08-17 16:29:29 +08:00
96d9d05eb9 Merge branch 'fix/config_error' into 'dev-5.31.0'
fix: 修复阿里云OSS图片数据处理字段使用错误问题 https://jira.shanqu.cc/browse/GHZS-3113

See merge request halo/android/assistant-android!1274
2023-08-17 14:04:14 +08:00
b1c848a7a6 fix: 修复阿里云OSS图片数据处理字段使用错误问题 2023-08-17 14:03:32 +08:00
eb4d84bb48 Merge branch 'feat/GHZS-3113' into 'dev-5.31.0'
feat: 阿里云OSS图片数据处理 https://jira.shanqu.cc/browse/GHZS-3113

See merge request halo/android/assistant-android!1273
2023-08-17 11:44:25 +08:00
04f72091e4 feat: 阿里云OSS图片数据处理 https://jira.shanqu.cc/browse/GHZS-3113 2023-08-17 11:34:54 +08:00
5d21d62140 Merge branch 'feature-GHZS-3163' into 'dev-5.31.0'
feat:插件化相关弹窗埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-3163

See merge request halo/android/assistant-android!1272
2023-08-17 10:34:59 +08:00
0a7b646779 feat:插件化相关弹窗埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-3163 2023-08-17 10:22:44 +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
9f9a675f04 Merge branch 'feature/GHZS-3176' into 'dev-5.31.0'
feat: 新游开测相关功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-3176

See merge request halo/android/assistant-android!1270
2023-08-16 17:35:23 +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
238220548a feat: 新游开测相关功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-3176 2023-08-16 17:18:18 +08:00
38c02380ad fix: 订阅&推送体系优化-消息中心优化—0816测试-客户端(2) https://jira.shanqu.cc/browse/GHZS-3242 2023-08-16 16:24:16 +08:00
dfc023a0cd Merge branch 'feat/GHZS-3161' into 'dev-5.31.0'
feat: 帖子发布图片数量限制开放 https://jira.shanqu.cc/browse/GHZS-3161

See merge request halo/android/assistant-android!1268
2023-08-16 15:57:28 +08:00
cbd9a5708b feat: 帖子发布图片数量限制开放 https://jira.shanqu.cc/browse/GHZS-3161 2023-08-16 15:56:50 +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
8b0a639196 Merge branch 'feature-GHZS-3063' into 'dev-5.31.0'
feat:游戏详情-开服日历表-反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3063

See merge request halo/android/assistant-android!1266
2023-08-16 15:14:43 +08:00
75f164249f feat:游戏详情-开服日历表-反馈优化—客户端 https://jira.shanqu.cc/browse/GHZS-3063 2023-08-16 15:01:48 +08:00
fd72f01b1d Merge branch 'feature/GHZS-3238' into 'dev-5.31.0'
feat: 游戏专区配置相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3238

See merge request halo/android/assistant-android!1265
2023-08-16 14:24:34 +08:00
c17a55e33c feat: 游戏专区配置相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-3238 2023-08-16 14:13:36 +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
1aded5ecf4 Merge branch 'refactor/main_dialog' into 'dev-5.31.0'
refactor: 重构首页弹窗显示逻辑

See merge request halo/android/assistant-android!1262
2023-08-16 11:45:02 +08:00
755a2a0633 fix: 订阅&推送体系优化-消息中心优化—0811优化-客户端(一级页面标题栏&红点提示样式优化) https://jira.shanqu.cc/browse/GHZS-3218 2023-08-16 11:28:13 +08:00
d86dc7a03c feat: 重构首页弹窗显示逻辑 2023-08-16 11:06:47 +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
9741334c2e Merge branch 'feature-GHZS-3181' into 'dev-5.31.0'
feat: 神策数据埋点第二期(2)—客户端 https://jira.shanqu.cc/browse/GHZS-3181

See merge request halo/android/assistant-android!1259
2023-08-15 16:07:19 +08:00
48f762140b feat: 神策数据埋点第二期(2)—客户端 https://jira.shanqu.cc/browse/GHZS-3181 2023-08-15 16:07:18 +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
eba7f31b32 Merge remote-tracking branch 'origin/dev' into dev-5.31.0 2023-08-15 15:07:40 +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
38d91af306 Merge branch 'dev' into dev-5.31.0 2023-08-14 10:22:13 +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
f2bf3df304 Merge branch 'feat/GHZS-3099' into 'dev-5.31.0'
feat: 安装方式管理-增加模糊匹配功能 https://jira.shanqu.cc/browse/GHZS-3099

See merge request halo/android/assistant-android!1250
2023-08-10 10:34:15 +08:00
c2b46ea5f2 feat: 安装方式管理-增加模糊匹配功能 https://jira.shanqu.cc/browse/GHZS-3099 2023-08-10 10:28:22 +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
f12c0f8066 Merge branch 'feat/GHZS-3140' into 'dev-5.31.0'
feat: 资讯文章-下载按钮相关优化 https://jira.shanqu.cc/browse/GHZS-3165

See merge request halo/android/assistant-android!1248
2023-08-09 14:51:16 +08:00
5f158f74e8 feat: 资讯文章-下载按钮相关优化 https://jira.shanqu.cc/browse/GHZS-3165 2023-08-09 14:42:11 +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
503376edc2 Merge branch 'fix/GHZS-3136' into 'dev-5.31.0'
fix:【光环助手】图片视图规范化 https://jira.shanqu.cc/browse/GHZS-3136

See merge request halo/android/assistant-android!1246
2023-08-09 10:32:11 +08:00
7490617191 fix:【光环助手】图片视图规范化 https://jira.shanqu.cc/browse/GHZS-3136 2023-08-09 10:24:27 +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
13949e86c4 Merge remote-tracking branch 'origin/dev' into dev-5.31.0 2023-08-08 10:10:07 +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
1207d53314 Merge branch 'fix/GHZS-3097' into 'dev-5.31.0'
feat: 平板适配相关优化 https://jira.shanqu.cc/browse/GHZS-3097

See merge request halo/android/assistant-android!1242
2023-08-07 17:54:48 +08:00
f02b232589 feat: 平板适配相关优化 https://jira.shanqu.cc/browse/GHZS-3097 2023-08-07 17:38:58 +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
d61abd1174 Merge remote-tracking branch 'origin/dev' into dev-5.31.0 2023-08-02 11:27:14 +08:00
fc9137a48d Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-08-02 11:21:14 +08:00
a460ae0788 chore: 版本更新至 5.31.0 2023-08-02 11:01:15 +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
33ed2796c8 Merge remote-tracking branch 'origin/dev' into dev-5.30.0 2023-07-24 10:48: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
8d5e6c8940 fix: 修复渠道更换的保存问题 2023-07-21 17:51:51 +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
5a8f1d663d feat: 游戏库增加顶部tab栏—客户端 https://jira.shanqu.cc/browse/GHZS-2912 2023-07-19 14:46:19 +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
9aaeee9b3d Merge remote-tracking branch 'origin/dev' into dev-5.30.0 2023-07-14 10:01:59 +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
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
f10b08e152 feat: 插件管理功能优化-新增插件发布上架通知提醒—客户端 https://jira.shanqu.cc/browse/GHZS-2806 2023-07-11 14:33:04 +08:00
56c8885030 chore: 版本更新至 5.30.0 2023-07-05 09:56:12 +08:00
1044 changed files with 36422 additions and 6877 deletions

View File

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

View File

@ -30,14 +30,7 @@
### git 版本管理
本项目使用简化版的 git flow 来管理分支,细节请看 [光环安卓简单 git 规范](https://git.ghzs.com/halo/android/assistant-android/-/wikis/%E5%85%89%E7%8E%AF%E5%AE%89%E5%8D%93%E7%AE%80%E5%8D%95-git-%E8%A7%84%E8%8C%83)
### API 环境配置
本项目使用 Build Variants 来切换 API 环境
* internal 为测试环境
* publish 为正式环境
本项目使用简化版的 git flow 来管理分支,细节请看 [光环安卓简单 git 规范](https://git.shanqu.cc/halo/android/assistant-android/-/wikis/%E5%85%89%E7%8E%AF%E5%AE%89%E5%8D%93%E7%AE%80%E5%8D%95-git-%E8%A7%84%E8%8C%83)
### 图片资源配置
@ -53,14 +46,3 @@
* 本项目使用了微信的 [AndResGuard](https://github.com/shwenzhang/AndResGuard) 作为资源混淆压缩方案,新增需要使用 `getIdentifier` 获取的资源文件时需要添加至白名单
* 本项目默认使用 R8 作为混淆工具,往 proguard-rules.txt 添加 proguard 新配置项时请检查可用性(如语法等)
### APK打包配置
> 打内部测试包:`./scripts/test_build.sh`
> 打邮件测试包:`./scripts/jenkins_build.sh`
### TODO
* 把原有 EventBus 的消息 Type 统一到一个文件内
* 将实现细节从 View(Fragment、Activity) 剥离并以 MVVM 结构改造
* 重构 MainActivity

View File

@ -14,6 +14,7 @@ android {
String SDK_VERSION = ""
String SDK_APP_ID = ""
String SDK_APP_NAME = ""
boolean USE_DEFAULT_CHANNEL_SDK = true
int ACTIVATE_REPORTING_RATIO = 100
buildFeatures {
@ -86,6 +87,7 @@ android {
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}\""
@ -186,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接口仅包含正式环境
@ -197,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 {
@ -207,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())
}
@ -219,6 +224,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}\""
}
gdt {
@ -229,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}\""
}
}
}
@ -330,18 +337,28 @@ dependencies {
implementation(project(':module_core_feature')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_feedback')) {
// implementation(project(':module_feedback')) {
// exclude group: 'androidx.swiperefreshlayout'
// }
implementation(project(':feature:new_feedback',)) {
exclude group: 'androidx.swiperefreshlayout'
}
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')

Binary file not shown.

View File

@ -12,6 +12,7 @@ import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.halo.assistant.HaloApp
import com.kwai.monitor.payload.TurboHelper
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {
@ -34,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
}

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
@ -270,7 +275,7 @@
<activity
android:name="com.gh.gamecenter.VoteActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
android:windowSoftInputMode="stateAlwaysHidden|adjustPan" />
<activity
android:name="com.gh.gamecenter.WeiBoShareActivity"
@ -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" />
@ -760,6 +745,18 @@
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"-->
@ -843,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

@ -205,14 +205,17 @@ RE.setOutdent = function() {
RE.setJustifyLeft = function() {
document.execCommand('justifyLeft', false, null);
RE.enabledEditingItems()
}
RE.setJustifyCenter = function() {
document.execCommand('justifyCenter', false, null);
RE.enabledEditingItems()
}
RE.setJustifyRight = function() {
document.execCommand('justifyRight', false, null);
RE.enabledEditingItems()
}
RE.setBlockquote = function() {
@ -227,6 +230,16 @@ RE.insertImage = function(url) {
RE.insertHTML(html);
}
// 设置分割线
RE.insertHorizontalRule = function() {
document.execCommand('insertHorizontalRule', false, null);
}
// 设置编辑器默认换行符
RE.setDefaultParagraphSeparator = function(separator) {
document.execCommand('defaultParagraphSeparator', false, separator);
}
// 替换成缩略图
RE.replaceTbImage = function(imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
@ -339,9 +352,9 @@ RE.ImageClickListener = function() {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link"|| img.className == "poster") continue;
window.imagelistener.imageArr(img.src);
window.NativeCallBack.invokeMethod("imageArr", img.src);
img.onclick = function() {
window.imagelistener.imageClick(this.src);
window.NativeCallBack.invokeMethod("imageClick", this.src);
}
}
}
@ -574,6 +587,10 @@ document.addEventListener("selectionchange", function(e) {
RE.sendElementNameToNative()
});
document.addEventListener("selectionchange", function(e) {
RE.enabledEditingItems(e)
});
RE.recursion = function(dom) {
var parenDom = dom.parentElement
if (parenDom && parenDom instanceof Element &&
@ -616,7 +633,6 @@ RE.sendElementNameToNative = function() {
// android function to open link
function customLinkgo(self) {
var datas = self.dataset.datas
// console.log(datas)
window.OnLinkClickListener.onClick(datas)
}

View File

@ -30,7 +30,6 @@ body {
}
#editor {
display: table-cell;
outline: 0px solid transparent;
background-repeat: no-repeat;
background-position: center;

View File

@ -0,0 +1,433 @@
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.exposure.ExposureSource
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.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
val vGameLaunchAd: AdConfig?
get() = mVGameLaunchAd
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

@ -57,11 +57,16 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
private lateinit var mEditorFontItalic: CheckableImageView
private lateinit var mEditorFontStrikeThrough: CheckableImageView
private lateinit var mEditorFontUnderline: CheckableImageView
private lateinit var mEditorParagraphDivider: CheckableImageView
private lateinit var mEditorParagraphH1: CheckableImageView
private lateinit var mEditorParagraphH2: CheckableImageView
private lateinit var mEditorParagraphH3: CheckableImageView
private lateinit var mEditorParagraphH4: CheckableImageView
private lateinit var mEditorParagraphQuote: CheckableImageView
private lateinit var mEditorAlignLeft: CheckableImageView
private lateinit var mEditorAlignCenter: CheckableImageView
private lateinit var mEditorAlignRight: CheckableImageView
private lateinit var mEditorAlignContainer: View
private lateinit var mEditorFontContainer: View
private lateinit var mEditorParagraphContainer: View
private lateinit var mEditorLinkContainer: View
@ -97,6 +102,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mRichEditor.insertCustomStyleLink(insertData)
}
}
INSERT_ARTICLE_CODE -> {
val article =
data?.getParcelableExtra<ArticleEntity>(ArticleEntity::class.java.simpleName)
@ -106,6 +112,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mRichEditor.insertCustomStyleLink(insertData)
}
}
INSERT_GAME_CODE -> {
val game = data?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
if (game != null) {
@ -114,6 +121,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mRichEditor.insertCustomStyleLink(insertData)
}
}
INSERT_GAME_COLLECTION_CODE -> {
val gameCollectionEntity =
data?.getParcelableExtra<GamesCollectionEntity>(GamesCollectionEntity::class.java.simpleName)
@ -123,9 +131,11 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mRichEditor.insertCustomStyleLink(insertData)
}
}
REQUEST_CODE_IMAGE -> {
if (data != null) mViewModel.uploadPic(data)
}
INSERT_MEDIA_VIDEO_CODE -> {
val localVideoList =
data?.getParcelableArrayListExtra<LocalVideoEntity>(LocalVideoEntity::class.java.name)
@ -135,12 +145,14 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
uploadVideo(localVideoList)
}
}
REQUEST_CODE_IMAGE_CROP -> {
val imagePath = data?.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
if (!imagePath.isNullOrEmpty()) {
mViewModel.uploadPoster(imagePath)
}
}
INSERT_VIDEO_CODE -> {
val videoEntity = data?.getParcelableExtra<MyVideoEntity>(MyVideoEntity::class.java.simpleName)
if (videoEntity != null) {
@ -194,7 +206,12 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mEditorParagraphH2 = findViewById(R.id.editor_paragraph_h2)
mEditorParagraphH3 = findViewById(R.id.editor_paragraph_h3)
mEditorParagraphH4 = findViewById(R.id.editor_paragraph_h4)
mEditorParagraphDivider = findViewById(R.id.editor_paragraph_divider)
mEditorParagraphQuote = findViewById(R.id.editor_paragraph_quote)
mEditorAlignLeft = findViewById(R.id.editor_align_left)
mEditorAlignCenter = findViewById(R.id.editor_align_center)
mEditorAlignRight = findViewById(R.id.editor_align_right)
mEditorAlignContainer = findViewById(R.id.editor_align_container)
mEditorFontContainer = findViewById(R.id.editor_font_container)
mEditorParagraphContainer = findViewById(R.id.editor_paragraph_container)
mEditorLinkContainer = findViewById(R.id.editor_link_container)
@ -241,6 +258,13 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mRichEditor.hasFocus()
} else false
}
mRichEditor.setOnDecorationChangeListener { _, types ->
mEditorAlignLeft.isChecked = types.contains(RichEditor.Type.JUSTIFYLEFT)
mEditorAlignCenter.isChecked = types.contains(RichEditor.Type.JUSTIFYCENTER)
mEditorAlignRight.isChecked = types.contains(RichEditor.Type.JUSTIFYRIGHT)
}
mOriginalCb.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
mOriginalTipsContainer.alpha = 0f
@ -325,6 +349,9 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-下滑线")
}
}
mEditorParagraphDivider.setOnClickListener {
mRichEditor.insertDivider()
}
mEditorParagraphH1.setOnClickListener {
if (mEditorParagraphH1.isChecked) {
mRichEditor.formatBlock()
@ -370,6 +397,27 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
}
mEditorParagraphQuote.isChecked = !mEditorParagraphQuote.isChecked
}
mEditorAlignLeft.setOnClickListener {
if (!mEditorAlignLeft.isChecked) {
mRichEditor.setAlignLeft()
MtaHelper.onEvent(mtaEventName(), "文本对齐选项", "文本对齐选项-靠左")
mEditorAlignLeft.isChecked = !mEditorAlignLeft.isChecked
}
}
mEditorAlignCenter.setOnClickListener {
if (!mEditorAlignCenter.isChecked) {
mRichEditor.setAlignCenter()
MtaHelper.onEvent(mtaEventName(), "文本对齐选项", "文本对齐选项-靠中")
mEditorAlignCenter.isChecked = !mEditorAlignCenter.isChecked
}
}
mEditorAlignRight.setOnClickListener {
if (!mEditorAlignRight.isChecked) {
mRichEditor.setAlignRight()
MtaHelper.onEvent(mtaEventName(), "文本对齐选项", "文本对齐选项-靠右")
mEditorAlignRight.isChecked = !mEditorAlignRight.isChecked
}
}
findViewById<View>(R.id.editor_link_answer).setOnClickListener {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-回答")
startActivityForResult(
@ -449,25 +497,22 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
return
}
try {
PermissionHelper.checkStoragePermissionBeforeAction(this,
object : EmptyCallback {
override fun onCallback() {
val maxChooseCount = if (videoCount + 3 <= MAX_MEDIA_COUNT) 3 else MAX_MEDIA_COUNT - videoCount
startActivityForResult(
LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
LocalMediaActivity.ChooseType.VIDEO,
maxChooseCount,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
), INSERT_MEDIA_VIDEO_CODE
)
NewLogUtils.logChooseMedia(
"view_media",
if (mtaEventName() == "提问帖") "提问帖" else "帖子",
"视频"
)
}
})
PermissionHelper.checkStoragePermissionBeforeAction(this) {
val maxChooseCount = if (videoCount + 3 <= MAX_MEDIA_COUNT) 3 else MAX_MEDIA_COUNT - videoCount
startActivityForResult(
LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
LocalMediaActivity.ChooseType.VIDEO,
maxChooseCount,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
), INSERT_MEDIA_VIDEO_CODE
)
NewLogUtils.logChooseMedia(
"view_media",
if (mtaEventName() == "提问帖") "提问帖" else "帖子",
"视频"
)
}
} catch (e: Exception) {
toast(R.string.media_image_hint)
e.printStackTrace()
@ -482,18 +527,16 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
return
}
try {
PermissionHelper.checkStoragePermissionBeforeAction(this, object : EmptyCallback {
override fun onCallback() {
val maxChooseCount = if (imageCount + 10 <= MAX_IMAGE_COUNT) 10 else MAX_IMAGE_COUNT - imageCount
val intent = LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
LocalMediaActivity.ChooseType.IMAGE,
maxChooseCount,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
)
startActivityForResult(intent, REQUEST_CODE_IMAGE)
}
})
PermissionHelper.checkStoragePermissionBeforeAction(this) {
val maxChooseCount = if (imageCount + 10 <= MAX_IMAGE_COUNT) 10 else MAX_IMAGE_COUNT - imageCount
val intent = LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
LocalMediaActivity.ChooseType.IMAGE,
maxChooseCount,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
)
startActivityForResult(intent, REQUEST_CODE_IMAGE)
}
} catch (e: Exception) {
toast(R.string.media_image_hint)
e.printStackTrace()
@ -516,6 +559,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
mEditorFontContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorParagraphContainer.visibility =
if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorAlignContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorLinkContainer.visibility = View.GONE
mTagsContainer.visibility = View.GONE
mIsExtendedKeyboardShow = mEditorFont.isChecked
@ -537,6 +581,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
if (mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorLinkContainer.visibility = if (mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorFontContainer.visibility = View.GONE
mEditorAlignContainer.visibility = View.GONE
mEditorParagraphContainer.visibility = View.GONE
mTagsContainer.visibility = View.GONE
mIsExtendedKeyboardShow = mEditorLink.isChecked
@ -776,7 +821,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarAct
const val INSERT_VIDEO_CODE = 415
const val MAX_INPUT_TEXT_NUM = 10000
const val MAX_MEDIA_COUNT = 20
const val MAX_IMAGE_COUNT = 35
const val MAX_IMAGE_COUNT = 70
const val REQUEST_CODE_IMAGE = 120
const val INSERT_MEDIA_VIDEO_CODE = 121

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

@ -24,10 +24,12 @@ import com.gh.gamecenter.common.callback.BiCallback
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.NotificationUgc
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.provider.IHelpAndFeedbackProvider
import com.gh.gamecenter.common.tracker.Tracker
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
@ -39,7 +41,6 @@ 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
@ -68,6 +69,7 @@ class DefaultJsApi(
val entrance: String = "",
private var mFragment: Fragment? = null,
private var mBbsId: String? = "",
private var mOriginUrl: String?= "",
) {
private var mLoginHandler: CompletionHandler<Any>? = null
@ -534,6 +536,18 @@ class DefaultJsApi(
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(url, null, false)
?: DownloadManager.getInstance().getDownloadEntitySnapshot(vUrl, null, false)
NewFlatLogUtils.logGameInstall(
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
trigger = "主动安装"
)
SensorsBridge.trackInstallGameClick(
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
action = "主动安装"
)
downloadEntity?.let {
PackageInstaller.install(context, it, showUnzipToast = false)
}
@ -632,12 +646,19 @@ class DefaultJsApi(
fun logExposure(event: Any) {
val simpleExposureEvent = event.toString().toObject() ?: SimpleExposureEvent()
if (simpleExposureEvent.id.isNotEmpty()) {
val exposureSource = ExposureSource("游戏活动", "${simpleExposureEvent.title}+${simpleExposureEvent.id}")
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)
}
}

View File

@ -350,7 +350,8 @@ object DefaultUrlHandler {
}
EntranceConsts.HOST_FORUM_DETAIL -> {
DirectUtils.directForumDetail(context, id, entrance)
val sectionId = uri.getQueryParameter("section_id") ?: ""
DirectUtils.directForumDetailSection(context, id, sectionId, entrance)
}
EntranceConsts.HOST_GAME_RATING_DETAIL -> {
@ -438,17 +439,17 @@ object DefaultUrlHandler {
directToFeedback(
context,
content,
null,
isQaFeedback,
qaContentId,
isPlugin = false,
isSmoothGame = false,
EntranceConsts.ENTRANCE_BROWSER
)
}
}
EntranceConsts.HOST_HELP_AND_FEEDBACK -> {
val position = uri.getQueryParameter("position") ?: ""
DirectUtils.directToHelpAndFeedback(context, position.toInt())
DirectUtils.directToHelpAndFeedback(context)
}
EntranceConsts.HOST_HELP_DETAIL -> {
@ -489,12 +490,13 @@ object DefaultUrlHandler {
val activityName = uri.getQueryParameter("activity_name") ?: ""
val gameId = uri.getQueryParameter("game_id") ?: ""
context.startActivity(
GameCollectionEditActivity.getIntent(
GameCollectionEditActivity.getCreateIntent(
context,
activityId,
activityName,
gameId,
entrance
entrance,
"其他"
)
)
}

View File

@ -84,11 +84,6 @@ object FixedRateJobHelper {
VideoRecordUtils.commitVideoRecord()
}
// 获取启动广告 (第一次不需要获取)
if (elapsedTime % STARTUP_AD == 0L && mExecuteCount != 0) {
AdHelper.getSettingAdCache()
}
mExecuteCount++
}
}

View File

@ -11,6 +11,7 @@ class BrowserInstallHandler : ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
BrowserInstallHelper.showBrowserInstallHintDialog(
context,
gameEntity,
gameEntity.isVGame() || gameEntity.isSplitXApk()
) {
if (hasNext()) {

View File

@ -9,7 +9,7 @@ class CheckDownloadHandler : ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {

View File

@ -2,20 +2,22 @@ package com.gh.common.chain
import android.content.Context
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.feature.entity.GameEntity
class CheckStoragePermissionHandler : ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
PermissionHelper.checkStoragePermissionBeforeAction(context, object : EmptyCallback {
override fun onCallback() {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {
processEndCallback?.invoke(null)
}
PermissionHelper.checkStoragePermissionBeforeAction(
context,
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese
) {
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

@ -10,7 +10,7 @@ class UpdateNewSimulatorHandler: ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
NewSimulatorGameManager.showUpdateNewsSimulator(context) {
NewSimulatorGameManager.showUpdateNewsSimulator(context, gameEntity) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {

View File

@ -3,6 +3,7 @@ package com.gh.common.chain
import android.content.Context
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.feature.entity.GameEntity
@ -19,13 +20,42 @@ class VersionNumberHandler : ChainHandler() {
if (!gameEntity.isShowVersionNumber()) {
confirmCallback.invoke()
} else {
SensorsBridge.trackGameDemoDialogShow(
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
DialogHelper.showGuideDialog(
context,
"温馨提示",
gameEntity.getVersionNumberString(),
"继续下载",
R.string.cancel.toResString(),
{ confirmCallback.invoke() },
{
confirmCallback.invoke()
SensorsBridge.trackGameDemoDialogClick(
buttonName = "继续下载",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
cancelClickCallback = {
SensorsBridge.trackGameDemoDialogClick(
buttonName = R.string.cancel.toResString(),
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackGameDemoDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(titleIcon = R.drawable.ic_dialog_tips)
)
}

View File

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

@ -13,14 +13,14 @@ import android.widget.PopupWindow
import androidx.core.content.ContextCompat
import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.callback.OnViewClickListener
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.KaifuAddItemBinding
import com.gh.gamecenter.databinding.LayoutAddKaifuPopupBinding
import com.gh.gamecenter.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.servers.add.AddKaiFuPopupAdapter
import java.text.SimpleDateFormat

View File

@ -28,6 +28,7 @@ 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;
@ -63,6 +64,8 @@ import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
@ -397,7 +400,7 @@ public class BindingAdapters {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(v.getContext(), gameEntity.getSimulator().getApk().getPackageName());
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
SimulatorDownloadManager.getInstance().showDownloadDialog(v.getContext(), gameEntity.getSimulator(),
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(), null);
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(), gameEntity.getCategoryChinese(), null);
return;
}
}
@ -412,6 +415,7 @@ 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());
@ -481,6 +485,19 @@ public class BindingAdapters {
case INSTALL_PLUGIN:
case INSTALL_NORMAL:
if (gameEntity.getApk().size() == 1) {
NewFlatLogUtils.INSTANCE.logGameInstall(
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
"主动安装"
);
SensorsBridge.trackInstallGameClick(
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
"主动安装"
);
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
if (gameEntity.isVGame()) {

View File

@ -1,6 +1,7 @@
package com.gh.common.dialog
import android.app.Activity.RESULT_OK
import android.content.DialogInterface
import android.content.Intent
import android.os.Build
import android.os.Bundle
@ -18,13 +19,10 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.PermissionHelper.INSTALL_PERMISSION_CODE
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.core.utils.SPUtils
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import kotlin.random.Random
class InstallPermissionDialogFragment : BaseDialogFragment() {
@ -34,8 +32,11 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
var url: String = ""
var gameId: String = ""
var gameName: String = ""
var gameType: String = ""
var mCallBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)? = null
private var dismissByTouchInside = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mView = inflater.inflate(R.layout.dialog_install_permission, null, false)
return mView
@ -55,6 +56,12 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
if (isXapk) NewFlatLogUtils.logXApkInstallPermissionDialogShowed(gameId, gameName)
SensorsBridge.trackInstallPermissionDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameType
)
val randomNumber = if (isXapk) 1 else Random.nextInt(2)
closeTv.goneIf(randomNumber == 0)
closeIv.goneIf(randomNumber != 0)
@ -64,18 +71,38 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
}
closeTv.setOnClickListener {
dismissByTouchInside = true
if (isXapk) {
NewFlatLogUtils.logXApkInstallPermissionDialogClick("尝试解压", false, gameId, gameName)
mCallBack?.invoke(false)
}
SensorsBridge.trackInstallPermissionDialogClick(
buttonName = "尝试解压",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
dismiss()
}
closeIv.setOnClickListener {
dismissByTouchInside = true
if (isXapk) NewFlatLogUtils.logXApkInstallPermissionDialogClick("关闭", false, gameId, gameName)
SensorsBridge.trackInstallPermissionDialogClick(
buttonName = "关闭",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
dismiss()
}
activateTv.setOnClickListener {
NewFlatLogUtils.logXApkInstallPermissionDialogClick("立即开启", false, gameId, gameName)
SensorsBridge.trackInstallPermissionDialogClick(
buttonName = "立即开启",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
PermissionHelper.toInstallPermissionSetting(requireActivity())
if (isXapk) {
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, requireActivity().javaClass.name)
@ -84,9 +111,23 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
}
}
override fun onDismiss(dialog: DialogInterface) {
if (!dismissByTouchInside) {
SensorsBridge.trackInstallPermissionDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
}
super.onDismiss(dialog)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) {
dismissByTouchInside = true
NewFlatLogUtils.logXApkInstallPermissionDialogClick("立即开启", true, gameId, gameName)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
@ -136,6 +177,7 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
installPermissionDialogFragment.url = downloadEntity.url
installPermissionDialogFragment.gameId = downloadEntity.gameId
installPermissionDialogFragment.gameName = downloadEntity.name
installPermissionDialogFragment.gameType = downloadEntity.categoryChinese
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
transaction.show(installPermissionDialogFragment)
transaction.commit()
@ -146,6 +188,7 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
this.url = downloadEntity.url
this.gameId = downloadEntity.gameId
this.gameName = downloadEntity.name
this.gameType = downloadEntity.categoryChinese
}
installPermissionDialogFragment.show(
activity.supportFragmentManager,

View File

@ -2,6 +2,7 @@ package com.gh.common.dialog
import android.animation.ValueAnimator
import android.content.Context
import android.content.DialogInterface
import android.content.pm.PackageInfo
import android.os.Bundle
import android.view.LayoutInflater
@ -11,6 +12,7 @@ import android.view.animation.LinearInterpolator
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.LinearLayoutManager
@ -61,6 +63,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
private var mDismissByTouchInside = false
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
val packageName = downloadEntity.packageName
@ -90,6 +94,11 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
EventBus.getDefault().register(this)
gameEntity?.let {
LogUtils.uploadPackageCheck("pkg_check_pop_click", "出现弹窗", it, "", "", "", "")
SensorsBridge.trackPkgCheckDialogShow(
gameId = it.id,
gameName = it.name ?: "",
gameType = it.categoryChinese
)
}
}
@ -128,6 +137,18 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
"",
""
)
SensorsBridge.trackPkgCheckDialogClick(
buttonName = "点击链接",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null,
linkId = link.link ?: "",
linkType = link.type ?: "",
linkText = link.linkText ?: ""
)
DirectUtils.directToLinkPage(requireContext(), link, "包名检测弹窗", "")
}.build()
spanBuilder.append(linkSpan)
@ -176,6 +197,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
val isAllPackageInstalled = isAllPackageInstalled(mAllInstalledPackages, entity)
if (isAllPackageInstalled) {
mDismissByTouchInside = true
callBack?.onConfirm()
dismissAllowingStateLoss()
} else {
@ -193,6 +215,15 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
"",
""
)
SensorsBridge.trackPkgCheckDialogClick(
buttonName = "点击前往下载",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null
)
DirectUtils.directToLinkPage(requireContext(), packageLink, "包名检测弹窗", "")
}
}
@ -206,6 +237,19 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
saveRecord(entity)
LogUtils.uploadPackageCheck("pkg_check_pop_click", "不再提示", gameEntity, "", "", "", "")
}
mDismissByTouchInside = true
SensorsBridge.trackPkgCheckDialogClick(
buttonName = binding.cancelTv.text.toString(),
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null
)
dismissAllowingStateLoss()
}
}
@ -300,6 +344,21 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
DownloadManager.getInstance().removeObserver(dataWatcher)
}
override fun onDismiss(dialog: DialogInterface) {
if (!mDismissByTouchInside) {
SensorsBridge.trackPkgCheckDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null
)
}
super.onDismiss(dialog)
}
//安装、卸载事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {

View File

@ -62,17 +62,17 @@ object ExposureUtils {
host: String? = "unknown",
path: String? = "unknown",
downloadType: DownloadType
) {
): ExposureEvent? {
val gameEntity = entity.copy()
gameEntity.platform = platform
gameEntity.downloadCompleteType = downloadType.toString()
val traceEvent = trace?.toObject<ExposureEvent>()
if (TextUtils.isEmpty(entity.id)) return
if (TextUtils.isEmpty(entity.id)) return null
// 避免生成 trace 相同的下载完成事件,根据日志看下载完成的同一秒有可能生成两条
if (mDownloadCompleteTraceEventIdSet.contains(traceEvent?.id)) {
return
return null
}
traceEvent?.payload?.gameId?.let { mDownloadCompleteTraceEventIdSet.add(it) }
@ -91,6 +91,8 @@ object ExposureUtils {
ExposureManager.log(exposureEvent)
ExposureManager.commitSavedExposureEvents(forcedUpload = true)
return exposureEvent
}
@JvmStatic

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

@ -0,0 +1,134 @@
package com.gh.common.prioritychain
import android.app.Activity
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.PopupAccelerateNotificationBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.fragment.MainWrapperViewModel
class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priority) {
private var mActivity: Activity? = null
private var mBaseHandler: BaseFragment.BaseHandler? = null
private var mGameList: List<GameEntity>? = null
private var mViewModel: MainWrapperViewModel? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(
activity: Activity,
baseHandler: BaseFragment.BaseHandler,
gameEntityList: List<GameEntity>?,
viewModel: MainWrapperViewModel
) {
mActivity = activity
mGameList = gameEntityList
mBaseHandler = baseHandler
mViewModel = viewModel
if (getStatus() == STATUS_PENDING) {
if (gameEntityList == null) {
processNext()
} else {
onProcess()
}
} else {
if (gameEntityList == null) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val accelerateSet =
HashSet(SPUtils.getStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET))
if (!mGameList.isNullOrEmpty() && !accelerateSet.contains(mGameList!![0].messageId)) {
showAccelerateNotificationPopupWindow(mActivity!!, mViewModel, mBaseHandler, mGameList!![0]) {
processNext()
}
accelerateSet.add(mGameList!![0].messageId)
SPUtils.setStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET, accelerateSet)
} else {
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
}
companion object {
fun showAccelerateNotificationPopupWindow(
activity: Activity,
viewModel: MainWrapperViewModel?,
baseHandler: BaseFragment.BaseHandler?,
gameEntity: GameEntity?,
dismissCallback: (() -> Unit)?
) {
val binding: PopupAccelerateNotificationBinding =
PopupAccelerateNotificationBinding.inflate(LayoutInflater.from(activity))
if (gameEntity != null) {
binding.gameIconView.displayGameIcon(gameEntity)
binding.gameNameTv.text = gameEntity.name
binding.root.setOnClickListener {
NewFlatLogUtils.logMessageInformClickPluginVersion(
gameEntity.id,
gameEntity.name!!
)
if (gameEntity.messageId.isNotEmpty()) {
// 把对应系统消息设为已读
viewModel?.postMessageRead(gameEntity.messageId)
}
GameDetailActivity.startGameDetailActivity(
context = activity,
gameId = gameEntity.id,
entrance = "首页插件上架弹窗",
defaultTab = -1,
isSkipGameComment = false,
scrollToLibao = false,
openVideoStreaming = false,
openPlatformWindow = true,
traceEvent = null
)
}
}
BugFixedPopupWindow(
binding.root,
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
).apply {
isTouchable = true
isFocusable = true
isOutsideTouchable = true
animationStyle = R.style.popup_window_ease_in_and_out_anim_style
showAtLocation(
activity.window.decorView,
Gravity.TOP,
0,
DisplayUtils.getStatusBarHeight(activity.resources) + DisplayUtils.dip2px(42f)
)
setOnDismissListener {
dismissCallback?.invoke()
}
baseHandler?.postDelayed({ dismiss() }, 5000)
}
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,20 @@
package com.gh.common.prioritychain
import com.gh.gamecenter.common.entity.NotificationUgc
import com.gh.gamecenter.common.utils.NotificationHelper
import com.gh.gamecenter.login.user.UserManager
class NotificationPermissionDialogHandler(priority: Int) : PriorityChainHandler(priority) {
override fun onProcess() {
// 仅登录后再启动光环时请求一次权限
if (UserManager.getInstance().isLoggedIn) {
NotificationHelper.showNotificationHintDialog(NotificationUgc.LOGIN) {
processNext()
}
} else {
processNext()
}
}
}

View File

@ -0,0 +1,22 @@
package com.gh.common.prioritychain
import java.util.*
import java.util.concurrent.PriorityBlockingQueue
class PriorityChain {
private val mHandlerQueue: Queue<PriorityChainHandler> = PriorityBlockingQueue()
fun addHandler(handler: PriorityChainHandler) {
mHandlerQueue.add(handler.also {
it.setPriorityChain(this)
})
}
fun start() {
mHandlerQueue.poll()?.process(mHandlerQueue)
}
fun isHandlerQueueEmpty() = mHandlerQueue.isEmpty()
}

View File

@ -0,0 +1,71 @@
package com.gh.common.prioritychain
import com.lightgame.utils.Utils
import java.util.*
abstract class PriorityChainHandler(private val mPriority: Int) : Comparable<PriorityChainHandler> {
private var mStatus = STATUS_UNKNOWN
private var mQueue: Queue<PriorityChainHandler>? = null
private var mPriorityChain: PriorityChain? = null
/**
* 获取当前 handler 的状态
* - 等待结果返回 STATUS_PENDING
* - 无需执行 STATUS_INVALID
* - 可执行 STATUS_VALID
* - 未知 STATUS_UNKNOWN
*/
fun getStatus(): Int = mStatus
fun updateStatus(status: Int) {
Utils.log(TAG, "${javaClass.simpleName} updateStatus $status")
mStatus = status
}
fun setPriorityChain(priorityChain: PriorityChain) {
mPriorityChain = priorityChain
}
fun process(queue: Queue<PriorityChainHandler>) {
Utils.log(TAG, "${javaClass.simpleName} process $mStatus")
mQueue = queue
// 若当前 handler 未经处理,将其状态改为 pending
if (mStatus == STATUS_UNKNOWN) {
updateStatus(STATUS_PENDING)
}
onProcess()
}
/**
* 执行相关功能的地方
*/
abstract fun onProcess()
/**
* 分发给下一个 handler 处理
*/
fun processNext() {
Utils.log(TAG, "${javaClass.simpleName} processNext $mStatus")
mQueue?.poll()?.process(mQueue!!)
}
override fun compareTo(other: PriorityChainHandler): Int {
return (mPriority - other.mPriority)
}
companion object {
internal const val STATUS_PENDING = 0
internal const val STATUS_INVALID = 1
internal const val STATUS_VALID = 2
internal const val STATUS_UNKNOWN = 3
const val TAG = "PriorityChainHandler"
}
}

View File

@ -0,0 +1,47 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.dialog.PrivacyPolicyDialogFragment
import com.gh.gamecenter.entity.DialogEntity
class PrivacyPolicyDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mActivity: FragmentActivity? = null
private var mPrivacyPolicyEntity: DialogEntity.PrivacyPolicyEntity? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(fragmentActivity: FragmentActivity, privacyPolicyEntity: DialogEntity.PrivacyPolicyEntity?) {
mActivity = fragmentActivity
mPrivacyPolicyEntity = privacyPolicyEntity
if (getStatus() == STATUS_PENDING) {
if (privacyPolicyEntity == null) {
processNext()
} else {
onProcess()
}
} else {
if (privacyPolicyEntity == null) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
}
}
}
override fun onProcess() {
when(getStatus()) {
STATUS_VALID -> {
PrivacyPolicyDialogFragment.show(mActivity!!, mPrivacyPolicyEntity) { _: Boolean? ->
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -0,0 +1,52 @@
package com.gh.common.prioritychain
import androidx.fragment.app.Fragment
import com.gh.common.dialog.ReserveDialog
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.message.MessageUnreadRepository
class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mFragment: Fragment? = null
private var mReserveData: List<SimpleGameEntity>? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(fragment: Fragment, reserveData: List<SimpleGameEntity>?) {
mFragment = fragment
mReserveData = reserveData
if (getStatus() == STATUS_PENDING) {
if (reserveData.isNullOrEmpty()) {
processNext()
} else {
onProcess()
}
} else {
if (reserveData.isNullOrEmpty()) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val reserveDialog = ReserveDialog.getInstance(mReserveData!!)
reserveDialog.setOnDismissListener {
MessageUnreadRepository.loadMessageUnreadData()
processNext()
}
reserveDialog.show(mFragment!!.childFragmentManager, "reserveDialog")
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -0,0 +1,17 @@
package com.gh.common.prioritychain
import android.content.Context
import com.gh.gamecenter.manager.UpdateManager
class UpdateDialogHandler(context: Context, priority: Int) : PriorityChainHandler(priority) {
private val mUpdateManager = UpdateManager.getInstance(context)
override fun onProcess() {
mUpdateManager.checkUpdate(true, null)
mUpdateManager.setDismissCallback {
processNext()
}
}
}

View File

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

View File

@ -19,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 ?: ""
}

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

@ -56,6 +56,22 @@ class ConfigProviderImpl : IConfigProvider {
return Config.getSettings()?.image?.oss?.gifWaterMark ?: ""
}
override fun getVideoSnapshotSuffix(): String {
return Config.getSettings()?.image?.oss?.snapshot ?: ""
}
override fun getImageCropSuffix(): String {
return Config.getSettings()?.image?.oss?.crop ?: ""
}
override fun getImageInfoSuffix(): String {
return Config.getSettings()?.image?.oss?.info ?: ""
}
override fun getImageResizeSuffix(): String {
return Config.getSettings()?.image?.oss?.resize ?: ""
}
override fun getQQ(): String {
return Config.getSettings()?.support?.qq ?: ""
}

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

@ -1,6 +1,7 @@
package com.gh.common.provider
import android.content.Context
import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.common.constant.RouteConsts
@ -53,22 +54,72 @@ class DirectProviderImpl : IDirectProvider {
DirectUtils.directDouyin(context, userId)
}
override fun directToSuggestionFromDiagnosis(context: Context, diagnosis: String) {
DirectUtils.directToSuggestion(context, diagnosis = diagnosis)
override fun directToSuggestionFromDiagnosis(context: Context, content: String, diagnosis: String) {
DirectUtils.directToSuggestion(context, content = content, diagnosis = diagnosis)
}
override fun directToQa(context: Context, text: String?, id: String) {
DirectUtils.directToQa(context, text, id)
}
override fun directToHelpAndFeedback(context: Context, position: Int) {
DirectUtils.directToHelpAndFeedback(context, position)
override fun directToHelpAndFeedback(context: Context, bundle: Bundle?) {
DirectUtils.directToHelpAndFeedback(context, bundle)
}
override fun directToQqGroup(context: Context, groupNumber: String?): Boolean {
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

@ -5,9 +5,11 @@ 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.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.provider.IDownloadButtonClickedProvider
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.packagehelper.PackageRepository
@ -25,6 +27,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
var downloadStatusInChinese = ""
var gameSchemaType = ""
var packageName = ""
var exposureSourceList: List<ExposureSource>? = null
val boundedObject = downloadButton.getObject()
@ -47,6 +50,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
downloadStatusInChinese = boundedObject.downloadStatusChinese
gameSchemaType = boundedObject.gameBitChinese
packageName = boundedObject.getUniquePackageName() ?: ""
exposureSourceList = boundedObject.exposureEvent?.source
}
is GameUpdateEntity -> {
@ -57,6 +61,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
gameTypeInChinese = boundedObject.categoryChinese
downloadStatusInChinese = boundedObject.downloadStatusChinese
packageName = boundedObject.packageName
exposureSourceList = boundedObject.exposureEvent?.source
}
is DownloadEntity -> {
@ -65,6 +70,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
gameCategory = boundedObject.getGameCategory()
downloadStatus = if (boundedObject.isVGame()) "畅玩" else "下载"
packageName = boundedObject.packageName
exposureSourceList = boundedObject.exposureTrace?.toObject<ExposureEvent>()?.source
}
}
@ -92,8 +98,9 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
) {
// 上报神策点击事件
SensorsBridge.trackEvent(
SensorsBridge.trackEventWithExposureSource(
"DownLoadbuttonClick",
exposureSourceList,
"game_id", gameId,
"game_name", gameName,
"game_type", gameTypeInChinese,
@ -105,10 +112,9 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
"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
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId,
)
}
}
}

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,8 +4,8 @@ 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
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.provider.ILinkDirectUtilsProvider
@ -47,21 +47,20 @@ class LinkDirectUtilsProviderImpl : ILinkDirectUtilsProvider {
DirectUtils.directToSuggestion(context, type, suggestHintType, content, isQaFeedback, qaContentId)
}
override fun directToSuggestion(
context: Context,
type: SuggestType,
suggestHintType: String?,
content: String?,
game: SimpleGameEntity,
platform: String
) {
DirectUtils.directToSuggestion(context, type, suggestHintType, content, game, platform)
}
override fun directToSuggestion(context: Context, type: SuggestType, hiddenHint: String) {
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

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

@ -41,7 +41,7 @@ object NewSimulatorGameManager {
private const val KEY_USE_DEBUG_API = "USE_DEBUG_API"
private const val KEY_META = "META"
// private const val GH_RETRO_EMU_APP_PACKAGE_NAME = "com.gh.retroemu"
// private const val GH_RETRO_EMU_APP_PACKAGE_NAME = "com.gh.retroemu"
private const val GH_RETRO_EMU_APP_LAUNCHER_ACTIVITY_NAME = "com.gh.retroemu.ui.SplashActivity"
@ -61,10 +61,10 @@ object NewSimulatorGameManager {
}
/**
* 弹出更新弹框
*/
* 弹出更新弹框
*/
@JvmStatic
fun showUpdateNewsSimulator(context: Context, callback: EmptyCallback? = null){
fun showUpdateNewsSimulator(context: Context, gameEntity: GameEntity, callback: EmptyCallback? = null) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
DialogHelper.showDialog(
context,
@ -76,7 +76,13 @@ object NewSimulatorGameManager {
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
val simulator = Config.getNewSimulatorEntitySetting()
if (simulator != null) {
SimulatorDownloadManager.getInstance().showDownloadingDialog(context, simulator)
SimulatorDownloadManager.getInstance().showDownloadingDialog(
context,
simulator,
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese
)
}
},
cancelClickCallback = {
@ -127,7 +133,10 @@ object NewSimulatorGameManager {
)
val intent = Intent()
intent.setClassName(SimulatorGameManager.NEW_SIMULATOR_PACKAGE_NAME, GH_RETRO_EMU_APP_LAUNCHER_ACTIVITY_NAME)
intent.setClassName(
SimulatorGameManager.NEW_SIMULATOR_PACKAGE_NAME,
GH_RETRO_EMU_APP_LAUNCHER_ACTIVITY_NAME
)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.data = gamePackageFileUri
gameEntity.getApk().safelyGetInRelease(0)?.let { apk ->
@ -138,7 +147,10 @@ object NewSimulatorGameManager {
intent.putExtra(KEY_GAME_ICON, it)
intent.putExtra(KEY_GAME_PACKAGE_PATH, downloadEntity.path) // 游戏包文件路径,冗余参数)
intent.putExtra(KEY_GAME_PACKAGE_SDCARD_PATH, true)
intent.putExtra(KEY_GAME_PACKAGE_LAST_MODIFICATION, File(downloadEntity.path).lastModified()) // 游戏包文件修改时间
intent.putExtra(
KEY_GAME_PACKAGE_LAST_MODIFICATION,
File(downloadEntity.path).lastModified()
) // 游戏包文件修改时间
intent.putExtra(KEY_GAME_EMU_SYSTEM, gameEntity.simulatorType) // 模拟器类型
intent.putExtra(KEY_GAME_ID, gameEntity.id)
// TODO 补充光环模拟器的游戏 id

View File

@ -14,6 +14,7 @@ import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.base.TrackableDialog
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
@ -47,6 +48,7 @@ class SimulatorDownloadManager private constructor() {
private var simulator: SimulatorEntity? = null
private var gameId: String = ""
private var gameName: String = ""
private var gameType: String = ""
private var downloadType: String = ""
private val dataWatcher = object : DataWatcher() {
@ -99,33 +101,43 @@ class SimulatorDownloadManager private constructor() {
downloadDialog?.dismiss()
}
}
DownloadStatus.diskisfull == downloadEntity.status -> {
ToastUtils.showToast("存储空间已满,下载任务已暂停")
}
DownloadStatus.diskioerror == downloadEntity.status -> {
ToastUtils.showToast("下载 IO 出现异常,下载任务已暂停")
}
DownloadStatus.neterror == downloadEntity.status -> {
ToastUtils.showToast("网络不稳定,下载任务已暂停")
}
DownloadStatus.timeout == downloadEntity.status -> {
ToastUtils.showToast("网络不稳定,下载任务已暂停")
}
DownloadStatus.notfound == downloadEntity.status -> {
ToastUtils.showToast("下载链接异常,请稍后重试")
}
DownloadStatus.uncertificated == downloadEntity.status -> {
ToastUtils.showToast("请先进行实名认证")
}
DownloadStatus.unqualified == downloadEntity.status -> {
ToastUtils.showToast("未成年人暂不允许在此时间下载游戏")
}
DownloadStatus.unavailable == downloadEntity.status -> {
ToastUtils.showToast("该游戏未接入防沉迷系统,暂不支持下载")
}
DownloadStatus.banned == downloadEntity.status -> {
ToastUtils.showToast("网络异常")
}
DownloadStatus.hijack == downloadEntity.status -> {
ToastUtils.showToast("网络劫持,请稍后重试")
}
@ -135,7 +147,7 @@ class SimulatorDownloadManager private constructor() {
}
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation) {
showDownloadDialog(context, simulator, location, "", "", null)
showDownloadDialog(context, simulator, location, "", "", "", null)
}
fun showDownloadDialog(
@ -144,6 +156,7 @@ class SimulatorDownloadManager private constructor() {
location: SimulatorLocation,
gameId: String = "",
gameName: String = "",
gameCategoryChinese: String = "",
cancelCallback: (() -> Unit)? = null
) {
if (context == null) return
@ -152,6 +165,7 @@ class SimulatorDownloadManager private constructor() {
this.simulator = simulator
this.gameId = gameId
this.gameName = gameName
this.gameType = gameCategoryChinese
PermissionHelper.checkGetInstalledAppsListBeforeAction(context, object : EmptyCallback {
override fun onCallback() {
@ -183,7 +197,8 @@ class SimulatorDownloadManager private constructor() {
return
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message = if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
@ -195,6 +210,25 @@ class SimulatorDownloadManager private constructor() {
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
@ -207,16 +241,79 @@ class SimulatorDownloadManager private constructor() {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator)
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
)
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
@ -228,7 +325,13 @@ class SimulatorDownloadManager private constructor() {
})
}
fun showDownloadingDialog(context: Context, simulator: SimulatorEntity?) {
fun showDownloadingDialog(
context: Context,
simulator: SimulatorEntity?,
gameId: String = "",
gameName: String = "",
gameCategoryChinese: String = "",
) {
mContextRef = WeakReference(context)
val msg = FileUtils.isCanDownload(context, simulator?.apk?.size)
if (!msg.isNullOrEmpty()) {
@ -261,6 +364,11 @@ class SimulatorDownloadManager private constructor() {
}
downloadDialog?.setOnDismissListener {
SensorsBridge.trackSimulatorDownloadDialogClose(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese
)
DownloadManager.getInstance().removeObserver(dataWatcher)
}
@ -273,7 +381,7 @@ class SimulatorDownloadManager private constructor() {
params?.width = context.resources.displayMetrics.widthPixels - DisplayUtils.dip2px(60f)
downloadDialog?.window?.attributes = params
download(simulator)
download(simulator, gameId, gameName, gameCategoryChinese)
}
private fun showNoneEmulatorDialog(context: Context) {
@ -293,7 +401,12 @@ class SimulatorDownloadManager private constructor() {
)
}
private fun download(simulator: SimulatorEntity?) {
private fun download(
simulator: SimulatorEntity?,
gameId: String = "",
gameName: String = "",
gameCategoryChinese: String = ""
) {
val apkEntity = simulator?.apk ?: return
val entity = DownloadManager.getInstance().getDownloadEntityByUrl(apkEntity.url)
@ -308,18 +421,30 @@ class SimulatorDownloadManager private constructor() {
DownloadStatus.diskisfull -> {
DownloadManager.getInstance().addObserver(dataWatcher)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, true) }, 200)
SensorsBridge.trackSimulatorDownloadDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese
)
downloadDialog?.show()
}
DownloadStatus.done -> NDataChanger.notifyDataChanged(entity)
else -> createDownload(apkEntity, simulator)
else -> createDownload(apkEntity, simulator, gameId, gameName, gameCategoryChinese)
}
} else {
createDownload(apkEntity, simulator)
createDownload(apkEntity, simulator, gameId, gameName, gameCategoryChinese)
}
}
private fun createDownload(apkEntity: ApkEntity, simulator: SimulatorEntity) {
private fun createDownload(
apkEntity: ApkEntity,
simulator: SimulatorEntity,
gameId: String = "",
gameName: String = "",
gameCategoryChinese: String = ""
) {
DownloadManager.getInstance().addObserver(dataWatcher)
val downloadId = PackageInstaller.createDownloadId(simulator.name)
val downloadEntity = DownloadEntity()
@ -351,6 +476,11 @@ class SimulatorDownloadManager private constructor() {
downloadType,
""
)
SensorsBridge.trackSimulatorDownloadDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese
)
downloadDialog?.show()
}

View File

@ -150,7 +150,7 @@ object SimulatorGameManager {
SimulatorDownloadManager.getInstance().showDownloadDialog(
AppManager.getInstance().recentActiveActivity, simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
?: ""
?: "", gameEntity.categoryChinese
) {
jumpToSimulator(downloadEntity, gameEntity)
}

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

@ -109,12 +109,12 @@ object ArchiveDownloadButtonHelper {
R.string.archive_download_dialog_content.toResString(),
R.string.archive_download_dialog_confirm.toResString(),
R.string.cancel.toResString(),
{
confirmClickCallback = {
NewFlatLogUtils.logCloudArchiveGameDownloadDialogClick(R.string.archive_download_dialog_confirm.toResString())
VHelper.disableLaunchGameAfterInstallation()
EventBus.getDefault().post(EBReuse("download"))
},
{
cancelClickCallback = {
NewFlatLogUtils.logCloudArchiveGameDownloadDialogClick(R.string.cancel.toResString())
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)

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;
@ -177,6 +177,8 @@ public class CommentUtils {
return null;
},
null,
null,
null,
new DialogHelper.Config("", false, true, true, false, -1)
);
break;

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
@ -33,6 +34,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -71,8 +73,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;
@ -121,7 +123,7 @@ public class DialogUtils {
return dialog;
}
public static void checkDownload(Context context, String size, String gameId, String gameName, CheckDownloadCallBack callBack) {
public static void checkDownload(Context context, String size, String gameId, String gameName, String gameCategoryChinese, CheckDownloadCallBack callBack) {
if (!NetworkUtils.isNetworkConnected(context)) {
showNoConnectionDownloadDialog(context, () -> {
},
@ -138,7 +140,8 @@ public class DialogUtils {
() -> callBack.onResponse(false),
() -> callBack.onResponse(true),
gameId,
gameName);
gameName,
gameCategoryChinese);
}
}
@ -167,7 +170,9 @@ public class DialogUtils {
DialogHelper.showDialog(context, "下载提示", "网络异常,请检查手机网络状态", "知道了", "WiFi自动下载", listener::onConfirm, cancelListener::onCancel, false, "", "");
}
public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener, String gameId, String gameName) {
public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener, String gameId, String gameName, String gameCategoryChinese) {
SensorsBridge.trackDownloadMobileDataDialogShow(gameId, gameName, gameCategoryChinese);
context = checkDialogContext(context);
NewFlatLogUtils.logDownloadMobileDataDialogShow(gameId, gameName);
@ -182,6 +187,7 @@ public class DialogUtils {
Context finalContext = context;
allowOnce.setOnClickListener(v -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "允许一次");
SensorsBridge.trackDownloadMobileDataDialogClick("允许一次", gameId, gameName, gameCategoryChinese);
AppExecutor.getUiExecutor().executeWithDelay(() -> {
Utils.toast(finalContext, "已使用移动网络下载,请注意流量消耗");
}, 500);
@ -191,12 +197,14 @@ public class DialogUtils {
});
wifiAuto.setOnClickListener(v -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "WiFi自动下载");
SensorsBridge.trackDownloadMobileDataDialogClick("WiFi自动下载", gameId, gameName, gameCategoryChinese);
cancelListener.onCancel();
dialog.dismiss();
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
});
allowAlways.setOnClickListener(v -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "总是允许");
SensorsBridge.trackDownloadMobileDataDialogClick("总是允许", gameId, gameName, gameCategoryChinese);
SPUtils.setBoolean(getTrafficDownloadHintKey(), false);
AppExecutor.getUiExecutor().executeWithDelay(() -> {
// 显示了弹窗以后,即便下面这个 toast 放在 listener.onConfirm 后调用也是显示 listener.onConfirm 里的 toast
@ -208,7 +216,10 @@ public class DialogUtils {
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
});
dialog.setOnCancelListener(downloadDialog -> NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "关闭弹窗"));
dialog.setOnCancelListener(downloadDialog -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "关闭弹窗");
SensorsBridge.trackDownloadMobileDataDialogClick("关闭弹窗", gameId, gameName, gameCategoryChinese);
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
@ -730,42 +741,102 @@ public class DialogUtils {
// 海外下载地址弹窗
public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
SensorsBridge.trackOverseasAddressDialogShow(
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
gameEntity.getCategoryChinese()
);
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);
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();
});
AtomicBoolean dismissByTouchInside = new AtomicBoolean(false);
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
binding.closeIv.setOnClickListener(v -> {
dismissByTouchInside.set(true);
SensorsBridge.trackOverseasAddressDialogClick(
"取消",
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
gameEntity.getCategoryChinese()
);
dialog.dismiss();
});
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 -> {
dismissByTouchInside.set(true);
SensorsBridge.trackOverseasAddressDialogClick(
"下载",
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
gameEntity.getCategoryChinese()
);
listener.onConfirm();
dialog.dismiss();
});
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.setOnDismissListener(dialog1 -> {
if (!dismissByTouchInside.get()) {
SensorsBridge.trackOverseasAddressDialogClick(
"关闭弹窗",
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
gameEntity.getCategoryChinese()
);
}
});
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 +844,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();
@ -1184,7 +1255,7 @@ public class DialogUtils {
@Override
public Unit invoke() {
SimpleGameEntity entity = new SimpleGameEntity(gameId, gameName, "");
HelpAndFeedbackBridge.startSuggestionActivity(finalContext, SuggestType.gameQuestion, "notfound", "模拟器安装包解析错误", entity, "-");
HelpAndFeedbackBridge.startSuggestionActivity(finalContext, SuggestType.GAME, "notfound", "模拟器安装包解析错误", entity);
dialog.dismiss();
return null;
}
@ -1293,11 +1364,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 +1391,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,10 +10,12 @@ 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
import com.gh.common.util.EntranceUtils.jumpActivity
import com.gh.common.util.EntranceUtils.jumpActivityCompat
import com.gh.gamecenter.*
import com.gh.gamecenter.amway.AmwayActivity
import com.gh.gamecenter.catalog.CatalogActivity
@ -22,27 +25,30 @@ import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout
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.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
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.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
@ -68,6 +74,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
@ -91,7 +100,6 @@ import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException
import java.net.URLEncoder
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.roundToInt
/**
@ -99,53 +107,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)
@ -261,11 +222,12 @@ 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")
}
else -> directToWebView(
context,
url = linkEntity.link!!,
@ -319,7 +281,16 @@ object DirectUtils {
)
}
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance, "", exposureEvent)
"column_collection", "专题合集" -> directToColumnCollection(
context,
linkEntity.link!!,
-1,
entrance,
"",
linkEntity.blockId,
linkEntity.blockName,
exposureEvent
)
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path, exposureEvent)
@ -339,7 +310,7 @@ object DirectUtils {
"libao", "礼包" -> directToGiftDetail(context, linkEntity.link ?: "", entrance)
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, false, "", entrance)
"feedback" -> directToFeedback(context, linkEntity.name, false, "", false, false, entrance)
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
@ -349,7 +320,12 @@ object DirectUtils {
?: ""
)
"anliwall", "安利墙" -> directToAmway(context, fixedTopAmwayCommentId = null, entrance = entrance, path = path)
"anliwall", "安利墙" -> directToAmway(
context,
fixedTopAmwayCommentId = null,
entrance = entrance,
path = path
)
"game_detail_comment" -> directToGameDetail(context, linkEntity.link ?: "", entrance)
@ -413,7 +389,7 @@ object DirectUtils {
"column_test" -> context.startActivity(
GameServerTestActivity.getIntent(
context, linkEntity.link
?: "", linkEntity.text ?: "", entrance
?: "", linkEntity.text ?: "", entrance, exposureEvent
)
)
@ -441,7 +417,7 @@ object DirectUtils {
//"h5_game_center" -> directLetoGameCenter(context)
"game_list" -> directToGameCollectionSquare(context, entrance, "", "", "")
"game_list" -> directToGameCollectionSquare(context, entrance, traceEvent = exposureEvent)
"game_list_detail" -> directToGameCollectionDetail(
context,
@ -466,9 +442,12 @@ object DirectUtils {
)
)
"qq_mini_game_column" -> directToQGameHome(context)
"" -> {
// do nothing
}
else -> {
if (unknownCallback != null) {
unknownCallback.invoke()
@ -517,6 +496,8 @@ object DirectUtils {
position: Int = -1,
entrance: String,
columnName: String = "",
blockId: String = "",
blockName: String = "",
exposureEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
@ -525,9 +506,11 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_COLLECTION_ID, id)
bundle.putString(KEY_COLUMNNAME, columnName)
bundle.putString(KEY_BLOCK_ID, blockId)
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putInt(KEY_POSITION, position)
if (exposureEvent != null) {
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST ,ArrayList(exposureEvent.source))
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source))
}
jumpActivity(context, bundle)
}
@ -755,11 +738,13 @@ 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)
@ -773,72 +758,68 @@ object DirectUtils {
// 反馈
@JvmStatic
fun directToFeedback(context: Context, content: String? = null, entrance: String? = null) {
directToFeedback(context, content, null, false, "", entrance)
directToFeedback(context, content, false, "", false, false, entrance)
}
@JvmStatic
fun directToFeedback(
context: Context,
content: String? = null,
hintType: String? = null,
isQaFeedback: Boolean = false,
qaContentId: String? = "",
isPlugin: Boolean = false,
isSmoothGame: Boolean = false,
entrance: String? = null
) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
val destination = RouteConsts.activity.suggestionActivity.toDestinationClass()
bundle.putString(KEY_TO, destination?.name ?: "")
bundle.putBoolean(KEY_PLUGIN, isPlugin)
bundle.putBoolean(KEY_SMOOTH_GAME, isSmoothGame)
if (isPlugin) {
bundle.putString(KEY_HIDE_SUGGEST_HINT, "【插件问题】")
}
if (isSmoothGame) {
bundle.putString(KEY_HIDE_SUGGEST_HINT, "【畅玩问题】")
}
if (isQaFeedback) {
bundle.putBoolean(KEY_IS_QA_FEEDBACK, true)
bundle.putString(KEY_QA_CONTENT_ID, qaContentId)
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.normal)
} else {
bundle.putString(KEY_CONTENT, content)
if (TextUtils.isEmpty(hintType)) {
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.gameQuestion)
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
} else {
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.normal)
bundle.putString(KEY_SUGGEST_HINT_TYPE, hintType)
}
}
jumpActivity(context, bundle)
context.startActivity(HelpAndFeedbackBridge.getSuggestionCategoryIntent(context, bundle))
}
/**
* 畅玩助手反馈跳转
* 跳转至使用帮助与反馈,请不要随意修改方法名
*/
@JvmStatic
fun directToVGameFeedback(
fun directToHelpAndFeedback(
context: Context,
content: String? = null,
hintType: String? = null,
isQaFeedback: Boolean = false,
qaContentId: String? = "",
isPlugin: Boolean = false,
isSmoothGame: Boolean = false,
entrance: String? = null
) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
val destination = RouteConsts.activity.suggestionActivity.toDestinationClass()
bundle.putString(KEY_TO, destination?.name ?: "")
bundle.putBoolean(KEY_PLUGIN, isPlugin)
bundle.putBoolean(KEY_SMOOTH_GAME, isSmoothGame)
if (isPlugin) {
bundle.putString(KEY_HIDE_SUGGEST_HINT, "【插件问题】")
}
if (isSmoothGame) {
bundle.putString(KEY_HIDE_SUGGEST_HINT, "【畅玩问题】")
}
if (isQaFeedback) {
bundle.putBoolean(KEY_IS_QA_FEEDBACK, true)
bundle.putString(KEY_QA_CONTENT_ID, qaContentId)
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.cwzsQuestion)
} else {
bundle.putString(KEY_CONTENT, content)
if (TextUtils.isEmpty(hintType)) {
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.gameQuestion)
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
} else {
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.cwzsQuestion)
bundle.putString(KEY_SUGGEST_HINT_TYPE, hintType)
}
}
EntranceUtils.jumpActivityCompat(context, bundle)
directToHelpAndFeedback(context, bundle)
}
@JvmStatic
@ -1468,7 +1449,7 @@ object DirectUtils {
fun directForumDetailSection(
context: Context,
bbsId: String? = "",
sectionId: String = "",
sectionId: String? = "",
entrance: String? = null
) {
val bundle = Bundle()
@ -1563,15 +1544,14 @@ object DirectUtils {
/**
* 跳转至使用帮助与反馈,请不要随意修改方法名
* @param position 使用帮助:[CommonConsts.TAB_MAIN],意见反馈:[CommonConsts.TAB_SUB]
*/
@JvmStatic
fun directToHelpAndFeedback(context: Context, position: Int = CommonConsts.TAB_MAIN) {
fun directToHelpAndFeedback(context: Context, bundle: Bundle? = null) {
val destination = RouteConsts.activity.helpAndFeedbackActivity.toDestinationClass()
val bundle = Bundle()
bundle.putString(KEY_TO, destination?.name ?: "")
bundle.putInt(BaseActivity_TabLayout.PAGE_INDEX, position)
jumpActivity(context, bundle)
val newBundle = Bundle()
newBundle.putString(KEY_TO, destination?.name ?: "")
bundle?.let { newBundle.putAll(it) }
jumpActivityCompat(context, newBundle)
}
/**
@ -1871,8 +1851,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)
)
}
/**
@ -1886,9 +1869,11 @@ object DirectUtils {
gameCollectionTitle: String = "",
gameCollectionId: String = "",
collectionName: String = "",
collectionId: 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)
@ -1896,6 +1881,11 @@ object DirectUtils {
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)
}
@ -1942,16 +1932,16 @@ object DirectUtils {
@JvmStatic
fun directToSuggestion(
context: Context,
type: SuggestType = SuggestType.normal,
type: SuggestType = SuggestType.APP,
hiddenHint: String = "",
suggestHintType: String? = null,
content: String? = null,
platform: String = "",
game: SimpleGameEntity? = null,
isQaFeedback: Boolean = false,
qaContentId: String = "",
fromRatingKey: Boolean = false,
diagnosis: String = "",
forceLogin: Boolean = true,
requestCode: Int? = null
) {
val intent = HelpAndFeedbackBridge.getIntent(
@ -1960,12 +1950,12 @@ object DirectUtils {
hiddenHint,
suggestHintType,
content,
platform,
game,
isQaFeedback,
qaContentId,
fromRatingKey,
diagnosis
diagnosis,
forceLogin
)
if (requestCode != null) {
(context as Activity).startActivityForResult(intent, requestCode)
@ -2008,12 +1998,19 @@ object DirectUtils {
}
@JvmStatic
fun directToSuggestion(context: Context, type: SuggestType, hiddenHint: String, requestCode: Int?) {
fun directToSuggestion(
context: Context,
type: SuggestType,
hiddenHint: String,
forceLogin: Boolean = true,
requestCode: Int?
) {
directToSuggestion(
context = context,
type = type,
hiddenHint = hiddenHint,
suggestHintType = null,
forceLogin = forceLogin,
requestCode = requestCode,
)
}
@ -2039,22 +2036,69 @@ object DirectUtils {
}
@JvmStatic
fun directToSuggestion(
fun directToQGameHome(context: Context) {
context.startActivity(QGameHomeWrapperActivity.getIntent(context))
}
@JvmStatic
fun directToQGameSearch(
context: Context,
type: SuggestType,
suggestHintType: String? = null,
content: String? = null,
game: SimpleGameEntity,
platform: String = ""
hint: String,
sourceEntrance: String
) {
directToSuggestion(
context = context,
type = type,
hiddenHint = "",
suggestHintType = suggestHintType,
content = content,
game = game,
platform = platform
)
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

@ -2,7 +2,10 @@ package com.gh.common.util
import android.content.Context
import android.os.Build
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.GameEntity
@ -21,7 +24,43 @@ object DownloadDialogHelper {
) {
val dialog = retrieveAvailableDialog(gameEntity, apkEntity)
if (dialog != null) {
showDownloadDialog(context, dialog, callback)
SensorsBridge.trackGameDownloadDialogShow(
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
DialogHelper.showDialogWithHtmlContent(
context,
dialog.title,
dialog.content,
"继续下载",
"取消",
confirmClickCallback = {
SensorsBridge.trackGameDownloadDialogClick(
buttonName = "继续下载",
gameId = gameEntity.id ,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
cancelClickCallback = {
SensorsBridge.trackGameDownloadDialogClick(
buttonName = "取消",
gameId = gameEntity.id ,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
callback.onCallback()
},
touchOutsideCallback = {
SensorsBridge.trackGameDownloadDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id ,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
}
)
} else {
callback.onCallback()
}
@ -109,14 +148,4 @@ object DownloadDialogHelper {
return null
}
private fun showDownloadDialog(context: Context, dialog: GameEntity.Dialog, callback: EmptyCallback) {
DialogHelper.showDialogWithHtmlContent(
context,
dialog.title,
dialog.content,
"继续下载",
"取消",
{ callback.onCallback() })
}
}

View File

@ -26,6 +26,7 @@ import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
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
@ -237,6 +238,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
@ -275,11 +294,6 @@ object DownloadItemUtils {
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
}
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
if (downloadEntity == null) {
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
}
if (downloadEntity != null) {
downloadBtn.apply {
when (downloadEntity.status) {
@ -366,15 +380,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) {
@ -630,15 +636,43 @@ object DownloadItemUtils {
gamePermissionDialogFragment?.dismissAllowingStateLoss()
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
downloadBtn.setOnClickListener {
SensorsBridge.trackAdolescentModeDialogShow(
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
DialogHelper.showDialog(
context,
"提示",
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
"退出青少年模式",
"关闭",
{ context.startActivity(TeenagerModeActivity.getIntent(context)) },
{},
DialogHelper.Config(
confirmClickCallback = {
context.startActivity(TeenagerModeActivity.getIntent(context))
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "退出青少年模式",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
cancelClickCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(
centerTitle = true,
centerContent = true
)
@ -665,7 +699,7 @@ object DownloadItemUtils {
}
},
{},
DialogHelper.Config(
extraConfig = DialogHelper.Config(
centerTitle = true,
centerContent = true
)
@ -740,6 +774,15 @@ object DownloadItemUtils {
}
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 {
allStateClickCallback?.onCallback()
@ -779,7 +822,13 @@ object DownloadItemUtils {
if (downloadBtn is DownloadButton && downloadBtn.text == context.getString(R.string.launch)) {
clickRunnable.onCallback()
} else {
PermissionHelper.checkStoragePermissionBeforeAction(context, clickRunnable)
PermissionHelper.checkStoragePermissionBeforeAction(
context,
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese,
clickRunnable
)
}
}
} else {
@ -827,6 +876,7 @@ object DownloadItemUtils {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(OverseaDownloadHandler())
addHandler(LandPageAddressHandler())
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback {
@ -845,6 +895,7 @@ object DownloadItemUtils {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
addHandler(CheckDownloadHandler())
}
@ -862,6 +913,7 @@ object DownloadItemUtils {
addHandler(DownloadDialogHelperHandler())
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(LandPageAddressHandler())
addHandler(OverseaDownloadHandler())
addHandler(CheckStoragePermissionHandler())
addHandler(ValidateVSpaceHandler())
@ -889,6 +941,19 @@ object DownloadItemUtils {
}
} else if (str == context.getString(R.string.install)) {
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.url)
com.gh.gamecenter.common.utils.NewFlatLogUtils.logGameInstall(
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
trigger = "主动安装"
)
SensorsBridge.trackInstallGameClick(
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
action = "主动安装"
)
if (gameEntity.simulator != null) {
val isInstalled =
PackageUtils.isInstalledFromAllPackage(context, gameEntity.simulator!!.apk!!.packageName)
@ -901,8 +966,13 @@ object DownloadItemUtils {
}
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled && !isInstalledNewSimulator) {
SimulatorDownloadManager.getInstance().showDownloadDialog(
context, simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name!!, null
context,
simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH,
gameEntity.id,
gameEntity.name!!,
gameEntity.categoryChinese,
null
)
return
}
@ -917,7 +987,7 @@ object DownloadItemUtils {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
NewSimulatorGameManager.showUpdateNewsSimulator(context, null)
NewSimulatorGameManager.showUpdateNewsSimulator(context, gameEntity, null)
return
}
val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk()[0].url)
@ -943,16 +1013,25 @@ object DownloadItemUtils {
VHelper.updateOrReDownload(gameEntity)
return
}
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
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,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
}
}
}
}
.buildHandlerChain()
?.handleRequest(context, gameEntity)
} else {
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
@ -1083,7 +1162,16 @@ object DownloadItemUtils {
}
PackageUtils.isCanPluggable(apkEntity) -> {
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
DialogHelper.showPluginDialog(
context,
pluginDesc = gameEntity.pluginDesc,
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese,
platform = gameEntity.platform ?: ""
) {
PackageInstaller.uninstall(context, path)
}
}
else -> {

View File

@ -17,6 +17,11 @@ import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBShowDialog
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.GameEntity
@ -73,19 +78,47 @@ object DownloadObserver {
val currentActivity = AppManager.getInstance().currentActivity() ?: return
SensorsBridge.trackDownloadLinkRotDialogShow(
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
DialogHelper.showDialog(
currentActivity,
"下载失败",
"下载链接已失效,建议提交反馈",
"立即反馈",
"取消",
{
confirmClickCallback = {
HelpAndFeedbackBridge.startSuggestionActivity(
currentActivity,
SuggestType.gameQuestion, "notfound",
StringUtils.buildString(downloadEntity.name, "问题反馈:下载链接失效"),
SuggestType.GAME, "notfound",
"问题反馈:下载链接失效",
SimpleGameEntity(gameId, downloadEntity.name, "")
)
SensorsBridge.trackDownloadLinkRotDialogClick(
buttonName = "立即反馈",
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
},
cancelClickCallback = {
SensorsBridge.trackDownloadLinkRotDialogClick(
buttonName = "取消",
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackDownloadLinkRotDialogClick(
buttonName = "关闭弹窗",
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
@ -196,6 +229,18 @@ object DownloadObserver {
// 会有 ActivityNotFoundException 异常catch 掉不管了
tryWithDefaultCatch {
if (Constants.SILENT_UPDATE != downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)) {
NewFlatLogUtils.logGameInstall(
gameId = downloadEntity.gameId ?: "",
gameName = downloadEntity.name ?: "",
trigger = "自动安装"
)
SensorsBridge.trackInstallGameClick(
gameName = downloadEntity.name,
gameId = downloadEntity.gameId,
action = "自动安装"
)
// TODO 在 Android 11 上没有授权安装未知应用的权限前第一次调用这个方法系统会杀掉我们的进程...
// 没能找到类似的解释,最接近的是这个 https://issuetracker.google.com/issues/154157387但也只是点授权杀进程而已
PackageInstaller.install(mApplication, downloadEntity);
@ -219,7 +264,7 @@ object DownloadObserver {
EBShowDialog(
BaseActivity.PLUGGABLE,
downloadEntity.path,
downloadEntity.pluginDesc
downloadEntity
)
)
@ -257,7 +302,7 @@ object DownloadObserver {
}
SimulatorDownloadManager.getInstance().showDownloadDialog(
currentActivity, simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, downloadEntity.gameId, gameName, null
SimulatorDownloadManager.SimulatorLocation.LAUNCH, downloadEntity.gameId, gameName, downloadEntity.categoryChinese, null
)
SimulatorGameManager.recordDownloadSimulatorGame(downloadEntity.gameId, simulator.type)
SimulatorGameManager.postPlayedGame(downloadEntity.gameId, downloadEntity.packageName)
@ -277,6 +322,17 @@ object DownloadObserver {
) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
tryWithDefaultCatch {
NewFlatLogUtils.logGameInstall(
gameId = downloadEntity.gameId ?: "",
gameName = downloadEntity.name ?: "",
trigger = "自动安装"
)
SensorsBridge.trackInstallGameClick(
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
action = "自动安装"
)
PackageInstaller.install(mApplication, downloadEntity, false)
}
} else {
@ -286,14 +342,15 @@ object DownloadObserver {
EBShowDialog(
BaseActivity.PLUGGABLE,
downloadEntity.path,
downloadEntity.pluginDesc
downloadEntity
)
)
} else {
EventBus.getDefault().post(
EBShowDialog(
BaseActivity.SIGNATURE_CONFLICT,
downloadEntity.path
downloadEntity.path,
downloadEntity
)
)
}
@ -364,53 +421,19 @@ object DownloadObserver {
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
}
if (downloadEntity.isVGame()) {
SensorsBridge.trackEvent(
"HaloFunGameDownloadDone",
"game_name", downloadEntity.name,
"game_id", downloadEntity.gameId,
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位"
)
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
SensorsBridge.trackEvent(
"HaloFunDownloadDone",
"space_schema_type",
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
)
} else if (downloadEntity.gameId != Constants.GHZS_GAME_ID && downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD) {
SensorsBridge.trackEvent(
"DownloadProcessFinish",
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
"page_name", getCurrentPageEntity().pageName,
"page_id", getCurrentPageEntity().pageId,
"page_business_id", getCurrentPageEntity().pageBusinessId,
"last_page_name", getLastPageEntity().pageName,
"last_page_id", getLastPageEntity().pageId,
"last_page_business_id", getLastPageEntity().pageBusinessId
)
}
var downloadSpeed = 0L
val elapsedTimeString = downloadEntity.meta[DownloadConfig.KEY_DOWNLOAD_ELAPSED_TIME]
if (elapsedTimeString != null) {
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
}
val isPlatformRecommend =
java.lang.Boolean.parseBoolean(downloadEntity.getMetaExtra(Constants.IS_PLATFORM_RECOMMEND))
ExposureUtils.logADownloadCompleteExposureEvent(
val exposureEvent = ExposureUtils.logADownloadCompleteExposureEvent(
GameEntity(
id = downloadEntity.gameId,
mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR),
@ -427,6 +450,41 @@ object DownloadObserver {
type
)
if (downloadEntity.isVGame()) {
SensorsBridge.trackEventWithExposureSource(
"HaloFunGameDownloadDone",
exposureEvent?.source,
"game_name", downloadEntity.name,
"game_id", downloadEntity.gameId,
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位"
)
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
SensorsBridge.trackEvent(
"HaloFunDownloadDone",
"space_schema_type",
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
)
}
if (downloadEntity.gameId != Constants.GHZS_GAME_ID
&& downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD
&& downloadEntity.gameId != Constants.HALO_FUN_GAME_ID) {
SensorsBridge.trackEventWithExposureSource(
"DownloadProcessFinish",
exposureEvent?.source,
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
"page_name", getCurrentPageEntity().pageName,
"page_id", getCurrentPageEntity().pageId,
"page_business_id", getCurrentPageEntity().pageBusinessId,
"last_page_name", getLastPageEntity().pageName,
"last_page_id", getLastPageEntity().pageId,
"last_page_business_id", getLastPageEntity().pageBusinessId
)
}
DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")
}

View File

@ -15,18 +15,19 @@ import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.SplashScreenActivity;
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager;
import com.gh.gamecenter.common.avoidcallback.Callback;
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.core.utils.ClassUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Utils;
import org.json.JSONException;
@ -66,8 +67,8 @@ public class EntranceUtils {
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
if (HaloApp.getInstance().isRunningForeground) {
// 应用正在运行,前台或后台
if (AppManager.getInstance().findActivity(MainActivity.class) != null) {
// 应用正在运行,前台或后台且MainActivity在栈中
String to = bundle.getString(KEY_TO);
Class<?> clazz = ClassUtils.forName(to);
if (clazz == null) clazz = MainActivity.class;
@ -92,8 +93,8 @@ public class EntranceUtils {
public static void jumpActivity(Context context, Bundle nextToBundle, Bundle bundle, Callback callback) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
if (HaloApp.getInstance().isRunningForeground) {
// 应用正在运行,前台或后台
if (AppManager.getInstance().findActivity(MainActivity.class) != null) {
// 应用正在运行,前台或后台且MainActivity在栈中
String to = bundle.getString(KEY_TO);
Class<?> clazz = ClassUtils.forName(to);
if (clazz == null) clazz = MainActivity.class;

View File

@ -19,13 +19,11 @@ import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.DataLogUtils
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.utils.*
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnUiThread
@ -37,7 +35,6 @@ import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
@ -112,15 +109,43 @@ object GameActivityDownloadHelper {
// 青少年模式
private fun isTeenageMode(context: Context): Boolean {
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
SensorsBridge.trackAdolescentModeDialogShow(
gameId = mGameEntity?.id ?: "",
gameName = mGameEntity?.name ?: "",
gameType = mGameEntity?.categoryChinese ?: ""
)
DialogHelper.showDialog(
context,
"提示",
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
"退出青少年模式",
"关闭",
{ context.startActivity(TeenagerModeActivity.getIntent(context)) },
{},
DialogHelper.Config(
confirmClickCallback = {
context.startActivity(TeenagerModeActivity.getIntent(context))
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "退出青少年模式",
gameId = mGameEntity?.id ?: "",
gameName = mGameEntity?.name ?: "",
gameType = mGameEntity?.categoryChinese ?: ""
)
},
cancelClickCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭",
gameId = mGameEntity?.id ?: "",
gameName = mGameEntity?.name ?: "",
gameType = mGameEntity?.categoryChinese ?: ""
)
},
touchOutsideCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭弹窗",
gameId = mGameEntity?.id ?: "",
gameName = mGameEntity?.name ?: "",
gameType = mGameEntity?.categoryChinese ?: ""
)
},
extraConfig = DialogHelper.Config(
centerTitle = true,
centerContent = true
)
@ -235,7 +260,7 @@ object GameActivityDownloadHelper {
) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
@ -259,7 +284,8 @@ object GameActivityDownloadHelper {
context,
apk.size,
gameEntity.id,
gameEntity.name
gameEntity.name,
gameEntity.categoryChinese
) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
@ -281,7 +307,7 @@ object GameActivityDownloadHelper {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
@ -295,6 +321,18 @@ object GameActivityDownloadHelper {
apk: ApkEntity,
downloadEntity: DownloadEntity?
) {
com.gh.gamecenter.common.utils.NewFlatLogUtils.logGameInstall(
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
trigger = "主动安装"
)
SensorsBridge.trackInstallGameClick(
gameName = downloadEntity?.name ?: "",
gameId = downloadEntity?.gameId ?: "",
action = "主动安装"
)
val simulatorDownloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.url)
if (gameEntity.simulator != null) {
val isInstalled =
@ -310,7 +348,7 @@ object GameActivityDownloadHelper {
if (simulatorDownloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled && !isInstalledNewSimulator) {
SimulatorDownloadManager.getInstance().showDownloadDialog(
context, simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name!!, null
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name!!, gameEntity.categoryChinese, null
)
return
}
@ -337,7 +375,7 @@ object GameActivityDownloadHelper {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
NewSimulatorGameManager.showUpdateNewsSimulator(context, null)
NewSimulatorGameManager.showUpdateNewsSimulator(context, gameEntity, null)
return
}
val simulatorDownloadEntity =
@ -374,7 +412,7 @@ object GameActivityDownloadHelper {
location: String,
traceEvent: ExposureEvent
) {
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name, gameEntity.categoryChinese) { isSubscribe: Boolean ->
update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
@ -489,7 +527,16 @@ object GameActivityDownloadHelper {
gameEntity.getEntryMap().remove(apkEntity.getPlatform())
}
PackageUtils.isCanPluggable(apkEntity) -> {
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
DialogHelper.showPluginDialog(
context,
pluginDesc = gameEntity.pluginDesc,
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese,
platform = gameEntity.platform ?: ""
) {
PackageInstaller.uninstall(context, path)
}
}
else -> {
PackageInstaller.install(context, downloadEntity)

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

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

View File

@ -24,7 +24,7 @@ import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PackageDialogEntity;
import com.gh.gamecenter.feature.entity.Questions;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.feature.exposure.ExposureSource;
import com.gh.gamecenter.common.exposure.ExposureSource;
import com.gh.gamecenter.login.user.UserManager;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
@ -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

@ -1623,12 +1623,13 @@ object NewFlatLogUtils {
}
//新游开测详情页点击游戏类型
fun logGameTestDetailGameCategoryClick(tabName: String, gameCategory: String, gameTestStartType: String) {
fun logGameTestDetailGameCategoryClick(tabName: String, gameCategory: String, gameTestStartType: String, isOn: Boolean) {
val json = json {
"event" to "game_test_detail_game_category_click"
"tab_name" to tabName
KEY_GAME_CATEGORY to gameCategory
"game_test_start_type" to gameTestStartType
"is_on" to isOn
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
@ -2340,4 +2341,102 @@ object NewFlatLogUtils {
}
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)
}
// QA视频事件
@JvmStatic
fun logQAVideo(
event: String,
contentId: String,
contentTitle: String,
type: String,
sequence: Int,
videoId: String,
playAction: String,
playProcess: Float,
playTime: Int
) {
val json = json {
KEY_EVENT to event
"content_id" to contentId
"content_title" to contentTitle
"type" to type
"sequence" to sequence
"video_id" to videoId
"play_action" to playAction
"play_process" to playProcess
"play_time" to playTime
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

@ -1646,7 +1646,7 @@ object NewLogUtils {
}
//进入创建游戏单
fun logEnterGameCollectionEdit(entrance: String) {
fun logEnterGameCollectionCreate(entrance: String) {
val json = json {
KEY_EVENT to "enter_game_collect_create_location"
KEY_ENTRANCE to entrance

View File

@ -16,6 +16,7 @@ import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.categoryChinese
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.core.utils.CurrentActivityHolder
@ -120,12 +121,24 @@ object PackageInstaller {
}
} else {
if (isPluggin) {
DialogHelper.showPluginDialog(context, downloadEntity?.pluginDesc) {
DialogHelper.showPluginDialog(
context,
pluginDesc = downloadEntity?.pluginDesc,
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
gameType = downloadEntity?.categoryChinese ?: "",
platform = downloadEntity?.platform ?: ""
) {
uninstall(context, pkgPath)
}
} else {
// 非插件化的同包名不同签名冲突
DialogHelper.showSignatureConflictDialog(context) {
DialogHelper.showSignatureConflictDialog(
context,
gameId = downloadEntity?.gameId ?: "",
gameName = downloadEntity?.name ?: "",
gameType = downloadEntity?.categoryChinese ?: ""
) {
uninstall(context, pkgPath)
}
}
@ -317,11 +330,13 @@ object PackageInstaller {
showCloseIcon = true,
showAlternativeCancelStyle = !isTheFirstTimeToShowVpnHintDialog
),
uiModificationCallback = { binding, dialog ->
uiModificationCallback = { binding ->
binding.cancelTv.visibility = View.GONE
binding.closeContainer.setOnClickListener {
binding.markDismissByTouchInside()
install(currentActivity, pkgPath)
dialog.dismiss()
binding.dismiss()
downloadEntity?.let {
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "关闭按钮")

View File

@ -2,7 +2,7 @@ package com.gh.common.util
import android.content.Context
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.GameInstall
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.packagehelper.PackageRepository

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

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

@ -83,8 +83,8 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
private fun addTags() {
removeAllViews()
mTags.forEach {
addView(createView(it))
mTags.forEachIndexed { index, tag ->
addView(createView(tag, index))
}
if (mTotalCount != mTags.size) {
val imageView = ImageView(context).apply {
@ -102,7 +102,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
}
}
private fun createView(tag: TagStyleEntity): View {
private fun createView(tag: TagStyleEntity, position: Int): View {
return TextView(context).apply {
text = tag.name
includeFontPadding = false
@ -117,7 +117,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
setTextColor(if (tag.isTop) "#${tag.color}".hexStringToIntColor() else R.color.text_title.toColor(context))
background = if (tag.isTop) createTopBackgroundDrawable(tag) else createNormalBackgroundDrawable()
setOnClickListener {
onClickListener?.onItemClickListener(tag)
onClickListener?.onItemClickListener(tag, position)
}
}
}
@ -140,6 +140,6 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
interface OnItemClickListener {
fun onMoreClickListener()
fun onItemClickListener(tag: TagStyleEntity)
fun onItemClickListener(tag: TagStyleEntity, position: Int)
}
}

View File

@ -11,9 +11,12 @@ import android.util.AttributeSet;
import android.view.Gravity;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.Nullable;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Config;
@ -40,8 +43,10 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* Copyright (C) 2017 Wasabeef
@ -60,6 +65,12 @@ import java.util.Locale;
*/
public class RichEditor extends WebView {
/**
* 默认的编辑器换行符
*/
public final static String DEFAULT_PARAGRAPH_SEPARATOR = "p";
private boolean mContentOwner;
private boolean mInputEnabled;
@ -68,6 +79,8 @@ public class RichEditor extends WebView {
private EmptyCallback mInitialLayoutCallback;
private Map<String, DynamicJsInterface> mDynamicJsInterfaces = new HashMap<>();
private String mCurrentContent = "";
public enum Type {
@ -87,7 +100,7 @@ public class RichEditor extends WebView {
UNORDEREDLIST,
JUSTIFYCENTER,
JUSTIFYFULL,
JUSTUFYLEFT,
JUSTIFYLEFT,
JUSTIFYRIGHT
}
@ -116,6 +129,7 @@ public class RichEditor extends WebView {
private OnDecorationStateListener mDecorationStateListener;
private AfterInitialLoadListener mLoadListener;
private WebChromeClientListener mChromeClientListener;
private WebResourceRequestInterceptor mWebResourceRequestInterceptor;
private PageFinishedListener mPageFinishedListener;
public RichEditor(Context context) {
@ -173,6 +187,10 @@ public class RichEditor extends WebView {
mChromeClientListener = chromeClientListener;
}
public void setWebResourceRequestInterceptor(WebResourceRequestInterceptor interceptor) {
mWebResourceRequestInterceptor = interceptor;
}
public void setPageFinishedListener(PageFinishedListener pageFinishedListener) {
mPageFinishedListener = pageFinishedListener;
}
@ -396,6 +414,14 @@ public class RichEditor extends WebView {
exec("javascript:RE.insertImage('" + url + "');");
}
/**
* 插入分割线
*/
public void insertDivider() {
exec("javascript:RE.prepareInsert();");
exec("javascript:RE.insertHorizontalRule();");
}
public void insertHtml(String html) {
exec("javascript:RE.prepareInsert();");
exec("javascript:RE.insertHTML('" + html + "');");
@ -447,6 +473,14 @@ public class RichEditor extends WebView {
exec("javascript:RE.setBaseTextColor('" + hex + "');");
}
/**
* 设置编辑器默认换行符
* @param separator 换行符
*/
public void setDefaultParagraphSeparator(String separator) {
exec("javascript:RE.setDefaultParagraphSeparator('" + separator + "')");
}
public void insertPlaceholderImage(String id) {
exec("javascript:RE.prepareInsert();");
exec("javascript:RE.insertPlaceholderImage('" + id + "');");
@ -575,6 +609,14 @@ public class RichEditor extends WebView {
exec("javascript:RE.formatBlock();");
}
public void registerDynamicJsInterface(String method, DynamicJsInterface jsInterface) {
mDynamicJsInterfaces.put(method, jsInterface);
}
public void unregisterDynamicJsInterface(String method) {
mDynamicJsInterfaces.remove(method);
}
/**
* 调用 JS 方法,告诉网页端该 url 对应视频播放的进度
*/
@ -625,6 +667,9 @@ public class RichEditor extends WebView {
@Override
public void onPageFinished(WebView view, String url) {
isReady = url.equalsIgnoreCase(SETUP_HTML);
if (isReady) {
setDefaultParagraphSeparator(DEFAULT_PARAGRAPH_SEPARATOR);
}
if (mLoadListener != null) {
mLoadListener.onAfterInitialLoad(isReady);
}
@ -658,6 +703,16 @@ public class RichEditor extends WebView {
return super.shouldOverrideUrlLoading(view, url);
}
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (mWebResourceRequestInterceptor != null) {
return mWebResourceRequestInterceptor.shouldInterceptRequest(view, url);
}
return super.shouldInterceptRequest(view, url);
}
}
public void setContentOwner(boolean contentOwner) {
@ -674,6 +729,10 @@ public class RichEditor extends WebView {
boolean shouldOverrideUrlLoading(WebView view, String url);
}
public interface WebResourceRequestInterceptor {
WebResourceResponse shouldInterceptRequest(WebView view, String url);
}
public interface PageFinishedListener {
void onPageFinished();
}
@ -815,6 +874,14 @@ public class RichEditor extends WebView {
public void logMtaEvent(String event) {
// do nothing, mta is deprecated
}
@JavascriptInterface
public void invokeMethod(String method, String data) {
DynamicJsInterface jsInterface = mDynamicJsInterfaces.get(method);
if (jsInterface != null) {
jsInterface.invoke(data);
}
}
}
@Override
@ -827,4 +894,8 @@ public class RichEditor extends WebView {
mInitialLayoutCallback = null;
}
}
public interface DynamicJsInterface {
void invoke(String data);
}
}

View File

@ -14,9 +14,7 @@ import com.gh.gamecenter.common.activityresult.ActResultRequest
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.utils.DialogHelper
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.lightgame.download.DownloadEntity
@ -31,11 +29,18 @@ object XapkDialogHelper {
val trigger = if (isManualAction) "手动触发" else "自动触发"
NewFlatLogUtils.logXApkUnzipFailedDialogShowed(trigger, downloadEntity.gameId, downloadEntity.name)
SensorsBridge.trackGameDecompressionFailedDialogShow(
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
val previousShowedDialog = mUnzipFailureDialogRef?.get()
if (previousShowedDialog != null
&& previousShowedDialog.isShowing
&& context == previousShowedDialog.ownerActivity) {
&& context == previousShowedDialog.ownerActivity
) {
// 上一个解压失败弹窗还在显示,当前 activity 不用再显示新的弹窗了
return
}
@ -57,6 +62,13 @@ object XapkDialogHelper {
downloadEntity.name
)
SensorsBridge.trackGameDecompressionFailedDialogClick(
buttonName = "开启权限",
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
// 记录应用重启前需要重解压的信息
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, context.javaClass.name)
SPUtils.setString(Constants.SP_XAPK_URL, downloadEntity.url)
@ -88,10 +100,10 @@ object XapkDialogHelper {
}
},
cancelClickCallback = {
val hint = "" + downloadEntity.name + "游戏安装包解压失败,问题反馈:"
val hint = "游戏安装包解压失败,问题反馈:"
HelpAndFeedbackBridge.startSuggestionActivity(
context,
SuggestType.normal,
SuggestType.GAME,
null,
hint,
SimpleGameEntity(downloadEntity.gameId, downloadEntity.name, downloadEntity.icon)
@ -102,23 +114,47 @@ object XapkDialogHelper {
downloadEntity.gameId,
downloadEntity.name
)
SensorsBridge.trackGameDecompressionFailedDialogClick(
buttonName = "提交反馈",
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
},
uiModificationCallback = { binding, dialog ->
uiModificationCallback = { binding ->
binding.headIv.setBackgroundResource(R.drawable.dialog_unzip_failure_head_background)
binding.titleTv.visibility = View.GONE
// VectorDrawable 的动态颜色设置只在支持 Vector 的系统版本上生效,为了能方便复用资源不支持的就用默认颜色,又不是不能用!
binding.closeIv.setColorFilter(Color.WHITE)
binding.contentTv.setLineSpacing(5.0F.dip2px().toFloat(), 1.0F)
binding.closeContainer.setOnClickListener {
binding.markDismissByTouchInside()
NewFlatLogUtils.logXApkUnzipFailedDialogClick(
"关闭",
false,
downloadEntity.gameId,
downloadEntity.name
)
dialog.dismiss()
SensorsBridge.trackGameDecompressionFailedDialogClick(
buttonName = "关闭",
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
binding.dismiss()
}
},
touchOutsideCallback = {
SensorsBridge.trackGameDecompressionFailedDialogClick(
buttonName = "关闭弹窗",
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(showCloseIcon = true)
)

View File

@ -27,8 +27,13 @@ class XapkInstallReceiver : Activity() {
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
val installIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
if (installIntent != null) {
context.startActivity(installIntent)
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION)
try {
context.startActivity(installIntent)
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION)
} catch (e: Exception) {
// OPPO低版本会出现CONFIRM_PERMISSIONS的权限异常这个问题无解直接取消安装
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
}
finish()
}
}

View File

@ -79,6 +79,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
if (MiuiUtils.isMiui() && !MiuiUtils.isMiuiOptimizationDisabled() && downloadEntity.format == Constants.XAPK_APKS_FORMAT) {// 小米手机开启miui以后需要引导用户关闭miui优化
DialogHelper.showMiuiOptimizationWarning(
context,
downloadEntity,
onHintClick = {
val guides = Config.getNewApiSettingsEntity()?.install
val miuiOptimizationGuide = guides?.guides?.findLast {
@ -95,7 +96,11 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
},
onConfirmClick = {
if (SystemUtils.isDevelopmentSettingsEnabled(context)) {
context.startActivity(Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS))
context.startActivity(
Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
it.markDismissByTouchInside()
it.dismiss()
} else {
ToastUtils.showToast(context.getString(R.string.miui_open_adb_hint))
@ -132,7 +137,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
override fun onProgress(apk: XApkFile, progress: Float) {
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
downloadEntity.meta[XAPK_UNZIP_PERCENT] = String.format("%.2f", progress * 100)
downloadEntity.meta[XAPK_UNZIP_PERCENT] = String.format(Locale.CHINA, "%.2f", progress * 100)
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
AppExecutor.ioExecutor.execute {
@ -181,6 +186,12 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
}
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
SensorsBridge.trackGameDecompressionFailed(
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
}
debugOnly {
@ -267,7 +278,11 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
} else if (sessionInfo.progress <= 0.8F) {
AppExecutor.ioExecutor.execute {
installer.abandonSession(sessionInfo.sessionId)
try {
installer.abandonSession(sessionInfo.sessionId)
} catch (_: Exception) {
// 有概率抛SecurityException这里只要直接catch不做处理即可
}
}
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
}

View File

@ -261,13 +261,6 @@ 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)

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