Compare commits

..

699 Commits

Author SHA1 Message Date
1ce04241f6 tinker base 4.2.0-202 2020-09-09 11:31:50 +08:00
f29b8da6d0 Version code 增至202 2020-09-08 14:28:03 +08:00
de968a4820 调整上报激活数据的时机 2020-09-08 14:26:42 +08:00
ddddda10a5 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-09-07 16:56:33 +08:00
30d6dabe4f 1.处理个人主页闪退问题 2.处理论坛帖子点赞数据同步 2020-09-07 16:56:27 +08:00
7655cc25be 捕抓通知栏闪退 2020-09-07 16:26:37 +08:00
52824e5baa 捕抓帖子详情列表动画异常 2020-09-07 16:11:00 +08:00
014c80cd18 激活信息添加 OAID https://gitlab.ghzs.com/pm/yunying/-/issues/1252 2020-09-07 16:05:56 +08:00
99eddec84a tinker_base 4.2.0-201 2020-09-07 14:12:00 +08:00
6b382ab080 暂时还原游戏库加载逻辑 2020-09-07 11:18:21 +08:00
d492cfdace Version code 升级到 201 2020-09-07 11:08:32 +08:00
256f0af0e9 修复一些闪退问题 2020-09-07 11:05:39 +08:00
58d2290e12 tinker_base 4.2.0-200 2020-09-04 18:27:59 +08:00
547e6da027 临时处理帖子详情状态栏颜色问题 2020-09-04 18:09:29 +08:00
c3e34ba644 应用内拦截光环url补充 m.ghzs666.com 2020-09-04 16:51:23 +08:00
077e17c5aa 捕抓分享异常,调整回答评论字数上限 2020-09-04 14:51:27 +08:00
f264875b7d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-09-04 09:24:28 +08:00
351b8a331c 处理上传视频封面错误问题 2020-09-04 09:24:24 +08:00
479f7c464b 调整游戏详情分享链接 2020-09-03 17:25:48 +08:00
e04a7fc4b9 修复资讯评论闪退问题 2020-09-03 17:19:54 +08:00
595f7747f4 调整帖子详情的评论楼层显示 2020-09-03 16:54:59 +08:00
8c1343fdba 优化帖子详情UI显示 2020-09-03 16:23:19 +08:00
c3717869bd 版规声明跳转至资讯文章详情 2020-09-03 15:34:03 +08:00
1e56dc533d 修改文案 2020-09-03 11:41:30 +08:00
1444531830 视频活动兼容老版本 2020-09-03 11:24:45 +08:00
4e759e446b 处理论坛详情全部列表筛选错误 2020-09-02 18:38:55 +08:00
ef6c09d27b 优化帖子评论的滚动效果 2020-09-02 16:12:46 +08:00
efc241429c 优化 gif 加载尺寸避免频繁内存回收 2020-09-02 15:51:27 +08:00
07be540ba1 补充错误码 2020-09-02 15:49:53 +08:00
50479d2e87 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-09-02 15:35:01 +08:00
2934c9dc38 处理ScrollView会自动滚动到焦点位置问题 2020-09-02 15:34:56 +08:00
30a60797e6 修复专题头图的曝光上报问题 2020-09-02 14:23:43 +08:00
53562297d5 修复启动时重复获取镜像地区配置数据的问题 2020-09-02 14:13:55 +08:00
144ee3ea8c 修改视频评论UI 2020-09-02 09:49:56 +08:00
e0c8697e75 延迟加载游戏库 2020-09-01 18:27:06 +08:00
6aba2906f6 完成论坛测试汇总的17~19 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/989 2020-09-01 17:14:28 +08:00
7bb468a1b1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-09-01 16:22:05 +08:00
871be728bf 光环助手V4.2.0-论坛与视频测试汇总(正式环境)(8-10,12-16) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/989 2020-09-01 16:22:01 +08:00
bbac0c8d93 修复帖子详情骨架图变形的问题 2020-09-01 15:04:40 +08:00
6b361ed077 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-09-01 11:39:29 +08:00
1cfa54f8e8 分片检测下载进度数据增加 host 字段 2020-09-01 11:39:13 +08:00
5bd028cbe9 更新正式环境接口 2020-09-01 09:00:04 +08:00
b8f8711ba4 修复专题列表无筛项时曝光上报缺失数据的问题 2020-08-31 18:43:06 +08:00
c1f899f0d5 去掉视频详情游戏名称的点后缀 2020-08-31 17:32:27 +08:00
e4fd74da7d 修复APP由自动更新切换为手动更新时的进度跳跃问题 2020-08-31 17:31:38 +08:00
bf9cc93daa 补充方法供网页弹起版本不支持弹窗 2020-08-31 16:01:11 +08:00
3b974268a9 修复视频合集游戏标题的显示问题 2020-08-31 11:56:10 +08:00
822853a4be 完成光环助手V4.2.0-数据统计需求(游戏专题) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/984 2020-08-31 11:49:47 +08:00
f699841427 论坛首页双击回到顶部显示发帖子图标 2020-08-31 10:59:59 +08:00
c700910b15 调整首页卡片分割线高度 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/820 2020-08-31 10:31:57 +08:00
3c8d0cb3ec 补充礼仪考试弹窗MTA统计 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/945 2020-08-31 10:26:16 +08:00
8492c762b5 Merge remote-tracking branch 'origin/dev' into dev 2020-08-31 09:40:46 +08:00
b2d70392bb 补充进入游戏详情触发自动下载游戏的参数 2020-08-31 09:40:30 +08:00
eb9cb08624 更换启动引导图 2020-08-31 09:16:07 +08:00
a4ca2628dc 增加分片检测下载进度数据 https://gitlab.ghzs.com/stats/stats-issues/-/issues/188#note_66919 2020-08-28 18:44:21 +08:00
727d78d0e5 去掉获取地理位置权限 2020-08-28 17:14:44 +08:00
693d8c4385 Merge remote-tracking branch 'origin/dev' into dev 2020-08-27 23:48:38 +08:00
d46e3fac2d 补充跳转首页论坛的urlScheme 2020-08-27 23:48:30 +08:00
7f0ec7f128 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-27 23:24:38 +08:00
73eb2f6ecb 修改视频上传标签UI 2020-08-27 23:24:34 +08:00
6bd7ced28c 修复帖子详情UI测试0827PM https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-27 23:15:38 +08:00
086c31a7d4 修复礼包页面重复跳转会复用第一个页面数据的问题 2020-08-27 23:09:00 +08:00
3a839f6770 修改系统消息点赞文案 2020-08-27 23:05:28 +08:00
b67c7e2803 修改论坛首页引导UI间距 2020-08-27 22:58:43 +08:00
b7dbf30845 修改论坛详情UI 2020-08-27 22:49:19 +08:00
lyr
ec86970cbe 登录界面顶部栏适配小米型号手机 2020-08-27 21:41:11 +08:00
956755b985 Merge remote-tracking branch 'origin/dev' into dev 2020-08-27 20:47:36 +08:00
fe2779196d 修复详情页点击tab偶尔失效的问题 2020-08-27 20:47:29 +08:00
9eeeba93d0 Merge branches 'dev' and 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-27 20:46:03 +08:00
d7df019d6d 调整论坛帖子底部按钮 2020-08-27 20:45:58 +08:00
lyr
68bfc26ddc 如果当前登录方式为手机号,在更换绑定手机号后,同步更新登录方式的值为已更换的手机号 2020-08-27 20:33:20 +08:00
94a1cfe4b2 修复帖子点赞通知的跳转问题 2020-08-27 20:13:13 +08:00
936c3b00bb 修改论坛UI问题 2020-08-27 20:04:49 +08:00
b34229e4c4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-27 19:53:11 +08:00
b51322b473 视频上传交互优化(第二期)(5,6) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/969 2020-08-27 19:53:04 +08:00
e0657ccdcc 优化帖子详情请求出错时的显示 2020-08-27 19:49:21 +08:00
4b67d8b5aa 微调帖子详情页UI 2020-08-27 17:50:46 +08:00
5b8cc49349 完成更新强退时清空下载通知的功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-27 16:58:01 +08:00
612f71e18c 原始回复显示作者标签 2020-08-27 16:55:37 +08:00
6239ccb8ab 删除多余代码 2020-08-27 16:47:12 +08:00
9680bea412 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-27 16:40:13 +08:00
a21d9096c8 处理论坛点赞错误问题 2020-08-27 16:40:09 +08:00
e6f3ad5cc2 视频上传交互优化(第二期)20200827ui反馈 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/969 2020-08-27 16:39:35 +08:00
c41e996add 修复更新进度跳跃问题 2020-08-27 16:32:29 +08:00
58f230038c 完成更新强退时清空下载通知的功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-27 16:27:05 +08:00
bda41d8a26 修复更新推送0827测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-27 15:49:44 +08:00
e3f41543a4 完成帖子详情测试内容 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-27 15:09:45 +08:00
lyr
78c4d7acef 1.修改"注册方式"判断逻辑;2.优化"账号与安全"模块UI 2020-08-27 14:51:41 +08:00
8c884b6d23 修复礼仪考试20200826测试问题2 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/945 2020-08-27 14:33:32 +08:00
a5f9af2df2 适配活动视频流接口 2020-08-27 14:30:33 +08:00
e2fd6dbf97 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-27 14:08:46 +08:00
e430b4e2de 视频上传交互优化(第二期)20200827测试(3) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/969 2020-08-27 14:08:42 +08:00
caa3f46c5c 初始下载不填加 range 请求头 2020-08-27 11:00:50 +08:00
b2beba4d36 论坛详情UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-27 10:52:51 +08:00
3a9c7fc71d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-27 08:38:41 +08:00
a5f8275f64 修改论坛帖子列表底部按钮错位问题 2020-08-27 08:38:36 +08:00
8fa3f3d832 调整更新推送逻辑 2020-08-26 19:52:38 +08:00
97472b8259 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-26 18:53:04 +08:00
ee07889b30 光环助手V4.2.0-引导设置“通知管理”(第3期)20200825UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/947 2020-08-26 18:52:59 +08:00
8582860116 光环助手V4.2.0-视频详情优化(第二期)20200825UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/970 2020-08-26 18:52:30 +08:00
b8903e7814 完成更新优化0826测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-26 18:10:43 +08:00
b47bcfc2c3 Merge branches 'dev' and 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-26 17:56:55 +08:00
35a987a835 完成光环助手V4.2.0-问答首页优化UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/955 2020-08-26 17:56:49 +08:00
lyr
6f413b27d4 优化"账户与安全"模块代码 2020-08-26 16:09:53 +08:00
92173b4794 游戏详情优化汇总(9) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/975 2020-08-26 15:46:51 +08:00
89e79154aa Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-26 15:21:16 +08:00
de9145cd70 视频上传交互优化(第二期)(1-4,9)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/969 2020-08-26 15:21:08 +08:00
8bf509ee2d 完成游戏类型优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/960 2020-08-26 15:00:42 +08:00
d7144265e1 完成更新推送功能优化0826补充及UI调整 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-26 14:30:28 +08:00
cc6c759658 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-25 18:34:32 +08:00
8e5d482f9e 修改通知弹窗不显示问题 2020-08-25 18:34:26 +08:00
5ed8f2499a 完成活动分享数据即时反馈需求 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/982 2020-08-25 18:29:39 +08:00
a8c9bcc1b0 完成礼仪考试功能20200825测试的3 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/945 2020-08-25 18:10:17 +08:00
21aabcc561 完成更新推送优化20200825的1 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-25 18:02:52 +08:00
a2b86a9e21 Merge remote-tracking branch 'origin/dev' into dev 2020-08-25 17:47:29 +08:00
74882f56ee 完成帖子详情20200825测试的(2, 4~10) 2020-08-25 17:47:19 +08:00
1eb9ec1dd3 光环助手V4.2.0-论坛详情功能20200825测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-25 17:44:49 +08:00
9e95c0cc7e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-25 17:00:34 +08:00
877238d2d5 光环助手V4.2.0-引导设置“通知管理”(第3期)20200825测试2 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/947 2020-08-25 17:00:30 +08:00
lyr
9c6f69b16a 修改绑定手机无法完成问题 2020-08-25 16:53:14 +08:00
64af456182 补充网页JS调用方法 2020-08-25 16:48:32 +08:00
1a84477700 修改视频评论作者标记显示问题 2020-08-25 16:20:29 +08:00
a0b6285596 修改文章标签详情列表不显示 2020-08-25 15:15:29 +08:00
951c139062 修改我的论坛我的帖子列表不显示 2020-08-25 14:23:00 +08:00
99efcd6bbf 光环助手V4.2.0-论坛详情功能20200824测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-25 11:53:24 +08:00
3482f58b1b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt
#	app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt
2020-08-25 10:07:45 +08:00
6b4f751a16 光环助手V4.2.0-论坛详情功能(1,7,10) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-25 10:03:26 +08:00
3be1308230 Merge remote-tracking branch 'origin/dev' into dev 2020-08-24 18:27:53 +08:00
b7710cffa3 微调帖子详情样式 2020-08-24 18:27:44 +08:00
lyr
dc4fe89521 账户与安全页底部增加联系客服文案和相应跳转 2020-08-24 18:20:47 +08:00
c33eb6829a 完成游戏详情优化(7,8) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/975 2020-08-24 17:59:21 +08:00
e1793d57eb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-24 17:28:30 +08:00
cc4c48f718 修改取消论坛后论坛首页数据刷新问题 2020-08-24 17:28:25 +08:00
aa20ed9744 完成自定义栏目的镜像优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/963 2020-08-24 16:44:48 +08:00
b6d8688a40 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-24 16:32:58 +08:00
d1da2bb7fa 光环助手V4.2.0-问答首页优化20200824测试(2,5,6,7) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/955 2020-08-24 16:32:53 +08:00
lyr
7828bce732 新增上传抖音方式登录日志 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/951 2020-08-24 15:38:00 +08:00
026a8d7093 Merge branch 'feature-change-gdt-key' into 'dev'
更换广点通ID https://gitlab.ghzs.com/pm/yunying/-/issues/1249

See merge request halo/assistant-android!24
2020-08-24 14:15:57 +08:00
6a9a29c5ff 更换广点通ID https://gitlab.ghzs.com/pm/yunying/-/issues/1249 2020-08-24 14:14:33 +08:00
lyr
16b4b6cc81 修复专题排行榜滑动卡顿问题 2020-08-24 12:00:20 +08:00
863e570b61 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-24 11:53:47 +08:00
c9e8408804 修改视频评论作者标记显示错误 2020-08-24 11:53:42 +08:00
31984f1737 基本完成论坛帖子详情功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-24 11:31:53 +08:00
ad2a0debdd 论坛列表数据同步 2020-08-24 09:56:30 +08:00
4c45657092 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-22 09:57:19 +08:00
5d7fc94d51 优化论坛首页 2020-08-22 09:57:14 +08:00
641b430fe5 优化帖子详情结构 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-21 18:46:37 +08:00
lyr
e1bb02f4e0 绑定手机号点击"跳过"增加弹窗提示 2020-08-21 18:24:33 +08:00
36fd8cf408 双击论坛tab回到顶部 2020-08-21 15:04:42 +08:00
e48b47b315 处理个人主页论坛列表不显示问题 2020-08-21 14:17:09 +08:00
46935e4cad 补充网页游戏详情用的跳转规则 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/966 2020-08-21 11:45:14 +08:00
b8a6b4baea 处理游戏详情的闪退 2020-08-21 11:42:36 +08:00
8a8f0a95ed 光环助手V4.2.0-视频详情优化(第二期)20200820测试(4,6) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/970 2020-08-21 10:32:52 +08:00
cdbefd2d4f 完成部分帖子详情的功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-20 21:01:40 +08:00
7e79b4e328 基本完成礼仪考试APP端功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/945 2020-08-20 19:53:10 +08:00
11dc9f9be0 游戏详情增加论坛Tab 2020-08-20 18:01:27 +08:00
ec255099eb 光环助手V4.2.0-论坛详情功能(9) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-20 16:21:49 +08:00
64738dceaf 光环助手V4.2.0-论坛详情功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-20 15:40:08 +08:00
7d518696f0 Merge branch 'dev_4.2.0' into dev
# Conflicts:
#	app/src/main/java/com/gh/common/util/EntranceUtils.java
2020-08-20 10:56:44 +08:00
fcd97b66df 光环助手V4.2.0-论坛详情功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/956 2020-08-20 10:53:26 +08:00
47f5c3b7c1 缩小保存测试路径的长按区域 2020-08-20 10:33:50 +08:00
b64fee9d25 Merge branch 'dev_4.2.0' into 'dev'
Dev 4.2.0

See merge request halo/assistant-android!23
2020-08-20 09:08:19 +08:00
498efdf5ea Merge branch 'dev' into 'dev_4.2.0'
# Conflicts:
#   dependencies.gradle
2020-08-20 09:08:12 +08:00
59d6450ded 更改论坛帖子详情的实现方式 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-19 18:41:47 +08:00
7da206af7e 压缩部分原图过大的图片 2020-08-19 18:38:56 +08:00
8bd669e11a 正式环境维持 v4d1 接口 2020-08-19 17:49:12 +08:00
62570aed9e Merge remote-tracking branch 'origin/dev_lyr' into dev_4.2.0
# Conflicts:
#	app/src/main/java/com/gh/common/constant/Constants.java
#	dependencies.gradle
2020-08-19 17:45:17 +08:00
lyr
bfe9c04384 修改登录界面关闭按钮高度 2020-08-19 17:38:15 +08:00
lyr
b27d007d47 1.完成光环助手V4.2.0-优化登录功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/949;2.完成光环助手V4.2.0-新增账户安全功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/948#note_63972 2020-08-19 16:38:04 +08:00
7e50e6570d 光环助手V4.2.0-问答首页优化(15) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/955 2020-08-19 11:32:22 +08:00
336d449889 全局搜索将'文章'替换为'帖子' 2020-08-18 17:46:13 +08:00
3dfea1e6f9 Merge branch 'dev_4.2.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.2.0 2020-08-18 17:11:15 +08:00
3c1780d9b5 视频上传交互优化UI 2020-08-18 17:11:10 +08:00
35ee7cf03d 光环助手V4.2.0-论坛其他优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/968 2020-08-18 17:05:56 +08:00
lyr
72e8c18f9c 1.完成登录界面UI改版;2.增加第三方抖音登录;3.增加账号安全模块 2020-08-18 15:57:02 +08:00
f3f876d213 完成礼仪考试功能的APP UI https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/945 2020-08-18 14:37:45 +08:00
398907db90 完成游戏详情优化汇总(2~5) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/975 2020-08-18 10:18:25 +08:00
5dd251eaa8 完成游戏专题功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/965 2020-08-17 20:47:29 +08:00
2c73e55f43 调整通用列表的显示元素 2020-08-17 17:31:11 +08:00
f4406d7960 调整帖子评论布局 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-17 17:22:10 +08:00
3e0a620ac5 更改帖子详情的实现方式 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-14 18:38:57 +08:00
9ea8c32608 论坛首页优化 2020-08-14 17:51:15 +08:00
e2ea197f9e 光环助手V4.2.0-问答首页优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/955 2020-08-14 17:14:30 +08:00
f92038b5bf 光环助手V4.2.0-视频详情优化(第二期)(9,10) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/970 2020-08-13 18:00:58 +08:00
fa9eee2c4a 修改删除视频评论列表刷新错误 2020-08-13 16:52:58 +08:00
3e62fb61e1 Merge branch 'dev_4.2.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.2.0 2020-08-13 16:22:07 +08:00
5d71e0ccc1 光环助手V4.2.0-视频详情优化(第二期)(1-8) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/970 2020-08-13 16:22:02 +08:00
4699923058 清理测试内容 2020-08-13 16:03:55 +08:00
9206938938 更新版本号 2020-08-13 16:00:50 +08:00
46ac569f70 优化静默更新下载逻辑 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-13 15:43:41 +08:00
b90d1b4f38 处理编译问题 2020-08-13 11:47:10 +08:00
592b7bbc5e 更新 gid 依赖 2020-08-13 11:31:11 +08:00
3ccb8b3772 基本完成更新推送功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-12 22:02:54 +08:00
422abe1b87 基本完成更新推送功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/946 2020-08-12 21:57:46 +08:00
a14f35a4f0 完成启动跳转方法预留 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/966 2020-08-12 17:36:53 +08:00
3bebc92106 恢复误删的包引入 2020-08-12 16:19:24 +08:00
21413cf250 新增跳转 urlScheme https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/966 2020-08-12 15:33:31 +08:00
04a34af370 光环助手V4.2.0-引导设置“通知管理”(第3期)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/947 2020-08-12 10:25:28 +08:00
e1e6924b6e tinker_base 4.1.0-191 2020-08-11 18:30:29 +08:00
fbd3a42e81 完成粗糙的帖子详情框架,细节待补充 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/967 2020-08-11 18:25:43 +08:00
80a2cbb8cd versionCode 改为191 2020-08-11 18:09:08 +08:00
96fc6cc183 论坛首页蒙层引导 2020-08-11 16:22:52 +08:00
b5ff891db1 修复动态页跳转礼包详情的游戏图标显示问题 2020-08-11 16:03:22 +08:00
d2171e7a3b 更换首页论坛tab图标和点击动画 2020-08-11 15:27:50 +08:00
c3a06f57b1 文章标签详情优化 2020-08-11 11:39:15 +08:00
18f41743bf Merge branch 'dev_4.2.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.2.0 2020-08-11 10:50:20 +08:00
fcc647a1f8 修改发帖子、提问页面 2020-08-11 10:50:15 +08:00
e80b198aa5 添加简单的页面快速跳转功能 2020-08-11 10:38:14 +08:00
52efa96e2c 修复游戏图标的列表复用问题 2020-08-11 10:10:56 +08:00
816dd60298 修复游戏图标角标的复用问题 2020-08-10 18:20:11 +08:00
a181292f80 修复游戏图标角标的复用问题 2020-08-10 18:09:55 +08:00
1b946c325c 光环助手V4.2.0-视频详情优化(第二期)8 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/970 2020-08-10 17:33:59 +08:00
befb323721 测试环境api版本升至v4d2d0 2020-08-10 17:33:20 +08:00
e62c0aaaad 论坛详情、板块成员UI 2020-08-10 17:08:36 +08:00
4ecc0c073b 补充GID获取异常的MTA统计 2020-08-10 11:36:47 +08:00
faa41248eb 修改获取Toast默认偏移量和位置闪退 2020-08-10 10:11:55 +08:00
6dca13e80b 论坛详情UI 2020-08-10 09:43:35 +08:00
f3fab1b3f6 tinker-base_4.1.0 2020-08-07 19:21:13 +08:00
5340a41298 fix bug 2020-08-07 14:24:31 +08:00
553ebc137b 选择论坛UI 2020-08-06 18:00:03 +08:00
caf2a379d9 修复xapk解压后安装包路径没有写入数据库的问题 2020-08-06 16:55:51 +08:00
c59b79427c 修复xapk解压后安装包路径没有写入数据库的问题 2020-08-06 16:42:32 +08:00
dd2338021e 论坛首页UI 2020-08-06 15:14:05 +08:00
e54fcca53e xapk解压失败增加MTA统计 2020-08-06 14:55:40 +08:00
ad416c6a5d xapk解压增加备用解决方案 2020-08-06 14:07:06 +08:00
4a65c1a5c8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-05 15:53:00 +08:00
878529f646 fix 2020-08-05 15:52:47 +08:00
d01bc1e2d1 移除无用的ijkplayer依赖 2020-08-04 15:59:34 +08:00
d63f5f5ab2 调整广点通激活数据的发送时机 2020-08-04 10:01:00 +08:00
ad0fb7a55a 处理游戏图标类型不一致导致的闪退问题 2020-08-03 16:25:57 +08:00
b0258eef77 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-08-03 16:06:33 +08:00
86d4df8ad9 修复新增开服默认选择时间分钟不准问题 2020-08-03 16:06:20 +08:00
bb11d984f9 处理消息中心闪退问题 2020-08-03 14:56:34 +08:00
d3f3d2ca98 下载详细过程埋点更新 https://gitlab.ghzs.com/stats/stats-issues/-/issues/188 2020-07-31 18:19:52 +08:00
0c1e712c79 编辑封面禁止左右滑动(与图片缩放会有冲突)
修复xapk提示存储不足后没有把当前解压线程移除问题
2020-07-31 15:21:33 +08:00
e193a40651 修改预约弹窗号码提示动画的持续时间 2020-07-31 14:47:42 +08:00
03f36476cb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-31 11:45:13 +08:00
a721637be3 预约弹窗增加号码提示弹出动画 2020-07-31 11:44:58 +08:00
722fb1ad64 调整视频数据UI间隔 2020-07-31 10:32:01 +08:00
52a05c3aa4 这是环境api版本改为v4d1d0 2020-07-31 10:31:30 +08:00
bcbdac6afc Merge remote-tracking branch 'origin/dev' into dev 2020-07-30 22:29:09 +08:00
a9507af3f4 修复镜像游戏的角标问题 2020-07-30 22:29:01 +08:00
68601ca8be 修改预约弹窗点击弹窗以外区域弹窗没有消失问题 2020-07-30 22:17:00 +08:00
a7adc27896 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-30 21:23:44 +08:00
d19d0eb571 修改预约弹窗的弹出位置 2020-07-30 21:23:30 +08:00
d8e365fe08 修改游戏评论显示异常 2020-07-30 21:12:17 +08:00
b34f61ce0d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-30 18:10:05 +08:00
1f24d16f95 h5游戏增加关闭按钮开关控制 2020-07-30 18:10:00 +08:00
738074ec00 光环助手V4.1.0-游戏评论功能强化20200730测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/925 2020-07-30 18:09:07 +08:00
c8eee33475 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-30 17:13:25 +08:00
badf9f9c20 修改编辑封面UI
防止手机登录连续点击获取验证码重复发送问题
2020-07-30 17:13:19 +08:00
0398cc4ffc 修改视频数据总览 2020-07-30 15:59:55 +08:00
b88abf6b9a link为空拦截跳转 2020-07-30 15:37:35 +08:00
a0d193bc52 web跳转视频流添加gameId参数 2020-07-30 15:24:33 +08:00
6ac635f8c6 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-30 14:38:11 +08:00
30c7d71114 外部跳转增加qq群 2020-07-30 14:38:05 +08:00
0223b3ab22 修复查看图片的bug(0730测试) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-30 11:57:48 +08:00
c9663662d5 补充遗漏的游戏图标显示优化页面 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/939 2020-07-30 11:41:17 +08:00
12bed97638 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-30 11:11:25 +08:00
a857af970d 修复游戏评分一直显示加载中问题 2020-07-30 11:11:20 +08:00
7da621583f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-30 11:08:38 +08:00
46a32b62c2 光环前端优化汇总(2020年7月第3周)20200729测试问题补充5 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-30 11:08:33 +08:00
45bcc95e7d 游戏详情玩家评论数据同步 2020-07-30 11:07:44 +08:00
7d7bcfaa1d 补充遗漏的游戏图标显示优化页面 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/939 2020-07-30 10:45:23 +08:00
3a9a561c77 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2020-07-30 10:08:03 +08:00
e8d344256a 光环助手V4.1.0-视频上传支持剪辑封面(20200729测试) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/941 2020-07-30 10:07:34 +08:00
1a7c1119bf 微调UI 2020-07-29 17:44:24 +08:00
0b6a2503aa Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-29 17:32:01 +08:00
459b9f65a9 修改封面尝试修复截帧失败问题 2020-07-29 17:31:49 +08:00
6c1ebe531e 更改游戏图标圆角逻辑 2020-07-29 16:47:53 +08:00
604450292b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-29 15:53:31 +08:00
e42361e84a 1.H5游戏跳转到指趣 2.修改web跳转到视频流闪退 2020-07-29 15:53:24 +08:00
a974652f7f 处理自动打包编译时间不对的问题 2020-07-29 14:40:51 +08:00
309ab54e90 微调UI 2020-07-29 14:40:07 +08:00
486d680c26 补充游戏图标显示优化的页面 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/939 2020-07-29 14:30:22 +08:00
61a5f3a275 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-29 14:22:08 +08:00
c865417a4b 光环助手V4.1.0-游戏评论功能强化20200729测试问题:4,6,7 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/925 2020-07-29 14:22:03 +08:00
b142feaaae 微调下载管理-游戏下载UI 2020-07-29 14:19:15 +08:00
7380854133 微调UI 2020-07-29 11:29:23 +08:00
8a0f185eda 修改视频上传UI 2020-07-29 10:59:17 +08:00
bd9604a53e 微调UI 2020-07-29 10:13:44 +08:00
1aeab51f94 修复上传视频后视频投稿页面无法及时刷新问题 2020-07-29 09:56:54 +08:00
b16a6fedc6 修改列表分页结束数量限制 2020-07-28 17:54:26 +08:00
b97c381ed4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-28 17:43:04 +08:00
acb8c723a3 微调UI 2020-07-28 17:42:51 +08:00
4492307e23 处理刷新列表MarkerView会显示问题 2020-07-28 17:42:29 +08:00
e31224b332 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-28 17:13:22 +08:00
6933d6c590 修复预约弹窗键盘弹出延迟问题 2020-07-28 17:13:09 +08:00
3d58841ce5 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-28 16:59:45 +08:00
0654b0a25f 更改评论弹窗动画实现方式 2020-07-28 16:59:41 +08:00
44dde3f91b Merge branch 'video_poster' 2020-07-28 16:27:56 +08:00
abad30595f 光环助手V4.1.0-视频上传支持剪辑封面 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/941 2020-07-28 15:14:51 +08:00
c4df411560 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-28 11:36:14 +08:00
2974fa4562 修改视频数据图表自定义MarkerView 2020-07-28 11:36:10 +08:00
b086b1cb0c 完成接入腾讯企点会话接待组件(0727测试4) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/928 2020-07-28 11:24:12 +08:00
22cf026335 删除无用注释 2020-07-28 11:03:48 +08:00
90bd53fe61 修复选择游戏弹窗的闪退问题 2020-07-28 11:03:16 +08:00
9c580a356e 腾讯企点唤起改成应用内 2020-07-28 10:30:05 +08:00
7198c28e6f 补充遗漏的游戏图标角标位置 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/939 2020-07-28 10:29:33 +08:00
7bf074fddc 光环助手4.1.0-前端新增视频数据统计20200727测试1,4 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/936 2020-07-28 09:59:46 +08:00
bea1a336e9 视频编辑封面支持线上视频链接截取 2020-07-27 21:10:11 +08:00
97a9e03192 光环助手V4.1.0-视频上传支持剪辑封面(初步完成,后续细节尚需调整) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/941 2020-07-27 18:05:42 +08:00
244d57b6bc 更改判断应用前后台状态的实现逻辑 2020-07-27 17:44:57 +08:00
3cbd484147 更改判断应用前后台状态的实现逻辑 2020-07-27 17:43:56 +08:00
8b81819c30 修改大图触发下拉消失的滑动阈值为大于60度 2020-07-27 16:31:53 +08:00
1873ac5d4e 光环前端优化汇总(2020年7月第3周)0727测试12 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-27 16:29:06 +08:00
cf70c1e7fe 光环助手4.1.0-前端新增视频数据统计20200727UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/936 2020-07-27 15:49:05 +08:00
6f6b26ea4d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-27 15:19:09 +08:00
e2708d9078 对接专区视频流接口 2020-07-27 15:19:05 +08:00
fb5a40c6e4 修复游戏图标的占位图显示问题 2020-07-27 12:03:03 +08:00
e2a10c1410 游戏评论显示折叠评论按钮 2020-07-27 12:01:08 +08:00
5461d3d548 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-27 11:45:26 +08:00
c47365e626 光环助手V4.1.0-游戏评论功能强化 20200725测试问题2,20200727UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/925 2020-07-27 11:45:22 +08:00
3476f8df3a 修复一些闪退问题 2020-07-27 11:14:48 +08:00
f812c1e5c8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-27 09:24:51 +08:00
391f196005 修改游戏大事件时间转换错误 2020-07-27 09:24:46 +08:00
097dbca26e 修复客服消息列表页复制ID按钮不显示的问题 2020-07-24 18:34:29 +08:00
a147118381 完成游戏图标显示优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/939 2020-07-24 16:31:58 +08:00
e6bdde8273 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-24 15:27:27 +08:00
747757faa7 处理视频数据图标显示问题 2020-07-24 15:27:21 +08:00
6f21b9d0ae 腾讯企点改由内部 webview 跳转 2020-07-24 14:47:20 +08:00
e505554aac 修改视频数据图表配置 2020-07-24 11:18:18 +08:00
3323cce890 删除本地导入的videocache 2020-07-24 09:41:22 +08:00
ffd468db1e 格式化视频数据 2020-07-23 18:29:52 +08:00
e98e0d1522 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-23 17:12:07 +08:00
13a4f2014c 光环助手4.1.0-前端新增视频数据统计 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/936 2020-07-23 17:12:01 +08:00
8cbfe6450a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-23 11:44:09 +08:00
bcc866888e 删除无用代码 2020-07-23 11:44:02 +08:00
60911d5dcb 移除无用的 glide 依赖 2020-07-23 11:15:35 +08:00
7e77d5749e 处理编译问题 2020-07-23 10:36:06 +08:00
6c3be5627d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-23 10:02:41 +08:00
f6a9585700 彻底移除用数据库存储登录信息的代码 2020-07-23 10:02:30 +08:00
06fddb7dcd 完成游戏管理apk包提供海外下载地址 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/930 2020-07-22 18:21:01 +08:00
3a3f9a625b 删除部分测试代码 2020-07-22 17:49:54 +08:00
3702b104fc 光环助手V4.1.0-安装游戏支持解压xapk文件(20200722测试) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/896 2020-07-22 17:39:46 +08:00
3e023089a1 Merge remote-tracking branch 'origin/dev' into dev 2020-07-22 16:24:37 +08:00
7455674f6b 完成7月第3周优化(3,11,14) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-22 16:24:26 +08:00
c93c0f2fc6 修改列表分页结束数量限制 2020-07-22 16:23:56 +08:00
727f02e571 光环助手V4.1.0-预约游戏自动填写手机号(20200722测试) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/926 2020-07-22 15:15:25 +08:00
784fae1f5d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-22 14:54:56 +08:00
42ef075912 光环助手V4.1.0-游戏名称点号处理(20200722补充) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/921
修改dev api host
2020-07-22 14:54:44 +08:00
15307c5223 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-22 14:18:38 +08:00
aad3b48883 光环助手V4.1.0-视频详情功能优化20200722测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/935 2020-07-22 14:18:31 +08:00
d65d8f1c4c 删除多余刷新动画图片 2020-07-22 11:46:02 +08:00
c581496975 Merge branch 'refresh' into dev 2020-07-22 11:41:41 +08:00
d5481a8888 修改问答-推荐的下拉刷新动画 2020-07-22 11:24:08 +08:00
e0a61278fc fix import 2020-07-22 10:25:57 +08:00
2c36283833 Merge branch 'dev_4.1.0' into 'dev'
Dev 4.1.0

See merge request halo/assistant-android!21
2020-07-22 10:17:38 +08:00
1b5a8f3a7e Merge branch 'dev' into 'dev_4.1.0'
# Conflicts:
#   app/src/main/java/com/gh/common/DefaultUrlHandler.kt
#   app/src/main/java/com/gh/common/util/ShareUtils.java
#   dependencies.gradle
2020-07-22 10:17:19 +08:00
95c918b4e3 光环助手V4.1.0-游戏大事件功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/938 2020-07-22 09:47:57 +08:00
f32cc1673c 调整查看大图过渡动画 2020-07-21 18:32:32 +08:00
f0fc2f06da Merge branch 'dev_4.1.0' of gitlab.ghzhushou.com:halo/assistant-android into dev_4.1.0 2020-07-21 18:23:58 +08:00
b6c6abaa5b 调整大图动画 2020-07-21 18:23:33 +08:00
6ed67c911c Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-21 18:14:44 +08:00
1eda223a1e 光环助手V4.1.0-预约游戏自动填写手机号 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/926 2020-07-21 18:14:27 +08:00
316c0c28ab 扩大安利墙列表的部分点击区域 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-21 17:27:18 +08:00
895d4d5cf1 tinker_base 4.0.3 2020-07-21 17:18:49 +08:00
877df95e02 添加安利墙列表的部分点击区域 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-21 17:15:57 +08:00
801f0b95e7 版本改为4.0.3 2020-07-21 17:01:07 +08:00
9019f555b5 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-21 16:52:00 +08:00
106b03a316 下载文件格式兼容xapk 2020-07-21 16:51:44 +08:00
d8faa554be 优化查看图片交互 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-21 16:44:59 +08:00
93080a74a7 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-21 15:54:08 +08:00
3ea2ede0cb 视频上传增加视频宽高字段 2020-07-21 15:53:59 +08:00
1242848b6f Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-21 15:35:50 +08:00
24d44a2c90 光环助手V4.1.0-游戏评论功能强化MTA数据统计 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/925 2020-07-21 15:35:45 +08:00
971779a529 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-21 15:28:59 +08:00
14f561c237 扩大下载管理删除按钮的点击范围 2020-07-21 15:28:38 +08:00
3a38e746f6 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-21 14:38:05 +08:00
dd3bc9d39d 光环助手V4.1.0-游戏评论功能强化1-5,6(1) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/925 2020-07-21 14:38:01 +08:00
39a8062aef 光环后台功能迁移测试汇总0717测试-1 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/923 2020-07-21 14:35:52 +08:00
55b6ccb760 merge xapk branch 2020-07-21 14:35:01 +08:00
a8a55eb9bd 修复首页游戏隐藏评论后还能显示评分问题 2020-07-21 14:30:15 +08:00
3eb73439aa 修改页面loading动画 2020-07-21 11:30:29 +08:00
466e118579 尝试替换SwipeRefreshLayout的下拉动画 2020-07-20 17:58:51 +08:00
b38032074b 按帧导入下拉刷新动画,SwipeRefreshLayout以源码的方式引入到主工程 2020-07-20 17:54:56 +08:00
9ee771e528 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-20 17:04:11 +08:00
9253ed47e6 微信浏览器跳转到app 2020-07-20 17:04:03 +08:00
bc82263286 更改获取 bitmap 的实现 2020-07-20 16:41:46 +08:00
11979240ab Merge branch 'dev_4.0.1_bugfix' into dev
# Conflicts:
#	app/src/main/java/com/gh/common/DefaultUrlHandler.kt
#	dependencies.gradle
#	gradle.properties
2020-07-20 15:57:50 +08:00
255e6182a9 更改评论弹窗点击更多按钮交互方式 2020-07-20 15:41:39 +08:00
f170abb7ea 修复分享内容含 gif 图片时会分享失败的问题 2020-07-20 11:00:44 +08:00
eb80deb413 升级应用版本号为 4.1.0, 正式环境接口退回 4.0.2 (正式环境 4.1.0 API 暂未开启) 2020-07-20 10:58:15 +08:00
10ba5a9ba5 修改注释 2020-07-17 17:15:23 +08:00
94c49cba8b 修复裁剪控件图片过大显示异常问题 2020-07-17 17:13:54 +08:00
354dca8b04 非视频作者也可以删除自己的评论 2020-07-17 16:56:51 +08:00
034488ff34 非视频作者也可以删除自己的评论 2020-07-17 16:53:30 +08:00
59c70e23dd 光环前端优化汇总(2020年7月第3周)(5, 8, 12) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-17 16:04:45 +08:00
7d98a842f1 完成接入腾讯企点会话接待组件 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/928 2020-07-17 14:37:15 +08:00
5f8006dc5a Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-17 11:24:10 +08:00
239bd69580 update LGLibrary version 2020-07-17 11:24:07 +08:00
bc96f102a1 光环前端优化汇总(2020年7月第3周)(2,4,6,7)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/940 2020-07-17 11:19:13 +08:00
e2ef3f4d01 尝试解决登录失效后,无法打开登录界面问题 2020-07-17 10:47:07 +08:00
5c20bbf5e4 光环助手V4.1.0-视频详情功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/935 2020-07-16 18:09:54 +08:00
b07edd256a 增加登录异常MTA事件 2020-07-16 17:15:34 +08:00
1478d37889 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0
# Conflicts:
#	app/src/main/res/values/colors.xml
2020-07-16 16:40:24 +08:00
7151b56de3 光环助手V4.1.0-预约游戏自动填写手机号 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/926 2020-07-16 16:37:55 +08:00
220fd9528b 去掉部分页面游戏图标右上角的礼包角标 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/939 2020-07-16 14:43:10 +08:00
1c26c35571 完成首页轮播图数据调整 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/933 2020-07-16 11:03:35 +08:00
78eb6b7b02 Merge branch 'dev_4.1.0' of gitlab.ghzs.com:halo/assistant-android into dev_4.1.0 2020-07-16 09:11:10 +08:00
9dc9add896 折叠评论UI 2020-07-16 09:11:05 +08:00
2d09f8c008 游戏专区外部跳转 2020-07-16 09:07:14 +08:00
166e1e77ec 完成首页弹窗数据统计 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/881 2020-07-15 18:32:07 +08:00
ea782d002b 光环助手V4.1.0-资讯文章配置的超链接跳转逻辑优化2(1,2,3) 3 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/927 2020-07-15 17:27:10 +08:00
f525a3c46d 接口版本改为v4d1d0 2020-07-15 17:23:22 +08:00
bef6cbb212 tinker_base 4.0.2-183 2020-07-15 17:00:17 +08:00
5e0af8654a 完成新首页轮播图数据上报调整 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/933 2020-07-15 16:56:04 +08:00
032a89e0cd versionCode 改为183 2020-07-15 16:48:28 +08:00
c9afb6df02 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-15 16:30:50 +08:00
b8092447ff 游戏列表默认不显示评分 2020-07-15 16:30:43 +08:00
bff20bea49 修复 7.1.1 系统上 toast 可能出现的闪退问题 2020-07-15 16:29:34 +08:00
87f2d9c85f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2020-07-15 15:04:43 +08:00
154dfc8538 DsBridge原生Api支持无参方法 2020-07-15 15:03:56 +08:00
59c4176983 尝试根据视频帧数获取视频截图 2020-07-15 14:40:10 +08:00
fddcdfb3aa 更改今日头条SDK的初始化位置 2020-07-15 09:41:29 +08:00
cdbf7d39a5 光环助手V4.1.0-资讯文章配置的超链接跳转逻辑优化(1) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/927 2020-07-14 17:56:18 +08:00
6a55821d4d 完成一些todo 2020-07-14 10:16:45 +08:00
a305db7b13 tinker_base 4.0.2-182 2020-07-13 17:14:15 +08:00
58b1cd4b12 versionCode 改为182 2020-07-13 16:45:19 +08:00
5e7559e43f 修复一些闪退问题 2020-07-13 16:42:03 +08:00
2a74e35388 修复 7.1.1 系统上 toast 可能出现的闪退问题 2020-07-13 16:41:22 +08:00
5b9bef79da 修复一些闪退问题 2020-07-13 16:01:11 +08:00
e89750c364 光环助手V4.1.0-游戏名称点号处理 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/921 2020-07-13 15:38:06 +08:00
9da6cbf097 修复 7.1.1 系统上 toast 可能出现的闪退问题 2020-07-13 15:23:08 +08:00
f83f719283 光环助手V4.1.0-安装游戏支持解压xapk文件(20200710补充) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/896 2020-07-13 11:16:31 +08:00
4a1c81ffb4 预留方法供网页端确定是否已安装某应用 2020-07-13 09:49:51 +08:00
be26f5168b 增加视频上传urlscheme参数 2020-07-11 21:03:55 +08:00
4e6c75995c tinker_base 4.0.2-bugfix 2020-07-10 17:38:36 +08:00
df693ce0c2 versionCode 改为181 2020-07-10 17:00:55 +08:00
f0236d7ad5 sync submodule 2020-07-10 16:59:18 +08:00
1d3e2b5c16 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-10 16:00:25 +08:00
545d257135 修复一些闪退问题 2020-07-10 16:00:03 +08:00
f5164d2102 修复在模拟器上可能卡启动页的问题 2020-07-10 15:55:58 +08:00
9af83be9a7 修复 7.1.1 系统上 toast 可能出现的闪退问题 2020-07-10 15:40:38 +08:00
49b0b982f5 基本完成Xapk解压安装,还有部分细节可能要调整 2020-07-09 18:31:27 +08:00
ad7543e7bc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-09 14:56:24 +08:00
1bd0db013b 处理Picasso获取Bitmap有时不显示问题 2020-07-09 14:56:18 +08:00
ef6a2c58ff tinker_base-4.0.2 2020-07-09 10:28:15 +08:00
2aa41661a2 首页横向专题备注默认隐藏 2020-07-09 09:49:24 +08:00
e63a374da1 重新整理Xapk解压部分以及增加取消操作 2020-07-09 09:28:57 +08:00
e326f072d2 视频合集用户信息扩大点击区域 2020-07-08 14:29:59 +08:00
f53cc18ab6 修改启动页调用获取设备弹窗接口错误 2020-07-08 10:38:54 +08:00
723a504d7c 开发环境不主动捕获RxJava抛出的异常 2020-07-08 10:23:21 +08:00
dab48607e8 修改文案 2020-07-08 09:59:23 +08:00
3ee69146bb 光环助手V4.0.2-视频上传与编辑功能优化(20200707测试补充 1) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/887 2020-07-08 09:57:33 +08:00
ca86a66b14 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-07 18:26:51 +08:00
c92bdd3014 修复首页竖向专题下载进度无法刷新问题 2020-07-07 18:26:35 +08:00
0be23f26f2 修复自定义栏目正文高亮文字点击提示复制成功的问题 2020-07-07 18:12:23 +08:00
6ce4592e5e 修改分享事件上报 2020-07-07 17:49:20 +08:00
92caedb011 光环助手V4.0.2-视频上传与编辑功能优化(20200707测试补充 3,5)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/887 2020-07-07 16:48:45 +08:00
f796411fa8 光环助手V4.0.2-视频上传与编辑功能优化(20200707测试补充 1,2,4)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/887 2020-07-07 16:06:38 +08:00
d45f185f77 处理分享数据未上传问题 2020-07-07 15:03:54 +08:00
6564de8a72 整理安装/卸载相关代码,尽量做到统一处理 2020-07-07 14:57:06 +08:00
10028dfebc 视频浏览记录、视频收藏列表扩大用户信息点击区域 2020-07-07 14:41:00 +08:00
fa06795cef Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-06 16:55:45 +08:00
c1eb324d79 分享功能数据埋点 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/919 2020-07-06 16:55:39 +08:00
cdf9528583 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-06 15:10:26 +08:00
5f5a621bd1 光环助手V4.0.2-视频上传与编辑功能优化(20200703测试补充1,2,3,5,6) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/887 2020-07-06 15:10:10 +08:00
b8d54dfa59 更新依赖库 hash 2020-07-06 11:55:37 +08:00
b4f39d09e4 Merge branch 'intergrate-antibot-sdk' into 'dev'
集成反爬虫SDK

See merge request halo/assistant-android!18
2020-07-06 11:47:52 +08:00
d57ac57f43 尝试将Xapk安装部分接入到原有的下载体系 2020-07-03 17:09:50 +08:00
a3aea6259c 光环助手V4.0.2 RELEASE(20200629-2330)测试汇总20200703测试问题(1) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/914 2020-07-03 15:31:32 +08:00
73e4c90956 恢复 chucker 2020-07-03 12:02:46 +08:00
c1432159f3 修复前台启动也会显示光环助手正在运行中的问题 2020-07-03 11:59:44 +08:00
45f47d98ba 补充部分遗漏的接口 2020-07-03 10:13:00 +08:00
2e9638b8c5 光环助手V4.0.2 RELEASE(20200629-2330)测试汇总(8,9) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/914 2020-07-03 09:42:25 +08:00
7ea30c1d0e 修改 keep 规则 2020-07-02 18:09:26 +08:00
034e04944a 调整API_HOST 2020-07-02 17:51:48 +08:00
99326596d5 接入阿里反爬虫 SDK https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/915 2020-07-02 17:39:51 +08:00
1cc2b85816 光环助手V4.0.2-开服日历表优化(20200702需求补充) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/893 2020-07-02 17:12:37 +08:00
942291d7c5 确定xapk的命名和存放路径问题 2020-07-02 16:59:57 +08:00
f4cd9419a4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-07-02 15:56:35 +08:00
a24b9d92c7 WebFragment页面支持js打开分享弹窗 2020-07-02 15:56:29 +08:00
8e7e83ad72 处理link跳转使用jumpActivity方式 2020-07-02 15:37:14 +08:00
cd810f0048 光环助手V4.0.2-游戏专题功能强化(前端)20200701优化补充(2,3,4) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885 2020-07-02 14:52:25 +08:00
fa050039cd 暂时停用chucker 2020-07-02 11:09:07 +08:00
935fb1149f DsBridge 转为本地依赖,暂时停用chucker(jitpack连不上) 2020-07-02 11:03:34 +08:00
951817455a 修复游戏列表评分数值字体大小不一问题 2020-07-01 18:22:53 +08:00
de597bdd36 初步完成Xapk解压部分 2020-07-01 16:06:03 +08:00
e71e7f6163 处理系统消息link不显示 2020-07-01 10:07:21 +08:00
09be5e157d 修复去掉游戏详情富文本正文换行符时会切掉最后一个字符的问题 2020-06-30 17:33:59 +08:00
1f5e59fc1d 处理系统推送列表link显示 2020-06-30 17:14:10 +08:00
e58861afa4 处理系统推送title为空问题 2020-06-30 16:47:36 +08:00
44e51ecb0a 补充一些代码注释 2020-06-30 15:10:59 +08:00
794c17a1bb 恢复误删的带 chucker 测试环境编译代码 2020-06-30 15:08:49 +08:00
1b287962f0 完成将镜像游戏隐藏的自定义栏目放置于详细信息之后的功能 2020-06-30 15:07:53 +08:00
8bdf98b9d8 修改游戏专题大图link跳转问题 2020-06-30 14:27:55 +08:00
e1aeb61c9b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-30 10:56:28 +08:00
a39a70ac2d 修复游戏列表和游戏详情评分数值不一致的问题 2020-06-30 10:56:22 +08:00
4fdcaaf591 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-30 00:07:04 +08:00
b4502638ff 修改光环助手V4.0.2-链接跳转做成通用模块bug 2020-06-30 00:07:00 +08:00
05502d56b1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-29 22:54:31 +08:00
90e1e8a40f 修复游戏列表和游戏详情评分数值不一致的问题 2020-06-29 22:54:26 +08:00
b10293da50 镜像游戏去掉大家都在玩 2020-06-29 22:50:43 +08:00
83cf0687e6 修复一些闪退问题 2020-06-29 22:32:15 +08:00
f56b03716a 我的光环进入游戏投稿前请求权限 2020-06-29 21:45:41 +08:00
61a41e6039 修复游戏详情游戏简介的显示异常 2020-06-29 21:02:03 +08:00
20ae9fe0ec 补充镜像游戏的镜像下载选项 2020-06-29 20:51:36 +08:00
74fdec9d72 UI优化 2020-06-29 19:31:51 +08:00
3437265cc1 Merge branches 'dev' and 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt
2020-06-29 19:08:36 +08:00
271993a876 光环助手V4.0.2-链接跳转做成通用模块0629测试1(2),2(1),5(3),9(2) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/879 2020-06-29 19:06:28 +08:00
3a8b7bb920 视频上传时把是否勾选"视频上传服务准则"的判断放到最后 2020-06-29 17:52:37 +08:00
fd85f3889d 修复镜像游戏的预约状态问题 2020-06-29 17:05:01 +08:00
556ecea749 修复游戏详情游戏简介的换行问题 2020-06-29 17:04:33 +08:00
8a97844676 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-29 16:58:06 +08:00
f152296e7a 游戏列表评分数值与游戏详情统一 2020-06-29 16:57:59 +08:00
4ccc789c7c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-29 16:09:55 +08:00
747b02eb7a 处理视频流内存泄漏问题 2020-06-29 16:09:50 +08:00
a73c033c03 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-29 15:57:59 +08:00
939db8c820 光环助手V4.0.2-游戏专题功能强化(前端)(20200629UI测试) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885 2020-06-29 15:57:54 +08:00
8601440d97 修复接口环境标识文字造成的显示问题 2020-06-29 15:12:48 +08:00
7a1fa90175 测试包右上角添加接口环境标识文字 2020-06-29 12:36:41 +08:00
46722ba69d 测试包右上角添加接口环境标识文字 2020-06-29 12:03:37 +08:00
70d9d461bf 更换web编辑器图标 2020-06-29 11:03:52 +08:00
91944df6a4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-29 10:59:40 +08:00
ef86c1158c 尝试修复Tab专题页面Fragment回收后无法重建的问题 2020-06-29 10:59:36 +08:00
0f3b6ed34b 镜像游戏去掉镜像标签中的特殊标签 2020-06-29 10:26:52 +08:00
8b50620ddc SpanBuilder的image方法使用application,避免出现内存泄漏 2020-06-29 10:12:39 +08:00
8b2a9eb6ca 我的收藏ui优化 2020-06-29 09:54:27 +08:00
7297f5480e 修改意见反馈文案 2020-06-28 19:58:41 +08:00
3bee8cc034 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-28 18:56:12 +08:00
584a16e111 上传视频流浏览记录 2020-06-28 18:55:25 +08:00
6460c7f8d6 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-28 18:24:15 +08:00
feb99c9f78 光环助手V4.0.2-开服日历表优化(20200628UI测试) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/893 2020-06-28 18:24:09 +08:00
68ac809bcb 恢复误删的华为离线推送配置 2020-06-28 17:58:35 +08:00
de207f66d9 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-28 17:53:09 +08:00
054fcd2049 修正横向专题第一行文案标红规则 2020-06-28 17:52:45 +08:00
497fc998fe 修复通知栏推送的跳转问题 2020-06-28 17:16:56 +08:00
03f76453ab 更正错误的游戏镜像判断规则 2020-06-28 15:57:55 +08:00
0a87bd354a 修复首次启动时根据 gid 获取已下载的游戏列表失败的问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/880 2020-06-28 15:13:36 +08:00
1baceaef15 光环助手V4.0.2-多版本下载面板:合集插件化提示 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/907 2020-06-28 10:50:28 +08:00
9719a7fa28 微调视频上传页面UI 2020-06-28 09:39:41 +08:00
1718a66126 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-24 18:21:38 +08:00
b317ef3a39 fix bug 2020-06-24 18:21:29 +08:00
8b0cd69ae6 DownloadService 的前台通知增加 channelId 避免在部分国产 ROM 上显示不出来 2020-06-24 16:50:33 +08:00
c7126e9836 处理一些内存泄漏问题 2020-06-24 15:33:53 +08:00
f3d01335a4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-24 15:07:01 +08:00
88e029b129 修复多平台下载面板-我的版本出现的未知类型 2020-06-24 15:06:54 +08:00
2bc72328c1 修复一些闪退异常 2020-06-24 14:45:44 +08:00
81179b1f72 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-24 11:54:59 +08:00
9a7d4997c2 修改更新弹窗文案 2020-06-24 11:54:53 +08:00
3b6ac881c2 正式环境api地址更新至4.0.2 2020-06-24 11:33:14 +08:00
6b5fb7d8bc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-24 10:47:42 +08:00
1551b0a358 测试环境App更新为了方便测试写死下载链接(测试环境的包链接是不可用的) 2020-06-24 10:47:35 +08:00
6540af8386 适配居中显示文字的渐隐文字颜色 2020-06-24 10:29:24 +08:00
9badcdc382 插件意见反馈跳转协议新增参数 2020-06-24 10:05:14 +08:00
0ba94fa56f 插件意见反馈跳转协议新增参数 2020-06-24 09:51:46 +08:00
52c1343ade 光环助手V4.0.2-视频上传与编辑功能优化(20200623测试1,4) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/887 2020-06-23 21:14:00 +08:00
7a0e633b79 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-23 20:53:46 +08:00
9b68b05d7d 光环助手V4.0.2-更新推送功能优化(20200619补充)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/882 2020-06-23 20:53:41 +08:00
9e7f6b0854 处理一些内存泄漏问题 2020-06-23 20:34:47 +08:00
cf20ad6fc2 修复曝光类型下载上报类型错误问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/884 2020-06-23 19:42:56 +08:00
cb7bdba338 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-23 18:13:58 +08:00
f1fc06ca84 游戏上传接口更改 2020-06-23 18:13:52 +08:00
18f9fe7fcf 游戏详情自定义栏目渐隐文字支持颜色继承 2020-06-23 17:51:28 +08:00
18816a8a4e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-23 17:15:24 +08:00
8d379501cb 光环助手V4.0.2-游戏上传功能优化20200623测试1,2,4 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/903 2020-06-23 17:15:18 +08:00
8f4c6abfd3 游戏详情自定义栏目富文本正文兼容低版本安卓系统 2020-06-23 16:44:28 +08:00
a24d0a9618 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-23 14:44:24 +08:00
8cdd66cd89 光环前端优化汇总(2020年6月第2周)0622测试:7(2) 9/10(1) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/895 2020-06-23 14:44:17 +08:00
3fd34576e8 更改游戏详情的自定义栏目富文本正文的展开实现 2020-06-23 11:58:27 +08:00
78d5cbcc42 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-23 10:43:40 +08:00
803f2bef75 修改新增开服的默认时间选择规则->开服表的选择时间(yyyy-MM-dd)+当前时间(HH:mm) 2020-06-23 10:43:33 +08:00
40c7e8f9e6 处理一些内存泄漏问题 2020-06-23 10:31:35 +08:00
b3c5ca6112 光环助手V4.0.2-意见反馈增加 版权申诉20200622测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/904 2020-06-22 18:22:20 +08:00
31067ea66d 光环助手V4.0.2-意见反馈增加 版权申诉 20200622UI测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/904 2020-06-22 18:05:31 +08:00
4e7626ff41 游戏上传UI优化 2020-06-22 17:50:58 +08:00
e62822505e urlscheme增加游戏上传 2020-06-22 17:02:28 +08:00
cbc705d1eb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-22 16:05:40 +08:00
aa2e147a51 光环助手V4.0.2-游戏上传功能优化(20200622测试 1-5,7-9,15) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/903 2020-06-22 16:05:34 +08:00
6249726839 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-22 16:05:04 +08:00
8f4bc5a164 修复游戏专题在部分情况游戏摘要无法控制的问题 2020-06-22 16:04:53 +08:00
eee459d08a 修复自定义栏目富文本正文的收起异常 2020-06-22 15:55:09 +08:00
81b4e40dbf Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-22 11:51:26 +08:00
261068e286 处理视频数据统计异常问题 2020-06-22 11:51:21 +08:00
84364a7c66 修复模拟器上游戏详情自定义栏目圆形头像导致闪退的问题 2020-06-22 10:52:58 +08:00
3beb47a8be 避免周期性任务在其它进程触发 2020-06-22 10:11:28 +08:00
ca76af4474 避免周期性任务在其它进程触发 2020-06-22 09:55:43 +08:00
bc33673533 完成MTA的AppKey替换和不需要事件的移除 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/910 2020-06-22 09:54:28 +08:00
c5d038a173 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-19 17:57:50 +08:00
b1e492df1b 修复APP更新弹窗点击弹窗边缘无法取消弹窗问题 2020-06-19 17:57:42 +08:00
9d9c213af7 修复插件化更新曝光事件没有附上版本号的问题 2020-06-19 17:25:46 +08:00
d3f97ea527 更新 leakCanary 2020-06-19 17:24:58 +08:00
0a5fb4cb1d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-19 17:03:19 +08:00
6905f7191a 修复一些闪退问题 2020-06-19 17:03:11 +08:00
bad7fb4922 游戏详情自定义栏目正文里的用户头像裁成圆形 2020-06-19 16:41:38 +08:00
250fa7eb7b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-19 16:22:03 +08:00
f0cd8567cb 1.增加视频流浏览记录表用于日志上传 2.视频流增加计时器 2020-06-19 16:21:58 +08:00
f6dd35e4b8 回答、文章web编辑器字数监听 2020-06-19 15:02:18 +08:00
2dc299e7f4 游戏投稿包名去掉后缀apk 2020-06-19 11:01:13 +08:00
366e8ded14 完成"下载数据统计需求"的0618测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/884 2020-06-19 09:35:32 +08:00
8175742143 完成"下载数据统计需求"的0618测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/884 2020-06-18 18:20:52 +08:00
fc858f1272 删除无用的多版本图片 2020-06-18 18:20:18 +08:00
84b668714b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-18 17:53:58 +08:00
5ea5346ee8 修改我的光环小红点规则 2020-06-18 17:53:53 +08:00
c2eb0b267c 完成"首页插件化提示区域优化"的红点优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/898 2020-06-18 17:32:17 +08:00
7fb502e87e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-18 17:27:24 +08:00
98726ddc3a 修改我的光环小红点规则 2020-06-18 17:27:20 +08:00
75ff76acf4 评论详情间距优化 2020-06-18 17:13:14 +08:00
ba552812a3 游戏详情自定义栏目正文内容支持用户头像 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/891 2020-06-18 14:53:29 +08:00
83bfeb0abc 修复一些闪退问题 2020-06-18 14:31:26 +08:00
70f1b7a678 游戏开服的新增取最后一条开服数据作为模板 2020-06-18 11:07:33 +08:00
455d53fee0 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-18 10:55:16 +08:00
39e4b5bf55 20200616测试问题:1 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/893 2020-06-18 10:55:00 +08:00
40a729b6f8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-18 10:40:26 +08:00
9643176e06 光环助手V4.0.2-意见反馈增加 版权申诉 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/904 2020-06-18 10:40:21 +08:00
1a70c33bef Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-18 10:25:45 +08:00
888ebe5f54 光环助手V4.0.2-多版本下载面板:合集插件化提示 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/907 2020-06-18 10:25:39 +08:00
cb02dbae57 游戏分地区配置添加网络状态切换重试 2020-06-18 09:43:51 +08:00
2683d02dcd Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-17 18:32:38 +08:00
ceb924e8f1 微调UI 2020-06-17 18:32:19 +08:00
bd91609a80 补充数据库升级配置 2020-06-17 18:31:39 +08:00
2fd74a4698 Merge remote-tracking branch 'origin/dev' into dev 2020-06-17 18:21:07 +08:00
e9e0d3b43e 基本完成游戏分地区管理供嗯 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/900 2020-06-17 18:20:59 +08:00
17e09ddad3 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-17 18:18:00 +08:00
65427c55d6 修改游戏投稿 2020-06-17 18:17:55 +08:00
7f99f75c6f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-17 17:39:10 +08:00
548aea8d13 光环助手V4.0.2-首页插件化提示区域优化(除4.4外,其它完成) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/898 2020-06-17 17:39:05 +08:00
a177137744 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-17 16:50:52 +08:00
3c6443d78f 版权申诉UI 2020-06-17 16:50:47 +08:00
ba81ed9cb0 完成游戏镜像功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/899 2020-06-17 15:19:48 +08:00
6a1cbd10c6 光环助手V4.0.2-游戏上传功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/903 2020-06-17 11:25:40 +08:00
7e9ac0c4f1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-16 17:26:10 +08:00
fe889639b3 游戏投稿(未完) 2020-06-16 17:26:05 +08:00
848e43af28 首页相关接口增加channel参数 2020-06-16 14:18:49 +08:00
c7a3893fae 修复虚拟按键遮挡启动图的问题 2020-06-16 11:51:51 +08:00
f7d633188c 光环助手V4.0.2-更新推送功能优化(3)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/882 2020-06-16 10:59:11 +08:00
e1e7d2d3d6 修复版块轮播图的曝光统计缺失问题 2020-06-15 18:18:43 +08:00
2b8a280768 移除无用代码 2020-06-15 18:18:08 +08:00
6efe96eb0d 微调UI 2020-06-15 18:06:33 +08:00
3562fe9273 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-15 16:29:04 +08:00
739ef44a8b 光环助手V4.0.2-开服日历表优化(1)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/893 2020-06-15 16:27:51 +08:00
879b42dbf2 修复游戏详情自定义栏目正文描述的显示问题 2020-06-15 15:02:43 +08:00
fae626bb98 移除下载限速相关的无用代码 2020-06-15 15:01:47 +08:00
cebd639d78 处理视频流全屏播放时点击返回键关闭页面问题 2020-06-15 11:32:35 +08:00
17a99a1cda 微调专题过滤选项UI 2020-06-15 10:50:02 +08:00
2a03683e1e 修改游戏专题平铺样式UI 2020-06-15 10:34:00 +08:00
a579b3fe10 修复游戏详情闪退问题 2020-06-15 09:33:51 +08:00
9c75dd18df Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-12 18:30:12 +08:00
cdc9c86852 光环助手V4.0.2-游戏专题功能强化(前端)(7) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885
修改专题详情游戏列表UI
修改多行类型专题控制选项UI(包换标签详情和分类详情)
2020-06-12 18:30:04 +08:00
fab1851436 完成自定义栏目优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/891 2020-06-12 11:54:04 +08:00
a6704e46a9 微调游戏列表UI 2020-06-12 11:49:19 +08:00
e188f70eb6 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-12 10:54:24 +08:00
02dd115886 移除游戏列表礼包图标相关代码
修复开服表闪退问题
2020-06-12 10:54:19 +08:00
5cbfc7b461 游戏评论、撰写问答、撰写文章toast居中显示 2020-06-12 10:43:48 +08:00
b4742b5645 更换富文本编辑器图标 2020-06-12 09:36:22 +08:00
5ec25475ea Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-11 18:34:20 +08:00
c58040ef83 光环助手V4.0.2-游戏专题功能强化(前端)(1,2,3,4,5,6) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885 2020-06-11 18:34:10 +08:00
75701b6875 游戏详情自定义栏目支持富文本 2020-06-11 18:29:44 +08:00
2155a33689 处理个人主页文章关闭评论显示问题 2020-06-11 15:21:05 +08:00
68a9d5d771 微调UI 2020-06-11 11:51:35 +08:00
ebf6107faf Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-10 18:19:43 +08:00
e4bc36a743 光环前端优化汇总(2020年6月第2周)2-6,8,13 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/895 2020-06-10 18:19:37 +08:00
7a64251811 Merge branch 'update_push_sdk' into 'dev'
Update push sdk

See merge request halo/assistant-android!17
2020-06-10 18:13:12 +08:00
65409d75a7 统一测试环境和正式环境的推送配置 2020-06-10 18:08:49 +08:00
d40081d58b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-10 16:34:46 +08:00
f276e981ed 光环助手V4.0.2-游戏专题功能强化(前端)(11)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885 2020-06-10 16:34:42 +08:00
e50db66b47 光环助手V4.0.2-游戏评论功能优化4,5 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/892 2020-06-10 15:06:16 +08:00
fc84022852 微调UI 2020-06-10 11:43:21 +08:00
b593f2f3ea 微调UI 2020-06-09 18:21:29 +08:00
e782d0542c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-09 17:59:28 +08:00
1a085cad98 光环助手V4.0.2-开服日历表优化2(3) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/893
修复开服备注字数过多产生的UI显示异常问题
2020-06-09 17:59:22 +08:00
1c33a0c4c5 去掉评论数为0时,点击评论内容卡片自动弹出键盘的功能 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/892 2020-06-09 17:36:36 +08:00
3c4a7961c2 处理EllipsizeTextView省略号不显示问题 2020-06-09 16:37:48 +08:00
712f9b84cf 简单升级推送SDK,离线推送还有很多问题 2020-06-09 16:08:19 +08:00
2efb7b76cc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-06-09 15:45:25 +08:00
5c4d93ce15 光环助手V4.0.2-视频上传与编辑功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/887 2020-06-09 15:45:16 +08:00
7addd92058 处理滑动视频流播放问题 2020-06-09 14:40:12 +08:00
82c5898b9a 光环助手V4.0.2-链接跳转做成通用模块 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/879 2020-06-09 11:40:12 +08:00
cced6b7035 光环助手V4.0.2-开服日历表优化(2(1),2(2))https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/893 2020-06-08 16:47:38 +08:00
ae0b5b3738 Merge branch 'dev_4.0.2' into 'dev'
Merge 4.0.2 feature changes

See merge request halo/assistant-android!16
2020-06-08 15:37:08 +08:00
6fdf9cbe5d Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-08 15:36:00 +08:00
009244c65d 游戏评论字数限制 2020-06-08 15:35:54 +08:00
73a720bb9c Merge branch 'dev_4.0.2' of gitlab.ghzhushou.com:halo/assistant-android into dev_4.0.2 2020-06-08 15:31:19 +08:00
fd9df9904f 完成首页游戏替换功能(第三期) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/880 2020-06-08 15:30:52 +08:00
e75fb3a40d 视频合集、浏览记录、我的收藏视频点击用户头像昵称跳转个人主页 2020-06-08 11:36:33 +08:00
0bef1a2aa8 视频合集、个人主页、浏览记录、我的收藏视频UI优化 2020-06-08 11:01:03 +08:00
395eb641e5 移除首页无用的下载监听 2020-06-05 16:21:32 +08:00
9019242ffb Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-05 15:10:49 +08:00
9433bb72ca 光环助手V4.0.2-游戏专题功能强化(后台)(8) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/886 2020-06-05 15:10:13 +08:00
500f751152 完成光环助手V4.0.2-下载数据统计需求 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/884 2020-06-05 15:03:01 +08:00
9ebe3f4a0e 处理关闭视频流页面上传播放数据progress为0的问题 2020-06-05 10:32:51 +08:00
8c92fc9a42 Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-04 17:40:11 +08:00
2a7cb34218 新增urlscheme跳转链接 2020-06-04 17:40:07 +08:00
e1a42b49c1 光环助手V4.0.2-更新推送功能优化(2) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/882 2020-06-04 17:24:07 +08:00
5a825debf5 Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-04 15:49:33 +08:00
e46b0a42b0 修复专题下载进度串行问题(10)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885 2020-06-04 15:49:25 +08:00
eb0c442a5e Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-04 10:58:29 +08:00
eb6460236b 视频UI封面图比例改为16:9 2020-06-04 10:58:24 +08:00
ef051daffd 历史记录数据库表新增字段 2020-06-04 10:55:50 +08:00
b6acb302d2 Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-04 10:54:36 +08:00
5cfc5a3971 光环助手V4.0.2-游戏专题功能强化(前端)(8,9)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/885 2020-06-04 10:54:28 +08:00
04de97af16 升级版本至4.0.2 2020-06-04 10:32:03 +08:00
6367f90589 Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-03 17:33:32 +08:00
bc8f9d07bb 页面回收重建,根据tag找回fragment避免每次都重新创建 2020-06-03 17:33:27 +08:00
e205abd120 Merge branch 'dev_4.0.2' of gitlab.ghzs.com:halo/assistant-android into dev_4.0.2 2020-06-03 17:22:56 +08:00
5da8fccef7 尝试修复首页-问答模块不能左右滑动的问题 2020-06-03 17:22:38 +08:00
c7e78142ee okhttp版本更新至3.12.12 2020-06-03 16:42:21 +08:00
354c7d1f85 光环助手V4.0.2-游戏关注功能优化 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/851 2020-06-03 14:49:33 +08:00
1142 changed files with 35515 additions and 11245 deletions

View File

@ -42,7 +42,7 @@ android {
}
ndk {
abiFilters "armeabi-v7a", "x86"
abiFilters "armeabi-v7a"
}
// 由于app只针对中文用户所以仅保留zh资源其他删掉
@ -67,6 +67,15 @@ android {
buildConfigField "String", "TD_APPID", "\"${TD_APPID}\""
buildConfigField "String", "LETO_APPID", "\"${LETO_APPID}\""
buildConfigField "String", "TTAD_APPID", "\"${TTAD_APPID}\""
buildConfigField "String", "DOUYIN_CLIENTKEY", "\"${DOUYIN_CLIENTKEY}\""
buildConfigField "String", "DOUYIN_CLIENTSECRET", "\"${DOUYIN_CLIENTSECRET}\""
buildConfigField "String", "MIPUSH_APPID", "\"${MIPUSH_APPID}\""
buildConfigField "String", "MIPUSH_APPKEY", "\"${MIPUSH_APPKEY}\""
buildConfigField "String", "MEIZUPUSH_APPID", "\"${MEIZUPUSH_APPID}\""
buildConfigField "String", "MEIZUPUSH_APPKEY", "\"${MEIZUPUSH_APPKEY}\""
resValue "string", "huawei_push_appid", "appid=${HUAWEI_PUSH_APPID}"
/**
* Build Time 供区分 jenkins 打包时间用
@ -95,7 +104,7 @@ android {
signingConfig signingConfigs.debug
buildConfigField "String", "EXPOSURE_REPO", "\"test\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E4\""
multiDexKeepProguard file("tinker_multidexkeep.pro")
}
@ -107,7 +116,7 @@ android {
signingConfig signingConfigs.release
buildConfigField "String", "EXPOSURE_REPO", "\"exposure\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E4\""
multiDexKeepProguard file("tinker_multidexkeep.pro")
}
@ -124,13 +133,10 @@ android {
dimension "nonsense"
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "SENSITIVE_API_HOST", "\"${SENSITIVE_API_HOST}\""
buildConfigField "String", "UMENG_APPKEY", "\"${UMENG_APPKEY}\""
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${UMENG_MESSAGE_SECRET}\""
buildConfigField "String", "MIPUSH_APPID", "\"${MIPUSH_APPID}\""
buildConfigField "String", "MIPUSH_APPKEY", "\"${MIPUSH_APPKEY}\""
buildConfigField "String", "MEIZUPUSH_APPID", "\"${MEIZUPUSH_APPID}\""
buildConfigField "String", "MEIZUPUSH_APPKEY", "\"${MEIZUPUSH_APPKEY}\""
buildConfigField "String", "BUGLY_APPID", "\"${BUGLY_APPID}\""
}
// internal test dev host
@ -140,14 +146,11 @@ android {
buildConfigField "String", "API_HOST", "\"${DEV_API_HOST}\""
buildConfigField "String", "UMENG_APPKEY", "\"${DEBUG_UMENG_APPKEY}\""
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${DEBUG_UMENG_MESSAGE_SECRET}\""
buildConfigField "String", "MIPUSH_APPID", "\"${DEBUG_MIPUSH_APPID}\""
buildConfigField "String", "MIPUSH_APPKEY", "\"${DEBUG_MIPUSH_APPKEY}\""
buildConfigField "String", "MEIZUPUSH_APPID", "\"${DEBUG_MEIZUPUSH_APPID}\""
buildConfigField "String", "MEIZUPUSH_APPKEY", "\"${DEBUG_MEIZUPUSH_APPKEY}\""
buildConfigField "String", "SENSITIVE_API_HOST", "\"${DEV_API_HOST}\""
buildConfigField "String", "BUGLY_APPID", "\"${DEBUG_BUGLY_APPID}\""
buildConfigField "String", "UMENG_APPKEY", "\"${DEV_UMENG_APPKEY}\""
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${DEV_UMENG_MESSAGE_SECRET}\""
buildConfigField "String", "BUGLY_APPID", "\"${DEV_BUGLY_APPID}\""
}
}
}
@ -171,7 +174,7 @@ rebuildChannel {
repositories {
flatDir {
dirs 'libs','libs/aars'
dirs 'libs', 'libs/aars'
}
}
@ -263,13 +266,12 @@ dependencies {
implementation "com.squareup.picasso:picasso:${picasso}"
// for video streaming
implementation ("com.shuyu:gsyVideoPlayer-java:$gsyVideo",{
implementation("com.shuyu:gsyVideoPlayer-java:$gsyVideo", {
exclude module: "gsyvideoplayer-androidvideocache"
exclude group: "tv.danmaku.ijk.media"
})
implementation "com.shuyu:GSYVideoPlayer-exo2:$gsyVideo"
implementation "com.github.wendux:DSBridge-Android:$dsBridge"
implementation "android.arch.work:work-runtime:${workManager}"
implementation "com.llew.huawei:verifier:${verifier}"
@ -284,14 +286,21 @@ dependencies {
debugImplementation "com.github.nichbar.chucker:library:$chucker"
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
implementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
implementation "com.bytedance.ies.ugc.aweme:opensdk-china-external:$bytedanceAweme"
implementation "com.bytedance.ies.ugc.aweme:opensdk-common:$bytedanceAweme"
implementation "com.aliyun.dpa:oss-android-sdk:${oss}"
implementation "com.airbnb.android:lottie:$lottie"
implementation "net.lingala.zip4j:zip4j:${zip4j}"
implementation("com.github.piasy:BigImageViewer:$bigImageViewer", {
exclude group: 'com.squareup.okhttp3'
exclude group: 'androidx.swiperefreshlayout'
exclude group: 'com.github.bumptech.glide'
})
implementation "com.github.PhilJay:MPAndroidChart:${chart}"
implementation project(':libraries:LGLibrary')
implementation project(':libraries:MTA')
@ -301,7 +310,6 @@ dependencies {
// implementation project(':libraries:WechatShare')
implementation project(':libraries:im')
implementation project(':libraries:Matisse')
implementation project(path: ':libraries:gsyVideoPlayer-proxy_cache')
}
File propFile = file('sign.properties')
if (propFile.exists()) {
@ -332,7 +340,7 @@ if (propFile.exists()) {
android.buildTypes.release.signingConfig = null
}
// 用于测试读取 META-INF 里的 JSON 的代码
// 用于测试读取 META-INF 里的文件
//task generateMetaJson {
// def resDir = new File(buildDir, 'generated/FILES_FOR_META_INF/')
// def destDir = new File(resDir, 'META-INF/')

Binary file not shown.

Binary file not shown.

BIN
app/libs/gid-1.1.jar Normal file

Binary file not shown.

View File

@ -248,4 +248,10 @@
-keep class com.pgl.sys.ces.* {*;}
-keep class com.gyf.immersionbar.* {*;}
-dontwarn com.gyf.immersionbar.**
-dontwarn com.gyf.immersionbar.**
-keep class com.taobao.securityjni.**{*;}
-keep class com.taobao.wireless.security.**{*;}
-keep class com.ut.secbody.**{*;}
-keep class com.taobao.dp.**{*;}
-keep class com.alibaba.wireless.security.**{*;}

View File

@ -4,7 +4,6 @@ import android.app.Application;
import com.facebook.stetho.Stetho;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.squareup.leakcanary.LeakCanary;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
@ -18,15 +17,6 @@ import okhttp3.logging.HttpLoggingInterceptor;
public class Injection {
public static boolean appInit(Application application) {
// init leakcanary
if (LeakCanary.isInAnalyzerProcess(application)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return false;
}
LeakCanary.install(application);
// init stetho
Stetho.initializeWithDefaults(application);

View File

@ -40,7 +40,7 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--可选,穿山甲提供“获取地理位置权限”和“不给予地理位置权限,开发者传入地理位置参数”两种方式上报用户位置,两种方式均可不选,添加位置权限或参数将帮助投放定位广告-->
<!--请注意:无论通过何种方式提供给穿山甲用户地理位置,均需向用户声明地理位置权限将应用于穿山甲广告投放,穿山甲不强制获取地理位置信息-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
<!-- 如果有视频相关的广告且使用textureView播放请务必添加否则黑屏 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
@ -52,14 +52,8 @@
com.shuyu.gsy.base,
com.google.android.exoplayer2,
tv.danmaku.ijk.media.exo2,
shuyu.com.androidvideocache,
pl.droidsonroids.gif,
com.ledong.lib.minigame,
com.ledong.lib.leto,
com.leto.game.base.glide4,
com.leto.game.ad.gdt,
com.leto.game.fcm,
com.leto.game.ad.toutiao" />
com.donkingliang.consecutivescroller" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -82,6 +76,7 @@
android:largeHeap="true"
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
tools:replace="android:allowBackup"
tools:targetApi="n">
<!--android:launchMode = "singleTask"-->
@ -112,7 +107,9 @@
android:screenOrientation="portrait" />
<!--android:theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" 退出时屏幕抖动 -->
<activity android:name="com.gh.gamecenter.ViewImageActivity" />
<activity
android:name="com.gh.gamecenter.ImageViewerActivity"
android:theme="@style/Theme.Transparent" />
<activity
android:name="com.gh.gamecenter.SearchActivity"
@ -167,6 +164,10 @@
android:name="com.gh.gamecenter.WebActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.FullScreenWebActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.ShareCardPicActivity"
android:screenOrientation="portrait" />
@ -176,9 +177,9 @@
android:screenOrientation="portrait" />
<activity
android:theme="@style/TransparentStatusBarAndNavigationBar"
android:name="com.gh.gamecenter.MessageDetailActivity"
android:screenOrientation="portrait" />
android:screenOrientation="portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar" />
<activity
android:name="com.gh.gamecenter.LibaoActivity"
@ -206,10 +207,18 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.CommentDetailActivity"
android:theme="@style/TransparentStatusBarAndNavigationBar"
android:name="com.gh.gamecenter.security.SecurityActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.security.BindPhoneActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.CommentDetailActivity"
android:screenOrientation="portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar" />
<activity
android:name="com.gh.gamecenter.mygame.MyGameActivity"
android:screenOrientation="portrait" />
@ -388,6 +397,10 @@
android:name="com.gh.gamecenter.qa.article.detail.ArticleDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.detail.comment.ArticleDetailCommentActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity"
android:screenOrientation="portrait" />
@ -418,9 +431,9 @@
android:screenOrientation="portrait" />
<activity
android:theme="@style/TransparentStatusBarAndNavigationBar"
android:name="com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
android:screenOrientation="portrait" />
android:screenOrientation="portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar" />
<activity
android:name="com.gh.gamecenter.history.HistoryActivity"
@ -448,7 +461,8 @@
<activity
android:name="com.gh.gamecenter.video.upload.view.UploadVideoActivity"
android:screenOrientation="portrait" />
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"/>
<activity
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
@ -513,11 +527,46 @@
<activity
android:name=".qa.answer.draft.AnswerDraftActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.rating.RatingFoldActivity"
android:screenOrientation="portrait" />
<activity
android:name=".video.data.VideoDataActivity"
android:screenOrientation="portrait" />
<activity
android:name=".video.poster.PosterEditActivity"
android:screenOrientation="portrait" />
<activity
android:name=".video.poster.PosterClipActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.select.ForumSelectActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.follow.ForumMyFollowActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.detail.ForumDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.moderator.ModeratorListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".video.label.VideoLabelActivity"
android:screenOrientation="portrait" />
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
<activity
android:name="com.gh.gamecenter.PushProxyActivity"
android:exported="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent" />
<activity
@ -540,6 +589,12 @@
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
<activity
android:name="${applicationId}.douyinapi.DouYinEntryActivity"
android:launchMode="singleTask"
android:taskAffinity="${applicationId}"
android:exported="true" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
@ -580,7 +635,7 @@
</receiver>
<!--魅族push应用定义消息receiver声明 -->
<receiver android:name="com.gh.gamecenter.receiver.MeizuPushReceiver">
<receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">
<intent-filter>
<!-- 接收push消息 -->
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
@ -605,7 +660,13 @@
</intent-filter>
</receiver>
<service android:name="com.gh.base.GHUmengNotificationService" />
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="@string/huawei_push_appid" />
<service
android:name="com.gh.base.GHUmengNotificationService"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!--<service android:name = "com.gh.gamecenter.statistics.AppStaticService" />-->

View File

@ -0,0 +1 @@
{"v":"5.6.9","fr":30,"ip":0,"op":20,"w":66,"h":66,"nm":"bottom bar tab/论坛/选中/E","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"矩形","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[110,110,100]},{"t":13,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.5],[1.5,-2.5],[2.5,-1.5],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.5]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-1.25],[1.5,-1.25],[2.5,-0.25],[2.5,0],[0,1.896],[-2.5,0],[-2.5,-0.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":9,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.938],[1.5,-2.938],[2.5,-1.938],[2.5,0],[0,2.833],[-2.5,0],[-2.5,-1.938]],"c":true}]},{"t":13,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.5],[1.5,-2.5],[2.5,-1.5],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":20,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"路径 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,34.599,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.2,0],[2.19,-0.35],[0,-1.82],[0,0],[0,0],[-1.98,0],[0,0],[0,0],[0,0],[-0.72,0.53],[0,0],[0,0],[0,2.05],[0,0],[1.8,0.28]],"o":[[-2.19,0],[-1.8,0.28],[0,0],[0,0],[0.1,1.96],[0,0],[0,0],[0,0],[0.58,0.65],[0,0],[0,0],[2.05,0],[0,0],[0,-1.82],[-2.2,-0.35]],"v":[[-0.003,-9.745],[-6.583,-9.215],[-9.712,-5.555],[-9.712,3.465],[-9.702,3.665],[-6.003,7.175],[-3.383,7.175],[-2.122,9.065],[-2.023,9.185],[0.277,9.405],[3.238,7.175],[5.997,7.175],[9.717,3.465],[9.717,-5.555],[6.587,-9.215]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-9.712,-9.745],"ix":5},"e":{"a":0,"k":[9.712,9.745],"ix":6},"t":1,"nm":"color","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[33,33,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":9,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":13,"s":[90,90,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"w":66,"h":66,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1,132 @@
[
{
"login": {
"title": "开启消息通知",
"content": "新游上线、互动回复,重要推送不错过",
"image": "bg_notification_login_style_1",
"styleNo": "样式A",
"scenes": "场景1"
},
"question": {
"title": "开启消息通知",
"content": "及时查看大神回答",
"image": "bg_notification_question_style_1",
"styleNo": "样式A",
"scenes": "场景2"
},
"answer": {
"title": "开启消息通知",
"content": "及时查看点赞与评论",
"image": "bg_notification_answer_style_1",
"styleNo": "样式A",
"scenes": "场景3"
},
"article": {
"title": "开启消息通知",
"content": "及时查看点赞与评论",
"image": "bg_notification_article_style_1",
"styleNo": "样式A",
"scenes": "场景4"
},
"video": {
"title": "开启消息通知",
"content": "实时获取审核与推荐进度",
"image": "bg_notification_video_style_1",
"styleNo": "样式A",
"scenes": "场景5"
},
"rating": {
"title": "开启消息通知",
"content": "成功上墙立即知道",
"image": "bg_notification_rating_style_1",
"styleNo": "样式A",
"scenes": "场景6"
},
"gift": {
"title": "开启消息通知",
"content": "新上礼包不再错过",
"image": "bg_notification_gift_style_1",
"styleNo": "样式A",
"scenes": "场景7"
},
"reserveGame": {
"title": "开启消息通知",
"content": "新游上线即时体验",
"image": "bg_notification_reserve_game_style_1",
"styleNo": "样式A",
"scenes": "场景8"
},
"feedback": {
"title": "开启消息通知",
"content": "及时查看客服回复",
"image": "bg_notification_feedback_style_1",
"styleNo": "样式A",
"scenes": "场景9"
}
},
{
"login": {
"title": "咦!是新的小伙伴耶!",
"content": "打开<font color=\"#1383EB\">通知开关</font>,游戏、礼包、抽奖活动不错过",
"image": "bg_notification_login_style_2",
"styleNo": "样式B",
"scenes": "场景1"
},
"question": {
"title": "发布成功!答案马上来!",
"content": "为了第一时间通知您,需要打开<font color=\"#1383EB\">通知开关</font>",
"image": "bg_notification_question_style_2",
"styleNo": "样式B",
"scenes": "场景2"
},
"answer": {
"title": "精彩的回答!大佬牛啤!",
"content": "打开<font color=\"#1383EB\">通知开关</font>,可以第一时间收获赞美和感谢哟!",
"image": "bg_notification_answer_style_2",
"styleNo": "样式B",
"scenes": "场景3"
},
"article": {
"title": "发布成功!不愧是你!",
"content": "打开<font color=\"#1383EB\">通知开关</font>,可以第一时间收获赞美和互动哟!",
"image": "bg_notification_article_style_2",
"styleNo": "样式B",
"scenes": "场景4"
},
"video": {
"title": "“百万”播放预定!",
"content": "<font color=\"#1383EB\">打开通知!</font>第一时间知道审核结果和互动信息哟!",
"image": "bg_notification_video_style_2",
"styleNo": "样式B",
"scenes": "场景5"
},
"rating": {
"title": "这游戏超好玩,我说的!",
"content": "想知道有多少人吃下安利?<font color=\"#1383EB\">打开通知</font>,马上知道!",
"image": "bg_notification_rating_style_2",
"styleNo": "样式B",
"scenes": "场景6"
},
"gift": {
"title": "获得道具:神奇的游戏礼包!",
"content": "<font color=\"#1383EB\">打开通知!</font>礼包上线,马上知道!",
"image": "bg_notification_gift_style_2",
"styleNo": "样式B",
"scenes": "场景7"
},
"reserveGame": {
"title": "玩最新的游戏,做游戏圈最靓的仔",
"content": "<font color=\"#1383EB\">打开通知!</font>游戏上线,更快知道!",
"image": "bg_notification_reserve_game_style_2",
"styleNo": "样式B",
"scenes": "场景8"
},
"feedback": {
"title": "真是重要的反馈!",
"content": "感恩有你,光环更精彩!<font color=\"#1383EB\">打开通知</font>,客服回复,马上知道!",
"image": "bg_notification_feedback_style_2",
"styleNo": "样式B",
"scenes": "场景9"
}
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,159 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.swiperefreshlayout.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ImageView;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
/**
* Private class created to work around issues with AnimationListeners being
* called before the animation is actually complete and support shadows on older
* platforms.
*/
class CircleImageView extends ImageView {
private static final int KEY_SHADOW_COLOR = 0x1E000000;
private static final int FILL_SHADOW_COLOR = 0x3D000000;
// PX
private static final float X_OFFSET = 0f;
private static final float Y_OFFSET = 1.75f;
private static final float SHADOW_RADIUS = 3.5f;
private static final int SHADOW_ELEVATION = 4;
private Animation.AnimationListener mListener;
int mShadowRadius;
CircleImageView(Context context, int color) {
super(context);
final float density = getContext().getResources().getDisplayMetrics().density;
final int shadowYOffset = (int) (density * Y_OFFSET);
final int shadowXOffset = (int) (density * X_OFFSET);
mShadowRadius = (int) (density * SHADOW_RADIUS);
ShapeDrawable circle;
if (elevationSupported()) {
circle = new ShapeDrawable(new OvalShape());
ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
} else {
OvalShape oval = new OvalShadow(mShadowRadius);
circle = new ShapeDrawable(oval);
setLayerType(View.LAYER_TYPE_SOFTWARE, circle.getPaint());
circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
KEY_SHADOW_COLOR);
final int padding = mShadowRadius;
// set padding so the inner image sits correctly within the shadow.
setPadding(padding, padding, padding, padding);
}
circle.getPaint().setColor(color);
ViewCompat.setBackground(this, circle);
}
private boolean elevationSupported() {
return android.os.Build.VERSION.SDK_INT >= 21;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!elevationSupported()) {
setMeasuredDimension(getMeasuredWidth() + mShadowRadius * 2, getMeasuredHeight()
+ mShadowRadius * 2);
}
}
public void setAnimationListener(Animation.AnimationListener listener) {
mListener = listener;
}
@Override
public void onAnimationStart() {
super.onAnimationStart();
if (mListener != null) {
mListener.onAnimationStart(getAnimation());
}
}
@Override
public void onAnimationEnd() {
super.onAnimationEnd();
if (mListener != null) {
mListener.onAnimationEnd(getAnimation());
}
}
/**
* Update the background color of the circle image view.
*
* @param colorRes Id of a color resource.
*/
public void setBackgroundColorRes(int colorRes) {
setBackgroundColor(ContextCompat.getColor(getContext(), colorRes));
}
@Override
public void setBackgroundColor(int color) {
if (getBackground() instanceof ShapeDrawable) {
((ShapeDrawable) getBackground()).getPaint().setColor(color);
}
}
private class OvalShadow extends OvalShape {
private RadialGradient mRadialGradient;
private Paint mShadowPaint;
OvalShadow(int shadowRadius) {
super();
mShadowPaint = new Paint();
mShadowRadius = shadowRadius;
updateRadialGradient((int) rect().width());
}
@Override
protected void onResize(float width, float height) {
super.onResize(width, height);
updateRadialGradient((int) width);
}
@Override
public void draw(Canvas canvas, Paint paint) {
final int viewWidth = CircleImageView.this.getWidth();
final int viewHeight = CircleImageView.this.getHeight();
canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2, mShadowPaint);
canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2 - mShadowRadius, paint);
}
private void updateRadialGradient(int diameter) {
mRadialGradient = new RadialGradient(diameter / 2, diameter / 2,
mShadowRadius, new int[] { FILL_SHADOW_COLOR, Color.TRANSPARENT },
null, Shader.TileMode.CLAMP);
mShadowPaint.setShader(mRadialGradient);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -3,19 +3,34 @@ package com.gh.base;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import com.gh.base.fragment.BaseFragment;
import com.gh.common.constant.Constants;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.RunningUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.StringUtils;
@ -36,9 +51,6 @@ import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import butterknife.ButterKnife;
import pub.devrel.easypermissions.EasyPermissions;
@ -88,10 +100,13 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == com.tencent.connect.common.Constants.REQUEST_QQ_SHARE
|| requestCode == com.tencent.connect.common.Constants.REQUEST_QZONE_SHARE) {
Tencent.onActivityResultData(requestCode, resultCode, data, ShareUtils.getInstance(this).QqShareListener);
}
ExtensionsKt.tryCatchInRelease(() -> {
if (requestCode == com.tencent.connect.common.Constants.REQUEST_QQ_SHARE
|| requestCode == com.tencent.connect.common.Constants.REQUEST_QZONE_SHARE) {
Tencent.onActivityResultData(requestCode, resultCode, data, ShareUtils.getInstance(this).QqShareListener);
}
return null;
});
}
@Override
@ -109,6 +124,15 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
}
}
@SuppressWarnings("ConstantConditions")
@Override
public void setContentView(View view) {
if (BuildConfig.DEBUG || BuildConfig.BUILD_TIME != 0) {
view = getRootViewWithEnvIndicator(view);
}
super.setContentView(view);
}
@Override
protected void onDestroy() {
if (useEventBus()) EventBus.getDefault().unregister(this);
@ -128,21 +152,63 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
String icon,
String shareTitle,
String shareSummary,
ShareUtils.ShareType shareType) {
ShareUtils.ShareEntrance shareEntrance, String id) {
ShareUtils.getInstance(this).showShareWindows(this,
getWindow().getDecorView(),
url,
icon,
shareTitle,
shareSummary,
shareType);
if (shareType == ShareUtils.ShareType.game || shareType == ShareUtils.ShareType.plugin) {
shareEntrance, id);
if (shareEntrance == ShareUtils.ShareEntrance.game || shareEntrance == ShareUtils.ShareEntrance.plugin) {
MtaHelper.onEvent("内容分享", "内容分享", shareTitle + shareSummary);
} else {
MtaHelper.onEvent("内容分享", "内容分享", shareTitle);
}
}
private View getRootViewWithEnvIndicator(View view) {
RelativeLayout screenRootView = new RelativeLayout(this);
screenRootView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
LinearLayout ll = new LinearLayout(this);
TextView tv = new TextView(this);
String envText = "正式环境";
tv.setBackground(ContextCompat.getDrawable(this, R.color.theme));
if (BuildConfig.FLAVOR.equals("internal")) {
envText = "测试环境";
tv.setBackground(ContextCompat.getDrawable(this, R.color.red));
}
tv.setText(envText);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(Color.WHITE);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
tv.measure(0, 0);
tv.setAlpha(0.15F);
int height = tv.getMeasuredHeight();
int width = tv.getMeasuredWidth();
tv.setPadding(DisplayUtils.dip2px(20), 0, DisplayUtils.dip2px(20), 0);
ll.setTranslationX(DisplayUtils.dip2px(20));
ll.setRotation(45);
ll.addView(tv);
ll.setPadding(0, (width - height) / 2, 0, (width - height) / 2);
if (BuildConfig.DEBUG) {
tv.setOnLongClickListener(v -> {
EntranceUtils.saveShortcut(this.getClass().getName(), getIntent().getExtras());
return true;
});
}
screenRootView.addView(view);
screenRootView.addView(ll);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) ll.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
return screenRootView;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(final EBShowDialog showDialog) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
@ -154,7 +220,7 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
if (FileUtils.isEmptyFile(showDialog.getPath())) {
toast(R.string.install_failure_hint);
} else {
startActivity(PackageUtils.getUninstallIntent(BaseActivity.this, showDialog.getPath()));
PackageInstaller.uninstall(BaseActivity.this, showDialog.getPath());
}
});
} else if (LOGIN_EXCEPTION.equals(showDialog.getType())) {

View File

@ -35,6 +35,7 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
val mRichEditor by bindView<RichEditor>(R.id.rich_editor)
val mDraftBtn by bindView<TextView>(R.id.draft_btn)
private val mEditorTextNumTv by bindView<TextView>(R.id.editorTextNumTv)
private val mEditorFont by bindView<CheckableImageView>(R.id.editor_font)
private val mEditorLink by bindView<CheckableImageView>(R.id.editor_link)
private val mEditorParagraph by bindView<CheckableImageView>(R.id.editor_paragraph)
@ -89,11 +90,12 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
mRichEditor.addJavascriptInterface(OnCursorChangeListener(), "OnCursorChangeListener")
mRichEditor.addJavascriptInterface(OnEditorTextChangeListener(), "OnEditorTextChangeListener")
mRichEditor.setInputEnabled(true)
mDraftBtn.text = if (this is AnswerEditActivity) {
"回答草稿"
} else "文章草稿"
} else "帖子草稿"
}
@OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_paragraph,
@ -258,6 +260,14 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
}
}
private inner class OnEditorTextChangeListener {
@JavascriptInterface
fun onTextChange(count: Int) {
val num = if (count > MAX_INPUT_TEXT_NUM) MAX_INPUT_TEXT_NUM - count else count
mEditorTextNumTv.text = num.toString()
}
}
abstract fun mtaEventName(): String
companion object {
@ -273,5 +283,6 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
const val INSERT_ANSWER_CODE = 411
const val INSERT_ARTICLE_CODE = 412
const val INSERT_GAME_CODE = 413
const val MAX_INPUT_TEXT_NUM = 10000
}
}

View File

@ -95,7 +95,7 @@ class GHUmengNotificationService : UmengMessageService() {
// 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
if (data != null
&& data.link?.target == "system"
&& data.link?.link == "system"
&& !UserManager.getInstance().isLoggedIn) {
return
}

View File

@ -14,8 +14,14 @@ import android.view.Window;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.MtaHelper;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.R;
@ -32,13 +38,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
/**
* 需要用到工具栏的页面使用
* <p>
@ -50,7 +49,7 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
@Nullable
private PackageViewModel mPackageViewModel;
protected RelativeLayout mToolbarContainer;
protected View mToolbarContainer;
protected Toolbar mToolbar;
@ -239,7 +238,7 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_download) {
MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
// MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(this, mEntrance);
startActivity(intent);
}

View File

@ -9,6 +9,14 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.OnListClickListener;
import com.gh.base.OnRequestCallBackListener;
import com.gh.common.constant.Constants;
@ -29,13 +37,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -210,6 +211,13 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
return mCachedView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
mCachedView = null;
}
@Override
public void onResume() {
super.onResume();

View File

@ -3,11 +3,10 @@ package com.gh.base.fragment
import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.CheckedTextView
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import butterknife.BindView
import com.gh.base.adapter.FragmentAdapter
@ -15,7 +14,6 @@ import com.gh.common.view.TabIndicatorView
import com.gh.gamecenter.R
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import com.lightgame.view.NoScrollableViewPager
@ -23,8 +21,10 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
@BindView(R.id.fragment_tab_layout)
lateinit var mTabLayout: TabLayout
@BindView(R.id.fragment_view_pager)
lateinit var mViewPager: NoScrollableViewPager
@BindView(R.id.fragment_tab_indicator)
lateinit var mTabIndicatorView: TabIndicatorView
@ -66,6 +66,10 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
if (arguments != null) mCheckedIndex = requireArguments().getInt(PAGE_INDEX, 0)
}
open fun providePagerAdapter(): PagerAdapter? {
return null
}
override fun onFragmentFirstVisible() {
super.onFragmentFirstVisible()
@ -74,7 +78,8 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
mViewPager.offscreenPageLimit = mFragmentsList.size
mViewPager.addOnPageChangeListener(this)
mViewPager.adapter = FragmentAdapter(childFragmentManager, mFragmentsList, mTabTitleList)
mViewPager.adapter = providePagerAdapter()
?: FragmentAdapter(childFragmentManager, mFragmentsList, mTabTitleList)
mViewPager.currentItem = mCheckedIndex
mTabLayout.setupWithViewPager(mViewPager)
mTabIndicatorView.setupWithTabLayout(mTabLayout)
@ -84,60 +89,10 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
val tab = mTabLayout.getTabAt(i) ?: continue
val tabTitle = if (tab.text != null) tab.text.toString() else ""
var tabView = provideTabView(i, tabTitle)
if (tabView == null) tabView = createDefaultTabCustomView(tabTitle)
if (tabView == null) tabView = BaseFragment_TabLayout.createDefaultTabCustomView(tabTitle)
tab.customView = tabView
}
initTabStyle(mTabLayout, mCheckedIndex)
}
open fun initTabStyle(tabLayout: TabLayout?, currentItem: Int) { // 默认选择addOnTabSelectedListener不会回调
val tabCount = tabLayout!!.tabCount
if (tabCount > 0) {
val tab = tabLayout.getTabAt(currentItem)
if (tab != null) updateTabStyle(tab, true)
}
tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
updateTabStyle(tab, true)
}
override fun onTabUnselected(tab: TabLayout.Tab) {
updateTabStyle(tab, false)
}
override fun onTabReselected(tab: TabLayout.Tab) {
updateTabStyle(tab, true)
}
})
}
open fun updateTabStyle(tab: TabLayout.Tab, isChecked: Boolean) {
val tabView = tab.customView
if (tabView == null) {
Utils.log("TabLayout->Tab样式不是通用样式,请检查")
return
}
val tabTitle: TextView?
tabTitle = if (tabView is TextView) {
tabView
} else {
tabView.findViewById(R.id.tab_title)
}
if (tabTitle == null) {
Utils.log("TabLayout->Tab样式不是通用样式,请检查")
return
}
tabTitle.typeface = if (isChecked) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
}
// 如果不设置View的话无法动态设置字体样式
open fun createDefaultTabCustomView(title: String?): View {
val view = LayoutInflater.from(HaloApp.getInstance().application.baseContext).inflate(R.layout.tab_item, null)
val tabTitle = view.findViewById<View>(R.id.tab_title)
if (tabTitle is CheckedTextView) {
tabTitle.text = title
}
return view
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex)
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

View File

@ -5,6 +5,7 @@ import android.os.Looper
import com.gh.common.AppExecutor.ioExecutor
import com.gh.common.AppExecutor.lightWeightIoExecutor
import com.gh.common.AppExecutor.uiExecutor
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.Executor
import java.util.concurrent.Executors
@ -25,6 +26,8 @@ object AppExecutor {
@JvmStatic
val ioExecutor = Executors.newCachedThreadPool() // 用 by lazy 可能影响初始化速度
val cachedScheduler by lazy { Schedulers.from(ioExecutor) }
class MainThreadExecutor : Executor {
private val mainThreadHandler = Handler(Looper.getMainLooper())

View File

@ -1,20 +1,24 @@
package com.gh.common
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.webkit.JavascriptInterface
import androidx.annotation.Keep
import androidx.appcompat.app.AppCompatActivity
import com.gh.base.CurrentActivityHolder
import com.gh.common.constant.Constants
import com.gh.common.util.*
import com.gh.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.LoginActivity
import com.gh.gamecenter.ViewImageActivity
import com.gh.gamecenter.entity.Badge
import com.gh.gamecenter.entity.MtaEvent
import com.gh.gamecenter.entity.NotificationUgc
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import com.gh.gamecenter.user.LoginTag
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
@ -23,7 +27,8 @@ import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.HttpException
import wendu.dsbridge.CompletionHandler
import java.util.*
import kotlin.collections.ArrayList
class DefaultJsApi(var context: Context) {
@ -46,7 +51,7 @@ class DefaultJsApi(var context: Context) {
@JavascriptInterface
fun getUserInfo(msg: Any): String {
return UserManager.getInstance().userInfoEntity.toJson()
return UserManager.getInstance().userInfoEntity?.toJson() ?: ""
}
@JavascriptInterface
@ -65,12 +70,11 @@ class DefaultJsApi(var context: Context) {
val userInfoEntity = UserManager.getInstance().userInfoEntity
if (msg.toString().isNotEmpty()) {
val badge = msg.toString().toObject() ?: Badge()
userInfoEntity.badge = badge
userInfoEntity?.badge = badge
} else {
userInfoEntity.badge = null
userInfoEntity?.badge = null
}
UserManager.getInstance().userInfoEntity = userInfoEntity
AppDatabase.getInstance(context).userInfoDao().updateUserInfo(userInfoEntity)
}
@JavascriptInterface
@ -83,6 +87,11 @@ class DefaultJsApi(var context: Context) {
return BuildConfig.VERSION_NAME
}
@JavascriptInterface
fun getAppVersionCode(msg: Any): Int {
return PackageUtils.getVersionCode()
}
@JavascriptInterface
fun bindWechat(msg: Any, handler: CompletionHandler<Any>) {
context.ifLogin("浏览器") {
@ -139,7 +148,21 @@ class DefaultJsApi(var context: Context) {
val context = CurrentActivityHolder.getCurrentActivity()
context?.startActivity(ViewImageActivity.getViewImageIntent(context, imageEvent.imageList, imageEvent.position, "浏览器"))
context?.startActivity(ImageViewerActivity.getIntent(context, imageEvent.imageList, imageEvent.position, "浏览器"))
}
@JavascriptInterface
fun isInstalled(event: Any): String {
val localInstalledPackageList = PackageUtils.getAllPackageName(HaloApp.getInstance().application)
val packageNameList: ArrayList<String> = event.toString().toObject() ?: ArrayList()
for (packageName in packageNameList) {
if (!localInstalledPackageList.contains(packageName)) {
return "false"
}
}
return "true"
}
@JavascriptInterface
@ -148,7 +171,48 @@ class DefaultJsApi(var context: Context) {
Base64ImageHolder.image = event.toString()
context?.startActivity(ViewImageActivity.getBase64ViewImageIntent(context, true))
context?.startActivity(ImageViewerActivity.getBase64Intent(context, true))
}
@JavascriptInterface
fun openNotificationSetting(msg: Any) {
NotificationHelper.show(context as AppCompatActivity, NotificationUgc.LOGIN)
}
@JavascriptInterface
fun useDarkStatusBarText(msg: Any) {
runOnUiThread {
DisplayUtils.transparentStatusBar(context as AppCompatActivity)
DisplayUtils.setLightStatusBar(context as AppCompatActivity, msg.toString() == "true")
}
}
@JavascriptInterface
fun exitWebView(msg: Any) {
runOnUiThread { (context as Activity).finish() }
}
@JavascriptInterface
fun updateRegulationTestStatus(msg: Any) {
if (msg.toString().toLowerCase(Locale.getDefault()) == "pass") {
SPUtils.setString(Constants.SP_REGULATION_TEST_PASS_STATUS, "pass")
}
}
@JavascriptInterface
fun getStatusBarHeight(msg: Any): String {
val statusBarHeight = DisplayUtils.getStatusBarHeight(context.resources)
return "$statusBarHeight"
}
@JavascriptInterface
fun getGid(msg: Any): String {
return HaloApp.getInstance().gid
}
@JavascriptInterface
fun showIncompatibleVersionDialog(msg: Any) {
DialogUtils.showLowVersionDialog(context)
}
@Keep

View File

@ -0,0 +1,391 @@
package com.gh.common
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import android.util.Base64
import com.gh.common.util.*
import com.gh.common.util.DirectUtils.directToGameDetailVideoStreaming
import com.gh.common.util.DirectUtils.directToGameServerCalendar
import com.gh.common.util.DirectUtils.directToGameVideo
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.DirectUtils.directToVideoDetail
import com.gh.common.util.GsonUtils.gson
import com.gh.gamecenter.LibaoDetailActivity
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.lightgame.utils.Utils
import java.nio.charset.Charset
object DefaultUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if ("ghzhushou" == uri.scheme) {
Utils.log("url = $url")
Utils.log("url = " + uri.scheme!!)
val host = uri.host
val path = uri.path
var id = ""
if (!TextUtils.isEmpty(path)) {
id = path!!.substring(1)
}
val intent: Intent
when (host) {
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
"game" -> DirectUtils.directToGameDetail(context, id = id, tab = uri.getQueryParameter("to"), autoDownload = uri.getQueryParameter("auto_download") == "true", entrance = entrance)
"column" -> SubjectActivity.startSubjectActivity(context, id, uri.getQueryParameter("name"), false, entrance)
"libao" -> context.startActivity(LibaoDetailActivity.getIntentById(context, id, entrance))
"qq" -> try {
DirectUtils.directToQqConversation(context, id)
} catch (e: Throwable) {
Utils.toast(context, "请检查是否已经安装手机QQ")
e.printStackTrace()
}
EntranceUtils.HOST_QQ_QUN -> {
val key = uri.getQueryParameter("key")
if (!DirectUtils.directToQqGroup(context, key)) {
Utils.toast(context, "请检查是否已经安装手机QQ")
}
}
"inurl" -> {
intent = Intent(context, WebActivity::class.java)
intent.putExtra(EntranceUtils.KEY_URL, uri.getQueryParameter("url"))
context.startActivity(intent)
}
"outurl" -> {
intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse(uri.getQueryParameter("url"))
try {
context.startActivity(intent)
} catch (e: Exception) {
Utils.toast(context, "请检查是否已经安装手机浏览器")
e.printStackTrace()
}
}
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
"community" -> {
val community = CommunityEntity()
community.id = id
community.name = uri.getQueryParameter("name") ?: ""
DirectUtils.directToCommunity(context, community)
}
"community_column" -> {
val community = CommunityEntity()
community.id = uri.getQueryParameter("community_id") ?: ""
community.name = uri.getQueryParameter("community_name") ?: ""
val columnId = uri.getQueryParameter("column_id") ?: ""
DirectUtils.directToCommunityColumn(context, community, columnId, entrance, "文章链接")
}
"answer" -> DirectUtils.directToAnswerDetail(context, id, entrance, "文章链接")
"communities" -> {
// ghzhushou://communities/5a32405b2397ab000f688de3/articles/5c99d262c140b321564f04e3
var communityId = ""
var type = ""
var typeId = ""
val split = id.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (text in split) {
if (TextUtils.isEmpty(communityId)) {
communityId = text
continue
}
if (TextUtils.isEmpty(type)) {
type = text
continue
}
if (TextUtils.isEmpty(typeId)) {
typeId = text
}
}
if ("articles" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接")
}
}
EntranceUtils.HOST_UPLOAD_VIDEO -> {
val titleParameter = uri.getQueryParameter("title")
val title = if (titleParameter.isNullOrEmpty()) "" else "#$titleParameter#"
val categoryId = uri.getQueryParameter("category_id") ?: ""
val link = uri.getQueryParameter("link") ?: ""
val gameId = uri.getQueryParameter("gameId") ?: ""
val gameName = uri.getQueryParameter("gameName") ?: ""
val tagActivityId = uri.getQueryParameter("tagActivityId") ?: ""
val tagActivityName = uri.getQueryParameter("tagActivityName") ?: ""
val linkEntity = VideoLinkEntity(title, categoryId, link, tagActivityId, tagActivityName)
val simpleGameEntity = SimpleGameEntity(gameId, gameName)
CheckLoginUtils.checkLogin(context, null, true, EntranceUtils.ENTRANCE_BROWSER) {
DirectUtils.directToVideoManager(context, linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "")
}
}
EntranceUtils.HOST_USERHOME -> {
val position = uri.getQueryParameter("position")
DirectUtils.directToHomeActivity(context, id, if (position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
}
EntranceUtils.HOST_VIDEO_MORE -> {
val referer = uri.getQueryParameter("referer") ?: ""
val type = uri.getQueryParameter("type") ?: ""
val act = uri.getQueryParameter("act") ?: ""
val gameId = uri.getQueryParameter("gameId") ?: ""
val fieldId = uri.getQueryParameter("fieldId") ?: ""
val sectionName = uri.getQueryParameter("sectionName") ?: ""
val paginationType = uri.getQueryParameter("paginationType")
?: "page"//活动分页方式 page filter
val location = if (!TextUtils.isEmpty(act)) {
VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value
} else if (!TextUtils.isEmpty(fieldId)) {
VideoDetailContainerViewModel.Location.GAME_ZONE.value
} else {
id
}
directToVideoDetail(context, id, location, false, gameId, entrance, "", referer, type, act, paginationType, fieldId, sectionName)
}
EntranceUtils.HOST_VIDEO_SINGLE -> {
val referer = uri.getQueryParameter("referer") ?: ""
directToVideoDetail(context, id, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.value,
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer)
}
EntranceUtils.HOST_VIDEO_STREAMING_HOME -> {
intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true)
context.startActivity(intent)
}
EntranceUtils.HOST_VIDEO_STREAMING_DESC -> {
directToGameDetailVideoStreaming(context, id, entrance)
}
EntranceUtils.HOST_VIDEO_COLLECTION -> {
directToGameVideo(context, id, entrance, "")
}
EntranceUtils.HOST_CATEGORY -> {
val title = uri.getQueryParameter("title")
DirectUtils.directCategoryDirectory(context, id, title ?: "", entrance, "")
}
EntranceUtils.HOST_COLUMN_COLLECTION -> {
val name = uri.getQueryParameter("name")
DirectUtils.directToColumnCollection(context, id, -1, entrance, name ?: "")
}
EntranceUtils.HOST_COLUMN -> {
DirectUtils.directToSubject(context, id, uri.getQueryParameter(EntranceUtils.KEY_NAME), entrance)
}
EntranceUtils.HOST_COMMUNITY_QUESTION_LABEL_DETAIL -> {
val community = CommunityEntity()
community.id = uri.getQueryParameter("community_id") ?: ""
community.name = uri.getQueryParameter("community_name") ?: ""
val tag = uri.getQueryParameter("tag") ?: ""
DirectUtils.directAskColumnLabelDetail(context, tag, community, entrance, "")
}
EntranceUtils.HOST_COMMUNITY_COLUMN_DETAIL -> {
val community = CommunityEntity()
community.id = uri.getQueryParameter("community_id") ?: ""
community.name = uri.getQueryParameter("community_name") ?: ""
val columnId = uri.getQueryParameter("column_id") ?: ""
DirectUtils.directAskColumnDetail(context, columnId, community, entrance, "")
}
EntranceUtils.HOST_BLOCK -> {
val name = uri.getQueryParameter("name")
?: ""
val entity = SubjectRecommendEntity(link = id, name = name, text = name)
DirectUtils.directToBlock(context, entity, entrance)
}
EntranceUtils.HOST_SERVER_BLOCK -> {
DirectUtils.directToGameServers(context, entrance = entrance, path = "")
}
EntranceUtils.HOST_AMWAY_BLOCK -> {
DirectUtils.directToAmway(context, entrance = entrance, path = "")
}
EntranceUtils.HOST_HELP -> {
val name = uri.getQueryParameter("name")
?: ""
DirectUtils.directToQa(context, name, id)
}
EntranceUtils.HOST_HELP_COLLECTION -> {
val name = uri.getQueryParameter("name")
?: ""
DirectUtils.directToQaCollection(context, name, id)
}
EntranceUtils.HOST_GAME_UPLOAD -> {
DirectUtils.directGameUpload(context, entrance = entrance, path = "")
}
EntranceUtils.HOST_GAME_ZONE -> {
val zoneUrl = uri.getQueryParameter("url") ?: ""
DirectUtils.directGameZone(context, id, zoneUrl, entrance)
}
EntranceUtils.HOST_LINK -> {
try {
val dataString = uri.getQueryParameter("data")
if (!TextUtils.isEmpty(dataString)) {
val linkData = Base64.decode(dataString, Base64.DEFAULT)
val linkDataString = String(linkData, Charset.defaultCharset())
val le = gson.fromJson(linkDataString, LinkEntity::class.java)
directToLinkPage(context, le, entrance, "")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
EntranceUtils.HOST_GAME_NEWS -> {
DirectUtils.directToGameNews(
context,
uri.getQueryParameter(EntranceUtils.KEY_GAME_ID),
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
entrance);
}
EntranceUtils.HOST_GAME_CALENDAR -> {
directToGameServerCalendar(context, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID))
}
EntranceUtils.HOST_HISTORY_APK -> {
DirectUtils.directToHistoryApk(context, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID))
}
EntranceUtils.HOST_FORUM_DETAIL -> {
DirectUtils.directForumDetail(context, id, entrance)
}
EntranceUtils.HOST_GAME_RATING_DETAIL -> {
DirectUtils.directToGameRatingDetail(context, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID), uri.getQueryParameter(EntranceUtils.KEY_COMMENT_ID), EntranceUtils.ENTRANCE_BROWSER)
}
EntranceUtils.HOST_FORUM -> {
DirectUtils.directToForum(context);
}
else -> DialogUtils.showLowVersionDialog(context)
}
return true
} else if ("zhiqu" == uri.scheme) {
if (PackageUtils.isInstalled(context, "com.beieryouxi.zqyxh")) {
val intent = Intent()
intent.data = Uri.parse(url)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
} else {
Utils.toast(context, "请安装指趣游戏盒")
}
}
if (url.startsWith("alipays:") || url.startsWith("alipay")) {
try {
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
} catch (e: Exception) {
ToastUtils.showToast("请安装支付宝客户端")
}
return true
} else if (url.startsWith("weixin")) {
try {
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
} catch (e: Exception) {
ToastUtils.showToast("请安装微信客户端")
}
return true
} else if (url.startsWith("mqqwpa")) {
try {
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
} catch (e: Exception) {
ToastUtils.showToast("请安装QQ客户端")
}
return true
}
if ("http" != uri.scheme && "https" != uri.scheme) return true
return false
}
@JvmStatic
fun transformNormalScheme(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if (uri.host == "www.ghzs666.com"
|| uri.host == "www.ghzs.com"
|| uri.host == "ask.ghzs.com"
|| uri.host == "m.ghzs.com"
|| uri.host == "m.ghzs666.com") {
Utils.log(uri.path)
uri.path?.apply {
when {
contains("game") -> {
val gameId = uri.getQueryParameter("gameId") ?: ""
DirectUtils.directToGameDetail(context, gameId, entrance, autoDownload = false, traceEvent = null)
}
contains("question") -> {
val questionId = split("/")[2]
val answerId = uri.getQueryParameter("answer")
if (answerId.isNullOrEmpty()) {
DirectUtils.directToQuestionDetail(context, questionId, entrance, "")
} else {
DirectUtils.directToAnswerDetail(context, answerId, entrance, "")
}
}
contains("communities") && contains("article") -> {
var communityId = ""
var type = ""
var typeId = ""
val split = replace("/communities", "").replace(".html", "").split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (text in split) {
if (TextUtils.isEmpty(communityId)) {
communityId = text
continue
}
if (TextUtils.isEmpty(type)) {
type = text
continue
}
if (TextUtils.isEmpty(typeId)) {
typeId = text
}
}
if ("articles" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接")
}
}
contains("article") -> {
val articleId = split("/")[2].replace(".html", "")
DirectUtils.directToArticle(context, articleId, entrance)
}
contains("columns") -> {
val columnsId = split("/")[3]
val id = uri.getQueryParameter("communityId") ?: ""
val name = uri.getQueryParameter("communityName") ?: ""
DirectUtils.directToCommunityColumn(context, CommunityEntity(id, name), columnsId, entrance, "")
}
contains("zone") -> {
val gameId = split("/")[2]
DirectUtils.directGameZone(context, gameId, url, entrance)
}
}
}
return true
}
return false
}
}

View File

@ -1,211 +0,0 @@
package com.gh.common
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import com.gh.common.util.*
import com.gh.common.util.DirectUtils.directToGameDetailVideoStreaming
import com.gh.common.util.DirectUtils.directToGameVideo
import com.gh.common.util.DirectUtils.directToVideoDetail
import com.gh.gamecenter.*
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.entity.VideoLinkEntity
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.lightgame.utils.Utils
object DefaultWebViewUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if ("ghzhushou" == uri.scheme) {
Utils.log("url = $url")
Utils.log("url = " + uri.scheme!!)
val host = uri.host
val path = uri.path
var id = ""
if (!TextUtils.isEmpty(path)) {
id = path!!.substring(1)
}
val intent: Intent
when (host) {
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
"game" -> GameDetailActivity.startGameDetailActivity(context, id, "libao" == uri.getQueryParameter("to"), entrance)
"column" -> SubjectActivity.startSubjectActivity(context, id, uri.getQueryParameter("name"), false, entrance)
"libao" -> context.startActivity(LibaoDetailActivity.getIntentById(context, id, entrance))
"qq" -> try {
DirectUtils.directToQqConversation(context, id)
} catch (e: Throwable) {
Utils.toast(context, "请检查是否已经安装手机QQ")
e.printStackTrace()
}
"qqqun" -> {
val key = uri.getQueryParameter("key")
if (!DirectUtils.directToQqGroup(context, key)) {
Utils.toast(context, "请检查是否已经安装手机QQ")
}
}
"inurl" -> {
intent = Intent(context, WebActivity::class.java)
intent.putExtra(EntranceUtils.KEY_URL, uri.getQueryParameter("url"))
context.startActivity(intent)
}
"outurl" -> {
intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse(uri.getQueryParameter("url"))
try {
context.startActivity(intent)
} catch (e: Exception) {
Utils.toast(context, "请检查是否已经安装手机浏览器")
e.printStackTrace()
}
}
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
"community" -> {
val community = CommunityEntity()
community.id = id
community.name = uri.getQueryParameter("name") ?: ""
DirectUtils.directToCommunity(context, community)
}
"community_column" -> {
val community = CommunityEntity()
community.id = uri.getQueryParameter("community_id") ?: ""
community.name = uri.getQueryParameter("community_name") ?: ""
val columnId = uri.getQueryParameter("column_id") ?: ""
DirectUtils.directToCommunityColumn(context, community, columnId, entrance, "文章链接")
}
"answer" -> DirectUtils.directToAnswerDetail(context, id, entrance, "文章链接")
"communities" -> {
// ghzhushou://communities/5a32405b2397ab000f688de3/articles/5c99d262c140b321564f04e3
var communityId = ""
var type = ""
var typeId = ""
val split = id.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (text in split) {
if (TextUtils.isEmpty(communityId)) {
communityId = text
continue
}
if (TextUtils.isEmpty(type)) {
type = text
continue
}
if (TextUtils.isEmpty(typeId)) {
typeId = text
}
}
if ("articles" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接")
}
}
EntranceUtils.HOST_UPLOAD_VIDEO -> {
val titleParameter = uri.getQueryParameter("title")
val title = if (titleParameter.isNullOrEmpty()) "" else "#$titleParameter#"
val categoryId = uri.getQueryParameter("category_id") ?: ""
val link = uri.getQueryParameter("link") ?: ""
val linkEntity = VideoLinkEntity(title, categoryId, link)
// if (!CheckLoginUtils.isLogin()) {
// HaloApp.put(EntranceUtils.HOST_UPLOAD_VIDEO, linkEntity)
// }
CheckLoginUtils.checkLogin(context, null, true, EntranceUtils.ENTRANCE_BROWSER) {
DirectUtils.directToVideoManager(context, linkEntity, EntranceUtils.ENTRANCE_BROWSER, "")
}
}
EntranceUtils.HOST_USERHOME -> {
val position = uri.getQueryParameter("position")
DirectUtils.directToHomeActivity(context, id, if (position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
}
EntranceUtils.HOST_VIDEO_MORE -> {
val referer = uri.getQueryParameter("referer") ?: ""
val type = uri.getQueryParameter("type") ?: ""
val act = uri.getQueryParameter("act") ?: ""
val loaction = if (TextUtils.isEmpty(act)) id else VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value
directToVideoDetail(context, id, loaction, false, "", entrance, "", referer, type, act)
}
EntranceUtils.HOST_VIDEO_SINGLE -> {
val referer = uri.getQueryParameter("referer") ?: ""
directToVideoDetail(context, id, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.value,
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer)
}
EntranceUtils.HOST_VIDEO_STREAMING_HOME -> {
intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true)
context.startActivity(intent)
}
EntranceUtils.HOST_VIDEO_STREAMING_DESC -> {
directToGameDetailVideoStreaming(context, id, entrance)
}
EntranceUtils.HOST_VIDEO_COLLECTION -> {
directToGameVideo(context, id, entrance, "")
}
EntranceUtils.HOST_CATEGORY -> {
val title = uri.getQueryParameter("title")
DirectUtils.directCategoryDirectory(context, id, title ?: "", entrance, "")
}
EntranceUtils.HOST_COLUMN_COLLECTION -> {
val name = uri.getQueryParameter("name")
DirectUtils.directToColumnCollection(context, id, -1, entrance, name ?: "")
}
EntranceUtils.HOST_COLUMN -> {
DirectUtils.directToSubject(context, id, uri.getQueryParameter(EntranceUtils.KEY_NAME), entrance)
}
EntranceUtils.HOST_COMMUNITY_QUESTION_LABEL_DETAIL -> {
val community = CommunityEntity()
community.id = uri.getQueryParameter("community_id") ?: ""
community.name = uri.getQueryParameter("community_name") ?: ""
val tag = uri.getQueryParameter("tag") ?: ""
DirectUtils.directAskColumnLabelDetail(context, tag, community, entrance, "")
}
EntranceUtils.HOST_COMMUNITY_COLUMN_DETAIL -> {
val community = CommunityEntity()
community.id = uri.getQueryParameter("community_id") ?: ""
community.name = uri.getQueryParameter("community_name") ?: ""
val columnId = uri.getQueryParameter("column_id") ?: ""
DirectUtils.directAskColumnDetail(context, columnId, community, entrance, "")
}
else -> DialogUtils.showLowVersionDialog(context)
}
return true
}
if (url.startsWith("alipays:") || url.startsWith("alipay")) {
try {
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
} catch (e: java.lang.Exception) {
ToastUtils.showToast("请安装支付宝客户端")
}
return true
} else if (url.startsWith("weixin")) {
try {
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
} catch (e: java.lang.Exception) {
ToastUtils.showToast("请安装微信客户端")
}
return true
}
if ("http" != uri.scheme && "https" != uri.scheme) return true
return false
}
}

View File

@ -0,0 +1,80 @@
package com.gh.common
import com.gh.common.exposure.ExposureManager
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.loghub.LoghubUtils
import com.gh.common.util.doOnMainProcessOnly
import com.gh.common.util.tryCatchInRelease
import com.gh.common.videolog.VideoRecordUtils
import com.gh.download.DownloadDataHelper
import com.gh.gamecenter.entity.TimeEntity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import kotlin.concurrent.fixedRateTimer
object FixedRateJobHelper {
private const val CHECKER_PERIOD: Long = 15 * 1000L
private const val TIME_PERIOD: Long = 600 * 1000L
private const val LOGHUB_PERIOD: Long = 120 * 1000L
private const val EXPOSURE_PERIOD: Long = 300 * 1000L
private const val REGION_SETTING_PERIOD: Long = 300 * 1000L
private const val VIDEO_RECORD_PERIOD: Long = 60 * 1000L
private const val DOWNLOAD_HEARTBEAT_PERIOD: Long = 60 * 1000L
private const val DOWNLOAD_HEARTBEAT_SHEET_PERIOD: Long = 15 * 1000L
private var mExecuteCount: Int = 0
var timeDeltaBetweenServerAndClient: Long = 0
@JvmStatic
fun begin() {
doOnMainProcessOnly {
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
// 时间校对10分钟一次
if ((mExecuteCount * CHECKER_PERIOD) % TIME_PERIOD == 0L) {
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
.subscribeOn(AppExecutor.cachedScheduler)
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let { timeDeltaBetweenServerAndClient = it * 1000 - System.currentTimeMillis() }
}
})
}
// 提交曝光数据
if ((mExecuteCount * CHECKER_PERIOD) % EXPOSURE_PERIOD == 0L) {
ExposureManager.commitSavedExposureEvents(true)
}
// 分片检测下载进度
if ((mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
tryCatchInRelease {
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
DownloadDataHelper.uploadDownloadHeartbeat(upload)
}
}
// 提交普通 loghub 数据
if ((mExecuteCount * CHECKER_PERIOD) % LOGHUB_PERIOD == 0L) {
LoghubUtils.commitSavedLoghubEvents()
}
// 更新游戏屏蔽信息
if ((mExecuteCount * CHECKER_PERIOD) % REGION_SETTING_PERIOD == 0L) {
RegionSettingHelper.getRegionSetting()
}
// 提交视频浏览记录数据
if ((mExecuteCount * CHECKER_PERIOD) % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
// ExposureUtils.logADownloadCompleteExposureEvent(GameEntity(id = mExecuteCount.toString(), name = "测试曝光上传"), platform = "", trace = null, downloadType = ExposureUtils.DownloadType.DOWNLOAD)
mExecuteCount++
}
}
}
}

View File

@ -38,22 +38,17 @@ object PushManager {
fun init(channel: String) {
tryWithDefaultCatch {
//初始化友盟推送
UMConfigure.init(mApplication,
Config.UMENG_APPKEY, channel,
UMConfigure.DEVICE_TYPE_PHONE,
Config.UMENG_MESSAGE_SECRET)
UMConfigure.init(mApplication, Config.UMENG_APPKEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Config.UMENG_MESSAGE_SECRET)
val pushAgent = PushAgent.getInstance(mApplication)
runOnIoThread { registerDevice() }
// 注册小米、华为和魅族通道
MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
HuaWeiRegister.register(mApplication)
MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
//友盟推送
val pushAgent = PushAgent.getInstance(mApplication)
//注册推送服务每次调用register方法都会回调该接口
runOnIoThread { registerDevice() }
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
mPreviousAlias = aliasInSp?.toObject()
@ -100,6 +95,7 @@ object PushManager {
jsonObject.put("os", meta.os)
jsonObject.put("os_version", meta.android_version)
jsonObject.put("mac", meta.mac)
jsonObject.put("gid", meta.gid)
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())

View File

@ -31,6 +31,7 @@ import io.reactivex.schedulers.Schedulers;
public class Config {
public static final String API_HOST = BuildConfig.API_HOST;
public static final String SENSITIVE_API_HOST = BuildConfig.SENSITIVE_API_HOST;
/**
* 需要配置的请使用{@link PreferenceManager#getDefaultSharedPreferences(Context)}
@ -50,6 +51,8 @@ public class Config {
public static final String BUGLY_APPID = BuildConfig.BUGLY_APPID;
public static final String LETO_APPID = BuildConfig.LETO_APPID;
public static final String TTAD_APPID = BuildConfig.TTAD_APPID;
public static final String DOUYIN_CLIENTKEY = BuildConfig.DOUYIN_CLIENTKEY;
public static final String DOUYIN_CLIENTSECRET = BuildConfig.DOUYIN_CLIENTSECRET;
// http://www.ghzs666.com/article/${articleId}.html
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
public static final String PATCHES = "patches";
@ -253,7 +256,7 @@ public class Config {
public static void getGhzsSettings() {
String channel = HaloApp.getInstance().getChannel();
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
.getApi().getSettings(PackageUtils.getVersionName(), channel)
.getSensitiveApi().getSettings(PackageUtils.getVersionName(), channel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<SettingsEntity>() {

View File

@ -1,6 +1,7 @@
package com.gh.common.constant;
import com.gh.common.util.PackageUtils;
import com.halo.assistant.HaloApp;
public class Constants {
@ -12,11 +13,12 @@ public class Constants {
public final static int NOT_NETWORK_CODE = 504; // 没有网络的状态码(应该是这个吧!)
public static final String LOGIN_TOKEN_ID = "userToken_id"; // 用户ID 与服务器无关
public static final String USER_TOKEN_KEY = "userTokenKey";
public static final String USER_INFO_KEY = "userInfoKey";
public static final String WELCOME_DIALOG_ID = "welcome_dialog_id";
public static final String WELCOME_DIALOG_LINK_TITLE = "welcome_dialog_link_title";
public static final String DEVICE_KEY = "deviceKey";
public static final String HAS_REQUESTED_NOTIFICATION_PERMISSIONS = "has_requested_notification_permissions";
@ -28,12 +30,12 @@ public class Constants {
public static final String XPOSED_INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer";
public static final String EB_QUIT_LOGIN = "quit_login";
// 用于避免历史下载掺和到普通下载状态的 ID 修饰符
public static final String GAME_ID_DIVIDER = ":";
// 用于避免历史下载影响到部分依赖名字作为数据更新条件的修饰符
public static final String GAME_NAME_DECORATOR = " ";
// 游戏详情进入时的自定义栏目标签是否已经默认展开过一次的标记
public static final String SP_HAS_EXPANDED_GAME_DETAIL_TAGS = "has_expanded_game_detail_tags";
// 游戏详情进入时的自定义栏目标签是否已经显示过一次展开更多的浮窗提示
@ -43,6 +45,17 @@ public class Constants {
public static final String SP_LAST_OPENING_ID = "last_opening_dialog_id";
public static final String SP_LAST_OPENING_TIME = "last_opening_dialog_time";
// 游戏图标和图标角标
public static final String RAW_GAME_ICON = "raw_game_icon";
public static final String GAME_ICON_SUBSCRIPT = "game_icon_subscript";
public static final String EXTRA_DOWNLOAD_TYPE = "extra_download_type";
public static final String SILENT_UPDATE = "静默更新";
public static final String LAST_GHZS_UPDATE_FILE_SIZE = "last_ghzs_update_file_size";
// 新用户首次启动光环的时间
public static final String SP_INITIAL_USAGE_TIME = "initial_usage_time";
//引导设置 “通知管理” 引导弹窗
public static final String SP_SHOWED_NOTIFICATION_LOGIN = "show_notification_login_hint";
public static final String SP_SHOWED_NOTIFICATION_QUESTION = "show_notification_question_hint";
@ -50,6 +63,9 @@ public class Constants {
public static final String SP_SHOWED_NOTIFICATION_ARTICLE = "show_notification_article_hint";
public static final String SP_SHOWED_NOTIFICATION_VIDEO = "show_notification_video_hint";
public static final String SP_SHOWED_NOTIFICATION_RATING = "show_notification_rating_hint";
public static final String SP_SHOWED_NOTIFICATION_GIFT = "show_notification_gift_hint";
public static final String SP_SHOWED_NOTIFICATION_RESERVE_GAME = "show_notification_reserve_game_hint";
public static final String SP_SHOWED_NOTIFICATION_FEEDBACK = "show_notification_feedback_hint";
// 新版本 也要触发一次“通知管理” 引导弹窗
public static final String SP_SHOWED_NOTIFICATION_NEW_VERSION = "show_notification_new_version";
// 今天是否已经触发了 “通知管理” 引导弹窗
@ -86,6 +102,19 @@ public class Constants {
public static final String SP_AUTH_DIALOG = "auth_dialog";
//顶部视频进度保存,重启恢复
public static final String SP_TOP_VIDEO_SCHEDULE = "top_video_schedule";
//我的光环小红点提示
public static final String SP_GH_RED_POINT_REMIND = "gh_red_point_remind";
//论坛首页引导
public static final String SP_FORUM_GUIDE = "forum_guide";
//礼仪考试开启状态
public static final String SP_REGULATION_TEST_LAST_REMIND_TIME = "regulation_test_last_remind_time";
public static final String SP_REGULATION_TEST_STATUS = "regulation_test_status";
public static final String SP_REGULATION_TEST_PASS_STATUS = "regulation_test_pass_status";
//相同设备号,每一种第三方登录方式登录后弹出绑定手机页面的次数
public static final String SP_QQ_SHOW_BIND_PHONE_TIME = "qq_show_bind_phone_time" + HaloApp.getInstance().getGid();
public static final String SP_WECHAT_SHOW_BIND_PHONE_TIME = "wechat_show_bind_phone_time" + HaloApp.getInstance().getGid();
public static final String SP_WEIBO_SHOW_BIND_PHONE_TIME = "weibo_show_bind_phone_time" + HaloApp.getInstance().getGid();
public static final String SP_DOUYIN_SHOW_BIND_PHONE_TIME = "douyin_show_bind_phone_time" + HaloApp.getInstance().getGid();
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
@ -95,14 +124,24 @@ public class Constants {
//输入规则
public static final String INPUT_RULE = "0123456789abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLNMOPQRSTUVWXYZ_";
// 微信绑定地址地址
// 微信绑定地址
public static final String WECHAT_BIND_ADDRESS_DEV = "https://resource.ghzs.com/page/wechat_dev/index.html#/";
public static final String WECHAT_BIND_ADDRESS = "https://resource.ghzs.com/page/wechat_pro/index.html#/";
// 礼仪考试地址
public static final String REGULATION_TEST_ADDRESS_DEV = "https://static-web.ghzs.com/etiquette-dev/index.html#/";
public static final String REGULATION_TEST_ADDRESS = "https://static-web.ghzs.com/etiquette/index.html#/";
// 徽章
public static final String BADGE_ADDRESS_DEV = "http://resource.ghzs.com/page/badge_dev/index.html#/";
public static final String BADGE_ADDRESS = "http://resource.ghzs.com/page/badge_pro/index.html#/";
// 腾讯企点地址
public static final String TENCENT_QIDIAN_ADDRESS = "https://url.cn/D80iyMVV?_type=wpa&qidian=true";
//版规声明
public static final String FORUM_REGULATIONS_NEWS_ID = "5f4db9cc34d44d01b92fd670";
//最少需要多少数据才能上传
public static final int DATA_AMOUNT = 20;

View File

@ -2,6 +2,7 @@ package com.gh.common.databind;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@ -13,6 +14,12 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.OnViewClickListener;
import com.gh.common.constant.Config;
@ -33,12 +40,14 @@ import com.gh.common.util.LogUtils;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.NumberUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.PermissionHelper;
import com.gh.common.util.PlatformUtils;
import com.gh.common.util.ReservationHelper;
import com.gh.common.view.DownloadProgressBar;
import com.gh.common.view.DrawableView;
import com.gh.common.view.GameIconView;
import com.gh.download.DownloadManager;
import com.gh.download.dialog.DownloadDialog;
import com.gh.gamecenter.DownloadManagerActivity;
@ -68,12 +77,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
/**
* Created by khy on 12/02/18.
*/
@ -95,6 +98,26 @@ public class BindingAdapters {
view.setTextSize(number);
}
@BindingAdapter("setTypeface")
public static void setTypeface(TextView view, String type) {
if (type == null) return;
switch (type) {
case "bold":
view.setTypeface(null, Typeface.BOLD);
break;
case "italic":
view.setTypeface(null, Typeface.ITALIC);
break;
case "bold_italic":
view.setTypeface(null, Typeface.BOLD_ITALIC);
break;
default:
view.setTypeface(null, Typeface.NORMAL);
break;
}
}
@BindingAdapter({"addDetailKaiFuView", "addDetailKaiFuViewListener", "isReadyPatch"})
public static void addDetailKaiFuView(LinearLayout view, List<ServerCalendarEntity> list
, OnViewClickListener listener, Boolean isReadyPatch) {
@ -292,6 +315,13 @@ public class BindingAdapters {
}
}
@BindingAdapter("game")
public static void setGame(View view, GameEntity gameEntity) {
if (gameEntity != null && view instanceof GameIconView) {
((GameIconView) view).displayGameIcon(gameEntity);
}
}
@BindingAdapter("articleType")
public static void setArticleType(TextView view, String articleType) {
NewsUtils.setNewsType(view, articleType, 0, 0);
@ -406,15 +436,16 @@ public class BindingAdapters {
case PLUGIN:
if (gameEntity.getApk().size() == 1) {
ApkEntity apk = gameEntity.getApk().get(0);
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk,
() -> {
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
});
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> {
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
});
});
});
});
} else {
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
@ -446,7 +477,7 @@ public class BindingAdapters {
if (gameEntity.getApk().size() == 1) {
DownloadEntity downloadEntity = DownloadManager.getInstance(progressBar.getContext()).getDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
PackageUtils.launchSetup(v.getContext(), downloadEntity);
PackageInstaller.install(v.getContext(), downloadEntity);
}
}
break;
@ -485,7 +516,7 @@ public class BindingAdapters {
HistoryHelper.insertGameEntity(gameEntity);
}
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay));
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton()));
progressBar.getContext().startActivity(i);
break;
}
@ -687,14 +718,15 @@ public class BindingAdapters {
}
}
@BindingAdapter({"setGameName", "isShowPlatform"})
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform) {
@BindingAdapter({"setGameName", "isShowPlatform", "isShowSuffix"})
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
if (isShowPlatform && game.getApk().size() > 0) {
view.setText(String.format("%s - %s", game.getName(),
view.setText(String.format("%s - %s", !isShowSuffix ? game.getNameWithoutSuffix() : game.getName(),
PlatformUtils.getInstance(view.getContext()).getPlatformName(
game.getApk().get(0).getPlatform())));
} else {
view.setText(game.getName());
view.setText(!isShowSuffix ? game.getNameWithoutSuffix() : game.getName());
}
}
@ -753,4 +785,17 @@ public class BindingAdapters {
}
view.setText(span);
}
@BindingAdapter({"setVideoData"})
public static void setVideoData(TextView view, int count) {
if (count > 0) {
view.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(view.getContext(), R.drawable.ic_video_data_up), null, null, null);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.text_EA3333));
view.setText(count + "");
} else {
view.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.text_999999));
view.setText("-");
}
}
}

View File

@ -10,6 +10,7 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.util.DirectUtils
import com.gh.common.util.DisplayUtils
import com.gh.common.util.MtaHelper
@ -18,7 +19,10 @@ import com.gh.gamecenter.entity.GameEntity
import kotlinx.android.synthetic.main.dialog_game_off_service.*
// 游戏关闭下载弹窗
class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
class GameOffServiceDialogFragment
// : BaseTrackableDialogFragment()
:BaseDialogFragment() {
private var mDialog: GameEntity.Dialog? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -42,7 +46,7 @@ class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {
MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
dismiss()
}
@ -52,13 +56,13 @@ class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
}
}
override fun getEvent(): String {
return "游戏下载状态按钮"
}
override fun getKey(): String {
return "查看详情弹窗"
}
// override fun getEvent(): String {
// return "游戏下载状态按钮"
// }
//
// override fun getKey(): String {
// return "查看详情弹窗"
// }
companion object {
@JvmStatic

View File

@ -2,28 +2,34 @@ package com.gh.common.dialog
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.content.res.AssetManager
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.common.util.DisplayUtils
import androidx.core.content.ContextCompat
import com.gh.common.util.GsonUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.PermissionHelper
import com.gh.common.util.fromHtml
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.NotificationHint
import com.gh.gamecenter.entity.NotificationStyleEntity
import com.gh.gamecenter.entity.NotificationUgc
import com.lightgame.utils.Utils
import kotlinx.android.synthetic.main.dialog_notification_hint.*
import org.json.JSONArray
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import kotlin.random.Random
// 通知权限弹窗
class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
private var mNotificationHint: NotificationHint? = null
private var mNotificationUgc: NotificationUgc? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_notification_hint, null)
@ -34,23 +40,34 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
titleTv.text = mNotificationHint?.title
contentContainer.removeAllViews()
for (item in mNotificationHint?.content ?: arrayListOf()) {
val tv = TextView(context)
tv.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
topMargin = if (contentContainer.childCount == 0) 0 else DisplayUtils.dip2px(12f)
}
tv.text = item
tv.setTextColor(Color.parseColor("#1383EB"))
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
contentContainer.addView(tv)
val jsonString = getJsonFromAssets()
if (jsonString.isNullOrEmpty()) {
Utils.log("Failed to obtain configuration file")
return
}
val index = Random.nextInt(2)
val jsonArray = JSONArray(jsonString)
val jsonObj = jsonArray.getJSONObject(index)
if (!jsonObj.has(mNotificationUgc?.value)) {
Utils.log("ugc type error")
return
}
val styleEntityJson = jsonObj.getJSONObject(mNotificationUgc!!.value)
val styleEntity = GsonUtils.fromJson(styleEntityJson.toString(), NotificationStyleEntity::class.java)
val drawableId = resources.getIdentifier(styleEntity.image, "drawable", requireContext().packageName)
notificationIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), drawableId))
notificationTitle.text = styleEntity.title
notificationContent.text = styleEntity.content.fromHtml()
if (index == 0) {
closeIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_notification_close_1))
} else {
activateTv.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_notification_open_btn_style_1)
activateTv.text = "优雅的开启"
}
activateTv.setOnClickListener {
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击立即开启")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击立即开启")
dismiss()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//这种方案适用于 API 26, 即8.0含8.0)以上可以用
@ -63,9 +80,10 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
}
}
laterTv.setOnClickListener {
closeIv.setOnClickListener {
dismiss()
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击以后再说")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击关闭")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击关闭")
}
dialog?.setCanceledOnTouchOutside(true)
@ -81,10 +99,30 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
override fun trackWithBasicDeviceInfo() = true
private fun getJsonFromAssets(): String? {
val stringBuilder = StringBuilder()
var bufferedReader: BufferedReader? = null
var inputStreamReader: InputStreamReader? = null
try {
inputStreamReader = InputStreamReader(requireContext().assets.open("notification_style.json"))
bufferedReader = BufferedReader(inputStreamReader)
var line: String?
while (bufferedReader.readLine().also { line = it } != null) {
stringBuilder.append(line)
}
} catch (e: IOException) {
e.printStackTrace()
} finally {
inputStreamReader?.close()
bufferedReader?.close()
}
return stringBuilder.toString()
}
companion object {
@JvmStatic
fun getInstance(hint: NotificationHint) = NotificationHintDialogFragment().apply {
mNotificationHint = hint
fun getInstance(ugc: NotificationUgc) = NotificationHintDialogFragment().apply {
mNotificationUgc = ugc
}
}
}

View File

@ -4,48 +4,80 @@ import android.annotation.SuppressLint
import android.app.Application
import android.os.Bundle
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.*
import android.view.animation.AnimationUtils
import android.widget.EditText
import android.widget.TextView
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.AppExecutor
import com.gh.common.constant.Config
import com.gh.common.history.HistoryHelper
import com.gh.common.repository.ReservationRepository
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.NotificationUgc
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONArray
import org.json.JSONObject
// 预约弹窗
class ReserveDialogFragment : BaseTrackableDialogFragment() {
class ReserveDialogFragment
: BaseDialogFragment(), KeyboardHeightObserver {
// : BaseTrackableDialogFragment() {
@BindView(R.id.reserve_hint_tv)
lateinit var reserveHintTv: TextView
@BindView(R.id.reserve_content_tv)
lateinit var reserveContentTv: TextView
@BindView(R.id.reserve_completed_content_tv)
lateinit var reserveCompletedContentTv: TextView
@BindView(R.id.mobile_et)
lateinit var mobileEt: EditText
@BindView(R.id.reserve_container)
lateinit var reserveContainer: View
@BindView(R.id.reserve_completed_container)
lateinit var reserveCompletedContainer: View
@BindView(R.id.customizable_btn)
lateinit var customizableBtn: TextView
@BindView(R.id.content_container)
lateinit var contentContainer: View
@BindView(R.id.mobile_index_container)
lateinit var mobileIndexContainer: View
@BindView(R.id.mobile_index_reserve)
lateinit var mobileIndexReserve: TextView
@BindView(R.id.mobile_index_user)
lateinit var mobileIndexUser: TextView
@BindView(R.id.mobile_et_delete)
lateinit var mobileEtDelete: View
@BindView(R.id.layout_container)
lateinit var layoutContainer: View
private lateinit var mViewModel: ReserveViewModel
private var mSuccessCallback: SuccessCallback? = null
@ -54,23 +86,32 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
private var mGameId: String = ""
private var mGameName: String = ""
private var mKeyboardHeightProvider: KeyboardHeightProvider? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewModel = viewModelProvider()
mKeyboardHeightProvider = KeyboardHeightProvider(activity)
mKeyboardHeightProvider?.start()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_reserve_game, null)
}
override fun getEvent(): String {
return "预约游戏"
}
override fun getKey(): String {
return "预约功能操作"
}
// override fun getEvent(): String {
// return "预约游戏"
// }
//
// override fun getKey(): String {
// return "预约功能操作"
// }
@Suppress("DEPRECATION")
@SuppressLint("SetTextI18n")
@ -78,11 +119,14 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
super.onViewCreated(view, savedInstanceState)
ButterKnife.bind(this, view)
val reserveContent = "游戏上线,您将<font color='#ff4147'>免费</font>收到短信提醒"
val reserveContent = "游戏上线,您将收到<font color='#1383EB'>免费短信</font>提醒"
reserveContentTv.text = Html.fromHtml(reserveContent)
mobileEt.setText(UserManager.getInstance().userInfoEntity.mobile)
mobileEt.setSelection(mobileEt.text.length)
mobileEt.setTextChangedListener { s, _, _, _ ->
mobileIndexContainer.visibility = View.GONE
mobileEtDelete.goneIf(s.trim().isEmpty())
}
mViewModel.reservation.observeNonNull(this) {
if (it.success) {
@ -91,6 +135,11 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
HistoryHelper.insertGameEntity(mGame!!)
}
}
mViewModel.reserveMobile.observe(viewLifecycleOwner, Observer {
setMobileIndexHint(it)
})
dialog?.setCanceledOnTouchOutside(true)
}
@ -109,7 +158,7 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
} else {
customizableBtn.text = dialogConfig?.text
customizableBtn.setOnClickListener {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击跳转按钮")
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击跳转按钮")
DirectUtils.directToLinkPage(
requireContext(),
dialogConfig!!.toLinkEntity(),
@ -120,35 +169,132 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
}
}
private fun setMobileIndexHint(reserveMobile: String?) {
var userMobile = UserManager.getInstance().userInfoEntity?.mobile
if (reserveMobile == userMobile) userMobile = null
if (!reserveMobile.isNullOrEmpty()) {
mobileIndexReserve.visibility = View.VISIBLE
mobileIndexReserve.text = reserveMobile
} else {
mobileIndexReserve.visibility = View.GONE
}
if (!userMobile.isNullOrEmpty()) {
mobileIndexUser.visibility = View.VISIBLE
mobileIndexUser.text = userMobile
} else {
mobileIndexUser.visibility = View.GONE
}
mobileIndexContainer.goneIf(mobileIndexUser.visibility == View.GONE && mobileIndexReserve.visibility == View.GONE)
if (mobileIndexContainer.visibility ==View.VISIBLE) {
mobileIndexContainer.animation = AnimationUtils.loadAnimation(requireContext(), R.anim.reserve_dialog_index_anim)
}
}
@OnClick(R.id.reserve_with_mobile_btn,
R.id.reserve_without_mobile_btn,
R.id.content_container,
R.id.close_btn,
R.id.customizable_btn)
R.id.customizable_btn,
R.id.mobile_index_reserve,
R.id.mobile_index_user,
R.id.mobile_et_delete,
R.id.mobile_et,
R.id.layout_container)
fun onClick(view: View) {
when (view.id) {
R.id.reserve_without_mobile_btn -> {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击无手机号预约")
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击无手机号预约")
if (mobileIndexContainer.visibility == View.VISIBLE) {
mobileIndexContainer.visibility = View.GONE
return
}
mViewModel.reserve(gameId = mGameId, gameName = mGameName)
}
R.id.reserve_with_mobile_btn -> {
if (mobileIndexContainer.visibility == View.VISIBLE) {
mobileIndexContainer.visibility = View.GONE
return
}
val mobile = mobileEt.text.toString()
if (mobile.length < 11 || !mobile.startsWith("1")) {
Utils.toast(context, "手机号格式错误,请检查并重新输入")
return
}
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击立即预约")
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击立即预约")
mViewModel.reserve(gameId = mGameId, gameName = mGameName, mobile = mobile)
}
R.id.close_btn -> {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击关闭")
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击关闭")
dismissAllowingStateLoss()
AppExecutor.uiExecutor.executeWithDelay(Runnable {
NotificationHelper.showNotificationHintDialog(NotificationUgc.RESERVE_GAME)
}, 1000)
}
R.id.content_container -> {
mobileIndexContainer.visibility = View.GONE
}
R.id.mobile_index_reserve -> {
mobileEt.setText(mobileIndexReserve.text.toString())
mobileEt.setSelection(mobileEt.text.length)
mobileIndexContainer.visibility = View.GONE
}
R.id.mobile_index_user -> {
mobileEt.setText(mobileIndexUser.text.toString())
mobileEt.setSelection(mobileEt.text.length)
mobileIndexContainer.visibility = View.GONE
}
R.id.mobile_et_delete -> {
mobileEt.setText("")
}
R.id.mobile_et -> {
mobileIndexContainer.visibility = View.GONE
}
R.id.layout_container -> {
dismissAllowingStateLoss()
}
}
}
override fun onResume() {
super.onResume()
if (HaloApp.getInstance().mCacheKeyboardHeight > 0) {
val attributes = dialog?.window?.attributes
val heightPixels = requireContext().resources.displayMetrics.heightPixels
val mCacheKeyboardHeight = HaloApp.getInstance().mCacheKeyboardHeight
val statusBarHeight = DisplayUtils.getStatusBarHeight(requireContext().resources)
dialog?.window?.attributes?.height = heightPixels - mCacheKeyboardHeight - statusBarHeight
attributes?.gravity = Gravity.TOP
dialog?.window?.attributes = attributes
}
mKeyboardHeightProvider?.setKeyboardHeightObserver(this)
}
override fun onPause() {
super.onPause()
mKeyboardHeightProvider?.setKeyboardHeightObserver(null)
}
override fun onDestroy() {
super.onDestroy()
mKeyboardHeightProvider?.close()
}
override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
if (height > 0) {
val attributes = dialog?.window?.attributes
attributes?.gravity = Gravity.CENTER
dialog?.window?.attributes = attributes
HaloApp.getInstance().mCacheKeyboardHeight = height
}
}
companion object {
@JvmStatic
fun getInstance(gameEntity: GameEntity, successCallback: SuccessCallback) = ReserveDialogFragment().apply {
@ -167,6 +313,12 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
class ReserveViewModel(application: Application) : AndroidViewModel(application) {
val reservation = MutableLiveData<Reservation>()
val reserveMobile = MutableLiveData<String>()
init {
getAppointmentMobile()
}
@SuppressLint("CheckResult")
fun reserve(gameId: String, gameName: String, mobile: String = "") {
@ -189,7 +341,7 @@ class ReserveViewModel(application: Application) : AndroidViewModel(application)
reservation.postValue(Reservation(success = true, withMobile = mobile.isNotEmpty(), boundWechat = boundWechat))
ReservationRepository.addReservationToMemoryAndRefresh(gameId)
MtaHelper.onEvent("预约游戏", "预约", gameName)
// MtaHelper.onEvent("预约游戏", "预约", gameName)
}
override fun onFailure(exception: Exception) {
@ -198,5 +350,30 @@ class ReserveViewModel(application: Application) : AndroidViewModel(application)
})
}
@SuppressLint("CheckResult")
private fun getAppointmentMobile() {
RetrofitManager.getInstance(getApplication()).api
.getAppointmentMobile(UserManager.getInstance().userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
var mobile: String? = null
tryCatchInRelease {
val jsonArray = JSONArray(data.string())
if (jsonArray.length() > 0) {
mobile = jsonArray.get(0).toString()
}
}
reserveMobile.postValue(mobile)
}
override fun onFailure(exception: Exception) {
reserveMobile.postValue(null)
}
})
}
class Reservation(var success: Boolean = false, var withMobile: Boolean = false, var boundWechat: Boolean = false)
}

View File

@ -11,8 +11,15 @@ data class ExposureEntity(
@SerializedName("game_id")
val gameId: String? = "",
val gameName: String? = "",
val gameVersion: String? = "",
val sequence: Int? = 0,
val platform: String? = "",
val downloadType: String? = "",
val downloadCompleteType: String? = ""
val downloadCompleteType: String? = "",
// 统计启动弹窗相关数据用的 (ugly)
@SerializedName("dialog_id")
var welcomeDialogId: String? = "",
@SerializedName("link_title")
var welcomeDialogLinkTitle: String? = ""
) : Parcelable

View File

@ -8,6 +8,7 @@ import com.gh.common.constant.Constants
import com.gh.common.exposure.meta.Meta
import com.gh.common.exposure.meta.MetaUtil
import com.gh.common.exposure.time.TimeUtil
import com.gh.common.util.getFirstElementDividedByDivider
import com.gh.gamecenter.entity.GameEntity
import kotlinx.android.parcel.Parcelize
import java.util.*
@ -27,13 +28,21 @@ data class ExposureEvent(
companion object {
@JvmStatic
fun createEvent(gameEntity: GameEntity?, source: List<ExposureSource>, eTrace: List<ExposureEvent>? = null, event: ExposureType = ExposureType.EXPOSURE): ExposureEvent {
if (gameEntity?.getApk()?.size == 1) {
gameEntity.gameVersion = gameEntity.getApk().elementAtOrNull(0)?.version ?: ""
}
return ExposureEvent(
payload = ExposureEntity(gameId = gameEntity?.id,
payload = ExposureEntity(
gameId = gameEntity?.id?.getFirstElementDividedByDivider(Constants.GAME_ID_DIVIDER),
gameName = gameEntity?.name?.removeSuffix(Constants.GAME_NAME_DECORATOR),
gameVersion = gameEntity?.gameVersion,
sequence = gameEntity?.sequence,
platform = gameEntity?.platform,
downloadType = gameEntity?.downloadType,
downloadCompleteType = gameEntity?.downloadCompleteType),
downloadCompleteType = gameEntity?.downloadCompleteType,
// ugly
welcomeDialogId = gameEntity?.welcomeDialogId ?: eTrace?.firstOrNull()?.payload?.welcomeDialogId,
welcomeDialogLinkTitle = gameEntity?.welcomeDialogTitle ?: eTrace?.firstOrNull()?.payload?.welcomeDialogLinkTitle),
source = source,
eTrace = eTrace,
event = event).apply { gameEntity?.exposureEvent = this }

View File

@ -26,6 +26,10 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
visibleState?.let { commitExposure(it) }
throttleBus?.clear()
}
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {
fragment.fragmentManager?.unregisterFragmentLifecycleCallbacks(this)
}
}, false)
}

View File

@ -9,7 +9,6 @@ import com.gh.loghub.LoghubHelper
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.util.concurrent.Executors
import kotlin.concurrent.fixedRateTimer
/**
* A handful tool for committing logs to aliyun loghub.
@ -17,7 +16,7 @@ import kotlin.concurrent.fixedRateTimer
* 如何简单地统计列表中每个 item 的曝光事件?
*
* 1. Adapter 实现 IExposable 接口,在 BindView 阶段更新 ExposureEventExposureEvent 供 getEventByPosition(pos) 方法获取用
* 2. 构建一个 ExposureListener 并作为入参添加至 recyclerview 的 Scroll 回调中
* 2. 构建一个 ExposureListener 并作为入参添加至 recyclerview 的 onScroll 回调中
* 3. 没了
*/
object ExposureManager {
@ -25,7 +24,6 @@ object ExposureManager {
private const val ENDPOINT = "cn-qingdao.log.aliyuncs.com"
private const val PROJECT = "ghzs"
private const val STORE_SIZE = 100
private const val STORE_FORCE_UPLOAD_PERIOD = 300 * 1000L
private const val LOG_STORE = BuildConfig.EXPOSURE_REPO
private val loghubHelper = LoghubHelper.getInstance()
@ -38,18 +36,12 @@ object ExposureManager {
@JvmStatic
fun init() {
TimeUtil.init()
loghubHelper.init(HaloApp.getInstance().application, ENDPOINT, PROJECT, LOG_STORE) { TimeUtil.currentTimeMillis() }
exposureExecutor.execute {
val eventList = exposureDao.getAll()
exposureSet.addAll(eventList)
}
fixedRateTimer(name = "ExposureManager-Store-Checker", initialDelay = 500, period = STORE_FORCE_UPLOAD_PERIOD) {
commitSavedExposureEvents(true)
}
}
/**

View File

@ -1,5 +1,6 @@
package com.gh.common.exposure
import android.text.TextUtils
import com.g00fy2.versioncompare.Version
import com.gh.common.constant.Constants
import com.gh.common.util.PackageUtils
@ -22,6 +23,7 @@ object ExposureUtils {
} else {
entity.id
}
gameEntity.gameVersion = entity.getApk().elementAtOrNull(0)?.version ?: gameEntity.gameVersion
gameEntity.platform = platform
gameEntity.downloadType = downloadType.toString()
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
@ -63,7 +65,11 @@ object ExposureUtils {
}
}
} else {
DownloadType.PLUGIN_DOWNLOAD
if (!TextUtils.isEmpty(apkEntity.ghVersion)) {
DownloadType.PLUGIN_DOWNLOAD
} else {
DownloadType.UPDATE
}
}
} else {
DownloadType.DOWNLOAD

View File

@ -1,30 +0,0 @@
package com.gh.common.exposure.time
import com.gh.gamecenter.entity.TimeEntity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
import kotlin.concurrent.fixedRateTimer
class Corrector {
companion object {
const val TIME_CORRECTOR_ADJUST_PERIOD: Long = 600000
}
var delta: Long = 0
init {
fixedRateTimer("TimeUtil-Corrector-Checker", initialDelay = 0, period = TIME_CORRECTOR_ADJUST_PERIOD) {
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
.subscribeOn(Schedulers.io())
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let { delta = it * 1000 - System.currentTimeMillis() }
}
})
}
}
}

View File

@ -1,23 +1,15 @@
package com.gh.common.exposure.time
import com.gh.common.FixedRateJobHelper
object TimeUtil {
private lateinit var corrector: Corrector
fun init() {
corrector = Corrector()
}
fun currentTimeMillis(): Long {
return corrector.delta + System.currentTimeMillis()
return FixedRateJobHelper.timeDeltaBetweenServerAndClient + System.currentTimeMillis()
}
fun currentTime(): Int {
return if (::corrector.isInitialized) {
((corrector.delta + System.currentTimeMillis()) / 1000).toInt()
} else {
(System.currentTimeMillis() / 1000).toInt()
}
return ((FixedRateJobHelper.timeDeltaBetweenServerAndClient + System.currentTimeMillis()) / 1000).toInt()
}
}

View File

@ -0,0 +1,21 @@
package com.gh.common.filter
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
@Keep
data class RegionSetting(
@SerializedName("game_mirror")
var mirrorGameIdSet: HashSet<String>,
@SerializedName("game_block")
var filterGameIdSet: HashSet<String>,
@SerializedName("channel_control")
var channelControl: ChannelControl) {
@Keep
data class ChannelControl(
@SerializedName("game_category")
var gameCategory: String,
@SerializedName("effect")
var effect: Boolean)
}

View File

@ -0,0 +1,101 @@
package com.gh.common.filter
import android.annotation.SuppressLint
import com.gh.common.AppExecutor
import com.gh.common.constant.Constants
import com.gh.common.util.SPUtils
import com.gh.common.util.debounceActionWithInterval
import com.gh.common.util.toJson
import com.gh.common.util.toObject
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Function
object RegionSettingHelper {
private var mChannelControl: RegionSetting.ChannelControl? = null
private var mFilterGameIdSet: HashSet<String>? = hashSetOf()
private var mDisplayMirrorIfoGameIdSet: HashSet<String>? = hashSetOf()
private const val SP_SETTING = "region_setting"
fun shouldThisGameDisplayMirrorInfo(gameId: String): Boolean {
return mDisplayMirrorIfoGameIdSet?.contains(gameId) ?: false
}
@JvmStatic
fun shouldThisGameBeFiltered(gameId: String?): Boolean {
return mFilterGameIdSet?.contains(gameId) ?: false
}
@JvmStatic
fun filterGame(list: List<GameEntity>?): ArrayList<GameEntity> {
if (list == null) return arrayListOf()
if (mFilterGameIdSet?.isEmpty() == true) {
if (list is ArrayList) return list
}
val listCopy: ArrayList<GameEntity> = if (list is ArrayList) list else ArrayList(list)
listCopy.removeAll { mFilterGameIdSet?.contains(it.id) ?: false }
return listCopy
}
@JvmField
var filterGame = Function { list: List<GameEntity> ->
filterGame(list)
list
}
fun shouldGameOfThisCategoryUseMirrorInfo(category: String): Boolean {
return if (mChannelControl == null || mChannelControl?.effect == false || !isUserUsedLessThan24Hours()) {
false
} else {
mChannelControl?.gameCategory == category
}
}
@SuppressLint("CheckResult")
@JvmStatic
fun getRegionSetting() {
debounceActionWithInterval(R.string.name, 3000) {
// 使用默认的 Schdulers.io() 可能会触发 OOM
RetrofitManager.getInstance(HaloApp.getInstance().application)
.sensitiveApi
.getRegionSetting(HaloApp.getInstance().channel)
.subscribeOn(AppExecutor.cachedScheduler)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<RegionSetting>() {
override fun onSuccess(data: RegionSetting) {
updateSettingsInMemory(data)
SPUtils.setString(SP_SETTING, data.toJson())
}
override fun onFailure(exception: Exception) {
SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
updateSettingsInMemory(it)
}
}
})
}
}
private fun updateSettingsInMemory(data: RegionSetting) {
mFilterGameIdSet = data.filterGameIdSet
mDisplayMirrorIfoGameIdSet = data.mirrorGameIdSet
mChannelControl = data.channelControl
}
/**
* 该用户是否是使用了不到 24 小时的新用户
*/
private fun isUserUsedLessThan24Hours(): Boolean {
val initialUsageTime = SPUtils.getLong(Constants.SP_INITIAL_USAGE_TIME, 0)
return !(initialUsageTime == 0L || System.currentTimeMillis() - initialUsageTime > 86400000)
}
}

View File

@ -15,7 +15,7 @@ import com.gh.gamecenter.room.converter.*
import com.gh.gamecenter.room.dao.*
import com.halo.assistant.HaloApp
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class], version = 5, exportSchema = false)
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class], version = 7, exportSchema = false)
@TypeConverters(CountConverter::class,
CommunityConverter::class,
TimeConverter::class,
@ -23,7 +23,8 @@ import com.halo.assistant.HaloApp
ThumbnailConverter::class,
TagStyleListConverter::class,
StringArrayListConverter::class,
CommunityVideoConverter::class)
CommunityVideoConverter::class,
UserConverter::class)
abstract class HistoryDatabase : RoomDatabase() {
@ -54,11 +55,27 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_5_6: Migration = object : Migration(5, 6) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE MyVideoEntity add title TEXT NOT NULL DEFAULT ''")
database.execSQL("Alter TABLE MyVideoEntity add commentCount INTEGER NOT NULL DEFAULT 0")
database.execSQL("Alter TABLE MyVideoEntity add user TEXT NOT NULL DEFAULT ''")
}
}
val MIGRATION_6_7: Migration = object : Migration(6, 7) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE HistoryGameEntity add iconSubscript TEXT DEFAULT ''")
}
}
val instance by lazy {
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
.addMigrations(MIGRATION_6_7)
.build()
}
}

View File

@ -41,7 +41,8 @@ object HistoryHelper {
historyGame.id = updateEntity.id
historyGame.brief = updateEntity.brief
historyGame.des = ""
historyGame.icon = updateEntity.icon
historyGame.icon = updateEntity.rawIcon ?: updateEntity.icon
historyGame.iconSubscript = historyGame.iconSubscript
historyGame.name = updateEntity.name
historyGame.tagStyle = updateEntity.tagStyle
historyGame.tag = updateEntity.tag
@ -55,11 +56,11 @@ object HistoryHelper {
historyGame.id = gameEntity.id
historyGame.brief = gameEntity.brief
historyGame.des = gameEntity.des
historyGame.icon = gameEntity.icon
historyGame.icon = gameEntity.rawIcon ?: gameEntity.icon
historyGame.iconSubscript = gameEntity.iconSubscript
historyGame.name = gameEntity.name
historyGame.tagStyle = gameEntity.tagStyle
historyGame.tag = gameEntity.getTag()
historyGame.isLibaoExist = gameEntity.isLibaoExists
return historyGame
}
@ -109,6 +110,7 @@ object HistoryHelper {
clearHtmlFormatCompletely().
replace(" +".toRegex()," ")
articleEntity.count = articleDetailEntity.count
articleDetailEntity.community.id = articleDetailEntity.communityId
articleEntity.community = articleDetailEntity.community
articleEntity.time = articleDetailEntity.time
articleEntity.title = articleDetailEntity.title

View File

@ -0,0 +1,5 @@
package com.gh.common.iinterface
interface IScrollable {
fun scrollToTop()
}

View File

@ -45,7 +45,7 @@ object ImManager {
HaloApp.getInstance().application,
ImReceiver.UNIQUE_BROADCAST_ACTION,
IM_KEY,
UserManager.getInstance().userInfoEntity.name + "(" + UserManager.getInstance().userId + ")",
UserManager.getInstance().userInfoEntity?.name + "(" + UserManager.getInstance().userId + ")",
UserManager.getInstance().userId)
shouldShowFloatingWindow = SPUtils.getBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId)
@ -75,11 +75,11 @@ object ImManager {
try {
SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, false)
shouldShowFloatingWindowDot = false
val chatHelper = KfStartHelper(activity, UserManager.getInstance().userInfoEntity.icon, inputContent, requestCode)
val chatHelper = KfStartHelper(activity, UserManager.getInstance().userInfoEntity?.icon, inputContent, requestCode)
chatHelper.initSdkChat(
ImReceiver.UNIQUE_BROADCAST_ACTION,
IM_KEY,
UserManager.getInstance().userInfoEntity.name + "(" + UserManager.getInstance().userId + ")"
UserManager.getInstance().userInfoEntity?.name + "(" + UserManager.getInstance().userId + ")"
+ "[" + BuildConfig.VERSION_NAME + "]",
UserManager.getInstance().userId)
} catch (e: Exception) {

View File

@ -1,18 +1,18 @@
package com.gh.common.loghub
import android.app.Application
import androidx.annotation.Keep
import com.aliyun.sls.android.sdk.model.Log
import com.aliyun.sls.android.sdk.model.LogGroup
import com.gh.common.exposure.ExposureEntity
import com.gh.common.exposure.meta.Meta
import com.gh.loghub.LoghubHelper
import org.json.JSONObject
import java.util.concurrent.Executors
import kotlin.concurrent.fixedRateTimer
object LoghubUtils {
private const val STORE_SIZE = 100
private const val STORE_FORCE_UPLOAD_INTERVAL = 120 * 1000L
private lateinit var mApplication: Application
private val loghubEventSet by lazy { hashSetOf<LoghubEvent>() }
@ -27,10 +27,6 @@ object LoghubUtils {
val eventList = loghubEventDao.getAll()
loghubEventSet.addAll(eventList)
}
fixedRateTimer(name = "Loghub-Event-Checker", initialDelay = 1000, period = STORE_FORCE_UPLOAD_INTERVAL) {
commitSavedLoghubEvents()
}
}
@JvmStatic
@ -50,11 +46,28 @@ object LoghubUtils {
}
}
@JvmStatic
fun log(jsonString: String, logStore: String, forcedUpload: Boolean) {
loghubEventExecutor.execute {
try {
val event = LoghubEvent(time = (System.currentTimeMillis() / 1000L).toString(), content = jsonString, logStore = logStore)
loghubEventSet.add(event)
loghubEventDao.insert(event)
} catch (e: Exception) {
e.printStackTrace()
}
if (forcedUpload || loghubEventSet.size >= STORE_SIZE) {
commitSavedLoghubEvents()
}
}
}
private fun uploadLogGroup(logGroup: LogGroup, logStore: String) {
LoghubHelper.getInstance().uploadLogGroup(logGroup, logStore)
}
private fun commitSavedLoghubEvents() {
fun commitSavedLoghubEvents() {
loghubEventExecutor.execute {
if (loghubEventSet.isEmpty()) return@execute
@ -93,4 +106,12 @@ object LoghubUtils {
}
}
}
}
@Keep
data class SimpleLogContainerEntity(
var event: String? = null,
var action: String? = null,
var meta: Meta? = null,
var payload: ExposureEntity? = null,
var timestamp: Long? = 0)

View File

@ -1,5 +1,6 @@
package com.gh.common.repository
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.ApkActiveUtils
import com.gh.common.util.RandomUtils
import com.gh.gamecenter.entity.GameEntity
@ -15,7 +16,8 @@ object RemenkapaiRepository {
@JvmStatic
fun getRemenkapai(size: Int): Observable<List<GameEntity>> {
return if (remenkapaiList.isEmpty()) {
RetrofitManager.getInstance(getApplication()).api.remenkapai
RetrofitManager.getInstance(getApplication()).sensitiveApi.remenkapai
.map(RegionSettingHelper.filterGame)
.map { gameList -> filterEntityWithoutApk(gameList) }
.map { pickRandomSizeEntity(size) }
.map(ApkActiveUtils.filterMapperList)

View File

@ -5,14 +5,17 @@ object SyncFieldConstants {
// 是否点赞
const val ANSWER_VOTE = "ANSWER_VOTE"
const val ARTICLE_VOTE = "ARTICLE_VOTE"
const val ARTICLE_COMMENT_VOTE = "ARTICLE_COMMENT_VOTE"
// 赞同数量
const val ANSWER_VOTE_COUNT = "ANSWER_VOTE_COUNT"
const val ARTICLE_VOTE_COUNT = "ARTICLE_VOTE_COUNT"
const val ARTICLE_COMMENT_VOTE_COUNT = "ARTICLE_COMMENT_VOTE_COUNT"
// 评论数量
const val ANSWER_COMMENT_COUNT = "ANSWER_COMMENT_COUNT"
const val ARTICLE_COMMENT_COUNT = "ARTICLE_COMMENT_COUNT"
const val ARTICLE_COMMENT_REPLY_COUNT = "ARTICLE_COMMENT_REPLY_COUNT"
// 回答数量
const val ANSWER_COUNT = "ANSWER_COUNT"

View File

@ -21,9 +21,7 @@ object ActivationHelper {
*/
@JvmStatic
fun sendActivationInfo() {
// 能获取到 IMEI 并且之前没发送过激活信息才发
if (!mHasSentActivatedInfo
&& Util_System_Phone_State.canGetImei(HaloApp.getInstance().application)) {
if (!mHasSentActivatedInfo) {
RetrofitManager.getInstance(HaloApp.getInstance().application)
.api.postActivationInfo()
.subscribeOn(Schedulers.io())

View File

@ -0,0 +1,14 @@
package com.gh.common.util
import com.alibaba.wireless.security.jaq.avmp.IJAQAVMPSignComponent
import com.alibaba.wireless.security.open.SecurityGuardManager
import com.halo.assistant.HaloApp
object AntiBotHelper {
@JvmStatic
val manager by lazy {
SecurityGuardManager.getInstance(HaloApp.getInstance().application).getInterface(IJAQAVMPSignComponent::class.java).apply {
this.initialize()
}
}
}

View File

@ -0,0 +1,6 @@
package com.gh.common.util
interface BiCallback<FIRST, SECOND> {
fun onFirst(first: FIRST)
fun onSecond(second: SECOND)
}

View File

@ -0,0 +1,9 @@
package com.gh.common.util
import com.gh.gamecenter.room.AppDatabase
import com.gh.gamecenter.room.dao.CommentDraftDao
import com.halo.assistant.HaloApp
object CommentDraftContainer {
val commentDraftDao: CommentDraftDao by lazy { AppDatabase.getInstance(HaloApp.getInstance().application).commentDraftDao() }
}

View File

@ -1,14 +1,19 @@
package com.gh.common.util
import android.content.Context
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.common.util.CommentUtils.copyText
import com.gh.common.view.BugFixedPopupWindow
import com.gh.gamecenter.CommentDetailActivity
import com.gh.gamecenter.MessageDetailActivity
import com.gh.gamecenter.adapter.OnCommentCallBackListener
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.entity.MeEntity
import com.gh.gamecenter.entity.Permissions
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
@ -23,27 +28,29 @@ import retrofit2.HttpException
object CommentHelper {
@JvmStatic
fun showCommunityArticleCommentOptions(context: Context,
fun showCommunityArticleCommentOptions(view: View,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String,
communityId: String,
listener: OnCommentCallBackListener?) {
showCommentOptions(context = context,
ignoreModerator: Boolean = false,
listener: OnCommentOptionClickListener?) {
showCommentOptions(view = view,
commentEntity = commentEntity,
showConversation = showConversation,
articleId = articleId,
communityId = communityId,
ignoreModerator = ignoreModerator,
listener = listener)
}
@JvmStatic
fun showAnswerCommentOptions(context: Context,
fun showAnswerCommentOptions(view: View,
commentEntity: CommentEntity,
showConversation: Boolean,
answerId: String,
listener: OnCommentCallBackListener?) {
showCommentOptions(context = context,
listener: OnCommentOptionClickListener?) {
showCommentOptions(view = view,
commentEntity = commentEntity,
showConversation = showConversation,
answerId = answerId,
@ -51,31 +58,41 @@ object CommentHelper {
}
@JvmStatic
fun showVideoCommentOptions(context: Context,
fun showVideoCommentOptions(view: View,
commentEntity: CommentEntity,
showConversation: Boolean,
videoId: String,
listener: OnCommentCallBackListener?) {
showCommentOptions(context = context,
isVideoAuthor: Boolean,
listener: OnCommentOptionClickListener?) {
showCommentOptions(view = view,
commentEntity = commentEntity,
showConversation = showConversation,
videoId = videoId,
isVideoAuthor = isVideoAuthor,
listener = listener)
}
private fun showCommentOptions(context: Context,
private fun showCommentOptions(view: View,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String? = null,
communityId: String? = null,
answerId: String? = null,
videoId: String? = null,
listener: OnCommentCallBackListener? = null) {
ignoreModerator: Boolean = false,
isVideoAuthor: Boolean = false,
listener: OnCommentOptionClickListener? = null) {
val context = view.context
val dialogOptions = ArrayList<String>()
if (isVideoAuthor || (videoId != null && commentEntity.user.id == UserManager.getInstance().userId)) {
dialogOptions.add("删除评论")
}
dialogOptions.add("复制")
dialogOptions.add("投诉")
commentEntity.me?.let {
if (ignoreModerator) return@let
if (it.isModerator || (it.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|| it.moderatorPermissions.topAnswerComment > Permissions.GUEST
|| it.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST
@ -88,55 +105,75 @@ object CommentHelper {
dialogOptions.add("查看对话")
}
DialogUtils.showListDialog(context, dialogOptions, null) {
when (it) {
"管理" -> showControlDialog(context, answerId, articleId, communityId, commentEntity, commentEntity.me!!)
val inflater = LayoutInflater.from(context)
val layout = inflater.inflate(R.layout.comment_more_option, null)
val popupWindow = BugFixedPopupWindow(layout,
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
val container = layout.findViewById<LinearLayout>(R.id.container)
for (text in dialogOptions) {
val item = inflater.inflate(R.layout.comment_more_option_item, container, false)
container.addView(item)
"复制" -> copyText(commentEntity.content, context)
val hitText = item.findViewById<TextView>(R.id.hint_text)
hitText.text = text
"投诉" -> {
context.ifLogin("回答详情-评论-投诉") {
showReportTypeDialog(context) { reportType ->
item.setOnClickListener {
popupWindow.dismiss()
listener?.onCommentOptionClick(commentEntity, text)
when (text) {
"管理" -> showControlDialog(context, answerId, articleId, communityId, commentEntity, commentEntity.me!!)
val commentListener = object : PostCommentUtils.PostCommentListener {
override fun postSuccess(response: JSONObject?) {
Utils.toast(context, "感谢您的投诉")
}
"复制" -> copyText(commentEntity.content, context)
override fun postFailed(error: Throwable?) {
if (error == null) {
Utils.toast(context, "投诉失败,请稍后重试")
} else {
Utils.toast(context, "投诉失败,${error.message}")
"投诉" -> {
context.ifLogin("回答详情-评论-投诉") {
showReportTypeDialog(context) { reportType ->
val commentListener = object : PostCommentUtils.PostCommentListener {
override fun postSuccess(response: JSONObject?) {
Utils.toast(context, "感谢您的投诉")
}
override fun postFailed(error: Throwable?) {
if (error == null) {
Utils.toast(context, "投诉失败,请稍后重试")
} else {
Utils.toast(context, "投诉失败,${error.message}")
}
}
}
}
if (answerId != null) {
PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
} else if (articleId != null) {
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
} else {
PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
if (answerId != null) {
PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
} else if (articleId != null) {
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
} else {
PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
}
}
}
}
}
"查看对话" -> {
if (answerId != null) {
context.startActivity(CommentDetailActivity
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
} else if (articleId != null) {
context.startActivity(CommentDetailActivity
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
} else {
context.startActivity(CommentDetailActivity
.getVideoCommentIntent(context, commentEntity.id, videoId, null))
"查看对话" -> {
if (answerId != null) {
context.startActivity(CommentDetailActivity
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
} else if (articleId != null) {
context.startActivity(CommentDetailActivity
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
} else {
context.startActivity(CommentDetailActivity
.getVideoCommentIntent(context, commentEntity.id, videoId, isVideoAuthor, null))
}
}
}
}
}
popupWindow.isTouchable = true
popupWindow.isFocusable = true
popupWindow.showAutoOrientation(view)
}
private fun showControlDialog(context: Context,

View File

@ -12,6 +12,8 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.gh.gamecenter.CommentDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
@ -38,7 +40,6 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.core.content.ContextCompat;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
@ -50,9 +51,13 @@ import retrofit2.HttpException;
public class CommentUtils {
public static void setCommentTime(TextView textView, long time) {
textView.setText(getCommentTime(time));
}
public static String getCommentTime(long timestamp) {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
try {
long day = time * 1000;
long day = timestamp * 1000;
String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
format.applyPattern("yyyy");
String currentYear = format.format(day);
@ -63,35 +68,34 @@ public class CommentUtils {
int hour = (int) (min / (60 * 60));
if (hour == 0) {
if (min < 60) {
textView.setText("刚刚");
return "刚刚";
} else {
textView.setText(String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60)));
return String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60));
}
} else {
textView.setText(String.format(Locale.getDefault(), "%d小时前", hour));
return String.format(Locale.getDefault(), "%d小时前", hour);
}
} else if (day >= today - 86400 * 1000 && day < today) {
format.applyPattern("HH:mm");
textView.setText("昨天 ");
return "昨天 ";
} else if (day >= today - 86400 * 1000 * 7 && day < today - 86400 * 1000) {
format.applyPattern("HH:mm");
long days = (today - day) / 86400000 + 1;
textView.setText(String.format(Locale.getDefault(), "%d天前 ", days));
return String.format(Locale.getDefault(), "%d天前 ", days);
} else if (day < today - 86400 * 1000 * 7 && year.equals(currentYear)) {
format.applyPattern("MM-dd");
textView.setText(format.format(day));
return format.format(day);
} else {
format.applyPattern("yyyy-MM-dd");
textView.setText(format.format(day));
return format.format(day);
}
} catch (ParseException e) {
e.printStackTrace();
format.applyPattern("yyyy-MM-dd");
textView.setText(format.format(time * 1000));
return format.format(timestamp * 1000);
}
}
public static void showReportDialog(final CommentEntity commentEntity,
final Context context,
final boolean showConversation,

View File

@ -6,7 +6,7 @@ import android.widget.LinearLayout;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.gamecenter.ViewImageActivity;
import com.gh.gamecenter.ImageViewerActivity;
import java.util.ArrayList;
import java.util.List;
@ -93,7 +93,7 @@ public class ConcernContentUtils {
break;
}
imageView.setOnClickListener(v -> {
Intent checkIntent = ViewImageActivity.getViewImageIntent(context, (ArrayList<String>) list, position, entrance);
Intent checkIntent = ImageViewerActivity.getIntent(context, (ArrayList<String>) list, position, entrance);
context.startActivity(checkIntent);
});
return imageView;

View File

@ -20,12 +20,13 @@ import java.util.Map;
public class DataLogUtils {
// 轮播图
public static void uploadLunbotuLog(Context context, String type, String text, String index, String source) {
public static void uploadLunbotuLog(Context context, String type, String text, String title, String index, String source) {
Map<String, Object> map = new HashMap<>();
map.put("index", index);
map.put("type", type);
map.put("text", text);
map.put("source", source);
map.put("slide_title", title);
uploadLog(context, "slide", map);
}

View File

@ -3,19 +3,16 @@ package com.gh.common.util;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import com.gh.common.constant.Config;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.BuildConfig;
import com.gh.gid.GidCallback;
import com.gh.gid.GidHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Util_System_Phone_State;
import com.lightgame.utils.Utils;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.stat.MtaSDkException;
@ -126,18 +123,25 @@ public class DataUtils {
public static void getGid() {
GidHelper.getInstance().registerDevice(new GidCallback() {
@Override
public void onSuccess(String s) {
Utils.log("Gid", s);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, s).apply();
public void onSuccess(String gid) {
Utils.log("Gid", gid);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
String originalGid = HaloApp.getInstance().getGid();
HaloApp.getInstance().setGid(gid);
// 避免重复调用
if (!TextUtils.isEmpty(gid) && !gid.equals(originalGid)) {
GameSubstituteRepositoryHelper.updateSubstitutableGames();
}
HaloApp.getInstance().setGid(s);
// 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
MetaUtil.INSTANCE.refreshMeta();
}
@Override
public void onFailure(String s) {
Utils.log(s);
MtaHelper.onEventWithBasicDeviceInfo("开发辅助", "GID 获取异常", s);
}
});
}
@ -197,36 +201,36 @@ public class DataUtils {
// 游戏下载
public static void onGameDownloadEvent(Context context, String gameName, String platform, String entrance, String status, String method) {
Map<String, Object> kv = new HashMap<>();
platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
kv.put("版本", platform);
kv.put("用户机型", Build.MODEL);
kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
kv.put("光环助手版本", BuildConfig.VERSION_NAME);
kv.put("位置", entrance);
kv.put("类型", method);
kv.put("厂商", Build.MANUFACTURER);
kv.put("Android版本", Build.VERSION.RELEASE);
onEvent(context, "游戏下载", gameName, kv);
Map<String, Object> kv2 = new HashMap<>();
kv2.put("状态", status);
kv2.put("位置", entrance);
if (status.equals("开始")) {
kv2.put("版本", entrance + "-开始");
kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
} else {
kv2.put("版本", platform);
kv2.put("游戏分平台", gameName + "-" + platform);
kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
}
onEvent(context, "游戏下载位置", gameName, kv2);
// Map<String, Object> kv = new HashMap<>();
//
// platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
//
// kv.put("版本", platform);
// kv.put("用户机型", Build.MODEL);
// kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
// kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
// kv.put("光环助手版本", BuildConfig.VERSION_NAME);
// kv.put("位置", entrance);
// kv.put("类型", method);
// kv.put("厂商", Build.MANUFACTURER);
// kv.put("Android版本", Build.VERSION.RELEASE);
// onEvent(context, "游戏下载", gameName, kv);
//
// Map<String, Object> kv2 = new HashMap<>();
// kv2.put("状态", status);
// kv2.put("位置", entrance);
//
// if (status.equals("开始")) {
// kv2.put("版本", entrance + "-开始");
// kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
// } else {
// kv2.put("版本", platform);
// kv2.put("游戏分平台", gameName + "-" + platform);
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
// }
//
// onEvent(context, "游戏下载位置", gameName, kv2);
}
// 游戏更新

View File

@ -6,6 +6,8 @@ import android.view.View;
import com.gh.common.constant.Config;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.view.DownloadProgressBar;
import com.gh.common.xapk.XapkInstaller;
import com.gh.common.xapk.XapkUnzipStatus;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
@ -13,7 +15,6 @@ import com.gh.gamecenter.entity.LinkEntity;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.Utils;
/**
* Created by khy on 27/06/17.
@ -112,8 +113,18 @@ public class DetailDownloadUtils {
}
public static void detailInvalidate(DetailViewHolder viewHolder) {
viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
DownloadEntity downloadEntity = viewHolder.downloadEntity;
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
viewHolder.mDownloadPb.setText("解压中(" + percent + "%");
viewHolder.mDownloadPb.setProgress((int) (Float.valueOf(percent) * 10));
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.XAPK_UNZIPPING);
return;
}
viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
switch (downloadEntity.getStatus()) {
case downloading:
case pause:

View File

@ -11,6 +11,8 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Util_System_Phone_State;
import com.tencent.stat.StatConfig;
@ -222,8 +224,7 @@ public class DeviceUtils {
// get sim
public static String getSim(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imsi = tm.getSubscriberId();
String imsi = getTelephonySubscriberId(context);
if (imsi == null) {
return "";
}
@ -239,6 +240,12 @@ public class DeviceUtils {
return "";
}
@Nullable
public static String getTelephonySubscriberId(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSubscriberId();
}
// ping domain
public static String ping(String domain) {
try {
@ -269,18 +276,21 @@ public class DeviceUtils {
// 只能获取WiFi的IpAddress
public static String getCurrentIpAddress() {
String ipAddress;
WifiManager wifiManager = (WifiManager) HaloApp.getInstance().
getApplication().
getApplicationContext().
getSystemService(Context.WIFI_SERVICE);
int address = wifiManager.getDhcpInfo().ipAddress;
ipAddress = ((address & 0xFF)
+ "." + ((address >> 8) & 0xFF)
+ "." + ((address >> 16) & 0xFF)
+ "." + ((address >> 24) & 0xFF));
return ipAddress;
String ipAddress = "0.0.0.0";
try {
WifiManager wifiManager = (WifiManager) HaloApp.getInstance().
getApplication().
getApplicationContext().
getSystemService(Context.WIFI_SERVICE);
int address = wifiManager.getDhcpInfo().ipAddress;
ipAddress = ((address & 0xFF)
+ "." + ((address >> 8) & 0xFF)
+ "." + ((address >> 16) & 0xFF)
+ "." + ((address >> 24) & 0xFF));
return ipAddress;
} catch (Exception e) {
return ipAddress;
}
}
}

View File

@ -8,7 +8,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.CountDownTimer;
import android.preference.PreferenceManager;
import android.text.Html;
@ -30,6 +29,12 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.gh.common.AppExecutor;
import com.gh.common.constant.Config;
@ -40,8 +45,10 @@ import com.gh.common.view.LimitHeightLinearLayout;
import com.gh.common.view.MaxHeightNestedScrollView;
import com.gh.gamecenter.AboutActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.SuggestionActivity;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder;
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
import com.gh.gamecenter.databinding.ImprintContentItemBinding;
import com.gh.gamecenter.databinding.PrivacyItemBinding;
import com.gh.gamecenter.entity.ApkEntity;
@ -49,23 +56,19 @@ import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.TrackableEntity;
import com.gh.gamecenter.suggest.SuggestType;
import com.halo.assistant.HaloApp;
import com.halo.assistant.fragment.SettingsFragment;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Utils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
public class DialogUtils {
public static Dialog showWaitDialog(Context context, String msg) {
@ -82,7 +85,6 @@ public class DialogUtils {
return dialog;
}
public static void showInstallHintDialog(Context context, final ConfirmListener cmListener) {
context = checkDialogContext(context);
@ -196,7 +198,7 @@ public class DialogUtils {
AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载,请注意流量消耗"), 500);
callBack.onResponse(false);
} else {
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
showDownloadDialog(context,
() -> callBack.onResponse(false),
() -> callBack.onResponse(true));
@ -256,12 +258,12 @@ public class DialogUtils {
}, 500);
listener.onConfirm();
dialog.dismiss();
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
});
wifiAuto.setOnClickListener(v -> {
cancelListener.onCancel();
dialog.dismiss();
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
});
allowAlways.setOnClickListener(v -> {
PreferenceManager
@ -276,7 +278,7 @@ public class DialogUtils {
}, 500);
listener.onConfirm();
dialog.dismiss();
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
@ -541,8 +543,6 @@ public class DialogUtils {
clListener.onCancel();
});
dialog.show();
}
@ -586,7 +586,6 @@ public class DialogUtils {
dialog.setContentView(contentView);
dialog.setCancelable(false);
dialog.show();
}
/**
@ -667,7 +666,6 @@ public class DialogUtils {
TextPaint tp = mesage.getPaint();
tp.setFakeBoldText(true);
}
}
public static void showSignDialog(Context context, String title, CharSequence message, CharSequence message2
@ -1101,6 +1099,21 @@ public class DialogUtils {
final ConfirmListener cmListener,
final CancelListener clListener,
TrackableEntity trackableEntity) {
return showTrackableDialog(context, false, title, message, positive, negative, cmListener, clListener, trackableEntity);
}
/**
* @param useRoundedCornerStyle 使用圆角样式
*/
public static Dialog showTrackableDialog(Context context,
boolean useRoundedCornerStyle,
String title,
CharSequence message,
String positive,
String negative,
final ConfirmListener cmListener,
final CancelListener clListener,
TrackableEntity trackableEntity) {
context = checkDialogContext(context);
final TrackableDialog dialog = new TrackableDialog(context,
@ -1112,7 +1125,17 @@ public class DialogUtils {
trackableEntity.getKeyBackValue(),
trackableEntity.getLogShowEvent());
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
View contentView;
if (useRoundedCornerStyle) {
contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert_with_rounded_corner, null);
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
} else {
contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
}
TextView contentTv = contentView.findViewById(R.id.dialog_content);
TextView titleTv = contentView.findViewById(R.id.dialog_title);
TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
@ -1267,6 +1290,45 @@ public class DialogUtils {
}
}
// 海外下载地址弹窗
public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
context = checkDialogContext(context);
if (gameEntity.getOverseasAddressDialog() == null
|| gameEntity.getApk().size() == 0
|| !gameEntity.getOverseasAddressDialog().isEnable()) {
listener.onConfirm();
} else {
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
DialogOverseaConfirmationBinding binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.dialog_oversea_confirmation, null, false);
View contentView = binding.getRoot();
binding.setGame(gameEntity);
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
binding.downloadBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
});
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
}
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 showImprintDialog(Context context, GameEntity gameEntity, String titleName) {
context = checkDialogContext(context);
Dialog dialog = new Dialog(context, R.style.full_dialog);
@ -1343,6 +1405,204 @@ public class DialogUtils {
dialog.show();
}
public static void showStopServerExplanationDialog(Context context, String content, String gameName) {
context = checkDialogContext(context);
final Dialog dialog = new TrackableDialog(context, R.style.GhAlertDialog, "评论说明弹窗", "弹窗", gameName, null, null, true);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_stop_service_explanation, null);
TextView contentTv = contentView.findViewById(R.id.contentTv);
MaxHeightNestedScrollView scrollView = contentView.findViewById(R.id.scrollView);
if (TextUtils.isEmpty(content)) {
content = context.getString(R.string.rating_protection);
}
contentTv.setText(content);
TextView ok = contentView.findViewById(R.id.dialog_ok);
scrollView.setScrollChangedListener((l, t, oldl, oldt) -> {
MtaHelper.onEvent("评论说明弹窗", "滑动内容", gameName);
});
ok.setOnClickListener(v -> {
MtaHelper.onEvent("评论说明弹窗", "弹窗", "点击我知道了");
MtaHelper.onEvent("评论说明弹窗", "点击我知道了", gameName);
dialog.dismiss();
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams params = window.getAttributes();
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(60f);
window.setAttributes(params);
}
}
public static void showPluggableNeverRemindDialog(Context context, String nameAndPlatform, @NonNull ConfirmListener listener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_pluggable_never_remind, null);
View cancelBtn = contentView.findViewById(R.id.cancel);
View confirmBtn = contentView.findViewById(R.id.confirm);
TextView contentTv = contentView.findViewById(R.id.content);
contentTv.setText(("助手首页将不再提示《" + nameAndPlatform + "》的所有插件化消息,确定吗?"));
cancelBtn.setOnClickListener(v -> {
dialog.dismiss();
});
confirmBtn.setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
public static void showRegulationTestDialog(Context context, @NonNull ConfirmListener confirmListener, @NonNull CancelListener cancelListener) {
context = checkDialogContext(context);
final Dialog dialog = new TrackableDialog(
context,
R.style.GhAlertDialog,
"礼仪考试",
"礼仪考试弹窗",
null, null, null,
true);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_regulation_test, null);
View cancelBtn = contentView.findViewById(R.id.cancel);
View confirmBtn = contentView.findViewById(R.id.confirm);
View linkTv = contentView.findViewById(R.id.link);
Context finalContext = context;
linkTv.setOnClickListener(v -> {
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "了解更多");
DirectUtils.directToArticle(finalContext, "5f4477be25e07e19be4e2a22", "(礼仪测试弹窗)");
});
cancelBtn.setOnClickListener(v -> {
cancelListener.onCancel();
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "跳过");
dialog.dismiss();
});
Context finalContext1 = context;
confirmBtn.setOnClickListener(v -> {
Util_System_Keyboard.hideSoftKeyboard((Activity) finalContext1);
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "确定");
confirmListener.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 showUnzipFailureDialog(Context context, DownloadEntity downloadEntity) {
final Context activityContext = checkDialogContext(context);
final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawableResource(android.R.color.transparent);
}
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_unzip_failure, null);
View cancelBtn = contentView.findViewById(R.id.cancel);
View confirmBtn = contentView.findViewById(R.id.confirm);
cancelBtn.setOnClickListener(v -> {
dialog.dismiss();
});
confirmBtn.setOnClickListener(v -> {
dialog.dismiss();
String hint = "" + downloadEntity.getName() + "》游戏安装包解压失败,问题反馈:";
SuggestionActivity.startSuggestionActivity(activityContext, SuggestType.normal, null, hint);
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
public static void showNoticeDialog(Context context, String title, String content, @NonNull ConfirmListener listener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_notice, null);
TextView titleTv = contentView.findViewById(R.id.dialog_title);
TextView contentTv = contentView.findViewById(R.id.dialog_content);
if (title == null) {
titleTv.setVisibility(View.GONE);
} else {
titleTv.setVisibility(View.VISIBLE);
titleTv.setText(title);
}
contentTv.setText(content);
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
listener.onConfirm();
dialog.dismiss();
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
public static void showUploadVideoChangeLabelDialog(Context context, @NonNull ConfirmListener confirmListener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_upload_video_change_label, null);
View cancelBtn = contentView.findViewById(R.id.cancel);
View confirmBtn = contentView.findViewById(R.id.confirm);
cancelBtn.setOnClickListener(v -> {
dialog.dismiss();
});
confirmBtn.setOnClickListener(v -> {
confirmListener.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();
}
/**
* @param context may be is application context
* @return activity context

View File

@ -6,11 +6,18 @@ import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.gh.base.BaseActivity
import com.gh.base.ToolBarActivity
import com.gh.base.fragment.BaseFragment_TabLayout
import com.gh.common.AppExecutor
import com.gh.common.constant.Config
import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureEvent.Companion.createEvent
import com.gh.common.exposure.ExposureManager.log
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
import com.gh.common.exposure.ExposureType
import com.gh.common.util.EntranceUtils.*
import com.gh.gamecenter.*
import com.gh.gamecenter.amway.AmwayActivity
@ -19,9 +26,14 @@ import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity
import com.gh.gamecenter.game.upload.GameSubmissionActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.mygame.PlayedGameActivity
import com.gh.gamecenter.personalhome.UserHomeActivity
@ -32,17 +44,24 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.servers.GameServersActivity
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.suggest.SuggestType
import com.gh.gamecenter.tag.TagsActivity
import com.gh.gamecenter.video.data.VideoDataActivity
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.gh.gamecenter.video.game.GameVideoActivity
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Util_System_ClipboardManager
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException
/**
* 跳转用的方法
@ -79,9 +98,6 @@ object DirectUtils {
}
}
/**
* 跳转到特定页面,只支持App内部跳转
*/
@JvmStatic
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
directToLinkPage(context, linkEntity, entrance, path, null)
@ -124,30 +140,39 @@ object DirectUtils {
when (linkEntity.type) {
"article", "news", "文章" -> {
NewsUtils.statNewsViews(context, linkEntity.link) // 统计阅读量
context.startActivity(NewsDetailActivity.getIntentById(context, linkEntity.link, BaseActivity.mergeEntranceAndPath(entrance, path)))
directToArticle(context, linkEntity.link
?: "", BaseActivity.mergeEntranceAndPath(entrance, path))
}
"game", "游戏" -> {
if (exposureEvent != null) {
GameDetailActivity.startGameDetailActivity(context, linkEntity.link, BaseActivity.mergeEntranceAndPath(entrance, path), exposureEvent)
directToGameDetail(context, linkEntity.link
?: "", BaseActivity.mergeEntranceAndPath(entrance, path), traceEvent = exposureEvent)
} else {
GameDetailActivity.startGameDetailActivity(context, linkEntity.link, BaseActivity.mergeEntranceAndPath(entrance, path))
directToGameDetail(context, linkEntity.link
?: "", BaseActivity.mergeEntranceAndPath(entrance, path))
}
}
"column", "游戏专题" -> SubjectActivity.startSubjectActivity(context, linkEntity.link, linkEntity.text, false, BaseActivity.mergeEntranceAndPath(entrance, path))
"column", "游戏专题" -> directToSubject(context, linkEntity.link
?: "", linkEntity.text, BaseActivity.mergeEntranceAndPath(entrance, path))
"question", "社区问题" -> context.startActivity(QuestionsDetailActivity.getIntent(context, linkEntity.link, entrance, path))
"question", "社区问题" -> directToQuestionDetail(context, linkEntity.link
?: "", entrance, path)
"answer", "社区回答" -> context.startActivity(AnswerDetailActivity.getIntent(context, linkEntity.link, entrance, path))
"answer", "社区回答" -> directToAnswerDetail(context, linkEntity.link ?: "", entrance, path)
"community", "问答社区" -> directToCommunity(context, CommunityEntity(linkEntity.link!!, linkEntity.text!!))
"community", "问答社区" -> {
if (linkEntity.link.isNullOrEmpty()) return
directToCommunity(context, CommunityEntity(linkEntity.link!!, linkEntity.text!!))
}
"community_article", "社区文章" -> context.startActivity(ArticleDetailActivity.getIntent(context, linkEntity.community!!, linkEntity.link!!, entrance, path))
"community_article", "社区文章" -> directToCommunityArticle(context, linkEntity.community!!, linkEntity.link!!, entrance, path)
"community_column", "社区专题" -> directToCommunityColumn(context, linkEntity.community, linkEntity.link!!, entrance, path)
"community_special_column" -> context.startActivity(AskColumnDetailActivity.getIntentByColumnId(context, linkEntity.link, linkEntity.community!!, entrance, path))
"community_special_column" -> directAskColumnDetail(context, linkEntity.link
?: "", linkEntity.community!!, entrance, path)
"web", "inurl", "web链接" -> {
when {
@ -166,37 +191,31 @@ object DirectUtils {
"tag" -> context.startActivity(TagsActivity.getIntent(context, linkEntity.text!!, linkEntity.title, entrance, path))
"all_community_article" -> {
context.startActivity(SimpleArticleListActivity.getIntent(
context,
linkEntity.link ?: "",
entrance,
path))
}
"all_community_article" -> directSimpleArticleList(context, linkEntity.link
?: "", entrance, path)
"category", "分类" -> {
context.startActivity(CategoryDirectoryActivity.getIntent(context, linkEntity.link!!, linkEntity.text!!))
}
"category", "分类" -> directCategoryDirectory(context, linkEntity.link!!, linkEntity.text!!)
"block", "版块" -> {
context.startActivity(BlockActivity.getIntent(context, SubjectRecommendEntity(
link = linkEntity.link,
text = linkEntity.text,
name = linkEntity.name,
display = linkEntity.display ?: Display())))
if (linkEntity.link.isNullOrEmpty()) return
directToBlock(context,
SubjectRecommendEntity(
link = linkEntity.link,
text = linkEntity.text,
name = linkEntity.name,
display = linkEntity.display ?: Display()),
entrance)
}
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
"server", "game_server" -> {
context.startActivity(GameServersActivity.getIntent(context, entrance, path))
}
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path)
"top_game_comment" -> directToAmway(context, null, entrance, path)
"wechat_bind" -> context.startActivity(WebActivity.getBindWechatIntent(context))
"video", "video_stream" -> directToVideoDetail(context,
"video", "video_stream", "视频" -> directToVideoDetail(context,
videoId = linkEntity.link!!,
fromLocation = VideoDetailContainerViewModel.Location.VIDEO_CHOICENESS.value,
entrance = entrance,
@ -204,16 +223,23 @@ object DirectUtils {
"game_video" -> directToGameVideo(context, linkEntity.link ?: "", entrance, path)
"libao" -> directToGiftDetail(context, linkEntity.link ?: "", entrance)
"libao", "礼包" -> directToGiftDetail(context, linkEntity.link ?: "", entrance)
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, entrance)
"qa" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
"qa_collection" -> directToQaCollection(context, linkEntity.text ?: "", linkEntity.link
"qa_collection", "Q&A合集" -> directToQaCollection(context, linkEntity.text
?: "", linkEntity.link
?: "")
"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)
"game_upload", "游戏投稿" -> directGameUpload(context, entrance, path)
"bbs_detail" -> directForumDetail(context, linkEntity.link ?: "", entrance)
//"h5_game_center" -> directLetoGameCenter(context)
@ -233,15 +259,27 @@ object DirectUtils {
/**
* 跳转至QA
*/
@JvmStatic
fun directToQa(context: Context, text: String, id: String) {
context.startActivity(QaActivity.getIntent(context, navigationTitle = text, qaId = id))
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, QaActivity::class.java.simpleName)
bundle.putString(KEY_NAVIGATION_TITLE, text)
bundle.putString(KEY_QA_ID, id)
jumpActivity(context, bundle)
}
/**
* 跳转至QA合集
*/
@JvmStatic
fun directToQaCollection(context: Context, text: String, id: String) {
context.startActivity(QaActivity.getIntent(context, navigationTitle = text, qaCollectionId = id))
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, QaActivity::class.java.simpleName)
bundle.putString(KEY_NAVIGATION_TITLE, text)
bundle.putString(KEY_QA_COLLECTION_ID, id)
jumpActivity(context, bundle)
}
/**
@ -249,7 +287,53 @@ object DirectUtils {
*/
@JvmStatic
fun directToColumnCollection(context: Context, id: String, position: Int = -1, entrance: String, columnName: String = "") {
context.startActivity(ColumnCollectionDetailActivity.getIntent(context, id, position, entrance, columnName))
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, ColumnCollectionDetailActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_COLLECTION_ID, id)
bundle.putString(KEY_COLUMNNAME, columnName)
bundle.putInt(KEY_POSITION, position)
jumpActivity(context, bundle)
}
/**
* 跳转至资讯文章列表
*/
@JvmStatic
fun directToGameNews(context: Context, gameId: String?, gameName: String?, entrance: String?) {
val bundle = Bundle()
bundle.putString(KEY_TO, GameNewsActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_GAMENAME, gameName)
jumpActivity(context, bundle)
}
/**
* 跳转至游戏日历表
*/
@JvmStatic
fun directToGameServerCalendar(context: Context, gameId: String?) {
val bundle = Bundle()
bundle.putString(KEY_TO, ServersCalendarActivity::class.java.name)
bundle.putParcelable(GameEntity::class.java.simpleName, GameEntity().apply {
id = gameId ?: ""
})
bundle.putParcelable(GameDetailServer::class.java.simpleName, GameDetailServer())
bundle.putParcelable(MeEntity::class.java.simpleName, MeEntity())
jumpActivity(context, bundle)
}
/**
* 跳转至游戏历史版本页面
*/
@JvmStatic
fun directToHistoryApk(context: Context, gameId: String?) {
val bundle = Bundle()
bundle.putString(KEY_TO, HistoryApkListActivity::class.java.name)
bundle.putString(KEY_GAMEID, gameId)
jumpActivity(context, bundle)
}
/**
@ -257,6 +341,7 @@ object DirectUtils {
*/
@JvmStatic
fun directToArticle(context: Context, id: String, entrance: String? = null) {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
@ -299,19 +384,42 @@ object DirectUtils {
* 跳转到游戏详情
*/
@JvmStatic
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null, scrollToLibao: Boolean = false) {
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null, tab: String? = "", traceEvent: ExposureEvent? = null) {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, GameDetailActivity::class.java.simpleName)
bundle.putString(KEY_GAMEID, id)
if (scrollToLibao) {
bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_TRENDES)
bundle.putBoolean(KEY_SCROLL_TO_LIBAO, scrollToLibao)
if (!TextUtils.isEmpty(tab)) {
when (tab) {
"comment" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_RATING)
"desc" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_DESC)
"forum" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_BBS)
"zone" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_TRENDES)
}
}
if (traceEvent != null) {
val clickEvent = createEvent(GameEntity(id), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK)
log(clickEvent)
bundle.putParcelable(KEY_TRACE_EVENT, clickEvent)
}
bundle.putBoolean(KEY_AUTO_DOWNLOAD, autoDownload ?: false)
jumpActivity(context, bundle)
}
/**
* 跳转到游戏评分详情
*/
@JvmStatic
fun directToGameRatingDetail(context: Context, gameId: String? = "", commentId: String? = "", entrance: String? = null) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_COMMENTID, commentId)
bundle.putString(KEY_TO, RatingReplyActivity::class.java.name)
jumpActivity(context, bundle)
}
/**
* 跳转视频流-游戏介绍进入
*/
@ -323,7 +431,16 @@ object DirectUtils {
bundle.putString(KEY_GAMEID, id)
bundle.putBoolean(KEY_OPEN_VIDEO_STREAMING, true)
bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_DESC)
// GameDetailActivity.startGameDetailToVideoStreaming(context, id, entrance)
jumpActivity(context, bundle)
}
@JvmStatic
fun directToGameDetail(context: Context, id: String, defaultTab: Int = GameDetailFragment.INDEX_DESC, entrance: String? = null) {
val bundle = Bundle()
bundle.putString(KEY_TO, GameDetailActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_GAMEID, id)
bundle.putInt(KEY_TARGET, defaultTab)
jumpActivity(context, bundle)
}
@ -335,6 +452,7 @@ object DirectUtils {
// 专栏
@JvmStatic
fun directToSubject(context: Context, id: String, subjectName: String? = "", entrance: String? = null) {
if (id.isEmpty()) return
val bundle = Bundle()
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false)
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
@ -411,6 +529,7 @@ object DirectUtils {
@JvmStatic
fun directToAnswerDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, AnswerDetailActivity::class.java.name)
@ -421,6 +540,7 @@ object DirectUtils {
@JvmStatic
fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, QuestionsDetailActivity::class.java.name)
@ -431,6 +551,7 @@ object DirectUtils {
@JvmStatic
fun directToWebView(context: Context, url: String, entrance: String? = null) {
if (url.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, WebActivity::class.java.simpleName)
@ -449,7 +570,11 @@ object DirectUtils {
@JvmStatic
fun directToExternalBrowser(context: Context, url: String) {
if (url.isEmpty()) return
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
if (context !is AppCompatActivity) {
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(browserIntent)
}
@ -470,7 +595,11 @@ object DirectUtils {
chatType = "wpa"
}
val str = "mqqwpa://im/chat?chat_type=$chatType&uin=$qq&version=1&src_type=web"
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str)))
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(str))
if (context !is AppCompatActivity) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
} else {
// 没有安装QQ 复制账号
Util_System_ClipboardManager.setText(context, qq)
@ -481,17 +610,25 @@ object DirectUtils {
// 跳转 QQ 群
@JvmStatic
fun directToQqGroup(context: Context, groupNumber: String? = null): Boolean {
val intent = Intent()
intent.data = Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$groupNumber")
// 此Flag可根据具体产品需要自定义如设置则在加群界面按返回返回手Q主界面不设置按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
context.startActivity(intent)
return true
} catch (e: Exception) {
// 未安装手Q或安装的版本不支持
if (groupNumber.isNullOrEmpty()) return false
if (ShareUtils.isQQClientAvailable(context)) {
val intent = Intent()
intent.data = Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$groupNumber")
// 此Flag可根据具体产品需要自定义如设置则在加群界面按返回返回手Q主界面不设置按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
return try {
if (context !is AppCompatActivity) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
true
} catch (e: Exception) {
false
}
} else {
Utils.toast(context, "请安装QQ客户端")
return false
}
}
/**
@ -499,10 +636,12 @@ object DirectUtils {
*/
@JvmStatic
fun directToGiftDetail(context: Context, giftId: String, entrance: String? = null) {
if (giftId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, LibaoDetailActivity::class.java.simpleName)
bundle.putString(EntranceUtils.KEY_ID, giftId)
HaloApp.put(LibaoEntity.TAG, null)
jumpActivity(context, bundle)
}
@ -551,11 +690,24 @@ object DirectUtils {
jumpActivity(context, bundle)
}
@JvmStatic
fun directToCommunityArticle(context: Context, community: CommunityEntity?, articleId: String?, entrance: String?, path: String?) {
if (articleId.isNullOrEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, ArticleDetailActivity::class.java.name)
bundle.putString(KEY_COMMUNITY_ARTICLE_ID, articleId)
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
jumpActivity(context, bundle)
}
/**
* 跳转到社区专题
*/
@JvmStatic
fun directToCommunityColumn(context: Context, community: CommunityEntity?, subjectId: String, entrance: String?, path: String?) {
if (subjectId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, CommunitySubjectActivity::class.java.name)
@ -569,7 +721,8 @@ object DirectUtils {
* @param fromLocation 可见 [VideoDetailContainerViewModel.Location]
*/
@JvmStatic
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null, path: String? = "", referer: String = "", type: String = "", act: String = "") {
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null,
path: String? = "", referer: String = "", type: String = "", act: String = "", paginationType: String = "", fieldId: String = "", sectionName: String = "") {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
@ -582,6 +735,9 @@ object DirectUtils {
bundle.putString(KEY_REFERER, referer)
bundle.putString(KEY_TYPE, type)
bundle.putString(KEY_ACTIVITY_NAME, act)
bundle.putString(KEY_PAGINATION_TYPE, paginationType)
bundle.putString(KEY_FIELD_ID, fieldId)
bundle.putString(KEY_SECTION_NAME, sectionName)
jumpActivity(context, bundle)
} else {
DialogUtils.showLowSystemVersionDialog(context)
@ -619,20 +775,37 @@ object DirectUtils {
* 跳转至上传视频
*/
@JvmStatic
fun directToVideoManager(context: Context, linkEntity: VideoLinkEntity, entrance: String? = null, path: String? = "") {
fun directToVideoManager(context: Context, linkEntity: VideoLinkEntity, simpleGameEntity: SimpleGameEntity, entrance: String? = null, path: String? = "") {
val bundle = Bundle()
bundle.putString(KEY_PATH, path)
bundle.putParcelable(VideoLinkEntity::class.java.simpleName, linkEntity)
bundle.putParcelable(SimpleGameEntity::class.java.simpleName, simpleGameEntity)
bundle.putString(KEY_TO, VideoManagerActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
jumpActivity(context, bundle)
}
@JvmStatic
fun directToFullScreenWebPage(context: Context, url: String, webViewHandleBackPressed: Boolean = false) {
context.startActivity(FullScreenWebActivity.getIntent(context, url, webViewHandleBackPressed))
}
@JvmStatic
fun directToRegulationTestPage(context: Context) {
val url = if ("internal" == BuildConfig.FLAVOR) {
Constants.REGULATION_TEST_ADDRESS_DEV
} else {
Constants.REGULATION_TEST_ADDRESS
}
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转视频合集
*/
@JvmStatic
fun directToGameVideo(context: Context, gameId: String, entrance: String? = null, path: String? = "") {
if (gameId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, GameVideoActivity::class.java.name)
@ -680,6 +853,7 @@ object DirectUtils {
*/
@JvmStatic
fun directCategoryDirectory(context: Context, categoryId: String, categoryTitle: String, entrance: String? = null, path: String? = "") {
if (categoryId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, CategoryDirectoryActivity::class.java.name)
bundle.putString(KEY_CATEGORY_ID, categoryId)
@ -708,6 +882,7 @@ object DirectUtils {
*/
@JvmStatic
fun directAskColumnDetail(context: Context, columnId: String, community: CommunityEntity, entrance: String? = null, path: String? = "") {
if (columnId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, AskColumnDetailActivity::class.java.name)
bundle.putString(KEY_COLUMN_ID, columnId)
@ -716,4 +891,118 @@ object DirectUtils {
bundle.putString(KEY_PATH, path)
jumpActivity(context, bundle)
}
/**
* 跳转到板块
*/
@JvmStatic
fun directToBlock(context: Context, blockData: SubjectRecommendEntity, entrance: String) {
val bundle = Bundle()
bundle.putString(KEY_TO, BlockActivity::class.java.name)
bundle.putParcelable(KEY_BLOCK_DATA, blockData)
bundle.putString(KEY_ENTRANCE, entrance)
jumpActivity(context, bundle)
}
/**
* 跳转到开服表
*/
@JvmStatic
fun directToGameServers(context: Context, entrance: String, path: String) {
val bundle = Bundle()
bundle.putString(KEY_TO, GameServersActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, ToolBarActivity.mergeEntranceAndPath(entrance, path))
jumpActivity(context, bundle)
}
/**
* 跳转到游戏上传
*/
@JvmStatic
fun directGameUpload(context: Context, entrance: String? = null, path: String? = "") {
val bundle = Bundle()
bundle.putString(KEY_TO, GameSubmissionActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_PATH, path)
jumpActivity(context, bundle)
}
/**
* 社区文章
*/
@JvmStatic
fun directSimpleArticleList(context: Context, sortType: String, entrance: String? = null, path: String? = "") {
if (sortType.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, SimpleArticleListActivity::class.java.name)
bundle.putString(KEY_TYPE, sortType)
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_PATH, path)
jumpActivity(context, bundle)
}
@JvmStatic
fun directGameZone(context: Context, gameId: String, url: String, entrance: String? = null) {
RetrofitManager.getInstance(HaloApp.getInstance().application)
.sensitiveApi
.getGameDigest(gameId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(response: GameEntity?) {
response?.apply {
if (zone.status == "on") {
if (zone.style == "link") {
directToGameDetail(context, gameId, GameDetailFragment.INDEX_TRENDES, entrance)
} else {
directToWebView(context, url, entrance)
}
} else {
directToWebView(context, url, entrance)
}
}
}
override fun onFailure(e: HttpException?) {
}
})
}
@JvmStatic
fun directVideoData(context: Context, entrance: String? = null) {
val bundle = Bundle()
bundle.putString(KEY_TO, VideoDataActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
jumpActivity(context, bundle)
}
@JvmStatic
fun directForumDetail(context: Context, bbsId: String? = "", entrance: String? = null) {
val bundle = Bundle()
bundle.putString(KEY_TO, ForumDetailActivity::class.java.name)
bundle.putString(KEY_BBS_ID, bbsId)
bundle.putString(KEY_ENTRANCE, entrance)
jumpActivity(context, bundle)
}
/**
* 到首页论坛 tab
*/
@JvmStatic
fun directToForum(context: Context) {
if (RunningUtils.isRunning(context)
&& MainActivity::class.java.name == RunningUtils.getBaseActivity(context)) {
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
// 这里换个线程操作是为了做一点延时
AppExecutor.ioExecutor.execute {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
}
} else {
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_ASK) })
}
}
}

View File

@ -9,6 +9,7 @@ import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
@ -271,6 +272,26 @@ public class DisplayUtils {
return metrics.heightPixels;
}
public static int getToastOffset() {
try {
int i = Resources.getSystem().getIdentifier("toast_y_offset", "dimen", "android");
return HaloApp.getInstance().getApplication().getResources().getDimensionPixelSize(i);
} catch (Resources.NotFoundException e) {
e.printStackTrace();
return dip2px(24);
}
}
public static int getToastDefaultGravity() {
try {
int i = Resources.getSystem().getIdentifier("config_toastDefaultGravity", "integer", "android");
return HaloApp.getInstance().getApplication().getResources().getInteger(i);
} catch (Resources.NotFoundException e) {
e.printStackTrace();
return Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
}
}
public static boolean hasSoftKeys(Context context) {
if (!(context instanceof Activity)) return false;

View File

@ -1,5 +1,6 @@
package com.gh.common.util
import com.gh.common.filter.RegionSettingHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.retrofit.Response
@ -18,8 +19,12 @@ object DownloadHelper {
* @param block 成功添加下载任务后执行的代码块
*/
fun createABrandNewDownloadTaskQuietly(gameId: String? = "", packageName: String? = "", block: () -> Unit) {
if (RegionSettingHelper.shouldThisGameBeFiltered(gameId)) {
return
}
RetrofitManager.getInstance(HaloApp.getInstance().application)
.api
.sensitiveApi
.getGameDigest(gameId)
.map(ApkActiveUtils.filterMapper)
.subscribeOn(Schedulers.io())

View File

@ -15,6 +15,8 @@ import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.history.HistoryHelper;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.xapk.XapkInstaller;
import com.gh.common.xapk.XapkUnzipStatus;
import com.gh.download.DownloadManager;
import com.gh.download.dialog.DownloadDialog;
import com.gh.gamecenter.DownloadManagerActivity;
@ -134,16 +136,23 @@ public class DownloadItemUtils {
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
boolean isShowPlatform) {
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, false);
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, false, null);
}
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
boolean isShowPlatform, boolean hideDownloadBtnIfNoAvailableContent) {
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, hideDownloadBtnIfNoAvailableContent);
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, hideDownloadBtnIfNoAvailableContent, null);
}
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
boolean isShowPlatform, PluginLocation pluginLocation, boolean hideDownloadBtnIfNoAvailableContent) {
boolean isShowPlatform, String briefStyle) {
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, false, briefStyle);
}
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
boolean isShowPlatform, PluginLocation pluginLocation,
boolean hideDownloadBtnIfNoAvailableContent,
@Nullable String briefStyle) {
// 控制是否显示下载按钮
if (!Config.isShowDownload(gameEntity.getId()) || context.getString(R.string.app_name).equals(gameEntity.getName())) {
@ -154,9 +163,7 @@ public class DownloadItemUtils {
// 显示预约
if (gameEntity.isReservable()) {
holder.gameDes.setVisibility(View.VISIBLE);
holder.gameProgressbar.setVisibility(View.GONE);
holder.gameInfo.setVisibility(View.GONE);
updateItemViewStatus(holder, false, briefStyle);
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
holder.gameDownloadBtn.setText("预约");
holder.gameDownloadBtn.setTextColor(Color.WHITE);
@ -174,9 +181,7 @@ public class DownloadItemUtils {
LinkEntity h5LinkEntity = gameEntity.getH5Link();
String offStatus = gameEntity.getDownloadOffStatus();
holder.gameDes.setVisibility(View.VISIBLE);
holder.gameProgressbar.setVisibility(View.GONE);
holder.gameInfo.setVisibility(View.GONE);
updateItemViewStatus(holder, false, briefStyle);
if (h5LinkEntity != null) {
if ("play".equals(h5LinkEntity.getType())) {
@ -201,16 +206,16 @@ public class DownloadItemUtils {
holder.gameDownloadBtn.setClickable(false);
}
} else if (gameEntity.getApk().size() == 1) {
updateNormalItem(context, holder, gameEntity, isShowPlatform, pluginLocation);
updateNormalItem(context, holder, gameEntity, isShowPlatform, pluginLocation, briefStyle);
} else {
updatePluginItem(context, holder, gameEntity, isShowPlatform, pluginLocation);
updatePluginItem(context, holder, gameEntity, isShowPlatform, pluginLocation, briefStyle);
}
}
// 更新正常的条目只有一个apk包
static void updateNormalItem(Context context, GameViewHolder holder, GameEntity gameEntity,
boolean isShowPlatform, PluginLocation pluginLocation) {
boolean isShowPlatform, PluginLocation pluginLocation, String briefStyle) {
final ArrayMap<String, DownloadEntity> entryMap = gameEntity.getEntryMap();
final ApkEntity apkEntity = gameEntity.getApk().get(0);
@ -226,14 +231,12 @@ public class DownloadItemUtils {
GameUtils.setDownloadBtnStatus(context, gameEntity, holder.gameDownloadBtn, pluginLocation);
holder.gameDes.setVisibility(View.VISIBLE);
holder.gameProgressbar.setVisibility(View.GONE);
holder.gameInfo.setVisibility(View.GONE);
updateItemViewStatus(holder, false, briefStyle);
}
// 更新插件的条目有多个apk包
private static void updatePluginItem(Context context, GameViewHolder holder, GameEntity gameEntity,
boolean isShowPlatform, PluginLocation pluginLocation) {
boolean isShowPlatform, PluginLocation pluginLocation, String briefStyle) {
GameUtils.setDownloadBtnStatus(context, gameEntity, holder.gameDownloadBtn, pluginLocation);
ArrayMap<String, DownloadEntity> entryMap = gameEntity.getEntryMap();
@ -252,18 +255,15 @@ public class DownloadItemUtils {
return;
}
}
holder.gameDes.setVisibility(View.VISIBLE);
holder.gameProgressbar.setVisibility(View.GONE);
holder.gameInfo.setVisibility(View.GONE);
updateItemViewStatus(holder, false, briefStyle);
}
// 更改进度条和提示文本的状态
public static void changeStatus(Context context, GameViewHolder holder, DownloadEntity downloadEntity,
boolean isShowPlatform, boolean isNormal) {
holder.gameDes.setVisibility(View.GONE);
holder.gameProgressbar.setVisibility(View.VISIBLE);
holder.gameInfo.setVisibility(View.VISIBLE);
updateItemViewStatus(holder, true, null);
holder.gameProgressbar.setProgressDrawable(context.getResources().getDrawable(R.drawable.progressbar_bg_style));
String platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.getPlatform());
@ -324,6 +324,17 @@ public class DownloadItemUtils {
holder.gameDownloadBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style));
}
} else if (status.equals(DownloadStatus.done)) {
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
holder.gameProgressbar.setProgressDrawable(context.getResources().getDrawable(R.drawable.progressbar_xapk_style));
holder.gameDownloadSpeed.setText(R.string.unzipping);
holder.gameProgressbar.setProgress((int) (Float.valueOf(percent) * 10));
holder.gameDownloadPercentage.setText(percent + "%");
holder.gameDownloadBtn.setText(R.string.unzipping);
return;
}
holder.gameProgressbar.setProgress(1000);
if (isShowPlatform && platform != null) {
holder.gameDownloadSpeed.setText(String.format("%s - 下载完成", platform));
@ -345,6 +356,29 @@ public class DownloadItemUtils {
}
}
private static void updateItemViewStatus(GameViewHolder holder, boolean hasDownload, @Nullable String briefStyle) {
if (hasDownload) {
if (holder.gameRating != null) holder.gameRating.setVisibility(View.GONE);
holder.gameDes.setVisibility(View.GONE);
holder.gameProgressbar.setVisibility(View.VISIBLE);
holder.gameInfo.setVisibility(View.VISIBLE);
} else {
holder.gameProgressbar.setVisibility(View.GONE);
holder.gameInfo.setVisibility(View.GONE);
if (briefStyle != null && briefStyle.contains("star")) {
if (holder.gameRating != null) holder.gameRating.setVisibility(View.VISIBLE);
} else {
if (holder.gameRating != null) holder.gameRating.setVisibility(View.GONE);
}
if (TextUtils.isEmpty(briefStyle) || briefStyle.contains("brief")) {
holder.gameDes.setVisibility(View.VISIBLE);
} else {
holder.gameDes.setVisibility(View.GONE);
}
}
}
public static void setOnClickListener(final Context context,
final TextView downloadBtn,
final GameEntity gameEntity,
@ -429,12 +463,12 @@ public class DownloadItemUtils {
LinkEntity linkEntity = gameEntity.getH5Link();
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
if (isPlay) {
HistoryHelper.insertGameEntity(gameEntity);
}
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay);
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton());
context.startActivity(i);
});
} else if (gameEntity.getApk().size() == 1) {
@ -500,8 +534,10 @@ public class DownloadItemUtils {
// 先弹下载弹窗(如果需要的话)
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
DialogUtils.checkDownload(context, apk.getSize(),
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
DialogUtils.checkDownload(context, apk.getSize(),
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
});
});
});
@ -510,8 +546,10 @@ public class DownloadItemUtils {
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
DialogUtils.checkDownload(context, apk.getSize(),
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
DialogUtils.checkDownload(context, apk.getSize(),
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
});
});
});
});
@ -539,10 +577,6 @@ public class DownloadItemUtils {
}
DataUtils.onGameLaunchEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk().get(0).getPackageName());
} else if (str.equals(context.getString(R.string.waiting))
|| str.equals(context.getString(R.string.downloading))) {
context.startActivity(DownloadManagerActivity.getDownloadMangerIntent(context,
apk.getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
} else if (str.equals(context.getString(R.string.update))) {
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.getName());
@ -551,6 +585,9 @@ public class DownloadItemUtils {
DialogUtils.checkDownload(context, apk.getSize(),
isSubscribe -> update(context, gameEntity, entrance, location, isSubscribe, traceEvent));
});
} else {
context.startActivity(DownloadManagerActivity.getDownloadMangerIntent(context,
apk.getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
}
}
@ -611,9 +648,9 @@ public class DownloadItemUtils {
}
adapter.notifyItemChanged(position);
} else if (PackageUtils.isCanPluggable(apkEntity)) {
DialogUtils.showPluginDialog(context, () -> context.startActivity(PackageUtils.getUninstallIntent(context, path)));
DialogUtils.showPluginDialog(context, () -> PackageInstaller.uninstall(context, path));
} else {
PackageUtils.launchSetup(context, downloadEntity);
PackageInstaller.install(context, downloadEntity);
}
}
}

View File

@ -10,6 +10,8 @@ import android.os.Build
import androidx.core.app.NotificationCompat
import com.gh.common.AppExecutor
import com.gh.common.constant.Constants
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.gamecenter.R
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
@ -38,9 +40,12 @@ object DownloadNotificationHelper {
var requireUpdateNotificationGroupDelay = false
val notificationManager = getNotificationManager()
val downloadNotificationId = (entity.gameId + entity.packageName).hashCode()
val xapkStatus = entity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SILENT_UPDATE) return
val intent = Intent()
if (entity.status == DownloadStatus.done) {
if (entity.status == DownloadStatus.done && xapkStatus != XapkUnzipStatus.FAILURE.name) {
intent.putExtra(EntranceUtils.KEY_DATA, entity.toJson())
intent.putExtra(EntranceUtils.KEY_PATH, entity.path)
intent.action = ACTION_INSTALL
@ -53,7 +58,6 @@ object DownloadNotificationHelper {
PendingIntent.FLAG_UPDATE_CURRENT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// importance == IMPORTANCE_DEFAULT 时每次更新都会触发震动
val channel = NotificationChannel(DOWNLOAD_CHANNEL_ID, DOWNLOAD_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW)
notificationManager.createNotificationChannel(channel)
}
@ -65,18 +69,22 @@ object DownloadNotificationHelper {
.setContentIntent(pendingIntent)
.setGroup(DOWNLOAD_GROUP_KEY)
.setWhen(whenTime)
.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
when (entity.status) {
DownloadStatus.downloading -> builder.setContentText(String.format("%s(剩%s)",
SpeedUtils.getSpeed(entity.speed),
SpeedUtils.getRemainTime(entity.size, entity.progress, entity.speed * 1024)))
DownloadStatus.done -> builder.setContentText("下载完成,点击立即安装")
DownloadStatus.waiting -> builder.setContentText("等待中")
DownloadStatus.subscribe,
DownloadStatus.timeout,
DownloadStatus.neterror -> builder.setContentText("已暂停连接WiFi自动下载")
else -> builder.setContentText("暂停中")
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {
builder.setContentText("" + entity.name + "》解压失败,点击查看详情~")
} else {
when (entity.status) {
DownloadStatus.downloading -> builder.setContentText(String.format("%s(剩%s)",
SpeedUtils.getSpeed(entity.speed),
SpeedUtils.getRemainTime(entity.size, entity.progress, entity.speed * 1024)))
DownloadStatus.done -> builder.setContentText("下载完成,点击立即安装")
DownloadStatus.waiting -> builder.setContentText("等待中")
DownloadStatus.subscribe,
DownloadStatus.timeout,
DownloadStatus.neterror -> builder.setContentText("已暂停连接WiFi自动下载")
else -> builder.setContentText("暂停中")
}
builder.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
}
when {
@ -88,30 +96,39 @@ object DownloadNotificationHelper {
else -> builder.setSortKey("C")
}
val notification = builder.build()
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
if (entity.status == DownloadStatus.delete
|| entity.status == DownloadStatus.cancel
|| entity.status == DownloadStatus.hijack
|| entity.status == DownloadStatus.notfound
|| entity.status == DownloadStatus.overflow
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty())) {
requireUpdateNotificationGroupDelay = true
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
} else {
if (entity.status != DownloadStatus.downloading) {
notificationManager.notify(entity.path, DOWNLOAD_NOTIFICATION_ID, notification)
tryCatchInRelease {
val notification = builder.build() // 可能会抛出异常
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
} else {
val time = mNotifyMap[entity.path]
val curTime = System.currentTimeMillis()
if (time == null || curTime - time > 2000) {
mNotifyMap[entity.path] = curTime
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
}
if (entity.status == DownloadStatus.delete
|| entity.status == DownloadStatus.cancel
|| entity.status == DownloadStatus.hijack
|| entity.status == DownloadStatus.notfound
|| entity.status == DownloadStatus.overflow
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty()
&& xapkStatus != XapkUnzipStatus.FAILURE.name)) {
requireUpdateNotificationGroupDelay = true
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
} else {
if (entity.status != DownloadStatus.downloading) {
notificationManager.notify(entity.path, DOWNLOAD_NOTIFICATION_ID, notification)
} else {
val time = mNotifyMap[entity.path]
val curTime = System.currentTimeMillis()
if (time == null || curTime - time > 2000) {
mNotifyMap[entity.path] = curTime
notificationManager.notify(entity.path, DOWNLOAD_NOTIFICATION_ID, notification)
}
}
}
}
if (requireUpdateNotificationGroupDelay) {
// 虽然运行到这里时 notification 已经被 cancel 了,但在下面的 notificationManager.getActiveNotifications 里它有可能还是 active 状态,
// 这里延时 100 ms 避免出现所有的任务都取消了以后依旧有一条 notification group 常驻
@ -122,32 +139,35 @@ object DownloadNotificationHelper {
}
private fun updateNotificationGroup() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val notificationManager = getNotificationManager()
val activeNotifications = notificationManager.activeNotifications
var downloadNotificationSize = 0
var downloadGroupNotificationSize = 0
for (activeNotification in activeNotifications) {
if (activeNotification.id == DOWNLOAD_NOTIFICATION_ID) {
downloadNotificationSize++
// 部分华为设备调用 getActiveNotifications() 方法时会触发方法内的空指针,这里整体包裹处理了
tryCatchInRelease {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val notificationManager = getNotificationManager()
val activeNotifications = notificationManager.activeNotifications
var downloadNotificationSize = 0
var downloadGroupNotificationSize = 0
for (activeNotification in activeNotifications) {
if (activeNotification.id == DOWNLOAD_NOTIFICATION_ID) {
downloadNotificationSize++
}
if (activeNotification.id == DOWNLOAD_NOTIFICATION_FOLD_ID) {
downloadGroupNotificationSize++
}
}
if (activeNotification.id == DOWNLOAD_NOTIFICATION_FOLD_ID) {
downloadGroupNotificationSize++
}
}
if (downloadNotificationSize == 0 && downloadGroupNotificationSize != 0) {
// 删除组可能会把组内所有通知一并删除
notificationManager.cancel(DOWNLOAD_NOTIFICATION_FOLD_ID)
} else if (downloadNotificationSize != 0 && downloadGroupNotificationSize == 0) {
val groupBuilder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
.setSmallIcon(R.mipmap.logo)
.setGroup(DOWNLOAD_GROUP_KEY)
.setGroupSummary(true)
.setStyle(NotificationCompat.BigTextStyle().bigText("下载任务"))
val groupNotification = groupBuilder.build()
groupNotification.flags = groupNotification.flags or Notification.FLAG_NO_CLEAR
notificationManager.notify(DOWNLOAD_NOTIFICATION_FOLD_ID, groupNotification)
if (downloadNotificationSize == 0 && downloadGroupNotificationSize != 0) {
// 删除组可能会把组内所有通知一并删除
notificationManager.cancel(DOWNLOAD_NOTIFICATION_FOLD_ID)
} else if (downloadNotificationSize != 0 && downloadGroupNotificationSize == 0) {
val groupBuilder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
.setSmallIcon(R.mipmap.logo)
.setGroup(DOWNLOAD_GROUP_KEY)
.setGroupSummary(true)
.setStyle(NotificationCompat.BigTextStyle().bigText("下载任务"))
val groupNotification = groupBuilder.build()
groupNotification.flags = groupNotification.flags or Notification.FLAG_NO_CLEAR
notificationManager.notify(DOWNLOAD_NOTIFICATION_FOLD_ID, groupNotification)
}
}
}
}

View File

@ -6,6 +6,8 @@ import android.preference.PreferenceManager
import com.gh.base.BaseActivity
import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
@ -43,11 +45,15 @@ object DownloadObserver {
fun initObserver() {
val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
// todo 如何处理xapk安装问题
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
if (!xapkStatus.isNullOrEmpty()) return
val gameId = downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER)
val downloadManager = DownloadManager.getInstance(HaloApp.getInstance().application)
if (downloadEntity.status != DownloadStatus.downloading) {
LogUtils.uploadDownloadEvent(downloadEntity)
tryCatchInRelease {
DownloadDataHelper.uploadDownloadEvent(downloadEntity)
}
if (DownloadStatus.hijack == downloadEntity.status) {
@ -55,9 +61,9 @@ object DownloadObserver {
processHijack(downloadEntity)
val nameAndPlatform = (downloadEntity.name + ":"
+ PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
MtaHelper.onEvent("下载劫持",
"游戏名字", nameAndPlatform,
"网络状态", DeviceUtils.getNetwork(mApplication))
// MtaHelper.onEvent("下载劫持",
// "游戏名字", nameAndPlatform,
// "网络状态", DeviceUtils.getNetwork(mApplication))
return
} else if (DownloadStatus.notfound == downloadEntity.status) {
// 404 Not Found
@ -66,9 +72,9 @@ object DownloadObserver {
downloadManager.cancel(downloadEntity.url)
Utils.toast(mApplication, "该链接已失效!请联系管理员。")
MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
"游戏", downloadEntity.name,
"平台", downloadEntity.platform)
// MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
// "游戏", downloadEntity.name,
// "平台", downloadEntity.platform)
DialogUtils.showAlertDialog(AppManager.getInstance().currentActivity(), "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
SuggestionActivity.startSuggestionActivity(AppManager.getInstance().currentActivity(),
@ -90,9 +96,9 @@ object DownloadObserver {
Utils.toast(mApplication, "网络不稳定,下载任务已暂停")
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停",
"游戏", downloadEntity.name,
"平台", downloadEntity.platform)
// MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停",
// "游戏", downloadEntity.name,
// "平台", downloadEntity.platform)
debugOnly {
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
}
@ -101,11 +107,13 @@ object DownloadObserver {
if (DownloadStatus.done == downloadEntity.status) {
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
MtaHelper.onEvent("软件更新", "下载完成")
// 会有 ActivityNotFoundException 异常catch 掉不管了
tryWithDefaultCatch {
// 会有 ActivityNotFoundException 异常catch 掉不管了
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path, true))
if (Constants.SILENT_UPDATE != downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)) {
PackageInstaller.install(mApplication, downloadEntity)
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
}
}
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
} else {
statDoneEvent(downloadEntity)
@ -131,7 +139,7 @@ object DownloadObserver {
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
tryWithDefaultCatch {
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path))
PackageInstaller.install(mApplication, downloadEntity, false)
}
} else {
// 弹出卸载提示框
@ -149,11 +157,11 @@ object DownloadObserver {
val pm = mApplication.packageManager
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
if (packageInfo == null) {
MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
"游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
"游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
// "游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
//
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
// "游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
}
}
@ -199,13 +207,13 @@ object DownloadObserver {
type = ExposureUtils.DownloadType.DOWNLOAD
}
val kv2 = HashMap<String, Any>()
kv2["版本"] = downloadEntity.platform
kv2["状态"] = "下载完成"
kv2["位置"] = downloadEntity.entrance ?: "null"
kv2["游戏分平台"] = downloadEntity.name + "-" + platform
kv2["光环助手版本"] = BuildConfig.VERSION_NAME
DataUtils.onEvent(mApplication, "游戏下载位置", downloadEntity.name, kv2)
// val kv2 = HashMap<String, Any>()
// kv2["版本"] = downloadEntity.platform
// kv2["状态"] = "下载完成"
// kv2["位置"] = downloadEntity.entrance ?: "null"
// kv2["游戏分平台"] = downloadEntity.name + "-" + platform
// kv2["光环助手版本"] = BuildConfig.VERSION_NAME
// DataUtils.onEvent(mApplication, "游戏下载位置", downloadEntity.name, kv2)
if (downloadEntity.isPluggable) {
val kv3 = HashMap<String, Any>()
@ -215,16 +223,18 @@ object DownloadObserver {
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
DataUtils.onEvent(mApplication, "插件化", downloadEntity.name, kv3)
MtaHelper.onEvent(
"插件化_新",
"位置", downloadEntity.entrance,
"游戏", downloadEntity.name + "-" + downloadEntity.platform,
"操作", "下载完成",
"网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
// MtaHelper.onEvent(
// "插件化_新",
// "位置", downloadEntity.entrance,
// "游戏", downloadEntity.name + "-" + downloadEntity.platform,
// "操作", "下载完成",
// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
}
ExposureUtils.logADownloadCompleteExposureEvent(
GameEntity(id = downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER), mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR)),
GameEntity(id = downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER),
mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR),
gameVersion = downloadEntity.versionName ?: ""),
downloadEntity.platform,
downloadEntity.exposureTrace,
type)

View File

@ -1,17 +1,31 @@
package com.gh.common.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Parcelable;
import android.text.TextUtils;
import com.gh.common.avoidcallback.AvoidOnResultManager;
import com.gh.common.avoidcallback.Callback;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.NormalActivity;
import com.gh.gamecenter.SplashScreenActivity;
import com.gh.gamecenter.normal.NormalFragment;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import org.json.JSONObject;
import java.util.Iterator;
import java.util.Set;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
/**
* @author CsHeng
@ -25,9 +39,12 @@ public class EntranceUtils {
public static final String KEY_NEXT_TO = "next_to";
public static final String KEY_NEWSID = "newsId";
public static final String KEY_GAMEID = "gameId";
public static final String KEY_GAME_ID = "game_id";
public static final String KEY_ID = "id";
public static final String KEY_URL = "url";
public static final String KEY_BUNDLE = "bundle";
public static final String KEY_GAMENAME = "gameName";
public static final String KEY_PACKAGE_MD5 = "package_md5";
public static final String HOST_ARTICLE = "article";
public static final String HOST_UPLOAD_VIDEO = "upload_video";//上传视频
public static final String HOST_VIDEO_SINGLE = "video_single";//指定视频-不能划动
@ -37,26 +54,41 @@ public class EntranceUtils {
public static final String HOST_VIDEO_COLLECTION = "video_collection";//视频合集
public static final String HOST_USERHOME = "userhome";//个人主页
public static final String HOST_VIDEO = "video";
public static final String HOST_FORUM = "forum";
public static final String HOST_CATEGORY = "category";//分类
public static final String HOST_COLUMN_COLLECTION = "column_collection";//专题合集
public static final String HOST_COMMUNITY_QUESTION_LABEL_DETAIL = "community_question_label_detail";//问题标签详情
public static final String HOST_COMMUNITY_COLUMN_DETAIL = "community_column_detail";//专栏详情
public static final String HOST_BLOCK = "block";//板块
public static final String HOST_SERVER_BLOCK = "server";//开服表板块
public static final String HOST_AMWAY_BLOCK = "amway";//安利墙板块
public static final String HOST_GAME_CALENDAR = "game_calendar";// 指定游戏的开服表页面
public static final String HOST_HISTORY_APK = "history_apk"; // 历史版本页面
public static final String HOST_HELP = "help";//Q&A
public static final String HOST_HELP_COLLECTION = "help_collection";//Q&A合集
public static final String HOST_GAME_UPLOAD = "game_upload";//游戏上传
public static final String HOST_GAME_ZONE = "game_zone";//游戏专区
public static final String HOST_COMMUNITY_ARTICLE = "community_article";
public static final String HOST_COMMUNITY_COLUMN = "community_column";
public static final String HOST_GAME = "game";
public static final String HOST_GAME_DOWNLOAD = "game_download";
public static final String HOST_GAME_NEWS = "game_news";
public static final String HOST_COLUMN = "column";
public static final String HOST_WEB = "web";
public static final String HOST_QQ = "qq";
public static final String HOST_QQ_GROUP = "qqgroup";
public static final String HOST_QQ_QUN = "qqqun";
public static final String HOST_DOWNLOAD = "download";
public static final String HOST_UPDATE = "update";
public static final String HOST_LINK = "link";
public static final String HOST_LIBAO = "libao";
public static final String HOST_COMMUNITY = "community";
public static final String HOST_SUGGESTION = "suggestion";
public static final String HOST_ANSWER = "answer";
public static final String HOST_QUESTION = "question";
public static final String HOST_TOOLBOX = "toolbox";
public static final String HOST_FORUM_DETAIL = "forum_detail";
public static final String HOST_GAME_RATING_DETAIL = "game_rating_detail";
public static final String KEY_DATA = "data";
public static final String KEY_MESSAGE = "message";
public static final String KEY_MESSAGE_ID = "message_id";
@ -74,6 +106,7 @@ public class EntranceUtils {
public static final String ENTRANCE_DOWNLOAD = "(下载跳转)";
public static final String ENTRANCE_RECOMMEND = "(落地页)";
public static final String ENTRANCE_BLOCK_RECOMMEND = "(推荐入口)";
public static final String ENTRANCE_AMWAY = "(安利墙)";
public static final String KEY_SUGGEST_HINT_TYPE = "suggestHintType";
public static final String KEY_PACKAGENAME = "packageName";
public static final String KEY_PLATFORM = "platform";
@ -84,6 +117,7 @@ public class EntranceUtils {
public static final String KEY_LOCATION = "location";
public static final String KEY_CURRENTITEM = "currentItem";
public static final String KEY_COMMENTID = "commentId";
public static final String KEY_COMMENT_ID = "comment_id";
public static final String KEY_SHOW_KEYBOARD_IF_NEEDED = "show_key_board_if_needed";
public static final String KEY_PATH = "path";
public static final String KEY_OUTER_INFO = "outerInfo";
@ -133,6 +167,7 @@ public class EntranceUtils {
public static final String KEY_COMMUNITY_ARTICLE_ID = "communityArticleId";
public static final String KEY_ARTICLE_COMMENT_ID = "articleCommentId";
public static final String KEY_SHOW_ARTICLE_COMMENT = "showArticleComment";
public static final String KEY_SCROLL_TO_COMMENT_AREA = "scroll_to_comment_area";
public static final String KEY_RATING_STAR_COUNT = "ratingStarCount";
public static final String KEY_QUESTION_MODERATOR_PATCH = "questionModeratorPatch";
public static final String KEY_SKIP_GAME_COMMENT = "skipGameComment";
@ -154,13 +189,24 @@ public class EntranceUtils {
public static final String KEY_IS_HOME = "isHome";
public static final String KEY_WEB_SHARE = "webShare";
public static final String KEY_ACTIVITY_NAME = "activityName";//活动名称
public static final String KEY_PAGINATION_TYPE = "paginationType";//活动分页方式
public static final String KEY_REQUIRE_REDIRECT = "require_redirect"; // 标记需要再跳转
public static final String KEY_FIELD_ID = "field_id"; // 专区板块id
public static final String KEY_SECTION_NAME = "section_name"; // 专区专题名
public static final String KEY_COLUMNNAME = "columnName";
public static final String KEY_QA_ID = "qaId";
public static final String KEY_QA_COLLECTION_ID = "qaCollectionId";
public static final String KEY_SHOW_EDIT_DRAFT = "showEditDraft";
public static final String KEY_ARTICLE_OPEN_IN_NEW_PAGE = "openArticleInNewPage";
public static final String KEY_ONLY_CREATE_DRAFT = "onlyCreateDraft";
public static final String KEY_KAIFU_SELECT_TIME = "kaifuSelectTime";
public static final String KEY_POSTER_PATH = "posterPath";
public static final String KEY_BLACK_THEME = "blackTheme";
public static final String KEY_FROM_LOGIN = "fromLogin";
public static final String KEY_CHANGE_PHONE = "changePhone";
public static final String KEY_CONFLICT_PHONE = "conflictPhone";
public static final String KEY_CONFLICT_USER = "conflictUser";
public static final String KEY_BBS_ID = "bbs_id";
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
@ -216,4 +262,82 @@ public class EntranceUtils {
context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
}
}
public static void saveShortcut(String activityName, @Nullable Bundle bundle) {
if (BuildConfig.DEBUG) {
JSONObject json = new JSONObject();
if (activityName.contains("MainActivity")) {
SPUtils.setString(EntranceUtils.KEY_BUNDLE, "");
return;
}
if (bundle == null) bundle = new Bundle();
try {
Set<String> keys = bundle.keySet();
json.put(KEY_TO, activityName);
for (String key : keys) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Object object = bundle.get(key);
if (object instanceof Parcelable) {
if (object.toString().toLowerCase().contains("gameentity")) {
Utils.toast(HaloApp.getInstance().getApplication(), "暂不支持带游戏实体的页面保存捷径");
return;
}
String parcelableName = key + ":parcelable";
String parcelableType = object.getClass().getName();
String objectJsonString = GsonUtils.toJson(object);
JSONObject jObject = new JSONObject(objectJsonString);
json.put(parcelableName, parcelableType);
json.put(key, jObject);
} else {
json.put(key, JSONObject.wrap(bundle.get(key)));
}
}
}
Utils.toast(HaloApp.getInstance().getApplication(), "保存捷径成功");
SPUtils.setString(EntranceUtils.KEY_BUNDLE, json.toString());
} catch (Exception e) {
e.printStackTrace();
SPUtils.setString(EntranceUtils.KEY_BUNDLE, "");
}
}
}
public static void jumpShortcut(Activity activity) {
if (BuildConfig.DEBUG) {
if (!hasShortcut()) return;
Bundle bundle = new Bundle();
try {
JSONObject jsonObject = new JSONObject(SPUtils.getString(EntranceUtils.KEY_BUNDLE));
Iterator iter = jsonObject.keys();
String parcelableName = "";
while (iter.hasNext()) {
String key = (String) iter.next();
String value = jsonObject.getString(key);
if (key.contains(":parcelable")) {
parcelableName = value;
} else {
if (!TextUtils.isEmpty(parcelableName)) {
Class<?> gClass = Class.forName(parcelableName);
bundle.putParcelable(key, ((Parcelable) GsonUtils.fromJson(value, gClass)));
} else {
bundle.putString(key, value);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
jumpActivity(activity, bundle);
}
}
public static boolean hasShortcut() {
return !TextUtils.isEmpty(SPUtils.getString(EntranceUtils.KEY_BUNDLE));
}
}

View File

@ -116,6 +116,8 @@ object ErrorHelper {
403078 -> Utils.toast(context, "已点赞")
403072 -> Utils.toast(context, R.string.comment_failed_userblocked)
403082 -> Utils.toast(context, "作者已关闭评论")
403022 -> Utils.toast(context, "不能回复自己")
403056 -> Utils.toast(context, "发布失败,字数已达上限")
403020 -> if (showHighPriorityHint) {
DialogUtils.showAlertDialog(context,

View File

@ -3,13 +3,17 @@ package com.gh.common.util
import android.animation.Animator
import android.content.ClipboardManager
import android.content.Context
import android.text.Editable
import android.text.Html
import android.text.Spanned
import android.text.TextWatcher
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.text.*
import android.text.style.ClickableSpan
import android.text.style.ImageSpan
import android.text.style.URLSpan
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.ColorRes
@ -18,16 +22,24 @@ import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import com.airbnb.lottie.LottieAnimationView
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.DefaultUrlHandler
import com.gh.common.constant.Config
import com.gh.common.constant.Constants
import com.gh.common.view.CenterImageSpan
import com.gh.common.view.CustomLinkMovementMethod
import com.gh.common.view.ExpandTextView
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.manager.UserManager
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
@ -35,7 +47,9 @@ import io.reactivex.disposables.Disposable
import okhttp3.MediaType
import okhttp3.RequestBody
import java.net.URI
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import kotlin.math.abs
/**
@ -54,6 +68,14 @@ inline fun <reified VM : ViewModel> Fragment.viewModelProviderFromParent(
) =
ViewModelProviders.of(requireActivity(), provider).get(VM::class.java)
/**
* 创建以 activity 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> FragmentActivity.viewModelProviderFromParent(
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(this, provider).get(VM::class.java)
/**
* 创建以 fragment 为观察者上下文的 viewModel
*/
@ -152,6 +174,17 @@ fun View.removeSelectableItemBackground() {
background = null
}
fun View.setRoundedColorBackground(@ColorRes color: Int, radius: Float) {
val shape = GradientDrawable()
shape.cornerRadius = radius.dip2px().toFloat()
shape.setColor(ContextCompat.getColor(context, color))
background = shape
}
fun View.setDebouncedClickListener(action: () -> Unit) {
setOnClickListener { debounceActionWithInterval(interval = 300L) { action.invoke() } }
}
/**
* LiveData Extensions
*/
@ -191,6 +224,50 @@ inline fun <reified T : Any> T.toJson(): String {
return GsonUtils.toJson(this)
}
fun String.insert(index: Int, string: String): String {
return this.substring(0, index) + string + this.substring(index, this.length)
}
/**
* TextView 内部处理 ul li ol 得跟 Android 版本走,这里换成专属的标签手动处理
*/
fun String.replaceUnsupportedHtmlTag(): String {
return this.replace("<ul", "<hul")
.replace("</ul>", "</hul>")
.replace("<li", "<hli")
.replace("</li>", "</hli>")
.replace("<ol", "<hol")
.replace("</ol>", "</hol>")
}
fun String.containHtmlTag(): Boolean {
val pattern = Pattern.compile("<(\"[^\"]*\"|'[^']*'|[^'\">])*>")
val matcher = pattern.matcher(this)
return matcher.find()
}
/**
* 用户行为相关
*/
fun Fragment.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
DialogUtils.showRegulationTestDialog(requireContext(),
{ DirectUtils.directToRegulationTestPage(requireContext()) },
{ action.invoke() })
} else {
action()
}
}
fun Context.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
DialogUtils.showRegulationTestDialog(this,
{ DirectUtils.directToRegulationTestPage(this) },
{ action.invoke() })
} else {
action()
}
}
/**
* 在限定 interval 里只触发一次 action
*/
@ -246,6 +323,15 @@ fun throwExceptionInDebug(message: String = "", predicate: Boolean = true) {
}
}
/**
* 主动抛出异常
*/
fun throwException(message: String = "", predicate: Boolean = true) {
if (predicate) {
throw RuntimeException(message)
}
}
/**
* String related
*/
@ -285,6 +371,17 @@ fun String.subStringIfPossible(length: Int): String {
}
}
fun String.countOccurrences(char: String): Int {
return StringTokenizer(" $this ", char).countTokens() - 1
}
fun String.getFirstElementDividedByDivider(divider: String): String {
if (this.contains(divider)) {
return this.split(divider.toRegex()).toTypedArray()[0]
}
return this
}
fun String.copyTextAndToast(toastText: String = "复制成功") {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
@ -328,6 +425,11 @@ fun Float.px2dip(): Int {
return (this / scale + 0.5f).toInt()
}
fun Float.sp2px():Int{
val scale: Float = HaloApp.getInstance().application.resources.displayMetrics.scaledDensity
return (this * scale + 0.5f).toInt()
}
/**
* PopupWindow 自动适配方向
* 弹出与锚点右对齐
@ -408,6 +510,15 @@ fun FragmentActivity.checkStoragePermissionBeforeAction(action: (() -> Unit)) {
})
}
/**
* List related.
*/
// Returns the second element, or `null` if the list is empty.
fun <T> List<T>.secondOrNull(): T? {
return if (isEmpty() || size == 1) null else this[1]
}
/**
* TextView related.
*/
@ -442,6 +553,75 @@ fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before
})
}
/**
* 拦截 TextView 中的 Url Span用应用内页面的形式打开链接
* @param shrankText 未展开时的文字
* @param expandedText 展开后的文字
*/
fun ExpandTextView.setTextWithInterceptingInternalUrl(shrankText: CharSequence, expandedText: CharSequence) {
var shrankSsb = shrankText.interceptUrlSpanAndRoundImageSpan()
var expandedSsb = expandedText.interceptUrlSpanAndRoundImageSpan()
// 去掉旧版本 Android 系统 [Html.FROM_HTML_MODE_LEGACY] 产生的两个换行符 (丑陋的代码)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
while (shrankSsb.contains("\n\n")) {
val index = shrankSsb.indexOf("\n\n", 0, true)
shrankSsb = SpannableStringBuilder(shrankSsb.subSequence(0, index)).append(shrankSsb.subSequence(index + "\n".length, shrankSsb.length))
}
while (expandedSsb.contains("\n\n")) {
val index = expandedSsb.indexOf("\n\n", 0, true)
expandedSsb = SpannableStringBuilder(expandedSsb.subSequence(0, index)).append(expandedSsb.subSequence(index + "\n".length, expandedSsb.length))
}
}
// 去掉多余的 P 标签换行
if (expandedSsb.endsWith("\n", true)) {
expandedSsb = SpannableStringBuilder((expandedSsb.subSequence(0, expandedSsb.length - "\n".length)))
}
movementMethod = CustomLinkMovementMethod.getInstance()
shrankSsb = TextHelper.updateSpannableStringWithHighlightedSpan(context, shrankSsb, highlightedTextClickListener = null)
expandedSsb = TextHelper.updateSpannableStringWithHighlightedSpan(context, expandedSsb, highlightedTextClickListener = null)
setShrankTextAndExpandedText(shrankSsb, expandedSsb)
}
fun CharSequence.interceptUrlSpanAndRoundImageSpan(): SpannableStringBuilder {
return SpannableStringBuilder.valueOf(this).apply {
getSpans(0, length, URLSpan::class.java).forEach {
setSpan(
object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(HaloApp.getInstance().application, R.color.theme_font)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
if (!DefaultUrlHandler.interceptUrl(widget.context, it.url, "")) {
widget.context.startActivity(WebActivity.getIntent(widget.context, it.url, true))
}
}
},
getSpanStart(it),
getSpanEnd(it),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
removeSpan(it)
}
getSpans(0, length, ImageSpan::class.java).forEach {
setSpan(
CenterImageSpan(it.drawable),
getSpanStart(it),
getSpanEnd(it),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
removeSpan(it)
}
}
}
fun Int.toColor(): Int {
return ContextCompat.getColor(HaloApp.getInstance().application, this)
}
@ -461,6 +641,21 @@ fun SimpleDraweeView.display(url: String) {
ImageUtils.display(this, url)
}
/**
* DownloadEntity extension
*/
fun DownloadEntity.addMetaExtra(key: String, value: String?) {
value?.let { meta[key] = value }
}
fun DownloadEntity.getMetaExtra(key: String): String {
return meta[key] ?: ""
}
fun DownloadEntity.isSilentUpdate(): Boolean {
return Constants.SILENT_UPDATE == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
}
/**
* Process related
*/
@ -473,7 +668,20 @@ inline fun Context.doOnMainProcessOnly(f: () -> Unit) {
if (processName == null || BuildConfig.APPLICATION_ID == processName) {
f.invoke()
} else {
Utils.log("Block one useless sub process method call.")
tryWithDefaultCatch {
Utils.log("Block one useless sub process method call from ${Thread.currentThread().stackTrace[3].methodName} -> ${Thread.currentThread().stackTrace[2].methodName}.")
}
}
}
inline fun doOnMainProcessOnly(f: () -> Unit) {
val processName = PackageUtils.obtainProcessName(HaloApp.getInstance().application)
if (processName == null || BuildConfig.APPLICATION_ID == processName) {
f.invoke()
} else {
tryWithDefaultCatch {
Utils.log("Block one useless sub process method call from ${Thread.currentThread().stackTrace[3].methodName} -> ${Thread.currentThread().stackTrace[2].methodName}.")
}
}
}
@ -562,4 +770,52 @@ fun LottieAnimationView.doOnAnimationEnd(action: () -> Unit) {
}
})
}
fun String?.getExtension(): String? {
this ?: return null
tryCatchInRelease {
val lastDotIndex = this.lastIndexOf('.')
return if (lastDotIndex == -1) null else this.substring(lastDotIndex + 1)
}
return null
}
/**
* 检查内容是否一致
* @return true:相同 false:不同
*/
fun List<String>?.checkSameFromStringArray(check2: List<String>?): Boolean {
if (this == check2) {
return true
}
if (this == null && check2 == null) {
return true
}
if (this == null || check2 == null) {
return false
}
if (this.size != check2.size) {
return false
}
for (tag in this) {
if (!check2.contains(tag)) return false
}
for (tag in check2) {
if (!this.contains(tag)) return false
}
return true
}
/**
* EditText弹出软键盘
*/
fun EditText.showKeyBoard() {
this.postDelayed({
this.requestFocus()
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(this, 0)
}, 300)
}

View File

@ -0,0 +1,183 @@
package com.gh.common.util
import android.text.Editable
import android.text.Html.TagHandler
import android.text.Spanned
import android.text.style.BulletSpan
import android.text.style.LeadingMarginSpan
import android.util.Log
import org.xml.sax.XMLReader
import java.util.*
/**
* Implements support for ordered (`<ol>`) and unordered (`<ul>`) lists in to Android TextView.
*
*
* This can be used as follows:<br></br>
* `textView.setText(Html.fromHtml("<ul><li>item 1</li><li>item 2</li></ul>", null, new HtmlListTagHandler()));`
*
*
* Implementation based on code by Juha Kuitunen (https://bitbucket.org/Kuitsi/android-textview-html-list),
* released under Apache License v2.0. Refactored & improved by Matthias Stevens (InThePocket.mobi).
*
*
* **Known issues:**
* * The indentation on nested `<ul>`s isn't quite right (TODO fix this)
* * the `start` attribute of `<ol>` is not supported. Doing so is tricky because
* [Html.TagHandler.handleTag] does not expose tag attributes.
* The only way to do it would be to use reflection to access the attribute information kept by the XMLReader
* (see: http://stackoverflow.com/a/24534689/1084488).
*
* https://bitbucket.org/Kuitsi/android-textview-html-list/src/master/app/src/main/java/fi/iki/kuitsi/listtest/MyTagHandler.java
*
*/
class ExtraTagHandler : TagHandler {
/**
* Keeps track of lists (ol, ul). On bottom of Stack is the outermost list
* and on top of Stack is the most nested list
*/
private val lists = Stack<ListTag>()
/**
* @see android.text.Html.TagHandler.handleTag
*/
override fun handleTag(opening: Boolean, tag: String, output: Editable, xmlReader: XMLReader) {
if (UL_TAG.equals(tag, ignoreCase = true)) {
if (opening) { // handle <ul>
lists.push(Ul())
} else { // handle </ul>
lists.pop()
}
} else if (OL_TAG.equals(tag, ignoreCase = true)) {
if (opening) { // handle <ol>
lists.push(Ol()) // use default start index of 1
} else { // handle </ol>
lists.pop()
}
} else if (LI_TAG.equals(tag, ignoreCase = true)) {
if (opening) { // handle <li>
lists.peek().openItem(output)
} else { // handle </li>
lists.peek().closeItem(output, lists.size)
}
} else {
Log.d("TagHandler", "Found an unsupported tag $tag")
}
}
/**
* Abstract super class for [Ul] and [Ol].
*/
private abstract class ListTag {
/**
* Opens a new list item.
*
* @param text
*/
open fun openItem(text: Editable) {
if (text.length > 0 && text[text.length - 1] != '\n') {
text.append("\n")
}
val len = text.length
text.setSpan(this, len, len, Spanned.SPAN_MARK_MARK)
}
/**
* Closes a list item.
*
* @param text
* @param indentation
*/
fun closeItem(text: Editable, indentation: Int) {
if (text.length > 0 && text[text.length - 1] != '\n') {
text.append("\n")
}
val replaces = getReplaces(text, indentation)
val len = text.length
val listTag = getLast(text)
val where = text.getSpanStart(listTag)
text.removeSpan(listTag)
if (where != len) {
for (replace in replaces) {
text.setSpan(replace, where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
protected abstract fun getReplaces(text: Editable?, indentation: Int): Array<Any>
/**
* Note: This knows that the last returned object from getSpans() will be the most recently added.
*
* @see Html
*/
private fun getLast(text: Spanned): ListTag? {
val listTags = text.getSpans(0, text.length, ListTag::class.java)
return if (listTags.size == 0) {
null
} else listTags[listTags.size - 1]
}
}
/**
* Class representing the unordered list (`<ul>`) HTML tag.
*/
private class Ul : ListTag() {
override fun getReplaces(text: Editable?, indentation: Int): Array<Any> {
// Nested BulletSpans increases distance between BULLET_SPAN and text, so we must prevent it.
var bulletMargin = INDENT_PX
if (indentation > 1) {
bulletMargin = INDENT_PX - BULLET_SPAN.getLeadingMargin(true)
if (indentation > 2) {
// This get's more complicated when we add a LeadingMarginSpan into the same line:
// we have also counter it's effect to BulletSpan
bulletMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX
}
}
return arrayOf(
LeadingMarginSpan.Standard(LIST_ITEM_INDENT_PX * (indentation - 1)),
BulletSpan(bulletMargin)
)
}
}
/**
* Class representing the ordered list (`<ol>`) HTML tag.
*/
private class Ol
/**
* Creates a new `<ul>` with start index of 1.
*/ @JvmOverloads constructor(private var nextIdx: Int = 1) : ListTag() {
override fun openItem(text: Editable) {
super.openItem(text)
text.append(Integer.toString(nextIdx++)).append(". ")
}
override fun getReplaces(text: Editable?, indentation: Int): Array<Any> {
var numberMargin = LIST_ITEM_INDENT_PX * (indentation - 1)
if (indentation > 2) {
// Same as in ordered lists: counter the effect of nested Spans
numberMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX
}
return arrayOf(LeadingMarginSpan.Standard(numberMargin))
}
/**
* Creates a new `<ul>` with given start index.
*
* @param nextIdx
*/
}
companion object {
private const val OL_TAG = "hol"
private const val UL_TAG = "hul"
private const val LI_TAG = "hli"
/**
* List indentation in pixels. Nested lists use multiple of this.
*/
private const val INDENT_PX = 10
private const val LIST_ITEM_INDENT_PX = INDENT_PX * 2
private val BULLET_SPAN = BulletSpan(INDENT_PX)
}
}

View File

@ -1,19 +1,28 @@
package com.gh.common.util
import android.content.Context
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
/**
* 首页补充游戏库辅助类
*/
object GameRepositoryHelper {
object GameSubstituteRepositoryHelper {
private const val KEY_GAME_REPOSITORY = "game_repository"
private const val KEY_GAME_REPOSITORY = "game_substitute_repository"
private var mSubstitutableGameIdSet = hashSetOf<String>()
private var mApi = RetrofitManager.getInstance(HaloApp.getInstance().application).api
private val mSensitiveApi = RetrofitManager.getInstance(HaloApp.getInstance().application).sensitiveApi
private var mApplicationContext = HaloApp.getInstance().application
var gameCollectionList: List<SubjectEntity> = arrayListOf()
@ -25,11 +34,8 @@ object GameRepositoryHelper {
* 获取游戏补充库
*/
@JvmStatic
fun getGameRepository(context: Context) {
RetrofitManager.getInstance(context)
.api
.reserveColumns
fun updateGameSubstituteRepository() {
mSensitiveApi.reserveColumns
.subscribeOn(Schedulers.io())
.subscribe(object : Response<List<SubjectEntity>>() {
override fun onResponse(response: List<SubjectEntity>?) {
@ -38,27 +44,41 @@ object GameRepositoryHelper {
updateGameRepository(response)
}
})
}
@JvmStatic
@SuppressLint("CheckResult")
fun updateSubstitutableGames() {
mApplicationContext.doOnMainProcessOnly {
val single = if (UserManager.getInstance().isLoggedIn) {
mApi.getIdListOfPlayedGames(UserManager.getInstance().userId, Utils.getTime(mApplicationContext))
} else {
mApi.getIdListOfDownloadedGames(HaloApp.getInstance().gid, Utils.getTime(mApplicationContext))
}
single.subscribeOn(Schedulers.io()).subscribe(object : BiResponse<List<String>>() {
override fun onSuccess(data: List<String>) {
mSubstitutableGameIdSet = data.toHashSet()
}
})
}
}
/**
* 刷新内存中的游戏库即从 SP 中再读一次
*/
@JvmStatic
fun refreshGameRepository() = loadSavedRepository()
fun refreshRepositoryFromLocal() = loadSavedRepository()
private fun loadSavedRepository() {
gameCollectionList = SPUtils.getString(KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
}
fun updateGameRepository(subjects: List<SubjectEntity>?) {
private fun updateGameRepository(subjects: List<SubjectEntity>?) {
if (subjects == null) return
SPUtils.setString(KEY_GAME_REPOSITORY, subjects.toJson())
gameCollectionList = subjects
}
/**
@ -66,7 +86,7 @@ object GameRepositoryHelper {
* @param collectionId 补充游戏库相应专题 ID
* @param gameIdList 该专题里已经包含的游戏 ID 列表
*/
fun getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
private fun getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
collectionId?.let {
val collection = gameCollectionList.find { it.id == collectionId }
collection?.let {
@ -82,10 +102,13 @@ object GameRepositoryHelper {
return null
}
fun replaceInstalledApp(gameList: MutableList<GameEntity>,
alreadyDisplayedGameIdSet: HashSet<String>,
relatedCollectionId: String,
shouldLogReplaceEvent: Boolean) {
/**
* 替换游戏包括 已安装历史下载历史已安装等类型
*/
fun replaceGames(gameList: MutableList<GameEntity>,
alreadyDisplayedGameIdSet: HashSet<String>,
relatedCollectionId: String,
shouldLogReplaceEvent: Boolean) {
val positionOfTheGameToReplaceList = arrayListOf<Int>()
// 标记需要替换的已安装游戏
@ -96,23 +119,32 @@ object GameRepositoryHelper {
continue
}
var isThisPositionAdded = false
var isThisPositionLabeled = false
// 从 游戏ID 判断当前游戏是否需要被替换
if (mSubstitutableGameIdSet.contains(game.id)) {
positionOfTheGameToReplaceList.add(index)
isThisPositionLabeled = true
}
// 检查是否已安装该游戏里同包名的 APK
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfTheGameToReplaceList.add(index)
isThisPositionAdded = true
break
if (!isThisPositionLabeled) {
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfTheGameToReplaceList.add(index)
isThisPositionLabeled = true
break
}
}
}
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
if (!isThisPositionAdded) {
if (!isThisPositionLabeled) {
var relatedPackageList = arrayListOf<String>()
for (entity in PackageHelper.relatedPackageList) {
if (entity.gameId == game.id) {
relatedPackageList = ArrayList(entity.packages)
relatedPackageList = ArrayList(entity.packages!!)
break
}
}
@ -139,14 +171,17 @@ object GameRepositoryHelper {
}
}
private fun isThisGameUnique(game: GameEntity, gameIdList: HashSet<String>): Boolean {
// 若该补充游戏已经存在关联关系,判定为非唯一
// 判断该游戏是否出现在已安装列表
if (mSubstitutableGameIdSet.contains(game.id)) return false
// 该补充游戏是否已经存在关联关系
for (relatedId in game.relatedGameIds!!) {
if (gameIdList.contains(relatedId)) {
return false
}
}
for (apk in game.getApk()) {
// 检查本地是否已安装该游戏,已过滤那部分框架服务的包名
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {

View File

@ -5,6 +5,8 @@ import android.graphics.Color;
import android.text.TextUtils;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.gh.common.constant.Config;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
@ -22,9 +24,6 @@ import com.lightgame.download.DownloadStatus;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
public class GameUtils {
/**
@ -183,6 +182,8 @@ public class GameUtils {
GameUpdateEntity gameUpdateEntity = new GameUpdateEntity();
gameUpdateEntity.setId(gameEntity.getId());
gameUpdateEntity.setIcon(gameEntity.getIcon());
gameUpdateEntity.setRawIcon(gameEntity.getRawIcon());
gameUpdateEntity.setIconSubscript(gameEntity.getIconSubscript());
gameUpdateEntity.setName(gameEntity.getName());
gameUpdateEntity.setPackageName(apkEntity.getPackageName());
gameUpdateEntity.setSize(apkEntity.getSize());
@ -199,6 +200,7 @@ public class GameUtils {
gameUpdateEntity.setDownload(gameEntity.getDownload());
gameUpdateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
gameUpdateEntity.setPluginDesc(gameEntity.getPluginDesc());
gameUpdateEntity.setFormat(apkEntity.getFormat());
GameCollectionEntity pluggableCollection = getPluggableCollectionFromGameEntity(gameEntity, apkEntity.getPackageName());
if (pluggableCollection != null) {

View File

@ -23,7 +23,7 @@ object GdtHelper {
const val PLATFORM = "PLATFORM"
fun init(application: Application) {
GDTAction.init(application, "1110071928", "7fe03caa04ed382e9dce401312b1d0ae")
GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
}
fun logAction(type: String) {

View File

@ -1,6 +1,7 @@
package com.gh.common.util
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
@ -10,6 +11,7 @@ import org.json.JSONArray
*/
object GsonUtils {
val gson: Gson = Gson()
val gsonThatIgnoreNull: Gson = GsonBuilder().serializeNulls().create()
@JvmStatic
fun <T> fromJson(json: String, t: Class<T>): T {
@ -32,4 +34,9 @@ object GsonUtils {
fun toJson(any: Any?): String {
return gson.toJson(any)
}
@JvmStatic
fun toJsonIgnoreNull(any: Any?): String {
return gsonThatIgnoreNull.toJson(any)
}
}

View File

@ -0,0 +1,50 @@
package com.gh.common.util
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.HomePluggableFilterEntity
import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
object HomePluggableHelper {
private val mHomePluggableFilterDao = AppDatabase.getInstance(HaloApp.getInstance().application).homePluggableFilterDao()
@JvmStatic
fun setHomePluggableFilterData(gameEntity: GameEntity, isNever: Boolean) {
val apkList = gameEntity.getApk()
if (apkList.isNotEmpty()) {
val apk = apkList.first()
val tag = if (isNever) "never" else apk.version ?: ""
mHomePluggableFilterDao.addData(HomePluggableFilterEntity(pkgName = apk.packageName, tag = tag, active = isNever))
}
}
@JvmStatic
fun showHomePluggable(gameEntity: GameEntity): Boolean {
val apkList = gameEntity.getApk()
if (apkList.isNotEmpty()) {
val apk = apkList.first()
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
if (filterData?.active == true) {
val filterTag = filterData.tag
return filterTag != "never" && apk.version != filterTag
}
}
return true
}
@JvmStatic
fun getPermanentInactivePluggablePackage() = mHomePluggableFilterDao.getDataByTag("never")
@JvmStatic
fun activationFilterData() {
val filterList = mHomePluggableFilterDao.getDataByActive(false)
if (filterList != null) {
for (entity in filterList) {
entity.active = true
}
mHomePluggableFilterDao.addData(filterList)
}
}
}

View File

@ -1,5 +1,6 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
@ -9,21 +10,21 @@ import android.net.Uri
import android.os.Build
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import com.facebook.common.executors.CallerThreadExecutor
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.controller.ControllerListener
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.core.ImagePipeline
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.gh.common.constant.Config
import com.gh.gamecenter.R
import com.halo.assistant.HaloApp
import com.squareup.picasso.Picasso
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.io.ByteArrayOutputStream
@ -31,6 +32,10 @@ object ImageUtils {
private const val PIC_MAX_FILE_SIZE: Long = 10 * 1024 * 1024
private val TINY_GIF_SIZE = 30F.dip2px()
private val LARGE_GIF_SIZE = 80F.dip2px()
private val STANDARD_GIF_SIZE = 60F.dip2px()
@JvmStatic
fun getUploadFileMaxSize(): Long {
val uploadLimitSize = Config.getSettings()?.image?.uploadLimitSize
@ -216,17 +221,21 @@ object ImageUtils {
.build()
}
// 获取bitmap
// 获取bitmap (使用 fresco 获取 gif bitmap 会为空https://github.com/facebook/fresco/issues/241)
// 所以这里换用 picasso
@SuppressLint("CheckResult")
@JvmStatic
fun display(context: Context?, url: String?, dataSubscriber: BaseBitmapDataSubscriber) {
val imageRequest = ImageRequestBuilder
.newBuilderWithSource(Uri.parse(url))
.setProgressiveRenderingEnabled(true)
.build()
Fresco.getImagePipeline()
.fetchDecodedImage(imageRequest, context)
.subscribe(dataSubscriber, CallerThreadExecutor.getInstance())
fun getBitmap(url: String, callback: BiCallback<Bitmap, Boolean>) {
Single.just(url)
.map { Picasso.with(HaloApp.getInstance().application).load(url).priority(Picasso.Priority.HIGH).get() }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
callback.onFirst(it)
}, {
callback.onSecond(true)
it.printStackTrace()
})
}
/**
@ -240,12 +249,23 @@ object ImageUtils {
// 图片是以 gif 结尾的就
if (it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false) {
if (view?.tag == url) return@let
val controller = Fresco.newDraweeControllerBuilder()
.setUri(url)
.setAutoPlayAnimations(true)
.build()
view?.controller = controller
val width = view?.layoutParams?.width
val height = view?.layoutParams?.height
if (width != null && width > 0) {
val controller = Fresco.newDraweeControllerBuilder()
.setUri(resizeGif(url, width, height ?: 0))
.setAutoPlayAnimations(true)
.build()
view.controller = controller
} else {
view?.post {
val controller = Fresco.newDraweeControllerBuilder()
.setUri(resizeGif(url, view.width, view.height))
.setAutoPlayAnimations(true)
.build()
view.controller = controller
}
}
} else {
val width = view?.layoutParams?.width
if (width != null && width > 0) {
@ -327,14 +347,34 @@ object ImageUtils {
//预加载图片
@JvmStatic
fun prefetchToDiskCache(url: String){
fun prefetchToDiskCache(url: String) {
val imagePipeline = Fresco.getImagePipeline()
val imageRequest = ImageRequest.fromUri(url)
imagePipeline.prefetchToDiskCache(imageRequest, HaloApp.getInstance().application)
}
private fun resizeGif(url: String, width: Int, height: Int): String {
val idealSize = getIdealGifSize(width, height)
return "$url?x-oss-process=image/resize,h_$idealSize,w_$idealSize"
}
private fun getIdealGifSize(width: Int, height: Int): String {
return if (width > LARGE_GIF_SIZE || height > LARGE_GIF_SIZE) {
"256"
} else if (width >= STANDARD_GIF_SIZE || height >= STANDARD_GIF_SIZE) {
"192"
} else if (width > TINY_GIF_SIZE || height > TINY_GIF_SIZE) {
"128"
} else {
"64"
}
}
public interface OnImageloadListener {
fun onLoadFinal(imageInfo: ImageInfo?)
}
fun getVideoSnapshot(videoUrl: String, progress: Long): String {
return "$videoUrl?x-oss-process=video/snapshot,t_$progress,f_jpg,w_0,h_0"
}
}

View File

@ -18,6 +18,7 @@ import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.LibaoEntity;
import com.gh.gamecenter.entity.LibaoStatusEntity;
import com.gh.gamecenter.entity.MeEntity;
import com.gh.gamecenter.entity.NotificationUgc;
import com.gh.gamecenter.entity.UserDataLibaoEntity;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBUISwitch;
@ -455,20 +456,26 @@ public class LibaoUtils {
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "ling", Utils.getTime(context)));
adapter.notifyDataSetChanged();
final String finalLibaoCode = libaoCode;
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, libaoCode))
, "关闭", " 复制礼包码"
, () -> {
copyLink(finalLibaoCode, context);
if (isInstallRequired) {
libaoBtn.postDelayed(() -> {
Spanned msg = Html.fromHtml(context.getString(R.string.linged_copy_dialog, finalLibaoCode));
lunningAppDialog(context
, msg, libaoEntity);
}, 300);
}
}, null);
NotificationHelper.showNotificationHintDialog(NotificationUgc.GIFT, isShow -> {
if (!isShow){
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, finalLibaoCode))
, "关闭", " 复制礼包码"
, () -> {
copyLink(finalLibaoCode, context);
if (isInstallRequired) {
libaoBtn.postDelayed(() -> {
Spanned msg = Html.fromHtml(context.getString(R.string.linged_copy_dialog, finalLibaoCode));
lunningAppDialog(context
, msg, libaoEntity);
}, 300);
}
}, null);
}
return null;
});
}
@Override

View File

@ -1,25 +1,32 @@
package com.gh.common.util;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.ExposureEntity;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureSource;
import com.gh.common.exposure.meta.Meta;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.loghub.LoghubUtils;
import com.gh.download.DownloadDataHelper;
import com.gh.common.loghub.SimpleLogContainerEntity;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.ShareResultEntity;
import com.gh.gamecenter.entity.SpecialColumn;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.gamecenter.retrofit.EmptyResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.Util_System_Phone_State;
import com.lightgame.utils.Utils;
@ -29,7 +36,9 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
/**
* Created by khy on 2/01/18.
@ -53,55 +62,6 @@ public class LogUtils {
uploadVideoStreaming(object);
}
public static void uploadDownloadEvent(DownloadEntity downloadEntity) {
Context context = HaloApp.getInstance().getApplication();
Meta meta = MetaUtil.INSTANCE.getMeta();
JSONObject object = new JSONObject();
try {
object.put("event", DownloadDataHelper.getDownloadStatusAlias(downloadEntity));
object.put("msg", downloadEntity.getError());
object.put("status", downloadEntity.getStatus().getStatus());
// payload
JSONObject payloadObject = new JSONObject();
payloadObject.put("game_id", downloadEntity.getGameId());
payloadObject.put("gameName", downloadEntity.getName());
payloadObject.put("platform", downloadEntity.getPlatform());
payloadObject.put("package", downloadEntity.getPackageName());
payloadObject.put("filename", downloadEntity.getPath().substring(downloadEntity.getPath().lastIndexOf("/") + 1));
payloadObject.put("total_size", (downloadEntity.getSize() / 1024 / 1024));
payloadObject.put("completed_size", (downloadEntity.getProgress() / 1024 / 1024));
object.put("payload", payloadObject);
// meta
JSONObject metaObject = new JSONObject();
metaObject.put("android_id", meta.getAndroid_id());
metaObject.put("android_sdk", meta.getAndroid_sdk());
metaObject.put("android_version", meta.getAndroid_version());
metaObject.put("appVersion", meta.getAppVersion());
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("imei", meta.getImei());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
metaObject.put("model", meta.getModel());
metaObject.put("network", DeviceUtils.getNetwork(context));
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
object.put("meta", metaObject);
object.put("timestamp", System.currentTimeMillis() / 1000);
} catch (Exception e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
LoghubUtils.log(object, "download_debug", false);
}
public static void uploadCommunityArticle(String tracers, String articleId, String articleTitle, int readTime, CommunityEntity community, SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
@ -283,7 +243,7 @@ public class LogUtils {
uploadToReservation(object);
}
private static void uploadToCommunity(JSONObject object) {
uploadToCommunity(object, false);
}
@ -419,4 +379,147 @@ public class LogUtils {
}
uploadVideoStreaming(object);
}
public static void uploadWelcomeDialog(String action, String dialogId, String linkTitle) {
ExposureEntity payload = new ExposureEntity();
payload.setWelcomeDialogId(dialogId);
payload.setWelcomeDialogId(linkTitle);
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
entity.setEvent("dialog");
entity.setAction(action);
entity.setMeta(MetaUtil.INSTANCE.getMeta());
entity.setPayload(payload);
entity.setTimestamp(System.currentTimeMillis() / 1000);
LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false);
}
public static void uploadLikeFromWelcomeDialog() {
String dialogId = (String) HaloApp.get(Constants.WELCOME_DIALOG_ID, false);
String linkTitle = (String) HaloApp.get(Constants.WELCOME_DIALOG_LINK_TITLE, false);
ExposureEntity payload = new ExposureEntity();
payload.setWelcomeDialogId(dialogId);
payload.setWelcomeDialogLinkTitle(linkTitle);
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
entity.setEvent("like");
entity.setMeta(MetaUtil.INSTANCE.getMeta());
entity.setPayload(payload);
entity.setTimestamp(System.currentTimeMillis() / 1000);
LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false);
}
public static void uploadCommentFromWelcomeDialog() {
String dialogId = (String) HaloApp.get(Constants.WELCOME_DIALOG_ID, false);
String linkTitle = (String) HaloApp.get(Constants.WELCOME_DIALOG_LINK_TITLE, false);
ExposureEntity payload = new ExposureEntity();
payload.setWelcomeDialogId(dialogId);
payload.setWelcomeDialogLinkTitle(linkTitle);
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
entity.setEvent("comment");
entity.setMeta(MetaUtil.INSTANCE.getMeta());
entity.setPayload(payload);
entity.setTimestamp(System.currentTimeMillis() / 1000);
LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false);
}
private static void uploadShare(JSONObject object) {
Meta meta = MetaUtil.INSTANCE.getMeta();
JSONObject metaObject = new JSONObject();
try {
metaObject.put("android_id", meta.getAndroid_id());
metaObject.put("android_sdk", meta.getAndroid_sdk());
metaObject.put("android_version", meta.getAndroid_version());
metaObject.put("appVersion", meta.getAppVersion());
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("imei", meta.getImei());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
metaObject.put("model", meta.getModel());
metaObject.put("network", meta.getNetwork());
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
object.put("event", "SHARE");
object.put("meta", metaObject);
object.put("timestamp", System.currentTimeMillis() / 1000);
} catch (JSONException e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
LoghubUtils.log(object, "event", false);
}
public static void uploadShareEnter(String entrance, String url, String title, String summary, String resourceId) {
JSONObject object = new JSONObject();
JSONObject payloadObject = new JSONObject();
try {
object.put("action", "entrance_source");
payloadObject.put("entrance", entrance);
payloadObject.put("url", url);
payloadObject.put("title", title);
payloadObject.put("summary", summary);
payloadObject.put("resource_id", resourceId);
object.put("payload", payloadObject);
} catch (JSONException e) {
e.printStackTrace();
}
uploadShare(object);
}
public static void uploadShareType(String shareType, String entrance, String url, String title, String summary, String resourceId) {
JSONObject object = new JSONObject();
JSONObject payloadObject = new JSONObject();
try {
object.put("action", "share_type");
payloadObject.put("share_type", shareType);
payloadObject.put("entrance", entrance);
payloadObject.put("url", url);
payloadObject.put("title", title);
payloadObject.put("summary", summary);
payloadObject.put("resource_id", resourceId);
object.put("payload", payloadObject);
} catch (JSONException e) {
e.printStackTrace();
}
uploadShare(object);
}
@SuppressLint("CheckResult")
public static void uploadShareResult(String shareType, String entrance, String shareResult, String url, String title, String summary, String resourceId) {
JSONObject object = new JSONObject();
JSONObject payloadObject = new JSONObject();
try {
object.put("action", "share_result");
payloadObject.put("share_type", shareType);
payloadObject.put("entrance", entrance);
payloadObject.put("share_result", shareResult);
payloadObject.put("url", url);
payloadObject.put("title", title);
payloadObject.put("summary", summary);
payloadObject.put("resource_id", resourceId);
object.put("payload", payloadObject);
} catch (JSONException e) {
e.printStackTrace();
}
uploadShare(object);
ShareResultEntity entity = new ShareResultEntity(new ShareResultEntity.Content(url, title, summary), shareType, shareResult);
RequestBody body = RequestBody.create(MediaType.parse("application/json"), GsonUtils.toJson(entity));
RetrofitManager.getInstance(HaloApp.getInstance().getApplication()).getApi()
.postShareResult(body)
.subscribeOn(Schedulers.io())
.subscribe(new EmptyResponse<>());
}
}

View File

@ -2,7 +2,9 @@ package com.gh.common.util
import android.app.Activity
import android.content.Intent
import android.widget.Toast
import com.bytedance.sdk.open.aweme.authorize.model.Authorization
import com.bytedance.sdk.open.douyin.DouYinOpenApiFactory
import com.bytedance.sdk.open.douyin.DouYinOpenConfig
import com.gh.common.constant.Config
import com.gh.gamecenter.R
import com.gh.gamecenter.user.LoginTag
@ -23,7 +25,7 @@ import com.tencent.tauth.Tencent
import com.tencent.tauth.UiError
import org.json.JSONException
import org.json.JSONObject
import java.lang.ref.WeakReference
/**
* 第三方登录辅助类
@ -37,12 +39,12 @@ object LoginHelper {
private var mTencent: Tencent // QQ
private var mIWXAPI: IWXAPI // 微信
private var mSsoHandler: SsoHandler? = null // 微博 // TODO 完成回调时清掉这个 handler
private var mSsoHandler: WeakReference<SsoHandler>? = null // 微博
private var mQqLoginListener: IUiListener
private var mAccessToken: Oauth2AccessToken? = null // weibo
private var mLoginCallback: LoginCallback? = null
private var mLoginCallback: WeakReference<LoginCallback>? = null
init {
val context = HaloApp.getInstance().application.applicationContext
@ -64,11 +66,11 @@ object LoginHelper {
content.put("access_token_expire", Utils.getTime(context) + o.getLong("expires_in"))
content.put("access_token", o.getString("access_token"))
mLoginCallback?.onLoginSuccess(LoginTag.qq, content) // 回调QQ登录成功
mLoginCallback?.get()?.onLoginSuccess(LoginTag.qq, content) // 回调QQ登录成功
} catch (e: JSONException) {
val errorString = "QQ登录数据回调异常$e"
mLoginCallback?.onLoginFailure(LoginTag.qq, errorString) // 回调QQ登录失败
mLoginCallback?.get()?.onLoginFailure(LoginTag.qq, errorString) // 回调QQ登录失败
Utils.log(errorString)
e.printStackTrace()
@ -77,18 +79,20 @@ object LoginHelper {
}
override fun onCancel() {
mLoginCallback?.onLoginFailure(LoginTag.qq,"登录取消")
mLoginCallback?.get()?.onLoginFailure(LoginTag.qq, "登录取消")
Utils.log("QQ 登录取消")
}
override fun onError(p0: UiError?) {
mLoginCallback?.onLoginFailure(LoginTag.qq,"登录失败")
mLoginCallback?.get()?.onLoginFailure(LoginTag.qq, "登录失败")
Utils.log("QQ 登录失败")
}
}
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
DouYinOpenApiFactory.init(DouYinOpenConfig(Config.DOUYIN_CLIENTKEY))
Utils.log("LoginHelper initialization")
}
@ -99,23 +103,33 @@ object LoginHelper {
@JvmStatic
fun onWechatLoginSuccess(content: JSONObject) {
mLoginCallback?.onLoginSuccess(LoginTag.wechat, content)
mLoginCallback?.get()?.onLoginSuccess(LoginTag.wechat, content)
}
@JvmStatic
fun onWechatLoginFailure(error: String) {
mLoginCallback?.onLoginFailure(LoginTag.wechat, error)
mLoginCallback?.get()?.onLoginFailure(LoginTag.wechat, error)
}
@JvmStatic
fun onDouYinLoginSuccess(content: JSONObject) {
mLoginCallback?.get()?.onLoginSuccess(LoginTag.douyin, content)
}
@JvmStatic
fun onDouYinLoginFailure(error: String) {
mLoginCallback?.get()?.onLoginFailure(LoginTag.douyin, error)
}
@JvmStatic
fun onWeiboLoginCallback(requestCode: Int, resultCode: Int, data: Intent?) {
mSsoHandler?.authorizeCallBack(requestCode, resultCode, data)
mSsoHandler?.get()?.authorizeCallBack(requestCode, resultCode, data)
}
// QQ登录
@JvmStatic
fun loginWithQQ(loginCallback: LoginCallback, activity: Activity) {
mLoginCallback = loginCallback
mLoginCallback = WeakReference(loginCallback)
if (!mTencent.isSessionValid) {
Utils.log("QQLogin")
mTencent.login(activity, "all", mQqLoginListener)
@ -132,7 +146,7 @@ object LoginHelper {
// 微信登录
@JvmStatic
fun loginWithWechat(loginCallback: LoginCallback) {
mLoginCallback = loginCallback
mLoginCallback = WeakReference(loginCallback)
val register = mIWXAPI.registerApp(Config.WECHAT_APPID)
val req = SendAuth.Req()
@ -149,9 +163,9 @@ object LoginHelper {
// 微博登录
@JvmStatic
fun loginWithWeibo(loginCallback: LoginCallback, context: Activity) {
mLoginCallback = loginCallback
mSsoHandler = SsoHandler(context)
mSsoHandler?.authorizeClientSso(object : WbAuthListener {
mLoginCallback = WeakReference(loginCallback)
mSsoHandler = WeakReference(SsoHandler(context))
mSsoHandler?.get()?.authorizeClientSso(object : WbAuthListener {
override fun onSuccess(token: Oauth2AccessToken?) {
token?.let {
RuntimeUtils.getInstance().runOnUiThread {
@ -159,7 +173,7 @@ object LoginHelper {
if (mAccessToken?.isSessionValid == true) {
// 保存 Token 到 SharedPreferences
AccessTokenKeeper.writeAccessToken(context, mAccessToken)
Toast.makeText(context, "授权成功", Toast.LENGTH_SHORT).show()
Utils.toast(context, "授权成功")
}
}
@ -170,23 +184,36 @@ object LoginHelper {
content.put("access_token_expire", Utils.getTime(context) + token.expiresTime)
content.put("refresh_token", token.refreshToken)
// content.put("refresh_token_expire", Utils.getTime(mContext) + 86400 * 30); // refresh_token 有效期30天
mLoginCallback?.onLoginSuccess(LoginTag.weibo, content)// 微博 登录回调
mLoginCallback?.get()?.onLoginSuccess(LoginTag.weibo, content)// 微博 登录回调
}
}
}
override fun onFailure(p0: WbConnectErrorMessage?) {
mLoginCallback?.onLoginFailure(LoginTag.weibo, "微博登录需要客户端支持,请先安装微博")
mLoginCallback?.get()?.onLoginFailure(LoginTag.weibo, "微博登录需要客户端支持,请先安装微博")
}
override fun cancel() {
mLoginCallback?.onLoginFailure(LoginTag.weibo, "取消授权")
mLoginCallback?.get()?.onLoginFailure(LoginTag.weibo, "取消授权")
}
})
// 第一次启动本应用AccessToken 不可用
mAccessToken = AccessTokenKeeper.readAccessToken(context)
}
// 抖音登录
@JvmStatic
fun loginWithDouYin(loginCallback: LoginCallback, context: Activity) {
mLoginCallback = WeakReference(loginCallback)
val douYinOpenApi = DouYinOpenApiFactory.create(context)
val request = Authorization.Request()
request.scope = "user_info" // 用户授权时必选权限
//request.state = "ww"; // 用于保持请求和回调的状态,授权请求后原样带回给第三方。
//request.callerLocalEntry = "com.xxx.xxx...activity";
douYinOpenApi.authorize(request)
}
interface LoginCallback {
fun onLoginSuccess(loginType: LoginTag, jsonContent: JSONObject)

View File

@ -55,6 +55,7 @@ public class LoginUtils {
@Override
public void onFailure(HttpException e) {
super.onFailure(e);
listener.onCaptcha(null);
if (e == null) {
Utils.toast(context, "无法获取验证码,请检查你的网络状态");
return;

View File

@ -4,6 +4,8 @@ import android.content.Context;
import android.graphics.Color;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.NewsEntity;
import com.gh.gamecenter.retrofit.Response;
@ -78,7 +80,7 @@ public class NewsUtils {
/**
* 设置新闻类型
*/
public static void setNewsType(TextView textView, String type, int priority, int position) {
public static void setNewsType(TextView textView, @Nullable String type, int priority, int position) {
if (priority != 0) {
if (position == 0) {
textView.setText(R.string.article_top);
@ -92,7 +94,7 @@ public class NewsUtils {
}
textView.setTextColor(Color.WHITE);
switch (type) {
switch (type != null ? type : "") {
case "活动":
textView.setBackgroundResource(R.drawable.textview_orange_style);
break;

View File

@ -18,7 +18,7 @@ import io.reactivex.schedulers.Schedulers
object NotificationHelper {
@JvmStatic
fun showNotificationHintDialog(ugc: NotificationUgc) {
fun showNotificationHintDialog(ugc: NotificationUgc, callBack: ((isShow: Boolean) -> Unit)? = null) {
val showedNewVersion = SPUtils.getInt(Constants.SP_SHOWED_NOTIFICATION_NEW_VERSION, 0)
val currentVersion = PackageUtils.getVersionCode()
// 版本升级后重置数据
@ -29,6 +29,9 @@ object NotificationHelper {
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_ARTICLE, false)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_VIDEO, false)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RATING, false)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_GIFT, false)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RESERVE_GAME, false)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_FEEDBACK, false)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, "")
SPUtils.setInt(Constants.SP_SHOWED_NOTIFICATION_NEW_VERSION, currentVersion)
@ -37,7 +40,10 @@ object NotificationHelper {
val isShowedToday = SPUtils.getString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, "")
// 每天最多只需提示一次
if (isShowedToday == TimeUtils.getToday()) return
if (isShowedToday == TimeUtils.getToday()){
callBack?.invoke(false)
return
}
val isShowedLogin = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_LOGIN, false)
val isShowedQuestion = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_QUESTION, false)
@ -45,78 +51,115 @@ object NotificationHelper {
val isShowedArticle = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_ARTICLE, false)
val isShowedVideo = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_VIDEO, false)
val isShowedRating = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_RATING, false)
val isShowedGift = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_GIFT, false)
val isShowedReserveGame = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_RESERVE_GAME, false)
val isShowedFeedback = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_FEEDBACK, false)
if (isShowedLogin && isShowedQuestion && isShowedAnswer && isShowedArticle && isShowedVideo && isShowedRating) return
if (isShowedLogin && isShowedQuestion && isShowedAnswer && isShowedArticle && isShowedVideo && isShowedRating && isShowedGift && isShowedReserveGame && isShowedFeedback) {
callBack?.invoke(false)
return
}
when (ugc) {
NotificationUgc.LOGIN -> {
if (!isShowedLogin) {
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_LOGIN, true)
// 设置今天的时间,表示今天已经触发过了
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.QUESTION -> {
if (!isShowedQuestion) {
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_QUESTION, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.ANSWER -> {
if (!isShowedAnswer) {
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_ANSWER, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.ARTICLE -> {
if (!isShowedArticle) {
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_ARTICLE, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.VIDEO -> {
if (!isShowedVideo) {
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_VIDEO, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.RATING -> {
if (!isShowedRating) {
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RATING, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.GIFT -> {
if (!isShowedGift) {
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_GIFT, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.RESERVE_GAME -> {
if (!isShowedReserveGame) {
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RESERVE_GAME, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
NotificationUgc.FEEDBACK -> {
if (!isShowedFeedback) {
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_FEEDBACK, true)
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
} else {
callBack?.invoke(false)
}
}
}
}
@SuppressLint("CheckResult")
private fun show(activity: AppCompatActivity?) {
fun show(activity: AppCompatActivity?, ugc: NotificationUgc, callBack: ((isShow: Boolean) -> Unit)? = null) {
if (activity == null) return
RetrofitManager.getInstance(activity).api.bootPopup
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<NotificationHint>() {
override fun onSuccess(data: NotificationHint) {
try {
showEnableNotificationDialogIfItsDisabled(activity, data)
} catch (ignore: Exception) {
}
}
})
showEnableNotificationDialogIfItsDisabled(activity, ugc, callBack)
}
@JvmStatic
fun showEnableNotificationDialogIfItsDisabled(activity: AppCompatActivity, notificationHint: NotificationHint) {
fun showEnableNotificationDialogIfItsDisabled(activity: AppCompatActivity, ugc: NotificationUgc, callBack: ((isShow: Boolean) -> Unit)? = null) {
if (notificationIsEnable()) {
Utils.log("notification is enable")
callBack?.invoke(false)
} else {
NotificationHintDialogFragment.getInstance(notificationHint).show(activity.supportFragmentManager, "notification")
callBack?.invoke(true)
NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
}
}

View File

@ -16,6 +16,18 @@ object NumberUtils {
}
return s
}
@JvmStatic
fun transSimpleLetterCount(count: Int): String {
val s: String
s = if (count > 10000) {
val number = count / 10000f
val fmt = DecimalFormat("#.0")
fmt.format(number) + "W"
} else {
count.toString()
}
return s
}
@JvmStatic
fun transSimpleUsageTime(second: Long): String {

View File

@ -0,0 +1,88 @@
package com.gh.common.util
import com.alibaba.sdk.android.oss.ClientConfiguration
import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.OSSClient
import com.alibaba.sdk.android.oss.ServiceException
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.gh.gamecenter.entity.OssEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
object OssUploadUtils {
//上传文件类型
enum class UploadType(val value: String) {
GAME("game")//后缀apk
}
//获取Oss配置
private fun getOssUpdateConfig(type: UploadType): Single<OssEntity> {
return RetrofitManager.getInstance(HaloApp.getInstance().application)
.api
.getOssUpdateConfig(type.value)
.subscribeOn(Schedulers.io())
}
//异步上传文件
@JvmStatic
fun uploadFile(path: String, uploadType: UploadType, listener: OnUploadFileListener?): Disposable {
return getOssUpdateConfig(uploadType)
.subscribeOn(Schedulers.io())
.flatMap { mOssEntity ->
Single.create<String> {
val conf = ClientConfiguration()
conf.connectionTimeout = 15 * 1000
conf.socketTimeout = 15 * 1000
conf.maxConcurrentRequest = 5
conf.maxErrorRetry = 2
val credentialProvider = OSSStsTokenCredentialProvider(mOssEntity.accessKeyId, mOssEntity.accessKeySecret, mOssEntity.securityToken)
val oss = OSSClient(HaloApp.getInstance().application, mOssEntity.endPoint, credentialProvider, conf)
// 构造上传请求
val put = PutObjectRequest(mOssEntity.bucket, mOssEntity.key, path)
val task: OSSAsyncTask<*> = oss.asyncPutObject(put, object : OSSCompletedCallback<PutObjectRequest?, PutObjectResult> {
override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult) {
it.onSuccess(mOssEntity.domain + mOssEntity.key)
}
override fun onFailure(request: PutObjectRequest?, clientExcepion: ClientException?, serviceException: ServiceException?) {
clientExcepion?.printStackTrace()
serviceException?.printStackTrace()
if (serviceException != null) {
it.onError(Throwable(message = clientExcepion?.message + "/" + serviceException.message))
}
}
})
}
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { url, throwable ->
if (url.isNotEmpty()) {
listener?.onSuccess(url)
return@subscribe
}
if (throwable != null) {
listener?.onError(throwable)
}
}
}
interface OnUploadFileListener {
fun onSuccess(url: String)
fun onError(e: Throwable?)
}
}

View File

@ -0,0 +1,129 @@
package com.gh.common.util
import android.app.Application
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import androidx.core.content.FileProvider
import com.gh.common.constant.Constants
import com.gh.common.xapk.XapkInstaller
import com.gh.gamecenter.BuildConfig
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File
object PackageInstaller {
/**
* 为了兼容java代码
*/
@JvmStatic
fun install(context: Context, downloadEntity: DownloadEntity) {
install(context, downloadEntity, true)
}
/**
* 启动安装应用程序并取消通知栏安装消息
*
* 兼容所有包安装(apk,xapk),后续可加上apks
*
* 主动点击安装如果是xapk则需要toast提示
*/
@JvmStatic
fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) {
// 取消状态栏下载完成的通知,若存在
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
val pkgPath = downloadEntity.path
if (XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()) {
XapkInstaller.install(context, downloadEntity, showUnzipToast)
} else {
install(context, downloadEntity.path)
}
}
/**
* 启动安装应用程序
*
* 除非特殊情况,请勿使用此方法进行应用安装操作
* 除非你已经确定该文件一定是Apk
*/
@JvmStatic
fun install(context: Context, pkgPath: String) {
try {
if (PackageUtils.isCanLaunchSetup(context, pkgPath)) {
val installIntent = getInstallIntent(context, pkgPath)
context.startActivity(installIntent)
} else {
DialogUtils.showPluginDialog(context) {
uninstall(context, pkgPath)
}
}
} catch (e: Exception) {
Utils.toast(context, e.message)
}
}
/**
* 获取启动安装意图
*
* 除非特殊情况,请勿使用此方法进行应用安装操作
* 除非你已经确定该文件一定是Apk且该次安装无需检查签名情况
*/
@JvmStatic
fun getInstallIntent(context: Context, path: String): Intent {
var uri = Uri.fromFile(File(path))
val installIntent = Intent(Intent.ACTION_VIEW)
if ("smartisan" == Build.MANUFACTURER) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, File(path))
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
installIntent.setDataAndType(uri, "application/vnd.android.package-archive")
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
} else {
// 应用内更新不加 FLAG_ACTIVITY_NEW_TASK 在模拟器上会出现安装完成后安装界面也一并消失的类似闪退的表现
// Application 上下文就更不用说了
val pkgName = PackageUtils.getPackageNameByPath(context, path)
if (pkgName == context.packageName || context is Application) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
installIntent.setDataAndType(uri, "application/vnd.android.package-archive")
}
InstallUtils.getInstance(context).addInstall(PackageUtils.getPackageNameByPath(context, path))
return installIntent
}
/**
* 卸载应用
*/
@JvmStatic
fun uninstall(context: Context, path: String) {
val uninstallIntent = Intent()
uninstallIntent.action = Intent.ACTION_DELETE
uninstallIntent.addCategory(Intent.CATEGORY_DEFAULT)
val packageName = PackageUtils.getPackageNameByPath(context, path)
uninstallIntent.data = Uri.parse("package:$packageName")
InstallUtils.getInstance(context).addUninstall(packageName)
context.startActivity(uninstallIntent)
}
@JvmStatic
fun getDownloadPath(gameName: String?, format: String?): String {
return FileUtils.getDownloadPath(HaloApp.getInstance().application, getDownloadFileName(gameName, format))
}
private fun getDownloadFileName(gameName: String?, format: String?): String {
var fileExtension = "apk"
if (format == XapkInstaller.XAPK_EXTENSION_NAME) {
fileExtension = XapkInstaller.XAPK_EXTENSION_NAME
}
return MD5Utils.getContentMD5(gameName + "_" + System.currentTimeMillis()) + "." + fileExtension
}
}

View File

@ -1,7 +1,6 @@
package com.gh.common.util;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@ -13,17 +12,18 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.g00fy2.versioncompare.Version;
import com.gh.common.constant.Constants;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.manager.PackagesManager;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.Utils;
import org.json.JSONArray;
@ -31,7 +31,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@ -42,9 +41,6 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
public class PackageUtils {
public static final String publicKey = "OpenSSLRSAPublicKey{modulus=a8c4bb5748fec8d5c35db1a7a182d41ba4721a91131a417330af79ef4ddb43f9fa0ff4907b0a613bfe152de0ed8fc1b2e6f94a908aa98a5f7adc1ce814ba7ec919d75d9910bdfd8649b4789da6a90ffb61f0d23ac4f828a78fcd0d6f6120c1c43c1f87f7498a89eb40ca8e32dfc2f9d5c10d612b95192870223674e241e53305abf320d7eed76ded398778576e4db7b17b3bc6a792f13de5e43a6a5fae4276c73e6990ce97f68dff0ec16fc9594f175c8d49cd0d7877340d9de60942ca0efc737e50b6c295dfe0713e4532b4e810e1ea11b702b4a27753e41559cbceb247e7f044ec4e3ab2e8bccd8b9fd71286e63307550bcde86deee95adb8133076269135b,publicExponent=10001}";
@ -63,6 +59,8 @@ public class PackageUtils {
updateEntity.setId(gameEntity.getId());
updateEntity.setName(gameEntity.getName());
updateEntity.setIcon(gameEntity.getIcon());
updateEntity.setRawIcon(gameEntity.getRawIcon());
updateEntity.setIconSubscript(gameEntity.getIconSubscript());
updateEntity.setPackageName(apkEntity.getPackageName());
updateEntity.setSize(apkEntity.getSize());
updateEntity.setVersion(apkEntity.getVersion());
@ -76,6 +74,7 @@ public class PackageUtils {
updateEntity.setDownload(gameEntity.getDownload());
updateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
updateEntity.setPluginDesc(gameEntity.getPluginDesc());
updateEntity.setFormat(apkEntity.getFormat());
updateList.add(updateEntity);
}
}
@ -113,6 +112,7 @@ public class PackageUtils {
updateEntity.setTagStyle(gameEntity.getTagStyle());
updateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
updateEntity.setPluginDesc(gameEntity.getPluginDesc());
updateEntity.setFormat(apkEntity.getFormat());
updateList.add(updateEntity);
}
}
@ -232,29 +232,6 @@ public class PackageUtils {
return ret;
}
/*
* 启动安装应用程序
*/
public static void launchSetup(final Context context, DownloadEntity downloadEntity) {
// 取消状态栏下载完成的通知,若存在
downloadEntity.getMeta().put(Constants.MARK_ALREADY_TRIGGERED_INSTALLATION, "YES");
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity);
launchSetup(context, downloadEntity.getPath());
}
private static void launchSetup(final Context context, final String path) {
try {
if (isCanLaunchSetup(context, path)) {
context.startActivity(PackageUtils.getInstallIntent(context, path));
} else {
DialogUtils.showPluginDialog(context,
() -> context.startActivity(PackageUtils.getUninstallIntent(context, path)));
}
} catch (Exception e) {
Utils.toast(context, e.getMessage());
}
}
/**
* 根据 path 获取 apk 信息确定处理方式
*
@ -291,37 +268,6 @@ public class PackageUtils {
return compareSignatureBetweenInstalledAppWithApk(context, packageName, path);
}
/*
* 根据路径,获取安装游戏的意图
*/
public static Intent getInstallIntent(Context context, String path) {
return getInstallIntent(context, path, false);
}
public static Intent getInstallIntent(Context context, String path, boolean isInAppUpdate) {
Uri uri = Uri.fromFile(new File(path));
Intent installIntent = new Intent(Intent.ACTION_VIEW);
if ("smartisan".equals(Build.MANUFACTURER)) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, new File(path));
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
// 应用内更新不加 FLAG_ACTIVITY_NEW_TASK 在模拟器上会出现安装完成后安装界面也一并消失的类似闪退的表现
// Application 上下文就更不用说了
if (isInAppUpdate || context instanceof Application) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
}
InstallUtils.getInstance(context).addInstall(getPackageNameByPath(context, path));
return installIntent;
}
/*
* 根据包名,获取卸载游戏的意图
*/
@ -552,9 +498,10 @@ public class PackageUtils {
&& !TextUtils.isEmpty(apkEntity.getGhVersion())
&& !PackageUtils.isSignedByGh(HaloApp.getInstance().getApplication(), apkEntity.getPackageName());
}
/**
* 获取调用者的进程名
*
* @param context 调用者的上下文
* @return 进程名
*/
@ -571,5 +518,38 @@ public class PackageUtils {
}
return null;
}
/**
* 应用是否在前台运行
*/
public static boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager == null) return false;
List<ActivityManager.RunningAppProcessInfo> appProcesses =
activityManager.getRunningAppProcesses();
if (appProcesses == null) return false;
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm == null) return false;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
if (!pm.isInteractive()) return false;
} else {
if (!pm.isScreenOn()) return false;
}
String packageName = context.getApplicationContext().getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName) && appProcess.importance
== ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,135 @@
package com.gh.common.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.widget.TextView;
import androidx.core.content.res.ResourcesCompat;
import com.gh.gamecenter.R;
import com.halo.assistant.HaloApp;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import com.squareup.picasso.Transformation;
public class PicassoImageGetter implements Html.ImageGetter {
private TextView textView = null;
public PicassoImageGetter() {
}
public PicassoImageGetter(TextView target) {
textView = target;
}
@Override
public Drawable getDrawable(String source) {
BitmapDrawablePlaceHolder drawable = new BitmapDrawablePlaceHolder();
Context context = HaloApp.getInstance().getApplication();
Picasso.with(context)
.load(source)
.transform(new CircleTransformation())
.placeholder(ResourcesCompat.getDrawable(context.getResources(), R.drawable.personal_user_default_icon, context
.getTheme()))
.into(drawable);
return drawable;
}
private class BitmapDrawablePlaceHolder extends BitmapDrawable implements Target {
protected Drawable drawable;
@Override
public void draw(final Canvas canvas) {
if (drawable != null) {
Paint.FontMetricsInt fmPaint = textView.getPaint().getFontMetricsInt();
float fontHeight = fmPaint.descent - fmPaint.ascent;
float textSize = textView.getTextSize();
if (fontHeight - textSize > 0) {
canvas.translate((fontHeight - textSize) / 2, 0);
}
drawable.draw(canvas);
}
}
@SuppressWarnings("SuspiciousNameCombination")
public void setDrawable(Drawable drawable) {
try {
this.drawable = drawable;
Paint.FontMetricsInt fmPaint = textView.getPaint().getFontMetricsInt();
int fontHeight = fmPaint.descent - fmPaint.ascent;
int textSize = (int) textView.getTextSize();
drawable.setBounds(0, 0, textSize, textSize);
setBounds(0, 0, fontHeight, fontHeight);
if (textView != null) {
textView.setText(textView.getText());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setDrawable(new BitmapDrawable(HaloApp.getInstance()
.getApplication()
.getResources(), bitmap));
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
setDrawable(placeHolderDrawable);
}
}
private class CircleTransformation implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap.Config config = source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888;
Bitmap bitmap = Bitmap.createBitmap(size, size, config);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
@Override
public String key() {
return "circle";
}
}
}

View File

@ -36,43 +36,23 @@ import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
public class PlatformUtils {
private static PlatformUtils mInstance;
private Context context;
private ArrayMap<String, String> platformMap;
private ArrayMap<String, Integer> platformPicMap;
private ArrayMap<String, String> platformPicUrlMap;
private ArrayMap<String, String> platformColorMap;
private boolean isCheck = false;
private boolean isUpdate = false;
private PlatformUtils(Context con) {
this.context = con.getApplicationContext();
initMap();
}
private void initMap() {
ArrayMap<String, Integer> platformPicMap = new ArrayMap<>();
platformPicMap.put("360", R.drawable.platform_360);
platformPicMap.put("37wan", R.drawable.platform_37);
platformPicMap.put("91", R.drawable.platform_91);
platformPicMap.put("9u", R.drawable.platform_9u);
platformPicMap.put("anzhi", R.drawable.platform_anzhi);
platformPicMap.put("baidu", R.drawable.platform_baidu);
platformPicMap.put("dangle", R.drawable.platform_dl);
platformPicMap.put("ewan", R.drawable.platform_ewan);
platformPicMap.put("gf", R.drawable.platform_gf);
platformPicMap.put("gf-w", R.drawable.platform_gfw);
platformPicMap.put("huawei", R.drawable.platform_hw);
platformPicMap.put("mi", R.drawable.platform_mi);
platformPicMap.put("oppo", R.drawable.platform_oppo);
platformPicMap.put("ouwan", R.drawable.platform_ouwan);
platformPicMap.put("pps", R.drawable.platform_pps);
platformPicMap.put("vivo", R.drawable.platform_vivo);
platformPicMap.put("wdj", R.drawable.platform_wdj);
ArrayMap<String, String> platformColorMap = new ArrayMap<>();
platformColorMap.put("360", "#218FA4");
platformColorMap.put("37wan", "#F5BD20");
@ -91,24 +71,20 @@ public class PlatformUtils {
platformColorMap.put("pps", "#FF8C27");
platformColorMap.put("vivo", "#3FA5E3");
platformColorMap.put("wdj", "#5ABA3F");
ArrayMap<String, String> platformMap = new ArrayMap<>();
ArrayMap<String, String> platformPicUrlMap = new ArrayMap<>();
SharedPreferences sharedPreferences = context.getSharedPreferences(
"gh_platform", Context.MODE_PRIVATE);
SharedPreferences sharedPreferences = context.getSharedPreferences("gh_platform", Context.MODE_PRIVATE);
Set<String> set = sharedPreferences.getStringSet("platform", null);
if (set == null) {
Properties properties = new Properties();
try {
properties
.load(context.getAssets().open("platform.properties"));
properties.load(context.getAssets().open("platform.properties"));
Set<String> pset = new HashSet<>();
for (Object object : properties.keySet()) {
platformMap.put(object.toString(),
(String) properties.get(object));
pset.add(object.toString() + "="
+ (String) properties.get(object) + "=" + "=");
platformMap.put(object.toString(), (String) properties.get(object));
pset.add(object.toString() + "=" + (String) properties.get(object) + "=" + "=");
}
Editor editor = sharedPreferences.edit();
editor.putStringSet("platform", pset);
@ -133,11 +109,10 @@ public class PlatformUtils {
// checkPlatformPic(urls);
}
}
updatePlatform(platformMap, platformPicMap, platformPicUrlMap,
platformColorMap);
updatePlatform(platformMap, platformPicUrlMap, platformColorMap);
}
private void checkPlatformPic(final ArrayList<String> urls) {
isCheck = true;
File file = new File(FileUtils.getPlatformPicDir(context));
@ -154,53 +129,41 @@ public class PlatformUtils {
}
}
if (urls.size() != 0) {
AppExecutor.getIoExecutor().execute(new Runnable() {
@Override
public void run() {
int success = 0;
for (int i = 0; i < urls.size(); i++) {
String url = urls.get(i);
String savePath = FileUtils.getPlatformPicDir(context)
+ File.separator
+ url.substring(url.lastIndexOf("/") + 1);
int code = FileUtils.downloadFile(url, savePath);
if (code == HttpURLConnection.HTTP_OK) {
success++;
}
AppExecutor.getIoExecutor().execute(() -> {
int success = 0;
for (int i = 0; i < urls.size(); i++) {
String url = urls.get(i);
String savePath = FileUtils.getPlatformPicDir(context) + File.separator + url
.substring(url.lastIndexOf("/") + 1);
int code = FileUtils.downloadFile(url, savePath);
if (code == HttpURLConnection.HTTP_OK) {
success++;
}
if (success == urls.size()) {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new EBReuse("PlatformChanged"));
}
});
}
isCheck = false;
}
if (success == urls.size()) {
Handler handler = new Handler(context.getMainLooper());
handler.post(() -> EventBus.getDefault().post(new EBReuse("PlatformChanged")));
}
isCheck = false;
});
} else {
isCheck = false;
}
}
private void updatePlatform(ArrayMap<String, String> pMap,
ArrayMap<String, Integer> pPMap, ArrayMap<String, String> pUMap,
ArrayMap<String, String> pCMap) {
private void updatePlatform(ArrayMap<String, String> pMap, ArrayMap<String, String> pUMap, ArrayMap<String, String> pCMap) {
platformMap = pMap;
platformPicMap = pPMap;
platformPicUrlMap = pUMap;
platformColorMap = pCMap;
}
public static PlatformUtils getInstance(Context context) {
if (mInstance == null) {
mInstance = new PlatformUtils(context);
}
return mInstance;
}
public String getPlatformColor(String platform) {
if ("".equals(platform) || "官方版".equals(platform)) {
return "#BB3D42";
@ -209,26 +172,16 @@ public class PlatformUtils {
if (color != null) {
return color;
}
int themeColor = ContextCompat.getColor(HaloApp.getInstance().getApplication(), R.color.theme);
int themeColor = ContextCompat.getColor(HaloApp.getInstance()
.getApplication(), R.color.theme);
return String.format("#%06X", 0xFFFFFF & themeColor);
}
public int getPlatformPic(String platform) {
if ("".equals(platform) || "官方版".equals(platform)) {
return R.drawable.platform_gf;
}
Integer id = platformPicMap.get(platform);
if (id != null) {
return id;
}
return 0;
}
public String getPlatformPicUrl(String platform) {
return platformPicUrlMap.get(platform);
}
public String getPlatformName(String platform) {
if ("".equals(platform) || "官方版".equals(platform)) {
return "官方版";
@ -242,38 +195,40 @@ public class PlatformUtils {
}
return platform;
}
public void getPlatform() {
if (isUpdate) {
return;
}
isUpdate = true;
RetrofitManager.getInstance(context).getApi().getGamePlatform()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<PlatformEntity>>() {
@Override
public void onResponse(List<PlatformEntity> response) {
Set<String> platformSet = new HashSet<>();
for (PlatformEntity platformEntity : response) {
platformSet.add(platformEntity.toString());
}
SharedPreferences sp = context.getSharedPreferences("gh_platform", Context.MODE_PRIVATE);
sp.edit().putStringSet("platform", platformSet).apply();
initMap();
EventBus.getDefault().post(new EBReuse("PlatformChanged"));
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String today = format.format(new Date());
sp.edit().putString("refresh_time", today).apply();
isUpdate = false;
RetrofitManager.getInstance(context)
.getApi()
.getGamePlatform()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<PlatformEntity>>() {
@Override
public void onResponse(List<PlatformEntity> response) {
Set<String> platformSet = new HashSet<>();
for (PlatformEntity platformEntity : response) {
platformSet.add(platformEntity.toString());
}
@Override
public void onFailure(HttpException e) {
isUpdate = false;
}
});
SharedPreferences sp = context.getSharedPreferences("gh_platform", Context.MODE_PRIVATE);
sp.edit().putStringSet("platform", platformSet).apply();
initMap();
EventBus.getDefault().post(new EBReuse("PlatformChanged"));
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String today = format.format(new Date());
sp.edit().putString("refresh_time", today).apply();
isUpdate = false;
}
@Override
public void onFailure(HttpException e) {
isUpdate = false;
}
});
}
}

View File

@ -120,7 +120,6 @@ public class PostCommentUtils {
final String commentId,
final PostCommentListener listener) {
Observable<ResponseBody> observable;
if (!TextUtils.isEmpty(answerId)) {
@ -260,7 +259,6 @@ public class PostCommentUtils {
});
}
public interface PostCommentListener {
void postSuccess(JSONObject response);

View File

@ -48,9 +48,9 @@ object ReservationHelper {
ReservationRepository.removeReservationFromMemoryAndRefresh(game.id)
if (deleteReservation) {
MtaHelper.onEvent("预约游戏", "取消预约", game.name)
// MtaHelper.onEvent("预约游戏", "取消预约", game.name)
} else {
MtaHelper.onEvent("预约游戏", "删除预约", game.name)
// MtaHelper.onEvent("预约游戏", "删除预约", game.name)
}
refreshCallback.onCallback()
@ -73,9 +73,10 @@ object ReservationHelper {
"暂不删除",
{ emptyCallback.onCallback() },
null,
trackMtaEvent = true,
mtaEvent = "预约游戏",
mtaKey = "删除预约弹窗")
trackMtaEvent = true
// , mtaEvent = "预约游戏",
// mtaKey = "删除预约弹窗"
)
}
@JvmStatic
@ -88,9 +89,10 @@ object ReservationHelper {
"暂不取消",
{ emptyCallback.onCallback() },
null,
trackMtaEvent = true,
mtaEvent = "预约游戏",
mtaKey = "取消预约弹窗")
trackMtaEvent = true
// , mtaEvent = "预约游戏",
// mtaKey = "取消预约弹窗"
)
}

View File

@ -24,13 +24,13 @@ import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.constant.Config;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WeiBoShareActivity;
import com.gh.gamecenter.entity.ShareEntity;
import com.gh.gamecenter.eventbus.EBShare;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.WbSdk;
@ -53,9 +53,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
/**
@ -71,7 +68,6 @@ public class ShareUtils {
private String mTitle;
private String mSummary;
private int[] arrLogo = {
R.drawable.share_wechat_logo,
R.drawable.share_wechatmoments_logo,
@ -83,24 +79,39 @@ public class ShareUtils {
R.drawable.share_cancel_logo
};
public enum ShareType {
news,
game, // 普通游戏
plugin, // 插件游戏
tools,
askInvite,
askNormal, // 问答问题/答案
shareGh,
communityArticle,
video
public enum ShareEntrance {
news("资讯文章"),
game("游戏详情"), // 普通游戏
plugin("游戏详情"), // 插件游戏
tools("工具箱"),
askInvite("邀请回答"),
askNormal("问题详情"), //问答问题
answerNormal("回答详情"), //问答答案
shareGh("APP分享"),
communityArticle("文章详情"),
video("视频"),
web("web链接");
private String name;
ShareEntrance(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
private String[] arrLabel = {"微信好友", "朋友圈", "QQ好友", "QQ空间", "新浪微博", "短信", "复制链接", "取消"};
private PopupWindow popupWindow;
private WeakReference<PopupWindow> popupWindow;
private ShareType mShareType;
public static ShareType shareType;//全局保存shareType分享成功后判断分享的类型
private ShareEntrance mShareEntrance;
public static String shareType = "";//分享类型(事件上报用)
public static ShareEntrance shareEntrance;//分享入口(事件上报和视频分享统计用)
public static String resourceId = "";//分享内容的id(事件上报用)
public static ShareEntity shareEntity;//分享信息(事件上报用)
private WeakReference<Activity> mActivity;
@ -110,25 +121,31 @@ public class ShareUtils {
@Override
public void onComplete(Object o) {
Utils.toast(mContext, R.string.share_success_hint);
EventBus.getDefault().post(new EBShare(ShareUtils.shareType));
EventBus.getDefault().post(new EBShare(ShareUtils.shareEntrance));
LogUtils.uploadShareResult(shareType, ShareUtils.shareEntrance.getName(), "success",
ShareUtils.shareEntity.getShareUrl(), ShareUtils.shareEntity.getShareTitle(), ShareUtils.shareEntity.getSummary(), ShareUtils.resourceId);
}
@Override
public void onError(UiError uiError) {
Utils.toast(mContext, R.string.share_fail_hint);
LogUtils.uploadShareResult(shareType, ShareUtils.shareEntrance.getName(), "fail",
ShareUtils.shareEntity.getShareUrl(), ShareUtils.shareEntity.getShareTitle(), ShareUtils.shareEntity.getSummary(), ShareUtils.resourceId);
}
@Override
public void onCancel() {
Utils.toast(mContext, R.string.share_cancel_hint);
LogUtils.uploadShareResult(shareType, ShareUtils.shareEntrance.getName(), "cancel",
ShareUtils.shareEntity.getShareUrl(), ShareUtils.shareEntity.getShareTitle(), ShareUtils.shareEntity.getSummary(), ShareUtils.resourceId);
}
};
private ShareUtils(Context context) {
mTencent = Tencent.createInstance(Config.TENCENT_APPID, context); //初始化QQ分享
mIWXAPI = WXAPIFactory.createWXAPI(context, Config.WECHAT_APPID); //初始化微信分享
WbSdk.install(context, new AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
mContext = context.getApplicationContext();
mTencent = Tencent.createInstance(Config.TENCENT_APPID, mContext); //初始化QQ分享
mIWXAPI = WXAPIFactory.createWXAPI(mContext, Config.WECHAT_APPID); //初始化微信分享
WbSdk.install(mContext, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
}
public static ShareUtils getInstance(Context context) {
@ -153,17 +170,20 @@ public class ShareUtils {
return false;
}
public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType, ShareCallBack callBack) {
public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = icon;
this.shareUrl = url;
this.mSummary = shareSummary;
this.mTitle = shareTitle;
this.mShareType = shareType;
ShareUtils.shareType = mShareType;
this.mShareEntrance = shareEntrance;
ShareUtils.shareEntrance = mShareEntrance;
ShareUtils.resourceId = id;
ShareUtils.shareEntity = new ShareEntity(shareUrl, mTitle, mSummary);
LogUtils.uploadShareEnter(mShareEntrance.getName(), shareUrl, mTitle, mSummary, id);
View contentView = View.inflate(activity, R.layout.share_popup_layout, null);
View contentView = View.inflate(mActivity.get(), R.layout.share_popup_layout, null);
contentView.setFocusable(true);
contentView.setFocusableInTouchMode(true);
RecyclerView shareRecyclerView = contentView.findViewById(R.id.share_rv);
@ -191,7 +211,7 @@ public class ShareUtils {
}
});
if (mShareType == ShareType.shareGh) {
if (mShareEntrance == ShareEntrance.shareGh) {
RelativeLayout layout = (RelativeLayout) view;
layout.addView(contentView);
arrLabel[6] = "邮件";
@ -206,41 +226,41 @@ public class ShareUtils {
arrLogo[7] = R.drawable.share_cancel_logo;
}
popupWindow = new SharePopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.MATCH_PARENT, true);
popupWindow.setAnimationStyle(R.style.popwindow_exit_only_anim_style);
popupWindow = new WeakReference<>(new SharePopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.MATCH_PARENT, true));
popupWindow.get().setAnimationStyle(R.style.popwindow_exit_only_anim_style);
//解决PopupWindow无法覆盖状态栏
popupWindow.setClippingEnabled(false);
popupWindow.get().setClippingEnabled(false);
int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity);
if (!DisplayUtils.isNavigationBarShow(activity)) {
bottomLocation = 0;
}
try {
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
popupWindow.get().showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
} catch (Exception e) {
e.printStackTrace();
}
contentView.setOnClickListener(v -> popupWindow.dismiss());
contentView.setOnClickListener(v -> safelyDismiss());
contentView.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0
&& popupWindow != null
&& popupWindow.isShowing()) {
&& popupWindow.get() != null
&& popupWindow.get().isShowing()) {
if (callBack != null) {
callBack.onCancel();
}
popupWindow.dismiss();
safelyDismiss();
}
return false;
});
}
public void showShareWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType) {
showShareWindowsCallback(activity, view, url, icon, shareTitle, shareSummary, shareType, null);
public void showShareWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id) {
showShareWindowsCallback(activity, view, url, icon, shareTitle, shareSummary, shareEntrance, id, null);
}
//QQ分享
@ -248,11 +268,12 @@ public class ShareUtils {
Utils.toast(mContext, R.string.share_skip);
Bundle params = new Bundle();
switch (mShareType) {
switch (mShareEntrance) {
case plugin:
mSummary += "(光环加速版)";
break;
case askNormal:
case answerNormal:
case video:
case communityArticle:
mTitle += " - 光环助手";
@ -271,8 +292,8 @@ public class ShareUtils {
mTencent.shareToQQ(activity, params, QqShareListener);
}
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
if (mShareEntrance != ShareEntrance.shareGh) {
safelyDismiss();
}
}
@ -289,11 +310,12 @@ public class ShareUtils {
WXMediaMessage msg = new WXMediaMessage(webpage);
webpage.webpageUrl = shareUrl;
switch (mShareType) {
switch (mShareEntrance) {
case plugin:
mSummary += "(光环加速版)";
break;
case askNormal:
case answerNormal:
case video:
case communityArticle:
mTitle += " - 光环助手";
@ -309,9 +331,9 @@ public class ShareUtils {
req.message = msg;
req.scene = SendMessageToWX.Req.WXSceneSession;
loadBitMap(shareIcon, msg, req);
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
loadBitmapAndShare(shareIcon, msg, req);
if (mShareEntrance != ShareEntrance.shareGh) {
safelyDismiss();
}
}
@ -319,18 +341,18 @@ public class ShareUtils {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}
private void loadBitMap(final String iconUrl, final WXMediaMessage msg, final SendMessageToWX.Req req) {
ImageUtils.display(mContext, iconUrl, new BaseBitmapDataSubscriber() {
private void loadBitmapAndShare(final String iconUrl, final WXMediaMessage msg, final SendMessageToWX.Req req) {
ImageUtils.getBitmap(iconUrl, new BiCallback<Bitmap, Boolean>() {
@Override
protected void onNewResultImpl(Bitmap bitmap) {
if (mShareType == ShareType.video) {
public void onFirst(Bitmap bitmap) {
if (mShareEntrance == ShareEntrance.video) {
// 分享类型为视频时裁为正方形
int dimension = Math.min(bitmap.getWidth(), bitmap.getHeight());
bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension);
}
Bitmap compressBp = compressBitmap(bitmap);
if (mShareType == ShareType.askNormal || mShareType == ShareType.askInvite) {
if (mShareEntrance == ShareEntrance.askNormal || mShareEntrance == ShareEntrance.askInvite) {
msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true);
} else {
Bitmap resultBp = addBackGround(compressBp);
@ -340,8 +362,7 @@ public class ShareUtils {
}
@Override
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
Utils.log("分享获取bitmap失败");
public void onSecond(Boolean aBoolean) {
}
});
}
@ -397,11 +418,12 @@ public class ShareUtils {
Utils.toast(mContext, R.string.share_skip);
Bundle params = new Bundle();
switch (mShareType) {
switch (mShareEntrance) {
case plugin:
mSummary += "(光环加速版)";
break;
case askNormal:
case answerNormal:
case video:
case communityArticle:
mTitle += " - 光环助手";
@ -425,8 +447,8 @@ public class ShareUtils {
mTencent.shareToQzone(activity, params, QqShareListener);
}
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
if (mShareEntrance != ShareEntrance.shareGh) {
safelyDismiss();
}
}
@ -444,7 +466,7 @@ public class ShareUtils {
webpage.webpageUrl = shareUrl;
switch (mShareType) {
switch (mShareEntrance) {
case plugin:
msg.title = mSummary + "(光环加速版)";
break;
@ -452,6 +474,7 @@ public class ShareUtils {
msg.title = mSummary;
break;
case askNormal:
case answerNormal:
case video:
case communityArticle:
msg.title = mTitle + " - 光环助手";
@ -468,9 +491,9 @@ public class ShareUtils {
req.message = msg;
req.scene = SendMessageToWX.Req.WXSceneTimeline;
loadBitMap(shareIcon, msg, req);
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
loadBitmapAndShare(shareIcon, msg, req);
if (mShareEntrance != ShareEntrance.shareGh) {
safelyDismiss();
}
}
@ -485,22 +508,23 @@ public class ShareUtils {
shareIcon,
mTitle,
mSummary,
mShareType.toString());
mShareEntrance.toString());
activity.startActivity(intent);
}
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
if (mShareEntrance != ShareEntrance.shareGh) {
safelyDismiss();
}
}
//短信分享
private void shortMessageShare() {
String smsBody;
switch (mShareType) {
switch (mShareEntrance) {
case news:
case tools:
case web:
smsBody = mTitle + shareUrl;
break;
case plugin:
@ -514,6 +538,7 @@ public class ShareUtils {
break;
case askInvite:
case askNormal:
case answerNormal:
case video:
case communityArticle:
smsBody = mTitle + " - 光环助手" + shareUrl;
@ -531,18 +556,20 @@ public class ShareUtils {
e.printStackTrace();
}
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
if (mShareEntrance != ShareEntrance.shareGh ) {
safelyDismiss();
}
}
//复制文字链接
private void copyLink(String copyContent) {
shareType = "copy_link";
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
ClipboardManager cmb = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setText(copyContent);
if (mShareType != ShareType.shareGh) {
if (mShareEntrance != ShareEntrance.shareGh) {
Utils.toast(mContext, "复制成功");
popupWindow.dismiss();
safelyDismiss();
} else {
Utils.toast(mContext, "复制成功,请到微信/QQ粘贴分享");
}
@ -567,7 +594,7 @@ public class ShareUtils {
holder.shareLogo.setImageResource(arrLogo[position]);
holder.shareLabel.setText(arrLabel[position]);
holder.itemView.setOnClickListener(v -> {
if (mShareType == ShareUtils.ShareType.shareGh) {
if (mShareEntrance == ShareEntrance.shareGh) {
MtaHelper.onEvent("我的光环_新", "分享光环", arrLabel[position]);
}
if (listener != null) {
@ -575,23 +602,33 @@ public class ShareUtils {
}
switch (holder.getPosition()) {
case 0:
shareType = "wechat_friend";
MtaHelper.onEvent("内容分享", "微信好友", mTitle);
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
wechatShare();
break;
case 1:
shareType = "wechat_moment";
MtaHelper.onEvent("内容分享", "微信朋友圈", mTitle);
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
wechatMomentsShare();
break;
case 2:
shareType = "qq_friend";
MtaHelper.onEvent("内容分享", "QQ好友", mTitle);
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
qqShare();
break;
case 3:
shareType = "qq_zone";
MtaHelper.onEvent("内容分享", "QQ空间", mTitle);
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
qZoneShare();
break;
case 4:
shareType = "sina_weibo";
MtaHelper.onEvent("内容分享", "新浪微博", mTitle);
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
sinaWeiboShare();
break;
case 5:
@ -600,11 +637,11 @@ public class ShareUtils {
break;
case 6:
MtaHelper.onEvent("内容分享", "复制链接", mTitle);
if (mShareType == ShareType.askInvite) {
if (mShareEntrance == ShareEntrance.askInvite) {
copyLink(mTitle + " - 光环助手" + shareUrl);
} else if (mShareType == ShareType.askNormal) {
} else if (mShareEntrance == ShareEntrance.askNormal || mShareEntrance == ShareEntrance.answerNormal) {
copyLink(shareUrl);
} else if (mShareType != ShareType.shareGh) {
} else if (mShareEntrance != ShareEntrance.shareGh) {
copyLink(shareUrl);
} else {
try {
@ -617,10 +654,11 @@ public class ShareUtils {
}
break;
case 7:
if (mShareType != ShareType.shareGh) {
popupWindow.dismiss();
if (mShareEntrance != ShareEntrance.shareGh) {
safelyDismiss();
} else {
copyLink("推荐光环助手,绿色安全的手游加速助手:" + shareUrl);
shareType = "copy_link";
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
}
break;
}
@ -645,6 +683,12 @@ public class ShareUtils {
}
}
}
private void safelyDismiss() {
if (popupWindow.get() != null) {
popupWindow.get().dismiss();
}
}
interface OnItemClickListener {
void onItemClick(int position);
@ -655,12 +699,12 @@ public class ShareUtils {
void onCancel();
}
private static class SharePopupWindow extends PopupWindow {
SharePopupWindow(View contentView, int width, int height, boolean focusable) {
super(contentView, width, height, focusable);
}
@Override
public void dismiss() {
View backgroundView = getContentView().findViewById(R.id.share_container);
@ -670,5 +714,5 @@ public class ShareUtils {
getContentView().postDelayed(super::dismiss, 0);
}
}
}

View File

@ -2,6 +2,7 @@ package com.gh.common.util
import android.content.Context
import android.content.SharedPreferences
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
object SPUtils {
@ -90,7 +91,20 @@ object SPUtils {
@JvmStatic
fun getStringSet(key: String): Set<String> {
return sp.getStringSet(key, HashSet())?: HashSet()
return sp.getStringSet(key, HashSet()) ?: HashSet()
}
@JvmStatic
fun setMap(key: String, map: Map<String, String>) {
val mapJson = GsonUtils.toJson(map)
setString(key, mapJson)
}
@JvmStatic
fun getMap(key: String): MutableMap<String, String> {
val mapJson = getString(key)
val type = object : TypeToken<MutableMap<String, String>>() {}.type
return GsonUtils.gson.fromJson(mapJson, type) ?: mutableMapOf()
}
@JvmStatic

View File

@ -5,13 +5,13 @@ import android.graphics.Color
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import android.text.TextPaint
import android.text.style.*
import android.view.View
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import com.gh.common.view.CenterImageSpan
import com.halo.assistant.HaloApp
class SpanBuilder(content: String) {
private var spannableString: SpannableStringBuilder = SpannableStringBuilder(content)
@ -22,6 +22,12 @@ class SpanBuilder(content: String) {
return this
}
fun color(start: Int, end: Int, colorRes: Int): SpanBuilder {
val colorSpan = ForegroundColorSpan(ContextCompat.getColor(HaloApp.getInstance().application, colorRes))
spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
fun color(start: Int, end: Int, colorHexInString: String): SpanBuilder {
tryWithDefaultCatch {
val colorSpan = ForegroundColorSpan(Color.parseColor(colorHexInString))
@ -58,12 +64,29 @@ class SpanBuilder(content: String) {
}
//添加图标
fun image(context: Context, start: Int, end: Int, @DrawableRes res: Int): SpanBuilder {
val imageSpan = CenterImageSpan(context, res)
fun image(start: Int, end: Int, @DrawableRes res: Int): SpanBuilder {
val imageSpan = CenterImageSpan(HaloApp.getInstance().application, res)
spannableString.setSpan(imageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
fun click(start: Int, end: Int, colorRes: Int, onClick: () -> Unit): SpanBuilder {
val clickSpan = object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(HaloApp.getInstance().application, colorRes)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
onClick.invoke()
}
}
spannableString.setSpan(clickSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
fun build(): SpannableStringBuilder {
return spannableString
}

View File

@ -35,4 +35,19 @@ public class SpeedUtils {
}
}
public static String getRemainSecondTime(long totalSize, long currentSize, long speed) {
long remainSize = totalSize - currentSize;
long remainTime;
if (speed != 0) {
remainTime = remainSize / speed;
} else {
return "-s";
}
int hour = (int) (remainTime / 3600);
remainTime = (remainTime - hour * 3660);
int minute = (int) (remainTime / 60);
int second = (int) (remainTime - minute * 60);
return second + "s";
}
}

View File

@ -66,7 +66,7 @@ public class TagUtils {
return;
}
isUpdate = true;
RetrofitManager.getInstance(context).getApi().getTags()
RetrofitManager.getInstance(context).getSensitiveApi().getTags()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<TagEntity>>() {

View File

@ -133,23 +133,38 @@ object TextHelper {
Utils.toast(application, "已复制:$arg")
}
}): SpannableStringBuilder {
val builder = SpannableStringBuilder(text)
return updateSpannableStringWithHighlightedSpan(context, builder, wrapper, highlightColorId, highlightedTextClickListener)
}
var modifiedText = text
if (modifiedText.endsWith(wrapper)) {
fun updateSpannableStringWithHighlightedSpan(
context: Context,
ssb: SpannableStringBuilder,
wrapper: String = "###",
@ColorRes
highlightColorId: Int = R.color.theme_font,
highlightedTextClickListener: SimpleCallback<String>? = object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cmb.text = arg
Utils.toast(application, "已复制:$arg")
}
}): SpannableStringBuilder {
if (ssb.endsWith(wrapper)) {
// 若高亮符在最后一位就在后面加一个空格,避免整行都能点击
modifiedText = "$modifiedText "
ssb.append(" ")
}
val sBuilder = SpannableStringBuilder(modifiedText)
val wrapperTextLength = wrapper.length
val matcher = Pattern.compile("$wrapper(.+?)$wrapper", Pattern.DOTALL).matcher(modifiedText)
val matcher = Pattern.compile("$wrapper(.+?)$wrapper", Pattern.DOTALL).matcher(ssb)
val pair = TreeMap<Int, Int>()
while (matcher.find()) {
// 保存起始位置和结束位置
pair[matcher.start(1)] = matcher.end(1)
sBuilder.setSpan(object : ClickableSpan() {
ssb.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(context, highlightColorId)
@ -174,12 +189,12 @@ object TextHelper {
val end = reversePair[key]
end?.let {
sBuilder.replace(end, end + wrapperTextLength, "")
sBuilder.replace(key - wrapperTextLength, key, "")
ssb.replace(end, end + wrapperTextLength, "")
ssb.replace(key - wrapperTextLength, key, "")
}
}
return sBuilder
return ssb
}
/**

View File

@ -23,6 +23,7 @@ object TimeUtils {
fun getFormatTime(time: Long, pattern: String = "yyyy-MM-dd"): String {
val f = SimpleDateFormat(pattern, Locale.CHINA)
f.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
return f.format(Date(time * 1000))
}
@ -60,7 +61,7 @@ object TimeUtils {
/**
* 判断时间戳是多少天前
*/
fun getBeforeDays(timestamp: Long):Int{
fun getBeforeDays(timestamp: Long): Int {
var days: Long = 0
val format = SimpleDateFormat("yyyyMMdd HH:mm", Locale.getDefault())
try {
@ -73,4 +74,30 @@ object TimeUtils {
return days.toInt()
}
/**
* 格式化视频时长
*/
@JvmStatic
fun formatVideoDuration(length: Long): String {
val minute = length / 60
val second = length % 60
return String.format(Locale.CHINA, "%02d:%02d", minute, second)
}
@JvmStatic
fun getDayString(date: Long): String {
val offSet = Calendar.getInstance().timeZone.rawOffset
val today = (System.currentTimeMillis() + offSet) / 86400000
val start = (date * 1000 + offSet) / 86400000
return when ((start - today).toInt()) {
-2 -> "(前天)"
-1 -> "(昨天)"
0 -> "(今天)"
1 -> "(明天)"
2 -> "(后天)"
else -> ""
}
}
}

View File

@ -3,14 +3,18 @@ package com.gh.common.util
import android.widget.Toast
import com.halo.assistant.HaloApp
import com.lightgame.utils.toast.ToastHandler
object ToastUtils {
/** 之前显示的内容 */
private var mOldMsg: String? = null
/** Toast对象 */
private var mToast: Toast? = null
/** 第一次时间 */
private var mOneTime: Long = 0
/** 第二次时间 */
private var mTwoTime: Long = 0
@ -19,19 +23,34 @@ object ToastUtils {
* @param message
*/
fun showToast(message: String) {
showToast(message, -1)
}
/**
* 显示Toast
* @param message
* @param gravity
*/
fun showToast(message: String, gravity: Int = -1, yOffset: Int = 0) {
if (mToast == null) {
mToast = Toast.makeText(HaloApp.getInstance().application, message, Toast.LENGTH_SHORT)
mToast = ToastHandler.INSTANCE.getToastInstance(HaloApp.getInstance().application, message, Toast.LENGTH_SHORT)
if (gravity != -1) mToast!!.setGravity(gravity, 0, yOffset) else
mToast!!.setGravity(DisplayUtils.getToastDefaultGravity(), 0, DisplayUtils.getToastOffset())
mToast!!.show()
mOneTime = System.currentTimeMillis()
} else {
mTwoTime = System.currentTimeMillis()
if (message == mOldMsg) {
if (mTwoTime - mOneTime > Toast.LENGTH_SHORT) {
if (gravity != -1) mToast!!.setGravity(gravity, 0, yOffset) else
mToast!!.setGravity(DisplayUtils.getToastDefaultGravity(), 0, DisplayUtils.getToastOffset())
mToast!!.show()
}
} else {
mOldMsg = message
mToast!!.setText(message)
if (gravity != -1) mToast!!.setGravity(gravity, 0, yOffset) else
mToast!!.setGravity(DisplayUtils.getToastDefaultGravity(), 0, DisplayUtils.getToastOffset())
mToast!!.show()
}
}

View File

@ -0,0 +1,127 @@
package com.gh.common.util;
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public class UriUtils {
@SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.parseLong(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
private static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}

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