Compare commits

...

612 Commits
v3.5 ... v3.6.5

Author SHA1 Message Date
8d55b251c3 3.6.5 tinker-base 2019-06-04 09:35:25 +08:00
386c7b19c1 versionName:3.6.5 versionCode:91
该版本为过度版本(修复3.6.4的bug)
2019-06-03 17:48:46 +08:00
eaaa168ee1 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-06-03 17:46:12 +08:00
d9f5811d86 默认关闭tinker更新弹窗 2019-06-03 16:18:31 +08:00
27d3470abc 修复使用错误上下文的问题 2019-06-03 14:31:54 +08:00
36f7427613 Merge branch '3.6.5' into 'dev'
修复 3.6.4 遗留问题

See merge request !6
2019-06-03 14:30:23 +08:00
929c117ddb 修复使用错误上下文的问题 2019-06-03 10:26:48 +08:00
7d6d77fae5 修复激活数据链接出错的问题 2019-06-03 10:22:20 +08:00
2297461d91 修复数组越界问题 2019-06-03 10:22:12 +08:00
a26a3bebad 修复 jenkins 打包时间时区不对的问题 2019-06-03 10:22:04 +08:00
4a673de424 修复激活数据链接出错的问题 2019-06-03 10:11:29 +08:00
a837c2ccd4 修复数组越界问题 2019-05-31 18:30:11 +08:00
10ee3132fd 修复 jenkins 打包时间时区不对的问题 2019-05-31 09:57:17 +08:00
783fbecb00 3.6.4 封包 2019-05-30 16:11:01 +08:00
de1b5ba2f3 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-30 15:49:21 +08:00
9a9e288c44 3.6.4 封包 2019-05-30 15:37:51 +08:00
424b48f631 更改远端 JS 和 CSS 至正式环境 2019-05-30 15:21:38 +08:00
86d1cd4e12 微调编译脚本 2019-05-30 15:01:02 +08:00
e700ff4744 微调编译脚本 2019-05-30 14:43:56 +08:00
34729c8c28 添加 jenkins 编译脚本 2019-05-30 14:26:54 +08:00
5a08611fdd 测试包在设置关于里显示编译时间 2019-05-30 11:51:57 +08:00
a73da1d6e4 修复游戏评论详情从弹窗回退后无法即时调起软键盘问题 2019-05-29 18:37:14 +08:00
28b8c20756 修复分类展开部分标签会丢失的问题 2019-05-29 14:41:47 +08:00
6941821b71 矫正网页资源的时间戳 2019-05-29 14:15:18 +08:00
3c2244701c 关闭 webview 调试 2019-05-29 14:07:21 +08:00
38dc873e2e Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-29 10:58:51 +08:00
c24ffb2489 修复插入数据造成浏览记录出现多个空格的问题 2019-05-29 10:58:34 +08:00
929864be30 优化游戏评论详情点赞刷新问题 2019-05-28 18:22:10 +08:00
bd87163a9b 显示/隐藏图片是无需回调(RE.callback()) 2019-05-28 17:52:23 +08:00
785c740668 修复图片名存在特殊字符无法显示的问题 2019-05-28 17:35:16 +08:00
25aa16f774 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-28 16:38:05 +08:00
9ec89c0dc1 光环助手V3.6.4测试遗留问题(2.3.5.15.16.17) https://gitlab.ghzs.com/pm/halo-app-issues/issues/536#note_22029 2019-05-28 16:37:25 +08:00
3e5bd2b087 修复我的提问、回答和文章页面分页的顺序变动问题 2019-05-28 15:31:56 +08:00
9de6cff13b 浏览记录的文章和答案过滤掉插入的内容 2019-05-27 17:53:19 +08:00
6b98bc9fca 修复了答案上下滑动可能出现页面偏移的问题 2019-05-27 17:52:39 +08:00
cdf9b0a071 去掉测试 toast 2019-05-26 15:14:49 +08:00
ff57e9c759 merge 2019-05-24 22:48:33 +08:00
b253113843 光环助手V3.6.4 RELEASE(20190524-2130)测试问题汇总(1.2.3.4.11) https://gitlab.ghzs.com/pm/halo-app-issues/issues/534 2019-05-24 22:47:32 +08:00
b7305337bf 修复浏览记录的游戏名字以及推送点击记录的问题 2019-05-24 22:10:34 +08:00
455e2ad723 处理文章隐藏时的弹两个 toast 的问题 2019-05-24 21:16:18 +08:00
8cf87b991b 推送辅助提示变更 2019-05-24 21:12:20 +08:00
ae0b289c3e 光环助手V3.6.4 RELEASE(20190524-1230)(1.2.3.4.5.6.7.8.9.10.11.12.14.15.16)测试问题汇总 https://gitlab.ghzs.com/pm/halo-app-issues/issues/533 2019-05-24 21:06:37 +08:00
9404c3349a 修复游戏评论详情重复点赞toast异常问题 2019-05-24 17:37:53 +08:00
28afbb8d35 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-24 17:16:18 +08:00
5b24443121 富文本编辑器添加样式之前将内容字符进行htmlEncode,防止JS端JSON解释失败 2019-05-24 17:15:37 +08:00
1f9aacbbbd 去掉多余的 toast 2019-05-24 16:52:32 +08:00
d194b33a5d 富文本编辑器初始化代码放置到assets目录,通过本地的rich_editor.js 访问远端的JS和CSS代码
目的:修复低版本内核浏览器的事件无法回调到原生android端问题
2019-05-24 16:02:13 +08:00
55010f0ef7 关闭rich_editor.js log 2019-05-24 14:21:10 +08:00
49fab9ed04 游戏详情判断是否安装该游戏时进行包名过滤 2019-05-24 11:44:04 +08:00
1cd1b578ec merge 2019-05-24 11:27:28 +08:00
184c56aac5 光环助手V3.6.4 DEV(20190517-1020)测试问题汇总(游戏评分)(补充) 2019-05-24 11:25:26 +08:00
7c39037472 修复记录安装新应用时记录了错误应用名的问题 2019-05-24 11:12:13 +08:00
786a803793 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-24 10:58:52 +08:00
273f0e185d 修复关闭插件功能资讯和专题相关操作失效问题
修改游戏评分引用区域样式
2019-05-24 10:58:46 +08:00
eebc2c3940 统一已开通社区的列表排序 2019-05-24 10:25:05 +08:00
3a964d629e Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-24 09:49:57 +08:00
ff041f705e 光环助手V3.6.4 DEV(20190521-1900)测试问题汇总(前端)(2.3.4.5(1).19.20.21) https://gitlab.ghzs.com/pm/halo-app-issues/issues/530#note_21778 2019-05-24 09:49:41 +08:00
af62fc9a68 替换关闭评论图标 2019-05-23 18:20:44 +08:00
6ff415cc0d 完成光环助手应用数据上报功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/531 2019-05-23 18:04:53 +08:00
41de94e6f5 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-23 16:58:36 +08:00
60d91ca04e 光环助手V3.6.4 DEV(20190521-1900)测试问题汇总(编辑器)(1.5.6.7.9.10.12.13.15.16.17.18) https://gitlab.ghzs.com/pm/halo-app-issues/issues/529 2019-05-23 16:58:29 +08:00
19004b2073 完成V3.6.4DEV(20190521-1900)测试问题汇总(6,7,8,9,10,12,14,16,17,22) https://gitlab.ghzs.com/pm/halo-app-issues/issues/530 2019-05-23 16:42:01 +08:00
70b536e6bd 修复社区编辑器插入自定义样式问题(上次兼容性修改遗留) 2019-05-23 14:36:45 +08:00
5009678587 本地JS与远程同步 2019-05-23 11:07:55 +08:00
a7a01bbe16 修复社区编辑框不兼容个别机型问题(VIVO x7 5.1.1) 2019-05-23 11:04:57 +08:00
9b2ce51c87 更换引导图 2019-05-22 16:46:36 +08:00
c735d4e717 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-22 16:26:10 +08:00
6fb4dac45d update CHANGELOG 2019-05-22 16:26:02 +08:00
3d49258b84 优化代码结构 2019-05-22 16:15:41 +08:00
c23aa12d09 优化编辑回答的接口异常处理 2019-05-22 16:08:58 +08:00
6f6ddf9fbd 更换引导图 2019-05-22 10:33:59 +08:00
63837b5c31 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-21 16:28:31 +08:00
27e245c241 我的关注不能点击关联关注进行关注操作 2019-05-21 16:28:24 +08:00
7775494ade 完成3.6.4 DEV(20190517-1020)测试问题汇总的(3,4,7,8,9,10,11,17,18) https://gitlab.ghzs.com/pm/halo-app-issues/issues/525 2019-05-21 16:12:06 +08:00
a3ce139b86 曝光增加 ROM 字段 2019-05-21 16:11:03 +08:00
ad470f10f4 光环助手V3.6.4 DEV(20190517-1020)测试问题汇总(编辑器)(1.2.3.4.5.6.8.9) https://gitlab.ghzs.com/pm/halo-app-issues/issues/527 2019-05-21 16:06:20 +08:00
302d12083b 光环助手V3.6.4 DEV(20190517-1020)测试问题汇总(游戏评分)(1.4.5.6.7.8.9.10.11) https://gitlab.ghzs.com/pm/halo-app-issues/issues/526 2019-05-21 11:17:29 +08:00
d40dd15af4 撰写回答页面添加我来回答遮罩 2019-05-20 15:28:18 +08:00
440eb8a07b 完成DEV(20190515-1900)测试问题汇总(1,2,3,16,17,18) https://gitlab.ghzs.com/pm/halo-app-issues/issues/524 2019-05-20 11:47:17 +08:00
361b861d5f 修复部分(关注/收藏)按钮,登录后不能即时刷新问题 2019-05-20 11:24:20 +08:00
b518b2961a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-17 18:24:38 +08:00
bfae4e1501 光环助手V3.6.4 DEV(20190515-1900)测试问题汇总(前端)(10.14.15) https://gitlab.ghzs.com/pm/halo-app-issues/issues/524#note_21505 2019-05-17 18:24:32 +08:00
d3e13dd8c6 完成需求 MTA 补充需求 2019-05-17 17:27:42 +08:00
073c35ca08 浏览记录去掉游戏名称后缀 2019-05-17 17:27:19 +08:00
99b4373561 处理闪退问题 2019-05-17 17:26:51 +08:00
52dcea477e 评分相关间距调整 2019-05-17 17:03:53 +08:00
6abb8d715b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-17 16:36:53 +08:00
51016b0704 社区编辑框插入链接样式时先将当前blockquote标签换成p标签再插入 2019-05-17 16:36:47 +08:00
d14c150070 完成需求'所有游戏名字处理成“名称+后缀”的格式的' https://gitlab.ghzs.com/pm/halo-app-issues/issues/521 2019-05-17 16:28:32 +08:00
f59f8a3e5b 完成光环前端需求汇总(2019年5月第3周)(1,3,11,12,13) https://gitlab.ghzs.com/pm/halo-app-issues/issues/522 2019-05-17 15:02:56 +08:00
965be0b5cd Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-17 14:40:46 +08:00
716900fc5d 社区编辑框增加长按选择回调 2019-05-17 14:40:31 +08:00
14280d802e 更改回答详情和文章详情底部按钮图标 2019-05-17 11:32:03 +08:00
39924857e5 我的游戏页面进行包名过滤处理 2019-05-17 10:51:47 +08:00
c88bda6615 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-16 18:37:47 +08:00
ecb80ca70d 光环助手V3.6.4 DEV(20190513-1900)编辑器相关(1.3.4.6.7.8.9.11.17) https://gitlab.ghzs.com/pm/halo-app-issues/issues/519#note_21413 2019-05-16 18:37:38 +08:00
51b03b78ce 在插入内容的 div 里添加 class 帮助后端生成摘要时去掉不需要的内容 2019-05-16 18:20:28 +08:00
a7fd029ed2 反馈提交的字段修改 2019-05-16 16:01:31 +08:00
5beb29ad09 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-16 15:03:57 +08:00
e7dc2ca810 光环前端需求汇总(2019年5月第3周)(5.6.7.9) https://gitlab.ghzs.com/pm/halo-app-issues/issues/522#note_21366 2019-05-16 15:03:45 +08:00
b5ce0db1ff 将 JS 和 CSS 的引用改为远端 2019-05-16 10:22:41 +08:00
c8b52902e9 评分相关的POST请求进行错误处理 2019-05-16 09:36:28 +08:00
dbc4e0ac26 历史搜索清空图标自适应宽高 2019-05-15 18:18:22 +08:00
a0d2860970 修改游戏搜索历史页面样式 2019-05-15 18:06:37 +08:00
77c1a05a4a 修改资讯中心标签样式 2019-05-15 17:59:23 +08:00
aeee2e049d 回答/文章 插入链接的默认图片换成网络图片 2019-05-15 17:13:21 +08:00
525b184ad4 游戏评论详情增加下载相关逻辑 2019-05-15 16:14:05 +08:00
76e0fe9f9a 光环助手V3.6.4 DEV(20190513-1900)游戏评分相关(2.4.5.6.8.9.12.13.16.18.19.20.21) https://gitlab.ghzs.com/pm/halo-app-issues/issues/520 2019-05-15 15:14:30 +08:00
06ddef114c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-14 14:48:52 +08:00
32cdcc1304 光环助手V3.6.4 DEV(20190509-1900)测试问题汇总(前端)(3.4.5)https://gitlab.ghzs.com/pm/halo-app-issues/issues/516#note_21124 2019-05-14 14:48:40 +08:00
4a2b414b59 社区选择列表增加关联置顶 2019-05-14 11:29:04 +08:00
937497aec9 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-13 18:18:15 +08:00
38d2c189e8 游戏详情标签样式由后台控制 2019-05-13 18:18:02 +08:00
57aeacf3f5 完成光环前端需求汇总(2019年4月第3周)(1,4,5) https://gitlab.ghzs.com/pm/halo-app-issues/issues/495 2019-05-13 16:53:47 +08:00
fe4036b768 完成光环助手V3.6.4数据统计需求(光环数据后台) https://gitlab.ghzs.com/pm/halo-app-issues/issues/509 2019-05-13 15:43:41 +08:00
5dd479c492 完成光环助手V3.6.4数据统计需求(光环数据后台) https://gitlab.ghzs.com/pm/halo-app-issues/issues/509 2019-05-13 15:15:27 +08:00
5f1ff1fc6f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-13 14:22:44 +08:00
b08fb1f170 光环前端需求汇总(2019年4月第5周)(3.6.9.10.13) https://gitlab.ghzs.com/pm/halo-app-issues/issues/512#note_21125 2019-05-13 14:20:57 +08:00
e2f6180d6d 完成光环助手V3.6.4数据统计需求(MTA) https://gitlab.ghzs.com/pm/halo-app-issues/issues/510 2019-05-13 11:00:02 +08:00
90d19ea381 补充下载进度超过 100% 的错误回调 2019-05-13 10:58:48 +08:00
13738f08eb 复用 Gson 对象 2019-05-13 10:00:08 +08:00
1b76184946 光环前端需求汇总(2019年4月第4周)(1.3.4.5.6.7.11.13) https://gitlab.ghzs.com/pm/halo-app-issues/issues/501#note_21126 2019-05-12 18:34:50 +08:00
711431f7c9 光环前端需求汇总(2019年4月第4周)(1.3.4.5.6.7.11.13) https://gitlab.ghzs.com/pm/halo-app-issues/issues/501#note_21126 2019-05-12 18:31:42 +08:00
4ea3f7ccf0 完成光环前端需求汇总(2019年4月第5周)的(2, 4, 5, 11, 12) https://gitlab.ghzs.com/pm/halo-app-issues/issues/512 2019-05-12 17:20:44 +08:00
80cd86ea29 优化游戏评论详情刷新问题 2019-05-10 17:05:56 +08:00
f87bb6cd06 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-10 16:41:10 +08:00
ea726a22bd 游戏评论相关优化 2019-05-10 16:41:02 +08:00
7e3afe7d70 Merge branch 'xiechanghong' into 'dev'
UI 变更

See merge request !5
2019-05-10 15:45:50 +08:00
8131c58fbf 规范化代码格式 2019-05-10 15:33:51 +08:00
674e32a096 优化上一版的代码问题 2019-05-10 11:52:40 +08:00
f5d42a3e01 优化上一版的代码问题 2019-05-09 20:48:05 +08:00
a079a03adc 首页猜你喜欢列表增加隐藏包过滤 2019-05-09 17:59:28 +08:00
8485f94133 优化内容:①文本输入框达到字数上限之后,继续输入内容直接出现Toast提示,不会把最后面的内容删掉,且光标停留在当前位置②如果发生闪退,再次打开光环时会提示立即反馈,这时如果玩家提交成功,会再次出现联系客服弹窗,点击"联系客服" 即直接跳转打开客服QQ对话页面 2019-05-09 17:01:59 +08:00
5d60a8f03b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
2019-05-09 16:52:16 +08:00
ec4319b74a 增加游戏评论相关的消息中心操作 2019-05-09 16:50:15 +08:00
41c3f9d073 更改游戏浏览记录的数据库结构 (从上几个测试版覆盖安装将清空所有浏览记录) 2019-05-09 14:04:05 +08:00
c27990b395 完成回答详情/社区文章详情增加反对功能 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/505 2019-05-08 18:43:10 +08:00
2e9a823ee1 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-08 17:42:01 +08:00
590afccae7 游戏详情-评论 增加小编评论 2019-05-08 17:41:53 +08:00
7a82780826 接入新的版主权限管理 2019-05-08 17:26:57 +08:00
c75e363a06 添加浏览记录图标 2019-05-08 17:12:24 +08:00
573b7b61cf Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	app/src/main/java/com/gh/common/util/Extensions.kt
2019-05-08 17:11:51 +08:00
9f9e1bc9fd 游戏评论/游戏评论详情完成'举报/复制'操作 2019-05-08 16:37:36 +08:00
34e11b1569 Merge remote-tracking branch 'origin/dev' into dev 2019-05-08 16:05:40 +08:00
cc7b77a8ad Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-08 11:50:42 +08:00
ed3a75ddc0 游戏评论详情页面用baseList实现 2019-05-08 11:50:26 +08:00
983c01df57 增加清除 HTML 标签的 extension 方法 2019-05-08 10:55:39 +08:00
9d95b7aa6b 修复首页游戏替换下拉刷新时会出现为确保页面游戏唯一而隐藏掉需要的游戏的问题 2019-05-08 10:06:19 +08:00
5319cb8679 回答详情页面增加反对功能(文章详情未完成) 2019-05-07 18:16:33 +08:00
b4b1a63c22 处理空指针异常 2019-05-07 09:52:03 +08:00
2dfd57de80 DataUtils 初始化同步执行 2019-05-06 18:22:56 +08:00
cbc8876656 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-06 15:39:46 +08:00
4e6b8bf6b3 优化游戏评论回复操作 2019-05-06 15:39:33 +08:00
da92826f6a 清理回答详情页面的无用代码 2019-05-06 11:13:44 +08:00
f1a4e429f3 修复回答详情预加载也会产生阅读时长的问题 2019-05-06 09:29:18 +08:00
3cd248a2c5 基本完成我的光环增加浏览记录需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/500#note_20735 2019-05-05 17:53:22 +08:00
7f5dd97359 统一游戏评论item数据设置 2019-05-05 17:37:12 +08:00
c0ee431d1f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-05-05 15:12:53 +08:00
f56de73eb6 完成游戏评论详情(回复)相关页面展示/分页/跳转/点赞操作 2019-05-05 15:12:36 +08:00
a0b5cd00d5 修复一个数组越界问题 2019-05-05 09:45:36 +08:00
66b5f3d896 调整回答详情页面的结构,增加回答详情的浏览记录 2019-05-04 16:48:19 +08:00
a4346a6f34 游戏评分评论详情页面(未完待续...) 2019-05-04 16:32:26 +08:00
83894f6530 修改游戏评分样式
增加游戏评分评论详情页面
2019-04-30 18:30:03 +08:00
9b776bb029 我的关注增加关联关注 2019-04-30 10:48:16 +08:00
ea72fb09e0 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-29 10:58:11 +08:00
b2b390cf8b community keep position when update search 2019-04-29 10:57:46 +08:00
926abe248f Merge branch '3.6.3-log-fixd' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-29 09:30:58 +08:00
95468cf83e 更新百度推广激活接口 2019-04-28 17:38:16 +08:00
259b93eb25 修复错误的 MTA 事件命名 2019-04-28 16:49:01 +08:00
f59646643f 修复关闭评论页面软键盘没有隐藏的问题 2019-04-28 14:32:31 +08:00
7130417e60 增加记录推送点击事件失败重试 2019-04-28 11:28:50 +08:00
458a9f2a63 更新 API 至 3.6.4 2019-04-28 11:27:03 +08:00
0f85497f75 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-27 17:06:56 +08:00
3c0c6afd43 整理代码 2019-04-27 17:06:45 +08:00
345cdb41bc 完成首页游戏替换功能(第二期)https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/498 2019-04-26 18:12:47 +08:00
b78fa40eff 修复在小内存设备上加载本地应用图标会内存不够然后闪退的问题 2019-04-26 16:18:44 +08:00
193831ae7e VersionName:3.6.4 VersionCode:90 2019-04-26 15:43:21 +08:00
bcb9dc3ba8 修复 loghub 启动日志都变成都变成升级安装的问题 2019-04-25 11:57:59 +08:00
7903cdc44a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-23 16:55:49 +08:00
a66c1ea50b 编辑框插入链接样式对以前版本隐藏 2019-04-23 16:55:33 +08:00
978e8f160b 修复 loghub 启动日志都变成都变成升级安装的问题 2019-04-23 14:52:08 +08:00
a49351a146 更改通用库 submodule 的远程地址 2019-04-22 16:27:04 +08:00
07d9b416a3 消息中心和系统推送添加跳转类型 2019-04-22 10:49:26 +08:00
f9edb69370 编辑插入回答/文章支持分享链接插入 2019-04-19 16:47:15 +08:00
deac313ba3 文章/回答详情处理链接跳转 2019-04-19 15:01:42 +08:00
b149f9acf2 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-19 09:59:35 +08:00
7c96ba090e 编辑框增加插入链接(文章,回答,游戏) 2019-04-19 09:59:18 +08:00
11ab908848 避免上传图片时闪退 2019-04-18 14:28:24 +08:00
3d2978b2e5 增加下载失败弹窗 2019-04-18 11:01:08 +08:00
7ad3a7ae92 下载进度超过100%的情况处理 2019-04-17 18:15:41 +08:00
9042488a65 把选择社区排序的操作放回主线程避免线程冲突造成闪退 2019-04-17 09:54:30 +08:00
b08e13f05a 捕抓发起网络重试请求时的各种异常 2019-04-17 09:53:20 +08:00
6271fd4998 编辑框增加插入文章 2019-04-16 16:08:09 +08:00
4d747a3df3 Merge branch 'dev-logo' into 'dev'
logo 添加多种尺寸

See merge request !4
2019-04-15 19:10:19 +08:00
5ce057d40e logo 添加多种尺寸 2019-04-15 19:01:55 +08:00
1e2e8f932f 编辑框增加插入游戏和插入回答页面 2019-04-15 18:03:45 +08:00
5accb9c1f1 Merge branch 'answer_animation' into 'dev'
答案详情页优化变更

See merge request !3
2019-04-15 11:52:08 +08:00
5b102d65c7 完成了光环前端需求汇总(2019年4月第2周)的(4,5,6,8) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/490 2019-04-15 11:51:04 +08:00
c609ddd721 修复了图片后有文字时不能删除图片的问题 2019-04-12 14:38:39 +08:00
0c3783d127 避免重复发送答案阅读事件 2019-04-12 14:24:17 +08:00
f702ab6115 修复回答图片后有文字不能删除的问题 2019-04-11 17:54:00 +08:00
7dd760e0fb 尝试将回答详情的上下滚动改以 viewpager 实现 2019-04-09 18:08:58 +08:00
c6f3b5998c tinkerBase 3.6.3 2019-04-08 19:11:47 +08:00
28440d97de 删除无用代码 2019-04-08 18:00:21 +08:00
2b2b71fe01 资讯文章超链接支持跳转到社区文章 2019-04-04 16:21:50 +08:00
f5a9e7b487 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-03 17:56:56 +08:00
d43842a0e6 社区搜索新增页面增加关键字统计和点击跳转时增加到历史搜索 2019-04-03 17:56:42 +08:00
a557962f17 微调UI 2019-04-02 18:32:49 +08:00
560c682157 完成光环助手V3.6.3 RELEASE(20190402-1130)测试问题汇总(6,7,8) 2019-04-02 17:41:48 +08:00
a0ae36f511 修复问题编辑图片数量的显示错误问题 2019-04-02 15:57:21 +08:00
bdee17ffc4 修复社区选择排序问题 2019-04-02 09:59:12 +08:00
5829f09f8c 调整文案 2019-04-01 20:18:00 +08:00
bc6fa5e7db 更换编辑框图标 2019-04-01 18:07:06 +08:00
1607cea9ce Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-04-01 17:58:33 +08:00
426019ea7c 光环助手V3.6.3 RELEASE(20190331-1830)测试问题汇总(前端)(1.3.4.10) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/483 2019-04-01 17:57:08 +08:00
1b878a50c4 调整关闭评论点击的 toast 文案 2019-04-01 17:13:43 +08:00
97525189b7 调整反馈文案 2019-04-01 16:59:38 +08:00
999947751a 修复回答浮窗在用户退出登录后也有可能显示的问题 2019-04-01 16:40:56 +08:00
2def61ab43 修复光环助手V3.6.3 RELEASE(20190331-1830)测试问题汇总(6,7,8,9) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/483 2019-04-01 16:28:17 +08:00
5e07ef488c 整理重复定义的权限 2019-04-01 11:10:40 +08:00
7af47c0caf 调整资源位置 2019-04-01 11:10:12 +08:00
1a5ed3c05f 调整代码 2019-03-31 17:05:47 +08:00
9cc9b09861 光环助手V3.6.3 RELEASE(20190328-1930)测试问题汇总(前端)(5.6.7.8.13) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/480 2019-03-31 15:21:12 +08:00
cef4432d97 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-31 14:17:02 +08:00
18be6acc34 光环助手V3.6.3 RELEASE(20190329-1930)测试问题汇总(前端)(1.2.3.8.9) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/482 2019-03-31 14:16:27 +08:00
27d0dd40d0 修复了版主不能修改问题图片数量的问题 2019-03-30 17:13:33 +08:00
b05fa626f6 处理一些内存泄漏问题 2019-03-30 14:41:31 +08:00
f1fc84ea5f 修复答案被隐藏时的闪退问题 2019-03-30 14:40:55 +08:00
3942154c05 修复缺少路径引起的闪退问题 2019-03-30 14:23:52 +08:00
ff182ee3c7 修复了光环助手V3.6.3 RELEASE(20190328-1930)测试问题汇总的(1,2,9,10,11) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/480 2019-03-30 10:38:01 +08:00
10cc275970 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/AskFragment.kt
2019-03-29 17:03:41 +08:00
21821d584e 光环助手V3.6.3 DEV(20190328-1830)测试问题汇总(前端)(1.6.7.13.14.15) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/479 2019-03-29 17:01:43 +08:00
6b8716eff8 补充社区搜索事件 MTA https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/478 2019-03-29 15:58:28 +08:00
47434e2943 处理了环助手V3.6.3 DEV(20190328-1830)测试问题汇总的(3,4,5,8,10,12) 2019-03-29 15:05:29 +08:00
4c3b327cff 完成数据统计需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/477 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/478 2019-03-29 11:00:37 +08:00
3454d13e48 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-28 20:55:58 +08:00
0aad7c59ee 源码引入matisse库 2019-03-28 20:55:49 +08:00
ee8e4e0338 修复社区文章无法置顶的问题 2019-03-28 18:29:50 +08:00
a430c51c97 让测试社区隐藏了也能点击进入 2019-03-28 18:20:53 +08:00
b59508e9e5 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-28 16:58:36 +08:00
08deac1dea 光环助手V3.6.3 DEV(20190327-1830)测试问题汇总(前端)(6.8.13.14.15) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/476 2019-03-28 16:58:28 +08:00
a2dc3f3d5b 修复了部分 光环助手V3.6.3 DEV(20190327-1830)测试问题 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/476 2019-03-28 16:25:42 +08:00
679cfab088 社区搜索历史页面间距微调 2019-03-28 10:11:22 +08:00
9144595aaf 修复打包错误问题 2019-03-27 18:44:36 +08:00
8a545180a2 文章详情-评论详情UI微调 2019-03-27 17:37:56 +08:00
17c5793558 增加关闭评论确定弹窗 2019-03-27 16:15:05 +08:00
8afc346a2c 添加测试用的推送点击 toast 2019-03-27 15:49:35 +08:00
026bb7f67b 添加 CSS 和 JS 的外联依赖 2019-03-27 15:48:39 +08:00
b971e7dbf6 添加敏感词错误码 2019-03-27 15:48:00 +08:00
ec39ef16e4 优化社区搜索历史数据库操作 2019-03-27 11:14:51 +08:00
ae07bacbb7 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-27 10:41:44 +08:00
0f0d8da6cd merge 2019-03-27 10:41:37 +08:00
2a1c99efac 社区搜索热门增加置顶功能 2019-03-27 10:40:01 +08:00
caa89d3f4c 修复了回答详情列表较长上下滑动时会存在偏移的问题 2019-03-27 10:26:24 +08:00
1602816d08 调整回答详情上下滑动动画距离 2019-03-26 19:58:50 +08:00
1062cf5924 处理一些内存泄漏问题 2019-03-26 19:45:46 +08:00
f6e5cd3fd7 更新微信分享、登录SDK 2019-03-26 18:14:06 +08:00
c675196cb2 修复一些闪退问题 2019-03-26 16:35:21 +08:00
8b9c2668d1 完成3月第4周需求汇总 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/475 2019-03-26 15:54:43 +08:00
c1a927ed88 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-26 15:09:56 +08:00
4d4416c1df 社区搜索增加文章和用户模块 2019-03-26 15:09:46 +08:00
f4833983c0 完成3月第3周需求汇总 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/473 2019-03-26 11:24:05 +08:00
89eb99d813 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-25 18:28:00 +08:00
683a68d179 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt
#	app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
2019-03-25 18:26:13 +08:00
598af67338 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt
#	app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
2019-03-25 18:25:41 +08:00
d9d0ffc3b9 基本完成社区前端优化需求汇总 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/470 2019-03-25 18:16:18 +08:00
4d8e04580e 1.问答模块增加提问悬浮按钮
2.问答搜索增加默认搜索文案
3.问答搜索增加热门搜索区域
2019-03-25 18:15:17 +08:00
cfaddf2f22 基本完成社区版主权限强化需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/471 2019-03-25 16:45:42 +08:00
c72b194107 优化问答模块社区隐藏的交互 2019-03-25 14:27:09 +08:00
d7f33ff8b1 修复编译问题 2019-03-23 17:33:31 +08:00
91e491b66a 基本完成回答详情与社区文章详情优化 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/463 2019-03-23 17:26:16 +08:00
31b7e40ab0 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-22 18:58:53 +08:00
f2b094fff0 统一内容数值显示规则 完成 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/468 2019-03-22 18:54:55 +08:00
185ee7f0f4 调整选择游戏社区的排序,已安装相应游戏的放到最前 2019-03-22 18:25:14 +08:00
f446b15f7a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-22 18:01:03 +08:00
52a833f18b 社区文章/回答 富文本编辑框统一插入样式 2019-03-22 18:00:51 +08:00
37fc68977c 根据接口调整回答详情的可拖动切换设定 2019-03-22 15:50:11 +08:00
96ee71a594 Merge remote-tracking branch 'origin/dev' into dev 2019-03-22 10:55:35 +08:00
1c2dda9353 基本完成提问与问题详情优化需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/464 2019-03-22 10:55:07 +08:00
96a9fd0ad7 富文本编辑框增加引用样式 2019-03-22 10:51:37 +08:00
c53c27e350 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-21 15:25:39 +08:00
fd4f32bb3c 回答编辑框增加各种内容样式 2019-03-21 15:25:31 +08:00
cbd2d8ed6c 修复图片上传闪退BUG 2019-03-20 18:32:11 +08:00
3dd06bc620 简单处理问题页面多张图片上传 2019-03-20 18:28:17 +08:00
3a829e1cfd 重构回答编辑 2019-03-20 15:40:48 +08:00
183e1a85c3 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-20 10:55:09 +08:00
6b696234ab 回答编辑支持批量插入图片 2019-03-20 10:54:58 +08:00
21ac1d1f17 基本完成答案详情上下滑动功能,待接口数据再调试 2019-03-20 10:23:33 +08:00
4163b81f70 Merge head 2019-03-19 18:10:34 +08:00
6c3268ce72 简单包裹答案详情页面以实现上下拖拽切换回答 2019-03-19 18:08:06 +08:00
4d87f86fcd Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-19 14:40:20 +08:00
4a37401dc2 RichEditor增加元件样式回调 2019-03-19 14:40:06 +08:00
8cf90193fc 修复一个数组越界造成的闪退问题 2019-03-18 16:12:27 +08:00
9942a51cad Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-11 18:24:47 +08:00
4980d96c8c 修复当后台返回错误的游戏标签时会闪退的问题 2019-03-11 18:24:37 +08:00
f32c8748ed Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-03-11 18:10:26 +08:00
7b886679e1 修改礼包图标大小 2019-03-11 18:08:52 +08:00
2620c04b09 捕抓闪退异常 (ObservableUtil 这个地方贡献了得有40%的闪退量) 2019-03-10 10:07:03 +08:00
c22157f2f5 修复了关注页面被销毁网络回调回来会导致闪退的问题 2019-03-08 09:44:54 +08:00
09f02bc225 修复插件化隐藏后无法一键修复问题 2019-03-07 15:57:38 +08:00
9fc9549a28 光环前端需求汇总(2019年3月第1周)(1.4.6.7.8)https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/461 2019-03-07 14:55:35 +08:00
0099afad09 update changelog 2019-03-04 10:00:08 +08:00
3e512634c6 tinkerBase:3.6.2 2019-03-04 09:51:55 +08:00
7045354808 修复推送系统通道内容乱码问题 2019-02-28 23:25:22 +08:00
dbcc97a250 修复版本说明弹窗圆角 2019-02-28 19:28:20 +08:00
050081b7b1 修复版本说明弹窗大小 修改求版本文案 2019-02-28 18:04:57 +08:00
993d1e7635 UI调整 2019-02-28 10:07:48 +08:00
a86a3c1f71 修复了游戏详情下载按钮文字过多导致超出可是范围的问题 2019-02-27 17:54:41 +08:00
b0a192ad9a 修复了未登录时游戏动态的热门推荐区域不显示的问题 2019-02-27 17:31:51 +08:00
ea7b478c6b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-02-27 16:23:01 +08:00
b673383f59 修复文章详情引用评论隐藏后没有显示"该内容已被隐藏"问题 2019-02-27 16:22:27 +08:00
06ae366b74 修复隐藏入口后一键修复无法即时更新页面问题 2019-02-27 16:20:57 +08:00
6b9cf7094e 修复关注页面刷新不及时的问题 2019-02-27 15:45:38 +08:00
5ae22bd2bc 修复了用户没有登录也能看到消息中心推送的问题 2019-02-27 10:40:46 +08:00
e951551531 修复了答案详情点击更多会闪退的问题 2019-02-27 10:39:50 +08:00
272e5fb6cc 调整专栏阅读日志的默认值 2019-02-26 14:49:42 +08:00
7dc17d09c1 记录专栏的阅读位置信息 2019-02-26 14:29:39 +08:00
cfacbe739d 修复一些空指针异常 2019-02-26 10:10:29 +08:00
0a72226ba5 下载平台面板增加翻页提示 2019-02-25 10:56:25 +08:00
5f22a14643 整理部分代码 2019-02-24 15:14:42 +08:00
5562e38c2f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-02-24 11:16:58 +08:00
f9027f7a61 消息中心样式修改 2019-02-24 11:16:46 +08:00
6d0e437ad4 完成 MTA 统计需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/456 2019-02-23 11:40:19 +08:00
3abc53d3b3 完成首页游戏替换功能 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/447 2019-02-23 10:33:55 +08:00
d0e4c2c3ab 补充注释 2019-02-22 15:39:09 +08:00
5be50c1638 修复数据统计缺失社区ID的问题 2019-02-22 15:38:31 +08:00
7c525aec79 推送功能优化 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/451 2019-02-22 15:35:11 +08:00
63d5edf892 光环前端需求汇总(2019年2月第4周)(2.3.6.7)https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/452 2019-02-22 15:32:34 +08:00
c9f2cf178a 去掉推送通知的本地过滤 2019-02-22 10:14:37 +08:00
fc98de3bc0 更换广点通接入帐号 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/454 2019-02-22 09:59:36 +08:00
dd8360f5e8 游戏下载面板增加公告(补充) 2019-02-21 11:13:06 +08:00
bc9b815b47 DownloadDialog 去除单例 2019-02-20 14:41:15 +08:00
2a93995221 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-02-20 10:32:15 +08:00
0e93f6521c 版本升为3.6.2 2019-02-20 10:32:09 +08:00
b3a6d0ce94 修复横排专题的曝光出现内容错乱的问题 2019-02-19 18:11:38 +08:00
de60d05190 插件游戏求版本功能完善 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/450#note_17274 2019-02-19 15:42:22 +08:00
2a2ce9a490 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-02-19 11:32:42 +08:00
639644e3c3 游戏下载面板增加公告功能 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/449#note_17186 2019-02-19 11:30:52 +08:00
2378e6e94e 基本完成首页游戏替换功能(本地测试通过,暂未与后台调试) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/447 2019-02-18 15:33:12 +08:00
87d9feae70 修改 Gson 的对象化实现,避免类型擦除 2019-02-18 15:27:49 +08:00
4a93d129bb 游戏下载面板增加公告 2019-02-16 15:46:15 +08:00
39e5e2e9f9 渠道包功能开关控制规则优化(未测试) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/448 2019-02-15 16:07:30 +08:00
8a5f777c65 社区和文章评论被删除的默认文案颜色修改 2019-02-14 10:48:53 +08:00
22c693e042 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-02-13 18:25:13 +08:00
36d04f5841 意见反馈修改 光环前端需求汇总(2019年2月第3周)(8.9.10.11) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/445#note_17027 2019-02-13 18:25:05 +08:00
409123337d 统一游戏动态和我的关注页面的游戏推荐样式 2019-02-13 17:32:06 +08:00
b180a210cb Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-02-13 15:38:40 +08:00
32dfdc4d08 更改草稿刷新逻辑 光环前端需求汇总(2019年2月第3周)(3) 2019-02-13 15:38:35 +08:00
4d46888995 修复更新非活跃状态的页面造成的闪退问题 2019-02-13 14:27:31 +08:00
69db836231 修复问题详情和答案详情页面会丢失部分阅读时长统计的问题 2019-02-12 17:46:54 +08:00
f82b9ad308 修复进入有视频的游戏详情时会造成手机被静音的问题 2019-02-12 15:14:46 +08:00
3ac91b1216 修复重复初始化七陌客服SDK造成后台产生空的聊天条目的问题 2019-02-11 15:36:05 +08:00
8d4b3e0851 修复更新非活跃状态的页面造成的闪退问题 2019-02-11 10:39:11 +08:00
67d8f46217 反馈图标大小自适应 2019-01-30 17:18:57 +08:00
f357136936 update CHANGELOG
3.6.1 Tinker Base
2019-01-30 15:48:00 +08:00
9d622d2be9 消息中心标黄内容复制后去除前后空格 2019-01-30 09:46:52 +08:00
800525227d update MessageSpannableTextView 2019-01-29 18:25:09 +08:00
c9dec9a31e 草稿刷新时定位到列表顶部 2019-01-29 16:23:57 +08:00
2ae4fda6e8 优化ListViewModel 2019-01-28 19:26:02 +08:00
609702715f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-28 17:59:06 +08:00
ec7e138208 光环助手V3.6.1 RELEASE(20190128-1200)测试问题汇总(2.4) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/443 2019-01-28 17:58:25 +08:00
bfd64a8bce 修复开服表曝光的提交问题 2019-01-28 17:12:15 +08:00
5571b6481f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-28 11:31:25 +08:00
6d6574988c 光环助手V3.6.1 RELEASE(20190125-1850)测试问题汇总(4.5.9.10.13) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/442#note_16676 2019-01-28 11:31:13 +08:00
af8d075bf2 修复了下载插件化应用时的卡顿问题 2019-01-26 17:44:12 +08:00
b7db66e90b 专题答案列表显示发布时间 2019-01-26 11:32:20 +08:00
13ac4658d9 通过微信分享前先检测用户是否安装微信 2019-01-25 18:22:02 +08:00
8ad3420822 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-25 15:40:16 +08:00
f842ced67e 更换反馈图标 添加渠道号 2019-01-25 15:39:48 +08:00
e0081e56df Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-25 14:22:52 +08:00
3202764f22 屏蔽安卓 5.0 以下设备的视频播放功能 2019-01-25 14:22:39 +08:00
f477876359 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-25 14:08:26 +08:00
86ffcb92f8 admin api host -> 3.6.1
1月25补充优化
2019-01-25 14:08:18 +08:00
a2088e5cd9 修复问题详情页面的答案没有显示发布时间的问题 2019-01-25 09:58:38 +08:00
6e1247f393 消息客服跳转过滤无链接数据 2019-01-24 18:19:27 +08:00
c33faa4918 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-24 15:39:57 +08:00
d0aeb1c411 修改反馈文案
修复插件化完成后更新不及时问题
2019-01-24 15:39:33 +08:00
485924527e 避免发送无用的关注请求 2019-01-24 15:19:15 +08:00
ca1bfda326 更换反馈图标 2019-01-23 18:31:27 +08:00
c7c786d662 修改社区搜索路径关键字 2019-01-23 17:47:02 +08:00
acf9fe308c 光环助手V3.6.1数据统计需求(光环数据后台) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/440 2019-01-23 16:59:53 +08:00
3b32231709 修复嵌套 recyclerview 因为焦点获取而触发莫名位移的问题 2019-01-23 16:43:18 +08:00
9dae198af2 修复曝光下载完成事件里 payload 没有游戏 id 的问题 2019-01-23 14:50:53 +08:00
29bfd5bb93 处理空指针异常 2019-01-23 11:49:51 +08:00
8da51d7f5a 回答数量限制弹窗优化
优化消息中心标黄判断
2019-01-23 11:30:42 +08:00
91964a0ffc Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-22 19:17:26 +08:00
479ef20859 dev api host -> 3.6.1
光环助手V3.6.1-消息中心优化(测试未通过)  https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/435
2019-01-22 19:17:08 +08:00
f458b7dcb8 将MTA的[游戏详情]计算事件换成普通事件[游戏详情_新] 2019-01-22 18:24:31 +08:00
2d25ff7836 开服表添加曝光统计 2019-01-22 18:13:46 +08:00
57dd5d0584 关注游戏区分自动和手动 2019-01-22 18:13:18 +08:00
757efec05e 回答卡片增加回答发布时间 2019-01-22 18:12:21 +08:00
4979045be2 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-21 17:00:59 +08:00
f59af60f70 游戏详情增加社区跳转提示 2019-01-21 17:00:04 +08:00
60bc2a02f4 修复一些闪退问题 2019-01-21 16:21:34 +08:00
996be3906e versionCode->60 versionName->3.6.1 2019-01-21 15:55:50 +08:00
14a054bdbc 游戏详情 增加加载骨架 2019-01-21 15:50:36 +08:00
07a9fd6273 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-21 14:43:21 +08:00
a067f7bc43 礼包详情/专题详情 增加加载骨架 2019-01-21 14:43:11 +08:00
a5eefbb6f4 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-21 10:57:35 +08:00
8d9f83c432 处理值转换异常 2019-01-21 10:57:24 +08:00
ae0df36a89 处理非空异常 2019-01-21 10:56:44 +08:00
72539671a1 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-21 10:31:43 +08:00
94277a4aeb 游戏分类增加加载骨架 2019-01-21 10:31:25 +08:00
e276d148cf 统一文本输入框的超出字数逻辑 2019-01-20 18:34:34 +08:00
a7152034e8 修复上传弹窗重复显示问题 2019-01-20 16:54:16 +08:00
4a5e9da34a 可以由后台控制关闭资讯相关的功能 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/434 2019-01-20 14:23:29 +08:00
1422365cc5 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-20 10:17:36 +08:00
7f55ff6340 根据包名过滤下载按钮状态 2019-01-20 10:17:23 +08:00
4722626fb7 添加百度信息流激活统计请求 2019-01-17 17:07:08 +08:00
39d87ad98d 图片加载支持 gif 2019-01-17 17:06:20 +08:00
85333b9eed 更新七陌客服 SDK 2019-01-17 16:03:58 +08:00
c99ae6db3e 修复游戏列表下载状态异常问题 2019-01-17 15:25:48 +08:00
c5be98adc2 修复手机没有图片选择应用时调用会崩溃的问题 2019-01-16 19:08:18 +08:00
5321aa2e9f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-16 19:00:50 +08:00
345707ef42 光环前端需求汇总(2019年1月第3周)1.9.11 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/432 2019-01-16 18:35:22 +08:00
6a9d05d916 修复部分以 .html 结尾的下载链接无法下载的问题 2019-01-16 15:45:40 +08:00
faf2a89706 修复了 GID 初始化顺序不一造成的闪退问题 2019-01-15 11:29:57 +08:00
ada51f90f1 修复了一个数组越界造成的闪退问题 2019-01-15 10:08:18 +08:00
53962116d5 修复了我的游戏中同包名游戏显示错误前缀以及安装包名刷新不及时的问题 2019-01-10 15:26:15 +08:00
3ea52745b3 如果已安装的是光环助手的游戏包那么对应的已安装列表只会存在一条已安装信息 2019-01-10 09:53:21 +08:00
a8f2289b27 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-01-09 18:16:31 +08:00
6dd56b5d16 光环前端需求汇总(2019年1月第2周)(1.3.4.5.6.7) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/428#note_15724 2019-01-09 18:15:45 +08:00
eb739cf6cb 修复了插件化弹窗安装状态更新不及时的问题 2019-01-09 17:08:18 +08:00
4853cd9047 修复了文章详情 gif 图片会闪烁的问题 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/424 2019-01-07 12:03:40 +08:00
4e0f14aeed 首页 tab 添加水波纹效果 2019-01-05 18:01:28 +08:00
5e37dac0f6 处理空指针异常 2019-01-05 10:06:01 +08:00
22bfa9051a 修复由于列表重用机制导致的游戏名字长度异常问题 2019-01-04 14:23:32 +08:00
0a1dca3aa3 修复游戏详情大家都在玩列表会显示下载'暂无'字样的游戏的问题 2019-01-04 10:55:15 +08:00
0b20896330 3.6封包 2018-12-29 19:00:46 +08:00
3b934578dd 修改游戏列表样式 2018-12-29 17:51:34 +08:00
c42e1a76bf 3.6封包 2018-12-29 09:21:23 +08:00
d3f2395d9c 捕抓删包异常 2018-12-28 20:41:01 +08:00
b5ba1e877f 将时间敏感的SP写入操作从 apply 换成 commit 2018-12-28 20:17:57 +08:00
eba27d8969 微调游戏列表间距 2018-12-28 18:32:01 +08:00
fe1d4d3406 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-28 17:41:34 +08:00
28418b0d49 update .gitignore 2018-12-28 17:41:16 +08:00
f35396c0e3 修复了关注页面,存在红点且为首次加载时重复加载的问题 2018-12-28 17:33:32 +08:00
67cc464607 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-28 15:57:51 +08:00
b0fa0392b7 调整首页游戏间距
我回答过的问题,最后答案都被隐藏了,在问题详情不要显示 [我来回答] 按钮
2018-12-28 15:57:38 +08:00
0fc4fddfe7 处理部分错误错误码 2018-12-28 11:42:27 +08:00
f092966c88 赞同列表弹窗的宽度改为80%屏幕宽度 2018-12-28 11:29:11 +08:00
0e1cb515ab 游戏列表摘要文案显示为灰色 2018-12-28 10:37:38 +08:00
35115d0581 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-27 18:19:43 +08:00
b1d1fc0e36 修复问答-关注切换社区关注用户可能多次调用刷新数据的问题 2018-12-27 18:19:30 +08:00
91f84cdd5c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-27 18:08:42 +08:00
ad2c155e54 光环助手V3.6 RELEASE(20181227-1530)测试问题汇总 https://gitlab.ghzhushou.com/pm/issues-Inbox/issues/838 2018-12-27 18:08:30 +08:00
fc4b383292 修复问答-关注切换社区关注用户可能多次调用刷新数据的问题,微调 UI 2018-12-27 18:08:09 +08:00
1a868d3f12 修复问答-关注切换社区关注用户可能多次调用刷新数据的问题 2018-12-27 17:53:34 +08:00
e4dd96e21a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-27 15:12:18 +08:00
8705f8d2e2 横向游戏列表游戏名加粗
游戏搜索显示游戏标签
版主修改历史优化
2018-12-27 15:12:10 +08:00
65fab5e990 修复关注页面赞同折叠的显示问题 2018-12-27 11:18:49 +08:00
1d92b070eb 将 listViewModel 里更新加载状态的方法由 postValue 换成 setValue 以避免快速多次调用触发分页问题 2018-12-27 10:27:23 +08:00
d72102784e Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-26 20:01:57 +08:00
d7351bf93e 修复了问答关注推荐用户界面即时关注了新用户依旧存在的问题 2018-12-26 20:01:47 +08:00
6bf40ca237 修复同一个包存在多个更新的问题
修复已安装列表出现下载按钮问题
版主修改标签增加默认标签
2018-12-26 17:34:44 +08:00
4be93781b2 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-26 14:26:04 +08:00
13fc6b8453 版主历史版本增加初始内容(未修改),修改app更新逻辑 2018-12-26 14:25:56 +08:00
34cbbdffb9 修复一个重复调用列表 onRefresh 造成的显示问题 2018-12-26 12:04:41 +08:00
e45eadb6e3 3.6 (20181225-1850) 问题汇总 (6,7,12,13,14) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/420 2018-12-26 10:51:56 +08:00
7bf2ef1007 修复点赞数量为零的情况,社区投票 已开通的toast文案修改 2018-12-26 10:33:25 +08:00
23c46cc4b2 修改邀请错误文案 2018-12-25 15:20:53 +08:00
259adbf145 光环助手V3.6 RELEASE(20181224-1145)测试问题汇总(前端)(2,3,6,10,11,13,14) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/419 2018-12-25 15:12:00 +08:00
95acc64e42 光环助手V3.6 RELEASE(20181224-1145)测试问题汇总(前端)(7.8.16)https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/419 2018-12-25 15:02:10 +08:00
974d4fcefa 修复查看礼包闪退问题 2018-12-24 15:22:49 +08:00
298733b192 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-24 11:22:34 +08:00
2ec4c75049 实现下拉刷新更新轮播图(首页-游戏,首页-问答) 2018-12-24 11:22:25 +08:00
bfac5398fc 优化曝光模块代码 2018-12-24 10:43:53 +08:00
d029b1692a 优化曝光模块代码 2018-12-23 16:19:55 +08:00
d7006f25f7 光环助手V3.6 DEV(20181220-1000)测试问题汇总(前端)(10.11.12.14.30.36) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/417#note_14957 2018-12-23 14:30:00 +08:00
ef56910da0 修复曝光事件里 gid 可能为空的问题 2018-12-23 10:20:11 +08:00
dbf73a0385 修复发现页面闪退问题 2018-12-22 18:03:19 +08:00
41b8cae6bd 光环助手V3.6 DEV(20181220-1000)测试问题汇总(前端)(23.24.26.27.28.38) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/417 2018-12-22 17:52:39 +08:00
0bea685ce1 优化信息流推荐关注 2018-12-21 18:09:59 +08:00
acd39aa969 完成光环助手V3.6 DEV(20181220-1000)测试问题汇总(前端) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/417 的 4、5、7、6、8、17、18 2018-12-21 17:22:32 +08:00
fd59e71714 光环助手V3.6 DEV(20181220-1000)测试问题汇总(前端)(9.25.31.33.34.35.37) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/417 2018-12-21 17:03:05 +08:00
47c37a1a7e 优化信息流 推荐关注,admin api 升为v3d6 2018-12-21 10:58:58 +08:00
774f9bac80 修复问答-推荐 重复刷新问题 2018-12-21 10:36:16 +08:00
316eb738ec Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-20 17:32:26 +08:00
af493d9dfb 登录事件触发地点修改,优化信息流推荐关注 2018-12-20 17:32:05 +08:00
3d626abbc2 修复自动搜索不显示广告的问题 2018-12-20 15:40:38 +08:00
a392f7f8d8 修復初始化闪退问题 2018-12-20 11:42:01 +08:00
8f8f4c645a 发现页面分割线,改为0.5dp 2018-12-19 16:54:54 +08:00
1cae62fb99 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/res/layout/fragment_discover.xml
2018-12-19 16:38:50 +08:00
6db72fa7e7 光环助手V3.6 DEV(20181213-1500)测试问题汇总(UI) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/415 2018-12-19 16:34:10 +08:00
6ee300c70e 将问答顶部几个 tab 的宽度变成自适应 2018-12-19 15:43:43 +08:00
0f16790535 基本完成广告入口需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/412 2018-12-19 14:55:36 +08:00
524742b8ea 光环助手V3.6 DEV(20181213-1500)测试问题汇总(前端)(9.10.16.17.24)https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/413 2018-12-18 19:41:31 +08:00
8c08bbea6a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-18 16:02:36 +08:00
d6c2bd6634 修复反馈闪退问题 2018-12-18 16:02:21 +08:00
4aeb42dee9 精简部分无用代码 2018-12-18 14:26:34 +08:00
0de7f40958 修复 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/413 的 3、4、5、6、19(2)、20、22、25 点 2018-12-18 14:25:51 +08:00
07fd8d986e 捕抓异常 2018-12-18 14:23:16 +08:00
c821923cd0 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-17 17:10:47 +08:00
6ce247d8d1 更改引导图 部分登录入口统计修改 2018-12-17 17:10:34 +08:00
473d8c43df Merge branch 'fix_background_service' into 'dev'
尝试解决 https://gitlab.ghzhushou.com/halo/assistant-android/issues/7

See merge request !2
2018-12-17 16:22:11 +08:00
e082b321eb 尝试解决 https://gitlab.ghzhushou.com/halo/assistant-android/issues/7
1. 当设备满足系统版本为 8.0+ 且应用在后台运行时,使用 startForegroundService() 启动 DownloadService ,否则使用原来的 startService() 启动 DownloadService

2. 当应用从后台切换回前台并且 DownloadService 是前台服务时,手动调用 Service.stopForeground() 来去掉前台服务标记
2018-12-17 16:18:05 +08:00
fd236857d4 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt
2018-12-14 17:35:27 +08:00
9290934ec3 光环助手V3.6数据统计需求(登录入口统计) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/407 2018-12-14 17:20:39 +08:00
b6d9118d05 修复一个在华为设备上注册过多 broadcast receiver 会崩溃的问题 2018-12-14 11:50:38 +08:00
544d21613a 增加腾讯广告用户分群 SDK 2018-12-14 10:56:32 +08:00
68a7720ea9 补充开服表 MTA 事件 2018-12-13 18:00:03 +08:00
01a537c0f6 修复打包失败问题(使用javax包下的内容导致) 2018-12-13 17:21:40 +08:00
11bd2a5831 versionName->3.6
versionCode->50
2018-12-13 16:26:08 +08:00
d615a07f27 基本完成 3.6 MTA 统计需求 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/408 2018-12-13 10:56:40 +08:00
ef941a7651 微调菜单UI 2018-12-13 09:42:56 +08:00
928ed40dd4 社区上报阅读数据增加相关字段 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/406#note_14390 2018-12-12 17:17:36 +08:00
03f3f174c3 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-12 16:24:13 +08:00
6a1a38fb5e 问答-推荐增加推荐关注完成 2018-12-12 16:23:59 +08:00
9f4ca9a3bb Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-12 15:06:58 +08:00
670786cc2d 完善点赞引导和关注引导 2018-12-12 15:06:52 +08:00
cc3b4ba7e9 禁言状态提醒从 toast 改为 dialog 2018-12-12 10:55:19 +08:00
b8d5246230 当引用的评论被隐藏 内容显示未该内容已被删除 2018-12-11 16:46:12 +08:00
37665acd3c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-11 15:03:59 +08:00
5aef4d649a 优化版主管理问题详情权限问题 2018-12-11 15:03:46 +08:00
90c050590a 搜索列表添加曝光统计 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/405 2018-12-11 14:33:50 +08:00
3115152f32 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-11 10:52:26 +08:00
923562ad8e 礼包增加查看状态,客服私信增加问题类型,社区推荐轮播图大小设为按比例缩放 2018-12-11 10:52:01 +08:00
1b2b9b3b91 更换显示游戏"新服"的字段,消息推送点击标记已读 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/402 2018-12-11 10:12:08 +08:00
8412044b88 增加检查登录的 extensions 2018-12-11 10:10:24 +08:00
ceb2384eb8 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
2018-12-10 16:18:45 +08:00
1244efd015 基本完成社区版主权限答案部分 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/395 2018-12-10 16:17:24 +08:00
1cc572f774 版主修改历史/详情 对接数据接口,app更新对比改用VersionCode 2018-12-10 16:16:20 +08:00
f43c9e5d67 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-09 17:40:56 +08:00
22387e8e60 光环助手V3.6优化需求汇总(20181206)(1.2.5.7.8.9.10.13.21.22)https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/402#note_14212 2018-12-09 17:40:47 +08:00
9284af351a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-08 15:44:51 +08:00
07cbd3c031 捕获写入曝光数据库的异常 2018-12-08 15:44:36 +08:00
1d03d171e0 发送游戏页面增加定位权限申请(避免在某些设备上没有权限闪退 2018-12-08 15:42:46 +08:00
1abb783f4c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-07 16:07:55 +08:00
d37c809973 版主隐藏问题对接数据接口 2018-12-07 16:07:43 +08:00
0feffda7f3 完成 V3.6 部分优化 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/402 2018-12-07 16:06:54 +08:00
b5bfbfaff6 基本完成社区关注 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/391 补充部分 2018-12-06 18:05:09 +08:00
25a4171631 更新 GID 库 2018-12-06 18:04:13 +08:00
8622aa787a 版主修改问题对接数据接口 2018-12-06 17:42:23 +08:00
dd44a34e18 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-06 11:55:25 +08:00
da91e7de1d 优化版主问题标签 2018-12-06 11:55:16 +08:00
c32798cbb0 捕抓异常,避免闪退 2018-12-06 10:15:11 +08:00
a03754d02b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-05 18:08:58 +08:00
a9351b29ab 问答推荐增加“推荐关注”(尚未对接网络数据) 2018-12-05 18:08:51 +08:00
84a27b504d 基本完成 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/400 答案详情引导修改 2018-12-05 17:59:57 +08:00
91e2432b48 微调问答关注页面 UI 2018-12-05 15:54:46 +08:00
505da678f0 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-05 14:19:53 +08:00
e0b44bf41c 整理app更新相关/礼包详情代码 2018-12-05 14:19:44 +08:00
f856ff5957 微调回答详情点赞动画特效 2018-12-05 10:21:48 +08:00
65fdb90ccb 回答详情添加动画效果,具体触发逻辑还得等后台确定接口 2018-12-05 10:12:34 +08:00
82372dc33b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-04 17:53:32 +08:00
14fb79b90c 更改过滤已隐藏包的逻辑 2018-12-04 17:53:19 +08:00
050c7f9d86 处理非空异常 2018-12-04 17:03:08 +08:00
6efd3a3239 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-03 15:36:12 +08:00
f1c0888309 修复对获取服务器时间这个接口的解析问题 2018-12-03 15:35:58 +08:00
1e9ade68f7 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-03 15:07:45 +08:00
58a0fd8fdb 修复游戏详情截图尺寸不对问题 2018-12-03 15:07:35 +08:00
cd523bd552 修复对获取服务器时间这个接口的解析问题 2018-12-03 14:59:16 +08:00
22f68d098c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-12-03 11:17:18 +08:00
5d3657938d 删除tinker_version_name(由于app推送更新方式变更,不再需要tinker_version_name) 2018-12-03 11:16:26 +08:00
f2002ff1ce 修复初始化问题 2018-12-03 10:51:08 +08:00
49600213b7 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/AskViewModel.kt
2018-11-30 18:18:17 +08:00
4d87edb1fd 删除部分无用代码 完成部分todo 2018-11-30 18:16:18 +08:00
b536f263f2 修复一个初始化异常问题 2018-11-30 16:36:10 +08:00
65c1300c63 去掉用不到的 iosched 2018-11-30 10:43:45 +08:00
f1cc12eea3 微调代码结构 2018-11-30 10:34:48 +08:00
0c5dd84c27 略微调整代码结构 2018-11-30 10:21:23 +08:00
df8753e1c4 优化管理员修改问题,修复资讯中心三张图片的Item无法显示问题 2018-11-29 17:21:54 +08:00
eb9dba3bc7 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-11-28 18:41:00 +08:00
86247e4a61 回退问答-推荐访问路径 增加问题历史和历史详情 2018-11-28 18:40:45 +08:00
fc46584735 修复初始化问题 2018-11-28 18:25:06 +08:00
dab87d46fa 修复初始化问题 2018-11-28 18:07:10 +08:00
1968f4b7f3 将应用初始化的操作移动到子线程,缩短启动速度 2018-11-28 17:41:11 +08:00
3b1556f931 将 annotationProcessor 换成 kapt
(文档 https://kotlinlang.org/docs/reference/kapt.html#using-in-gradle 说 kapt 可以完全替换掉 annotationProcessor,尝试去掉来确定 butterknife 偶发找不到 id 是不是这个造成的)
2018-11-28 16:33:41 +08:00
249332848c 修正问答统计访问路径(问答-推荐),修改编辑问题-标签选择 2018-11-27 19:02:54 +08:00
26058934cd 完善打特殊包的脚本 2018-11-26 17:12:11 +08:00
11298d26e7 更新 proguard 规则以适配新的 LogHub 依赖 2018-11-26 14:37:00 +08:00
394d558707 修复用户使用 AppOps 绕过外部存储权限授予限制,使游戏下载到内部存储 '/data/user/...' ,造成游戏无法安装/安装崩溃的问题 2018-11-26 11:39:21 +08:00
058d55ea82 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-11-26 10:31:49 +08:00
903109f8d5 增加打特殊包的脚本 2018-11-26 10:31:30 +08:00
4876abb0ed 更新 gid 依赖,修复崩溃问题 2018-11-26 10:27:07 +08:00
f75490aec2 捕获获取安装包信息的异常 2018-11-26 10:26:17 +08:00
b2e3ae684d 删除strings.xml重复参数 2018-11-25 18:36:14 +08:00
5b4f5e0ef8 下载状态相关字符串抽离到 Strings.xml 2018-11-25 18:25:27 +08:00
5fb6f7dbb2 默认隐藏游戏列表排序数值 2018-11-23 17:13:06 +08:00
c8e32fd968 更改游戏列表开服标签的实现方式 2018-11-22 19:17:18 +08:00
15f4f58164 整理社区选择‘投票中’代码 2018-11-22 15:52:26 +08:00
291410cc1c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-11-22 15:24:32 +08:00
dd9d6cc452 光环助手V3.6-问答社区优化需求汇总[社区投票优化] https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/394 2018-11-22 15:24:22 +08:00
8866d7f71e 修复 9.0 部分设备没有读写权限会崩溃的问题 2018-11-21 17:34:15 +08:00
83bcd89c0c 微调问答邀请列表的 UI 2018-11-21 16:58:08 +08:00
0a2160e18a 修复在部分无法获取 IMEI 的机器上无法加载网络数据的问题 2018-11-21 16:57:25 +08:00
acab1d89aa 光环助手V3.6-问答社区优化需求汇总(Bug汇总) https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/394 2018-11-21 15:53:20 +08:00
42176d334e 统一游戏列表样式,删除无用代码 2018-11-20 17:18:57 +08:00
5db3563400 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-11-19 17:41:49 +08:00
50f26101cb 首页游戏增加预览样式以及调整部分首页游戏样式 2018-11-19 17:41:30 +08:00
20915963f8 基本完成社区首页新增的[关注]时间线功能 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/391 2018-11-19 15:07:27 +08:00
e0fce2c2bf Merge branch 'install_helper' into dev 2018-11-15 11:08:28 +08:00
069340ecd1 修改包名 2018-11-15 11:07:48 +08:00
ca5a34e09d 删除部分todo 2018-11-15 10:41:10 +08:00
08fe5e8f83 PackageViewModel 增加重试功能 2018-11-14 16:30:31 +08:00
12623fd383 PackageRepository 添加光环助手更新逻辑 2018-11-14 11:33:25 +08:00
d52bd00ab9 删除无用代码 2018-11-14 10:12:06 +08:00
11963ef040 InstallManager相关的应用全部整合到PackagesManager 2018-11-13 18:26:27 +08:00
03ce6f80a1 下载管理-游戏更新接入PackageViewModel
重构PackageManager相关
2018-11-13 16:30:30 +08:00
42ea33612d 更新 logHubHelper ,支持无网发送失败时有网重试 2018-11-13 10:13:57 +08:00
1cc0c51390 重构本地已安装的相关数据(更新/插件化/已安装的游戏列表)
已对接:首页插件化区域,我的游戏页面
2018-11-12 16:52:26 +08:00
62740ffcb6 tinkerVersionName->3.5.1 2018-11-08 14:48:33 +08:00
727616c764 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/kaifu/KaiFuVpFragment.java
2018-11-08 11:33:44 +08:00
1b6fd03ba3 修复开服表存在置顶项进入直接点击下一开服会一直滚动到底部的问题 2018-11-08 11:26:54 +08:00
53bb1dee01 修复总开复表存在热门开服点击下一节直接跳到底部问题 2018-11-08 11:26:40 +08:00
467950ae2c 优化首页游戏以及板块页面交互问题 2018-11-07 18:14:37 +08:00
5248ad3b6a 选择社区列表增加“上拉加载”状态 2018-11-06 17:44:55 +08:00
3e41af7f41 社区推荐修改默认刷新文案 2018-11-06 15:08:01 +08:00
c01a9c1140 横向游戏列表加上礼包图标, 问题推荐增加默认刷新文案 2018-11-06 14:50:22 +08:00
36def0a511 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2018-11-06 10:09:29 +08:00
077f768d09 光环助手V3.5 RELEASE(20181101-1540)(2.4.5.6.7.8.9.12)测试问题汇总 https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/387 2018-11-06 10:09:12 +08:00
c2eafeb9a4 修复一些空指针异常问题 2018-11-02 09:42:29 +08:00
885 changed files with 35897 additions and 14257 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ local.properties
captures/
build/
release-app/
scripts/apk-channel/
scripts/apk-channel/
app/src/test/java/com/gh/gamecenter

2
.gitmodules vendored
View File

@ -1,4 +1,4 @@
[submodule "libraries/LGLibrary"]
path = libraries/LGLibrary
url = git@gitlab.ghzhushou.com:client/client-common.git
url = git@gitlab.ghzhushou.com:android/common-library.git
branch = master

View File

@ -1,4 +1,10 @@
### Ver 3.1
# 版本升级备忘
### Ver 2.5
* 此处写本次更新所做的业务和代码修改
### Ver 2.6
* xx
### Ver 3.0
* 升级账号系统(登录流程/用户信息相关/用户账号相关操作(评论,礼包...))
@ -10,8 +16,51 @@
* 游戏下载平台面板修改(加快弹出速度,不再读取本地平台图片)
* 接入bugly(tinker)
### Ver 2.6
* xx
### VER 3.1
### VER 3.2
### VER 3.3
### VER 3.4
### VER 3.5
### Ver 2.5
* 此处写本次更新所做的业务和代码修改
### Ver 3.6
* 首页游戏增加预览骨架,游戏ITEM样式微调和开服标签
* 首页问答增加关注页面
* 重构游戏更新管理(游戏更新/插件化/已安装的游戏),具体细节参考PackageRepository & PackageViewModel
* 重构APP更新管理(已VersionVode为更新基准,小版本更新改为光环后台控制)
- 删除TINKER_VERISON_NAME
- tinker打包方式变更(以小版本作为Base包,防止与数据后台小版本更新发生冲突)
* 社区增加版主功能(版主可以对存在的相关内容进行修改/隐藏操作,内容包括问题/回答/回答评论)
* 社区互动引导优化(问答推荐增加`推荐关注`,回答详情增加一些交互动效)
### Ver 3.6.1
* 可以后台控制关闭资讯功能
* 版块、分类、专题详情、游戏详情、礼包详情增加预览骨架
* 下载按钮状态可以通过接口屏蔽相应的包
### Ver 3.6.2
* 资讯/问答入口和插件功能线上控制(不可逆)
* 首页不显示已安装的游戏
* 插件求版本功能增加内部跳转
* 下载面板增加公告和版本说明功能
* 接入腾讯`广点通`(广告)
### ver 3.6.3
* 社区搜索修改
- 增加 `文章/用户` 模块
- 增加 `搜索置顶` 功能
* 回答详情/社区文章详情修改
- 支持文案样式(加粗/斜体/删除线)和段落样式(引用/标题)
- 支持关闭评论功能
- 回答详情新增上下切换回答
* 社区编辑框(回答/文章)修改
- 支持批量插入图片(使用知乎Matisse实现)
- 新增插入特殊样式,文案样式(加粗/斜体/删除线)和段落样式(引用/标题)
* 编辑框部分 JS/CSS 使用远程文件
### ver 3.6.4
* 增加浏览记录(回答/文章/资讯/游戏)
* 回答/社区文章 增加反对功能
* 社区编辑框增加插入文章/回答/游戏
- 低版本兼容方案: 插入的样式默认隐藏,只有在3.6.4及以上才会显示
* 游戏详情评分模块增加`小编评论`区域以及样式修改
* 游戏评分增加回复功能

View File

@ -68,7 +68,11 @@ android {
buildConfigField "String", "WEIBO_APPKEY", "\"${WEIBO_APPKEY}\""
buildConfigField "String", "MTA_APPKEY", "\"${MTA_APPKEY}\""
buildConfigField "String", "TD_APPID", "\"${TD_APPID}\""
buildConfigField "String", "PATCH_VERSION_NAME", "\"${PATCH_VERSION_NAME}\""
/**
* Build Time 供区分 jenkins 打包时间用
*/
buildConfigField "long", "BUILD_TIME", "0"
}
@ -92,7 +96,7 @@ android {
signingConfig signingConfigs.debug
buildConfigField "String", "EXPOSURE_REPO", "\"test\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E1\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
}
release {
debuggable false
@ -102,7 +106,7 @@ android {
signingConfig signingConfigs.release
buildConfigField "String", "EXPOSURE_REPO", "\"exposure\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E1\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
}
}
@ -188,6 +192,8 @@ dependencies {
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
testImplementation 'junit:junit:4.12'
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
debugImplementation "com.facebook.stetho:stetho:${stetho}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stetho}"
@ -218,12 +224,11 @@ dependencies {
implementation "com.j256.ormlite:ormlite-core:${ormlite}"
implementation "com.jakewharton:butterknife:${butterKnife}"
annotationProcessor "com.jakewharton:butterknife-compiler:${butterKnife}"
kapt "com.jakewharton:butterknife-compiler:${butterKnife}"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
implementation "org.greenrobot:eventbus:${eventbus}"
annotationProcessor "org.greenrobot:eventbus-annotation-processor:${eventbusApt}"
kapt "org.greenrobot:eventbus-annotation-processor:${eventbusApt}"
implementation "io.reactivex.rxjava2:rxjava:${rxJava2}"
implementation "io.reactivex.rxjava2:rxandroid:${rxAndroid2}"
@ -249,6 +254,7 @@ dependencies {
implementation "android.arch.lifecycle:extensions:${archLifecycleVersion}"
implementation "android.arch.persistence.room:runtime:${archRoomVersion}"
kapt "android.arch.persistence.room:compiler:${archRoomVersion}"
implementation "android.arch.persistence.room:rxjava2:${archRoomVersion}"
implementation 'com.google.android:flexbox:0.2.2'
@ -269,16 +275,23 @@ dependencies {
implementation "cn.jzvd:jiaozivideoplayer:${jiaoziVideoView}"
implementation "com.danikula:videocache:${videoCache}"
implementation "com.llew.huawei:verifier:1.0.6"
implementation 'com.ethanhua:skeleton:1.1.1'
implementation 'io.supercharge:shimmerlayout:2.1.0'
implementation "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:5.3.1"
implementation 'com.walkud.rom.checker:RomChecker:1.0.0'
implementation project(':libraries:gid')
implementation project(':libraries:LGLibrary')
implementation project(':libraries:MTA')
implementation project(':libraries:QQShare')
implementation project(':libraries:TalkingData')
implementation project(':libraries:UmengPush')
implementation project(':libraries:WechatShare')
implementation project(':libraries:iosched')
// implementation project(':libraries:WechatShare')
implementation project(':libraries:LogHub')
implementation project(':libraries:im')
implementation project(':libraries:Matisse')
}
File propFile = file('sign.properties')
if (propFile.exists()) {

Binary file not shown.

View File

@ -197,4 +197,29 @@
-keep @android.support.annotation.Keep class *
-keepclassmembers class ** {
@android.support.annotation.Keep *;
}
}
-keep class com.gh.loghub.** { *; }
### greenDAO 3
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties
-keep class org.greenrobot.greendao.** { *; }
# If you do not use SQLCipher:
-dontwarn org.greenrobot.greendao.database.**
# If you do not use RxJava:
-dontwarn rx.**
-dontwarn org.greenrobot.greendao.rx.**
-dontwarn org.greenrobot.greendao.**
### fastJson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature
-keepattributes Annotation
### 广点通
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}

View File

@ -41,12 +41,7 @@
<uses-permission android:name = "android.permission.WRITE_SETTINGS" />
<!-- bugly with tinker -->
<uses-permission android:name = "android.permission.READ_PHONE_STATE" />
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name = "android.permission.READ_LOGS" />
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name = "android.permission.REQUEST_INSTALL_PACKAGES" />
<supports-screens
@ -60,7 +55,7 @@
<application
android:name = "com.halo.assistant.TinkerApp"
android:allowBackup = "true"
android:icon = "@drawable/logo"
android:icon = "@mipmap/logo"
android:label = "@string/app_name"
android:resizeableActivity = "true"
android:theme = "@style/AppCompatTheme.APP"
@ -107,10 +102,7 @@
android:name = "com.gh.gamecenter.ConcernActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.subject.refactor.SubjectActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.PluginActivity"
android:name = "com.gh.gamecenter.subject.SubjectActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.NewsSearchActivity"
@ -329,7 +321,7 @@
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.fans.FollowersActivity"
android:name = "com.gh.gamecenter.personalhome.followers.FollowersActivity"
android:screenOrientation = "portrait" />
<activity
@ -363,8 +355,38 @@
<activity
android:name = "com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateVisible" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.manager.HistoryDetailActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.manager.HistoryActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.GameActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
android:screenOrientation = "portrait" />
<activity
android:name = ".history.HistoryActivity"
android:screenOrientation = "portrait" />
<activity
@ -392,8 +414,12 @@
</activity >
<activity
android:name = ".CommonActivity"
android:screenOrientation = "portrait" />
android:name = "${applicationId}.wxapi.WXEntryActivity"
android:exported = "true"
android:label = "@string/app_name"
android:launchMode = "singleTop"
android:screenOrientation = "portrait"
android:theme = "@android:style/Theme.Translucent.NoTitleBar" ></activity >
<provider
android:name = "android.support.v4.content.FileProvider"

View File

@ -1,28 +1,163 @@
function requestContentFocus() {
$('#editor').focus();
$("#editor").focus();
}
function setupWhenContentEditable() {
var editor = $('#editor');
if (!editor[0].hasAttribute('contenteditable')) {
return;
var editor = $("#editor");
if (!editor[0].hasAttribute("contenteditable")) {
return;
}
// paste
editor.on("paste", function(e) {
e.preventDefault();
var text = (e.originalEvent || e).clipboardData.getData("text/plain");
text = text.replace(/\n/g, "<br>");
if ("" != text) {
document.execCommand("insertHTML", false, text);
} else {
window.onPasteListener.onPaste();
}
});
// paste 回调只会获取粘贴之前的光标位置,需要自己手动加上粘贴文本的长度,并保证粘贴的是纯文本
editor.on('paste', function(e) {
e.preventDefault();
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
text = text.replace(/\n/g, '<br>');
if("" != text) {
document.execCommand("insertHTML", false, text);
} else {
window.onPasteListener.onPaste();
}
});
requestContentFocus();
requestContentFocus();
}
$(document).ready(function() {
setupWhenContentEditable();
function getStyle(dom, name) {
return window.getComputedStyle(dom)[name];
}
function customLinkgo(self) {
var datas = self.dataset.datas;
console.log(datas)
window.OnLinkClickListener.onClick(datas);
}
var typeClassList = [
"community_article-container",
"answer-container",
"game-container"
];
function removeDomByParent(curDom) {
if (curDom.parentElement) {
curDom.parentElement.removeChild(curDom);
}
}
window.addEventListener("load", function() {
var EditorDom = document.querySelector("#editor");
setupWhenContentEditable();
document.addEventListener("keydown", function(e) {
var event = e || window.event;
if (event.keyCode === 8) {
var s = document.getSelection();
var r = s.getRangeAt(0);
if (r.startOffset === r.endOffset && r.endOffset === 0) {
var preDOM = s.focusNode.previousElementSibling;
if (
preDOM &&
preDOM instanceof Element &&
preDOM.nodeName === "IMG" &&
getStyle(preDOM, "display") === "block"
) {
preDOM.parentElement.removeChild(preDOM);
}
}
var customDom = s.focusNode;
if (customDom) {
if (
r.startContainer.nodeName.toLowerCase() === "blockquote" &&
r.startOffset === 0
) {
RE.formatBlock();
e.preventDefault();
} else if (
customDom.nodeName === "#text" &&
customDom.previousElementSibling &&
typeClassList.indexOf(customDom.previousElementSibling.className) >
-1 &&
r.startOffset === 1
) {
var needDeleteDom = customDom.previousElementSibling;
needDeleteDom.insertAdjacentElement(
"afterend",
document.createElement("br")
);
} else if (
customDom instanceof Element &&
customDom.childNodes[s.focusOffset] &&
customDom.childNodes[s.focusOffset].previousElementSibling &&
typeClassList.indexOf(
customDom.childNodes[s.focusOffset].previousElementSibling.className
) > -1
) {
customDom =
customDom.childNodes[s.focusOffset].previousElementSibling;
customDom.parentElement.removeChild(customDom);
}
}
}
});
document.addEventListener("keyup", function(e) {
var event = e || window.event;
if (event.keyCode === 13) {
var s = document.getSelection();
var curDom = s.focusNode;
var preDom = curDom.previousElementSibling;
if (
curDom.nodeName.toLowerCase() === "blockquote" &&
preDom.nodeName.toLowerCase() === "blockquote"
) {
if (
preDom.childNodes.length > 1 ||
(preDom.childNodes.length === 1 &&
preDom.childNodes[0].tagName !== "BR")
) {
curDom.style.marginTop = 0;
preDom.style.marginBottom = 0;
} else if (
(curDom.childNodes.length === 0 ||
(curDom.childNodes.length === 1 &&
curDom.childNodes[0].tagName === "BR")) &&
(preDom.childNodes.length === 0 ||
(preDom.childNodes.length === 1 &&
preDom.childNodes[0].tagName === "BR"))
) {
removeDomByParent(curDom);
var startQuoteDom = preDom.previousElementSibling;
startQuoteDom && startQuoteDom.nodeName.toLowerCase() === "blockquote"
? (startQuoteDom.style.marginBottom = "10px")
: null;
var range = document.createRange();
range.selectNode(preDom);
s.removeAllRanges();
s.addRange(range);
RE.formatBlock();
}
}
}
});
document.addEventListener("selectionchange", function(e) {
var event = e || window.event;
var targetDom = event.target.activeElement;
if (targetDom.id === "editor" && targetDom.lastElementChild) {
if (typeClassList.indexOf(targetDom.lastElementChild.className) > -1) {
var brDom = document.createElement("br");
EditorDom.appendChild(brDom);
}
}
});
});

View File

@ -1,16 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="user-scalable=no">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<!--<link rel="stylesheet" type="text/css" href="https://resource.ghzs.com/css/halo_app.css">-->
</head>
<body>
<div id="editor" contenteditable="true"></div>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="rich_editor.js"></script>
<script type="text/javascript" src="content.js"></script>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/10.15.0/lazyload.min.js"></script>-->
<!--<script type="text/javascript" src="content.js"></script>-->
<!--<script type="text/javascript" src="https://resource.ghzs.com/js/halo_app.js"></script>-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -14,6 +14,8 @@
* limitations under the License.
*/
// alert("")
var RE = {};
RE.currentSelection = {
@ -22,6 +24,17 @@ RE.currentSelection = {
"endContainer": 0,
"endOffset": 0};
// 引用远端的JS 和 CSS
var script = document.createElement("script")
script.src = "https://resource.ghzs.com/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
document.body.appendChild(script)
var style = document.createElement("link")
style.rel = "stylesheet"
style.type = "text/css"
style.href = "https://resource.ghzs.com/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
document.head.appendChild(style)
RE.editor = document.getElementById('editor');
document.addEventListener("selectionchange", function() { RE.backuprange(); });
@ -94,16 +107,8 @@ RE.setInputEnabled = function(inputEnabled) {
RE.editor.contentEditable = String(inputEnabled);
}
RE.setFocusByEnd = function() {
//alert("111111")
// var txt =RE.editor.createTextRange();
// ("22222")
// txt.moveStart('character',-1);
// ("333333")
// txt.collapse(true);
// ("444444")
// txt.select();
// alert("ddddddd")
RE.formatBlock = function() {
document.execCommand('formatBlock', false, 'p');
}
RE.undo = function() {
@ -166,6 +171,7 @@ RE.setFontSize = function(fontSize){
RE.setHeading = function(heading) {
document.execCommand('formatBlock', false, '<h'+heading+'>');
RE.sendElementNameToNative()
}
RE.setIndent = function() {
@ -190,6 +196,9 @@ RE.setJustifyRight = function() {
RE.setBlockquote = function() {
document.execCommand('formatBlock', false, '<blockquote>');
// var blockId = window.getSelection().focusNode.parentNode;
// $(blockId).addClass("haloBlock")
RE.sendElementNameToNative()
}
RE.insertImage = function(url) {
@ -197,19 +206,17 @@ RE.insertImage = function(url) {
RE.insertHTML(html);
}
//RE.lazyLoad = function() {
// var myLazyLoad = new LazyLoad({
// elements_selector: ".lazy"
// })
//}
// 替换成缩略图
RE.replaceTbImage = function(imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
var index = 0
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
// console.log(imageClassName)
if (imageClassName == "image-link") continue;
if(img.src.indexOf("?") > 0) continue;
// console.log(i)
var tbImg
if(img.src.indexOf(".gif") > 0) {
tbImg = img.src + gifRuleFlag
@ -220,7 +227,7 @@ RE.replaceTbImage = function(imgRuleFlag, gifRuleFlag) {
img.style.cssText = "max-width: 60%; display:block; margin:15px auto; height: auto;"
img.src = tbImg;
if (i == 0) {
if (index == 0) {
var bigImg = document.createElement('img');
bigImg.src = "file:///android_asset/web_load_dfimg_icon.png";
bigImg.style.cssText = "max-width: 20%; margin:15px 0 0 0; height: auto;"
@ -236,6 +243,7 @@ RE.replaceTbImage = function(imgRuleFlag, gifRuleFlag) {
}
}
index ++;
}
}
@ -244,6 +252,8 @@ RE.replaceAllDfImage = function(imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
img.parentNode.removeChild(img.parentNode.childNodes[0]);
i--;
@ -268,6 +278,8 @@ RE.hideShowBigPic = function() {
var j = 0;
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if(img.src.indexOf(",thumbnail") > 0 && img.src.indexOf(".gif") == -1) {
j++;
}
@ -277,6 +289,8 @@ RE.hideShowBigPic = function() {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
img.parentNode.removeChild(img.parentNode.childNodes[0]);
break;
@ -289,6 +303,8 @@ RE.replaceDfImageByUrl = function(imgUrl, imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if (img.src.indexOf(imgUrl) != -1) {
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
if(img.src.indexOf(".gif") > 0) {
@ -305,6 +321,8 @@ RE.ImageClickListener = function() {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
window.imagelistener.imageArr(img.src);
img.onclick = function() {
window.imagelistener.imageClick(this.src);
@ -357,12 +375,16 @@ RE.backuprange = function(){
}
RE.restorerange = function(){
var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
selection.addRange(range);
try {
var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
selection.addRange(range);
} catch(error) {
}
}
RE.enabledEditingItems = function(e) {
@ -432,12 +454,145 @@ RE.removeFormat = function() {
document.execCommand('removeFormat', false, null);
}
RE.insertCustomStyleLink = function(data) {
var entity = JSON.parse(data)
var html = "<br/><div class='"+ entity.type +"-container'>\n" +
" <a class='"+ entity.type +"' href=\"javascript:void(0);\" contenteditable=\"false\" onclick=\"customLinkgo(this)\" data-datas='"+ data +"'>\n" +
" <div class='flex-container'>\n" +
" <div class='gh-internal-content img-left'>\n" +
" <img class = \"image-link\" src='"+ entity.icon +"' />\n" +
" </div>\n" +
" <div class='gh-internal-content content-right'>\n" +
" <p class='content-title'>"+ entity.title +"</p>\n" +
" <p class='contents'>"+ entity.brief +"</p>\n" +
" </div>\n" +
" </div>\n" +
" </a>\n" +
" </div><br/>"
var tags = "", gameHtml = ""
if (entity.tags != null) {
for (var i = 0; i < entity.tags.length; i++) {
tags += "<label>"+ entity.tags[i]+"</label>"
}
gameHtml = "<br/><div class='"+ entity.type +"-container'>\n" +
" <a class='"+ entity.type +"' href=\"javascript:void(0);\" contenteditable=\"false\" onclick=\"customLinkgo(this)\" data-datas='"+ data +"'>\n" +
" <div class='flex-container'>\n" +
" <div class='gh-internal-content img-left'>\n" +
" <img class='image-link' src='"+ entity.icon +"' />\n" +
" </div>\n" +
" <div class='gh-internal-content content-right'>\n" +
" <p class='content-title'>"+ entity.title +"</p>\n" +
" <p class='tags'>"+ tags +"</p>\n" +
" </div>\n" +
" </div>\n" +
" </a></div><br/>"
}
switch(entity.type) {
case "answer":
document.execCommand("insertHTML",false, html);
break
case "community_article":
document.execCommand("insertHTML",false, html);
break
case "game":
document.execCommand("insertHTML",false, gameHtml);
break
}
RE.callback();
}
RE.showLinkStyle = function() {
var answerElement = document.getElementsByClassName("answer-container");
for (var i=0;i<answerElement.length;i+=1){
answerElement[i].style.display = 'inline';
}
var articleElement = document.getElementsByClassName("community_article-container");
for (var i=0;i<articleElement.length;i+=1){
articleElement[i].style.display = 'inline';
}
var gameElement = document.getElementsByClassName("game-container");
for (var i=0;i<gameElement.length;i+=1){
gameElement[i].style.display = 'inline';
}
}
RE.hideLinkStyle = function() {
var answerElement = document.getElementsByClassName("answer-container");
for (var i=0;i<answerElement.length;i+=1){
answerElement[i].style.display = 'none';
}
var articleElement = document.getElementsByClassName("community_article-container");
for (var i=0;i<articleElement.length;i+=1){
articleElement[i].style.display = 'none';
}
var gameElement = document.getElementsByClassName("game-container");
for (var i=0;i<gameElement.length;i+=1){
gameElement[i].style.display = 'none';
}
}
// Event Listeners
RE.editor.addEventListener("input", RE.callback);
RE.editor.addEventListener("keyup", function(e) {
var KEY_LEFT = 37, KEY_RIGHT = 39;
if (e.which == KEY_LEFT || e.which == KEY_RIGHT) {
RE.enabledEditingItems(e);
}
RE.sendElementNameToNative()
});
RE.editor.addEventListener("click", RE.enabledEditingItems);
RE.editor.addEventListener("click", function(e) {
RE.enabledEditingItems
RE.sendElementNameToNative()
var s = document.getSelection()
var isNeedRemoveR = RE.recursion(e.target)
if (isNeedRemoveR && s.rangeCount) {
s.removeAllRanges()
}
});
document.addEventListener("selectionchange", function(e) {
RE.sendElementNameToNative()
});
RE.recursion = function(dom) {
var parenDom = dom.parentElement
if (parenDom && parenDom instanceof Element &&
typeClassList.indexOf(parenDom.className) > -1) {
return parenDom
} else if(parenDom && parenDom instanceof Element &&
typeClassList.indexOf(parenDom.className) === -1 && parenDom.nodeName !== 'BODY') {
return RE.recursion(parenDom)
} else {
return null
}
}
// 返回组件标签 多个标签以"空格"划分
RE.sendElementNameToNative = function() {
if (window.getSelection) {
var selection = window.getSelection()
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
var container = range.startContainer;
var elements = " " + container.localName + " ";
var parentElement;
while(true) {
if(parentElement != null) {
parentElement = parentElement.parentElement
} else {
parentElement = container.parentElement
}
if (parentElement == null || parentElement.localName == null) {
break;
}
elements = elements + " " + parentElement.localName + " "
}
// console.log(elements)
window.OnCursorChangeListener.onElements(elements);
}
}
}

View File

@ -75,7 +75,7 @@ public class AppUncaughtHandler implements UncaughtExceptionHandler {
// 保存log到本地
public static void saveLocalLog(Context context, Throwable ex) {
String errorMsg = Log.getStackTraceString(ex);
Config.setExceptionMsg(context, errorMsg);
Config.setExceptionMsg(errorMsg);
// 保存到本地
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault());

View File

@ -165,7 +165,8 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
, StringUtils.buildString("", manufacturer, " - ", model, "")
, "知道了", "重新登录"
, null
, () -> startActivity(LoginActivity.getIntent(BaseActivity.this))
, () -> startActivity(LoginActivity.getIntent(BaseActivity.this,
"你的账号已在另外一台设备登录多设备-重新登录"))
);
mBaseHandler.postDelayed(() -> mIsExistLogoutDialog = false, 5000);
} catch (JSONException e) {

View File

@ -0,0 +1,239 @@
package com.gh.base
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.webkit.JavascriptInterface
import butterknife.OnClick
import com.gh.common.view.RichEditor
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.qa.editor.GameActivity
import com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity
import com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.qa.entity.EditorInsertEntity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import com.lightgame.view.CheckableImageView
import kotterknife.bindView
abstract class BaseRichEditorActivity : BaseActivity() {
val mRichEditor by bindView<RichEditor>(R.id.rich_editor)
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)
private val mEditorFontBold by bindView<CheckableImageView>(R.id.editor_font_bold)
private val mEditorFontItalic by bindView<CheckableImageView>(R.id.editor_font_italic)
private val mEditorFontStrikeThrough by bindView<CheckableImageView>(R.id.editor_font_strikethrough)
private val mEditorParagraphH1 by bindView<CheckableImageView>(R.id.editor_paragraph_h1)
private val mEditorParagraphH2 by bindView<CheckableImageView>(R.id.editor_paragraph_h2)
private val mEditorParagraphH3 by bindView<CheckableImageView>(R.id.editor_paragraph_h3)
private val mEditorParagraphH4 by bindView<CheckableImageView>(R.id.editor_paragraph_h4)
private val mEditorParagraphQuote by bindView<CheckableImageView>(R.id.editor_paragraph_quote)
private val mEditorFontContainer by bindView<View>(R.id.editor_font_container)
private val mEditorParagraphContainer by bindView<View>(R.id.editor_paragraph_container)
private val mEditorLinkContainer by bindView<View>(R.id.editor_link_container)
private val mEditorInsertDetail by bindView<View>(R.id.editor_insert_detail)
private var mCurrentParagraphStyle = ""
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != Activity.RESULT_OK) return
var insertData: EditorInsertEntity? = null
when (requestCode) {
INSERT_ANSWER_CODE -> {
val answer = data?.getParcelableExtra<AnswerEntity>(AnswerEntity::class.java.simpleName)
if (answer != null) insertData = EditorInsertEntity.transform(answer)
}
INSERT_ARTICLE_CODE -> {
val article = data?.getParcelableExtra<ArticleEntity>(ArticleEntity::class.java.simpleName)
if (article != null) insertData = EditorInsertEntity.transform(article)
}
INSERT_GAME_CODE -> {
val game = data?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
if (game != null) insertData = EditorInsertEntity.transform(game)
}
}
if (mCurrentParagraphStyle == ELEMENT_PARAGRAPH_QUOTE || mCurrentParagraphStyle == ELEMENT_PARAGRAPH_P) {
mRichEditor.insertHtml("&nbsp")
if (mCurrentParagraphStyle == ELEMENT_PARAGRAPH_QUOTE) mRichEditor.formatBlock()
}
mRichEditor.insertCustomStyleLink(insertData)
}
@SuppressLint("AddJavascriptInterface")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mRichEditor.setPadding(20, 15, 20, 15)
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
mRichEditor.addJavascriptInterface(OnCursorChangeListener(), "OnCursorChangeListener")
}
@OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_paragraph,
R.id.editor_font_bold, R.id.editor_font_italic, R.id.editor_font_strikethrough,
R.id.editor_paragraph_h1, R.id.editor_paragraph_h2, R.id.editor_paragraph_h3,
R.id.editor_paragraph_h4, R.id.editor_font_container, R.id.editor_paragraph_container,
R.id.editor_paragraph_quote, R.id.editor_link_answer, R.id.editor_link_article,
R.id.editor_link_game)
fun onRichClick(view: View) {
when (view.id) {
R.id.editor_font -> {
mEditorFont.isChecked = !mEditorFont.isChecked
mEditorParagraph.isChecked = false
mEditorLink.isChecked = false
mEditorFontContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorParagraphContainer.visibility = if (!mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorLinkContainer.visibility = if (!mEditorFont.isChecked) View.VISIBLE else View.GONE
mEditorInsertDetail.visibility = mEditorFontContainer.visibility
}
R.id.editor_paragraph -> {
mEditorParagraph.isChecked = !mEditorParagraph.isChecked
mEditorFont.isChecked = false
mEditorLink.isChecked = false
mEditorParagraphContainer.visibility = if (mEditorParagraph.isChecked) View.VISIBLE else View.GONE
mEditorFontContainer.visibility = if (!mEditorParagraph.isChecked) View.VISIBLE else View.GONE
mEditorLinkContainer.visibility = if (!mEditorParagraph.isChecked) View.VISIBLE else View.GONE
mEditorInsertDetail.visibility = mEditorParagraphContainer.visibility
}
R.id.editor_link -> {
mEditorLink.isChecked = !mEditorLink.isChecked
mEditorFont.isChecked = false
mEditorParagraph.isChecked = false
mEditorLinkContainer.visibility = if (mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorParagraphContainer.visibility = if (!mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorFontContainer.visibility = if (!mEditorLink.isChecked) View.VISIBLE else View.GONE
mEditorInsertDetail.visibility = mEditorLinkContainer.visibility
}
R.id.editor_font_bold -> {
mEditorFontBold.isChecked = !mEditorFontBold.isChecked
mRichEditor.setBold()
}
R.id.editor_font_italic -> {
mEditorFontItalic.isChecked = !mEditorFontItalic.isChecked
mRichEditor.setItalic()
}
R.id.editor_font_strikethrough -> {
mEditorFontStrikeThrough.isChecked = !mEditorFontStrikeThrough.isChecked
mRichEditor.setStrikeThrough()
}
R.id.editor_paragraph_h1 -> {
if (mEditorParagraphH1.isChecked) {
mRichEditor.formatBlock()
} else {
mRichEditor.setHeading(1)
}
mEditorParagraphH1.isChecked = !mEditorParagraphH1.isChecked
}
R.id.editor_paragraph_h2 -> {
if (mEditorParagraphH2.isChecked) {
mRichEditor.formatBlock()
} else {
mRichEditor.setHeading(2)
}
mEditorParagraphH2.isChecked = !mEditorParagraphH2.isChecked
}
R.id.editor_paragraph_h3 -> {
if (mEditorParagraphH3.isChecked) {
mRichEditor.formatBlock()
} else {
mRichEditor.setHeading(3)
}
mEditorParagraphH3.isChecked = !mEditorParagraphH3.isChecked
}
R.id.editor_paragraph_h4 -> {
if (mEditorParagraphH4.isChecked) {
mRichEditor.formatBlock()
} else {
mRichEditor.setHeading(4)
}
mEditorParagraphH4.isChecked = !mEditorParagraphH4.isChecked
}
R.id.editor_paragraph_quote -> {
if (mEditorParagraphQuote.isChecked) {
mRichEditor.formatBlock()
} else {
mRichEditor.setBlockquote()
}
mEditorParagraphQuote.isChecked = !mEditorParagraphQuote.isChecked
}
R.id.editor_link_answer -> {
startActivityForResult(InsertAnswerWrapperActivity.getIntent(this), INSERT_ANSWER_CODE)
}
R.id.editor_link_article -> {
startActivityForResult(InsertArticleWrapperActivity.getIntent(this), INSERT_ARTICLE_CODE)
}
R.id.editor_link_game -> {
startActivityForResult(GameActivity.getIntent(this), INSERT_GAME_CODE)
}
}
}
private inner class OnCursorChangeListener {
@JavascriptInterface
fun onElements(elements: String) {
Utils.log("-----------------------")
Utils.log(elements)
Utils.log(mRichEditor.html)
Utils.log("-----------------------")
mCurrentParagraphStyle = when {
elements.contains(ELEMENT_PARAGRAPH_QUOTE) -> ELEMENT_PARAGRAPH_QUOTE
elements.contains(ELEMENT_PARAGRAPH_P) -> ELEMENT_PARAGRAPH_P
else -> ""
}
mBaseHandler.post {
mEditorFontBold.isChecked = elements.contains(ELEMENT_NAME_BOLD)
mEditorFontItalic.isChecked = elements.contains(ELEMENT_NAME_ITALIC)
mEditorFontStrikeThrough.isChecked = elements.contains(ELEMENT_NAME_STRIKE)
mEditorParagraphH1.isChecked = elements.contains(ELEMENT_PARAGRAPH_H1)
mEditorParagraphH2.isChecked = elements.contains(ELEMENT_PARAGRAPH_H2)
mEditorParagraphH3.isChecked = elements.contains(ELEMENT_PARAGRAPH_H3)
mEditorParagraphH4.isChecked = elements.contains(ELEMENT_PARAGRAPH_H4)
mEditorParagraphQuote.isChecked = elements.contains(ELEMENT_PARAGRAPH_QUOTE)
}
}
}
private inner class OnPasteListener {
@JavascriptInterface
fun onPaste() {
val clipboard =
HaloApp.getInstance().application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipText = clipboard.text.toString()
if (!TextUtils.isEmpty(clipText)) {
// 替换换行符号否则 插入失败
val text = clipText.replace("[ ]".toRegex(), "&nbsp;").replace("[\r\n]".toRegex(), "<br/>")
mBaseHandler.post { mRichEditor.insertHtml(text) }
}
}
}
companion object {
const val ELEMENT_NAME_BOLD = " b "
const val ELEMENT_NAME_ITALIC = " i "
const val ELEMENT_NAME_STRIKE = " strike "
const val ELEMENT_PARAGRAPH_H1 = " h1 "
const val ELEMENT_PARAGRAPH_H2 = " h2 "
const val ELEMENT_PARAGRAPH_H3 = " h3 "
const val ELEMENT_PARAGRAPH_H4 = " h4 "
const val ELEMENT_PARAGRAPH_P = " p "
const val ELEMENT_PARAGRAPH_QUOTE = " blockquote "
const val INSERT_ANSWER_CODE = 411
const val INSERT_ARTICLE_CODE = 412
const val INSERT_GAME_CODE = 413
}
}

View File

@ -101,6 +101,12 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
return mToolbar.getMenu().findItem(res);
}
public void clearMenu() {
if (mToolbar != null) {
mToolbar.getMenu().clear();
}
}
public Menu getMenu() {
return mToolbar.getMenu();
}

View File

@ -7,7 +7,7 @@ import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.GameDetailActivity;
import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.subject.refactor.SubjectActivity;
import com.gh.gamecenter.subject.SubjectActivity;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;

View File

@ -15,45 +15,47 @@ import android.view.View
import com.gh.common.notifier.Notifier
import com.gh.common.util.DataUtils
import com.gh.common.util.EntranceUtils
import com.gh.common.util.PackageUtils
import com.gh.common.util.StringUtils
import com.gh.gamecenter.BuildConfig
import com.gh.common.util.toObject
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.PushEntity
import com.gh.gamecenter.entity.PushMessageEntity
import com.gh.gamecenter.entity.PushMessageUnreadEntity
import com.gh.gamecenter.entity.PushNotificationEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.message.MessageUnreadRepository
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
import com.gh.gamecenter.receiver.UmengMessageReceiver
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_CLICK
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_REMOVE
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.Gson
import com.halo.assistant.HaloApp
import com.umeng.message.UmengMessageService
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.android.agoo.common.AgooConstants
import org.json.JSONObject
import retrofit2.HttpException
import java.util.*
class GHUmengNotificationService : UmengMessageService() {
companion object {
const val ACTION_UMENG = "com.gh.gamecenter.UMENG"
const val MESSAGE_FROM_SYSTEM = "message_from_system"
const val HALO_MESSAGE_DIALOG = "HALO_MESSAGE_DIALOG"
const val HALO_MESSAGE_CENTER = "HALO_MESSAGE_CENTER"
const val ANSWER = "answer"
const val FOLLOW_QUESTION = "follow_question"
const val NOTIFICATION_ID = 2015
const val DISPLAY_TYPE_NOTIFICATION = "notification"
const val DISPLAY_TYPE_CUSTOM = "custom"
const val MESSAGE_ID = "message_id"
const val PUSH_ID = "push_id"
}
val notificationTags = arrayOf("GH_UMENG_TAG_1", "GH_UMENG_TAG_2", "GH_UMENG_TAG_3")
@ -64,7 +66,7 @@ class GHUmengNotificationService : UmengMessageService() {
val isMessageFromSystem = intent.getBooleanExtra(MESSAGE_FROM_SYSTEM, false)
try {
val pushData = gson.fromJson(message, PushEntity::class.java)
val pushData = message.toObject<PushEntity>()
pushData?.let { handlePushData(context, it, message, isMessageFromSystem) }
} catch (e: Exception) {
e.printStackTrace()
@ -77,10 +79,10 @@ class GHUmengNotificationService : UmengMessageService() {
if (pushData.displayType == DISPLAY_TYPE_NOTIFICATION) {
// 其它类型的透传信息
// 显示到通知栏
val msg = gson.fromJson(message, PushNotificationEntity::class.java)
val msg = message.toObject<PushNotificationEntity>()
val data = msg?.extra?.data
// 系统推送,直接处理跳转
// 系统推送(非自定义信息),直接处理跳转
if (isMessageFromSystem) {
val intent = Intent()
intent.setClass(context, UmengMessageReceiver::class.java)
@ -91,45 +93,52 @@ class GHUmengNotificationService : UmengMessageService() {
return
}
// 判断是否过滤该消息
if (validatePush(data?.condition)) {
val clickIntent = Intent()
val removeIntent = Intent()
clickIntent.setClass(context, UmengMessageReceiver::class.java)
clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
removeIntent.setClass(context, UmengMessageReceiver::class.java)
removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(context, "Halo_Push")
.setSmallIcon(R.drawable.ic_notification)
.setTicker(pushData.body?.ticker)
.setContentTitle(pushData.body?.title)
.setContentText(pushData.body?.text)
.setContentIntent(clickPendingIntent)
.setDeleteIntent(deletePendingIntent)
.build()
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
// 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
if (data != null
&& data.link?.target == "system"
&& !UserManager.getInstance().isLoggedIn) {
return
}
val clickIntent = Intent()
val removeIntent = Intent()
clickIntent.setClass(context, UmengMessageReceiver::class.java)
clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
clickIntent.putExtra(MESSAGE_ID, msg?.msgId)
clickIntent.putExtra(PUSH_ID, data?.pushId)
clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
removeIntent.setClass(context, UmengMessageReceiver::class.java)
removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(context, "Halo_Push")
.setSmallIcon(R.drawable.ic_notification)
.setTicker(pushData.body?.ticker)
.setContentTitle(pushData.body?.title)
.setContentText(pushData.body?.text)
.setContentIntent(clickPendingIntent)
.setDeleteIntent(deletePendingIntent)
.build()
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
} else {
if (HALO_MESSAGE_DIALOG == pushData.body?.custom) {
if (UserManager.getInstance().isLoggedIn
&& HALO_MESSAGE_DIALOG == pushData.body?.custom) {
// 回答了问题或者关注了问题的消息
val msg = gson.fromJson(message, PushMessageEntity::class.java)
val data = msg?.extra?.data
@ -156,8 +165,25 @@ class GHUmengNotificationService : UmengMessageService() {
bundle.putString(EntranceUtils.KEY_TO, AnswerDetailActivity::class.java.name)
EntranceUtils.jumpActivity(context, bundle)
DataUtils.onMtaEvent(context, "消息弹窗",
type, "Does not contains any parameter.")
DataUtils.onMtaEvent(context, "消息弹窗", type, "Does not contains any parameter.")
// 标记已读
val jsonObject = JSONObject()
jsonObject.put("type", type)
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
RetrofitManager.getInstance(application).api.postMessageRead(UserManager.getInstance().userId, data?.id, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
super.onResponse(response)
MessageUnreadRepository.loadMessageUnreadData()
}
override fun onFailure(e: HttpException?) {
e?.printStackTrace()
}
})
Notifier.hide()
})
@ -173,37 +199,6 @@ class GHUmengNotificationService : UmengMessageService() {
}
}
private fun validatePush(condition: PushNotificationEntity.Data.Condition?): Boolean {
if (condition == null) return true
// 校验渠道是否匹配
condition.ghzs?.channel?.let {
if (it.isNotEmpty() && it != HaloApp.getInstance().channel) {
return false
}
}
// 校验光环版本版本是否匹配
condition.ghzs?.version?.let {
if (it.isNotEmpty() && !BuildConfig.VERSION_NAME.contains(it)) {
return false
}
}
// 校验已安装的应用里是否存在条件的包名
if (condition.packageName.isNotEmpty()) {
val installedPackageList = PackageUtils.getAllPackageName(HaloApp.getInstance().application)
for (packageName in installedPackageList) {
if (condition.packageName == packageName) {
return true
}
}
return false
}
return true
}
/**
* 规则:最多三条消息,以旧换新
*

View File

@ -43,6 +43,8 @@ import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
public abstract class BaseFragment<T> extends Fragment implements OnRequestCallBackListener<T>,
View.OnClickListener, OnListClickListener, OnTitleClickListener {
public static final int RESULT_REFRESH = 9528;
protected View mCachedView;
protected boolean isEverPause;
@ -130,10 +132,10 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
initView(mCachedView);
}
//TODO 尴尬,必须的有subscribe才能register
// 必须的有subscribe才能register
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onDummyEvent(EBMiPush push) {
//
}
@Nullable

View File

@ -17,5 +17,17 @@ object AppExecutor {
override fun execute(command: Runnable) {
mainThreadHandler.post(command)
}
fun executeWithDelay(command: Runnable, delay: Long) {
mainThreadHandler.postDelayed(command, delay)
}
}
}
fun runOnIoThread(f: () -> Unit) {
AppExecutor.ioExecutor.execute(f)
}
fun runOnUiThread(f: () -> Unit) {
AppExecutor.uiExecutor.execute(f)
}

View File

@ -1,14 +1,16 @@
package com.gh.common
import android.annotation.SuppressLint
import android.preference.PreferenceManager
import com.gh.base.GHUmengNotificationService
import com.gh.common.constant.Config
import com.gh.common.exposure.meta.MetaUtil
import com.gh.common.util.edit
import com.gh.common.util.toJson
import com.gh.common.util.toObject
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.entity.AliasEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.Gson
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import com.umeng.commonsdk.UMConfigure
@ -24,7 +26,6 @@ import org.json.JSONObject
object PushManager {
var gson = Gson()
var deviceToken: String? = ""
var previousAlias: AliasEntity? = null
var application = HaloApp.getInstance().application
@ -52,7 +53,7 @@ object PushManager {
registerDevice()
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(application).getString(SP_PUSH_ALIAS, "")
previousAlias = gson.fromJson(aliasInSp, AliasEntity::class.java)
previousAlias = aliasInSp.toObject()
if (previousAlias == null) {
getAndSetAlias()
@ -77,6 +78,7 @@ object PushManager {
})
}
@SuppressLint("CheckResult")
@JvmStatic
fun getAndSetAlias() {
if (deviceToken.isNullOrEmpty()) {
@ -112,7 +114,7 @@ object PushManager {
previousAlias = alias
PreferenceManager.getDefaultSharedPreferences(application).edit {
putString(SP_PUSH_ALIAS, gson.toJson(previousAlias))
putString(SP_PUSH_ALIAS, previousAlias?.toJson())
}
pushAgent.setAlias(alias.alias, alias.aliasType) { b, s ->

View File

@ -13,6 +13,8 @@ import java.util.concurrent.Executors
*/
class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
constructor() : this(null, null)
constructor(fragment: Fragment) : this(fragment, null)
constructor(activity: Activity) : this(null, activity)
@ -21,6 +23,9 @@ class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
var elapsedTime: Int = 0
var timeout: Int = 0
var timeoutCallback: TimeoutCallback? = null
init {
activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(a: Activity?) {
@ -76,12 +81,19 @@ class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
}, false)
}
private fun resumeCounting() {
fun resumeCounting() {
isWorking = true
TimeElapsedThreadHolder.threadService.execute {
while (isWorking) {
try {
elapsedTime++
if (timeout != 0 && timeout == elapsedTime) {
timeoutCallback?.run {
AppExecutor.uiExecutor.execute {
onTimeout()
}
}
}
Thread.sleep(1000)
} catch (e: Exception) {
e.printStackTrace()
@ -90,7 +102,11 @@ class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
}
}
private fun pauseCounting() {
fun resetCounting() {
elapsedTime = 0
}
fun pauseCounting() {
isWorking = false
}
@ -98,4 +114,8 @@ class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
object TimeElapsedThreadHolder {
val threadService = Executors.newSingleThreadExecutor()
}
interface TimeoutCallback {
fun onTimeout()
}

View File

@ -1,12 +1,14 @@
package com.gh.common.constant;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.SPUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.NewsEntity;
import com.gh.gamecenter.entity.SettingsEntity;
@ -42,45 +44,46 @@ public class Config {
public static final String UMENG_APPKEY = BuildConfig.UMENG_APPKEY;
public static final String UMENG_MESSAGE_SECRET = BuildConfig.UMENG_MESSAGE_SECRET;
public static final String BUGLY_APPID = BuildConfig.BUGLY_APPID;
public static final String PATCH_VERSION_NAME = BuildConfig.PATCH_VERSION_NAME; // 补丁包版本 对应关于->版本号 使用PackageUtils.getPatchVersionName()
// http://www.ghzs666.com/article/${articleId}.html
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // TODO ghzs/ghzs666 统一
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
public static final String PATCHES = "patches";
private static String SETTINGS_KEY = "settingsKey";
private static SettingsEntity mSettingsEntity;
public static final String FIX_DOWNLOAD_KEY = "isFixDownload";
public static final String FIX_PLUGIN_KEY = "isFixPlugin";
public static final String FIX_ARTICLE_KEY = "isFixArticle";
public static final String FIX_COMMUNITY_KEY = "isFixCommunity";
public static boolean isShow() {
if (PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication())
.getBoolean("isFixDownload", false)) return true;
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (!isExistDownloadFilter()) return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if ("all".equals(entity.getGame())) {
if (entity.isPluginfy() && "normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
if (entity.getPluginfy() && "normal".equals(entity.getPolicy()) && filterTime(entity.getTime())) {
return true;
}
}
}
return false;
}
public static String getExceptionMsg(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
return sp.getString("errMsg", null);
public static String getExceptionMsg() {
return getPreferences().getString("errMsg", null);
}
public static void setExceptionMsg(Context context, String errMsg) {
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("errMsg", errMsg).apply();
public static void setExceptionMsg(String errMsg) {
SPUtils.setString(getPreferences(), "errMsg", errMsg); //先用apply(),保存不了再用commit() 9.0机型保存不了信息
}
public static boolean isShowDownload(String gameId) {
if (PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication())
.getBoolean("isFixDownload", false)) return true;
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
return false;
@ -104,18 +107,25 @@ public class Config {
public static boolean isShowPlugin(String gameId) {
SharedPreferences preferences = getPreferences();
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
if (isFixPlugin) return true;
if (TextUtils.isEmpty(gameId) || !isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if (gameId.equals(entity.getGame())) {
if (entity.isPluginfy() && filterTime(entity.getTime())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
return true;
} else {
return false;
}
} else if ("all".equals(entity.getGame())) {
if (entity.isPluginfy() && filterTime(entity.getTime())) {
}
if ("all".equals(entity.getGame())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
preferences.edit().putBoolean(FIX_PLUGIN_KEY, true).apply();
return true;
}
}
@ -125,12 +135,17 @@ public class Config {
}
public static boolean isShowPlugin() {
SharedPreferences preferences = getPreferences();
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
if (isFixPlugin) return true;
if (!isExistDownloadFilter())
return false;
for (SettingsEntity.Download entity : getSettings().getDownload()) {
if ("all".equals(entity.getGame())) {
if (entity.isPluginfy() && filterTime(entity.getTime())) {
if (entity.getPluginfy() && filterTime(entity.getTime())) {
preferences.edit().putBoolean(FIX_PLUGIN_KEY, true).apply();
return true;
}
}
@ -152,19 +167,20 @@ public class Config {
}
public static void setSettings(SettingsEntity settingsEntity) {
SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit();
edit.putString(SETTINGS_KEY, GsonUtils.getInstance().toJson(settingsEntity)).apply();
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
// 加载完设置后刷新下
PackageHelper.initList();
}
@Nullable
public static SettingsEntity getSettings() {
if (mSettingsEntity == null) {
try {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
String json = sp.getString(SETTINGS_KEY, null);
String json = getPreferences().getString(SETTINGS_KEY, null);
if (!TextUtils.isEmpty(json)) {
mSettingsEntity = GsonUtils.getInstance().fromJsonBean(json, SettingsEntity.class);
mSettingsEntity = GsonUtils.fromJson(json, SettingsEntity.class);
}
} catch (Exception e) {
e.printStackTrace();
@ -194,4 +210,27 @@ public class Config {
}
}
public static SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
}
public static boolean isExistHideFunction() {
SharedPreferences preferences = getPreferences();
if (!preferences.getBoolean(FIX_DOWNLOAD_KEY, false)) return true;
if (!preferences.getBoolean(FIX_PLUGIN_KEY, false)) return true;
if (!preferences.getBoolean(FIX_COMMUNITY_KEY, false)) return true;
if (!preferences.getBoolean(FIX_ARTICLE_KEY, false)) return true;
return false;
}
public static void fixHideFunction() {
SharedPreferences preferences = PreferenceManager.
getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(Config.FIX_DOWNLOAD_KEY, true);
editor.putBoolean(Config.FIX_ARTICLE_KEY, true);
editor.putBoolean(Config.FIX_COMMUNITY_KEY, true);
editor.putBoolean(Config.FIX_PLUGIN_KEY, true);
editor.apply();
}
}

View File

@ -47,4 +47,5 @@ public class Constants {
//评论 cd间隔
public static final int COMMENT_CD = 60 * 1000;
public static final String[] REPORT_LIST = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它"};
}

View File

@ -26,13 +26,13 @@ public class ItemViewType {
public static final int GAME_PLUGIN = 18; // 游戏插件模块
public static final int ASK_REFRESH = 19; // 问答精选 刷新
public static final int ITEM_EMPTY = 20;
public static final int ASK_CONCERN = 21; // 问答精选 关注
/**
* 普通列表
*/
public static final int ITEM_BODY = 100;
public static final int ITEM_FOOTER = 101;
public static final int ITEM_TOP = 102;
public static final int ITEM_HEADER = 102;
}

View File

@ -23,10 +23,10 @@ import com.gh.common.util.DisplayUtils;
import com.gh.common.util.GameUtils;
import com.gh.common.util.GameViewUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.KaiFuUtils;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.NumberUtils;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.PlatformUtils;
import com.gh.common.util.StringUtils;
import com.gh.common.view.DownloadDialog;
import com.gh.common.view.DownloadProgressBar;
@ -41,7 +41,7 @@ import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.KaiFuCalendarEntity;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.manager.PackageManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
@ -63,12 +63,16 @@ public class BindingAdapters {
ImageUtils.displayIcon(view, imageUrl);
}
@BindingAdapter("imageUrl")
public static void loadImage(SimpleDraweeView view, String imageUrl) {
ImageUtils.display(view, imageUrl);
}
@BindingAdapter("setTextSize")
public static void setTextSize(TextView view, int number) {
view.setTextSize(number);
}
@BindingAdapter({"addDetailKaiFuView", "addDetailKaiFuViewListener", "isReadyPatch"})
public static void addDetailKaiFuView(LinearLayout view, List<KaiFuCalendarEntity> list
, OnViewClickListener listener, Boolean isReadyPatch) {
@ -344,7 +348,7 @@ public class BindingAdapters {
case neterror:
case waiting:
progressBar.setText(R.string.downloading);
if (downloadEntity.isPluggable() && PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
if (downloadEntity.isPluggable() && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
progressBar.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN);
} else {
progressBar.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL);
@ -353,7 +357,7 @@ public class BindingAdapters {
case done:
progressBar.setText(R.string.install);
if (downloadEntity.isPluggable()
&& PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
&& PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
progressBar.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
} else {
progressBar.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
@ -456,8 +460,8 @@ public class BindingAdapters {
View testView = LayoutInflater.from(layout.getContext()).inflate(R.layout.game_test_label, null);
TextView testType = testView.findViewById(R.id.test_type);
TextView testTime = testView.findViewById(R.id.test_time);
String type = gameEntity.getTest().getType();
KaiFuUtils.setKaiFuType(testType, type);
testType.setText(gameEntity.getTest().getType());
testType.setBackgroundColor(ContextCompat.getColor(layout.getContext(), R.color.tag_yellow));
if (gameEntity.getTest().getStart() == 0) {
testTime.setVisibility(View.GONE);
@ -479,4 +483,16 @@ public class BindingAdapters {
layout.setRefreshing(false);
}
}
@BindingAdapter({"setGameName", "isShowPlatform"})
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform) {
if (isShowPlatform && game.getApk().size() > 0) {
view.setText(String.format("%s - %s", game.getName(),
PlatformUtils.getInstance(view.getContext()).getPlatformName(
game.getApk().get(0).getPlatform())));
} else {
view.setText(game.getName());
}
}
}

View File

@ -2,7 +2,7 @@ package com.gh.common.exposure
import android.arch.persistence.room.TypeConverter
import com.gh.common.exposure.meta.Meta
import com.google.gson.Gson
import com.gh.common.util.GsonUtils
import java.util.*
import kotlin.collections.ArrayList
@ -10,32 +10,32 @@ class ExposureConverters {
@TypeConverter
fun convertPayload2String(any: ExposureEntity): String {
return Gson().toJson(any)
return GsonUtils.toJson(any)
}
@TypeConverter
fun convertString2Payload(string: String): ExposureEntity {
return Gson().fromJson(string, ExposureEntity::class.java)
return GsonUtils.fromJson(string, ExposureEntity::class.java)
}
@TypeConverter
fun convertSource2String(sourceList: List<ExposureSource>): String {
return Gson().toJson(sourceList)
return GsonUtils.toJson(sourceList)
}
@TypeConverter
fun convertString2Source(sourceList: String): List<ExposureSource> {
return ArrayList(Arrays.asList(Gson().fromJson(sourceList, Array<ExposureSource>::class.java))) as List<ExposureSource>
return ArrayList(Arrays.asList(GsonUtils.fromJson(sourceList, Array<ExposureSource>::class.java))) as List<ExposureSource>
}
@TypeConverter
fun convertETrace2String(sourceList: List<ExposureEvent>?): String {
return Gson().toJson(sourceList)
return GsonUtils.toJson(sourceList)
}
@TypeConverter
fun convertStringToETrace(sourceList: String): List<ExposureEvent> {
return ArrayList(Arrays.asList(Gson().fromJson(sourceList, Array<ExposureEvent>::class.java))) as List<ExposureEvent>
return ArrayList(Arrays.asList(GsonUtils.fromJson(sourceList, Array<ExposureEvent>::class.java))) as List<ExposureEvent>
}
@TypeConverter
@ -50,12 +50,12 @@ class ExposureConverters {
@TypeConverter
fun convertMeta2String(any: Meta): String {
return Gson().toJson(any)
return GsonUtils.toJson(any)
}
@TypeConverter
fun convertString2Meta(string: String): Meta {
return Gson().fromJson(string, Meta::class.java)
return GsonUtils.fromJson(string, Meta::class.java)
}
}

View File

@ -15,7 +15,7 @@ import java.util.*
@Parcelize
@Entity(tableName = "exposureEvent")
data class ExposureEvent(
val payload: ExposureEntity,
var payload: ExposureEntity,
val source: List<ExposureSource>,
var eTrace: List<ExposureEvent>? = arrayListOf(),
val event: ExposureType,
@ -26,7 +26,7 @@ data class ExposureEvent(
companion object {
fun createEvent(gameEntity: GameEntity?, source: List<ExposureSource>, eTrace: List<ExposureEvent>?, event: ExposureType): ExposureEvent {
return ExposureEvent(
ExposureEntity(gameId = gameEntity?.id,
payload = ExposureEntity(gameId = gameEntity?.id,
gameName = gameEntity?.name,
sequence = gameEntity?.sequence,
platform = gameEntity?.platform,

View File

@ -4,7 +4,6 @@ import android.arch.persistence.room.*
@Dao
interface ExposureEventDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertMany(eventList: List<ExposureEvent>)

View File

@ -8,9 +8,6 @@ import io.reactivex.functions.Consumer
/**
* Exposure Event Listener for RecyclerView
*
* TODO 1. Pull down refresh change in first page without scroll down action
* TODO 2. Item change not triggered by user scroll action (vm data change etc.)
*/
class ExposureListener(var fragment: Fragment, var exposable: IExposable) : RecyclerView.OnScrollListener() {
@ -58,8 +55,8 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
try {
exposable.getEventByPosition(pos)?.let { eventList.add(it) }
exposable.getEventListByPosition(pos)?.let { eventList.addAll(it) }
} catch (e: Exception) {
e.printStackTrace()
} catch (ignore: Exception) {
// Just ignore the error.
}
}

View File

@ -1,20 +1,24 @@
package com.gh.common.exposure
import android.app.Application
import com.aliyun.sls.android.sdk.LogException
import com.aliyun.sls.android.sdk.model.LogGroup
import com.gh.common.exposure.meta.MetaUtil
import com.gh.common.exposure.time.TimeUtil
import com.gh.common.util.toJson
import com.gh.gamecenter.BuildConfig
import com.gh.loghub.LgLOG
import com.gh.loghub.LoghubHelper
import com.google.gson.Gson
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.util.concurrent.Executors
import kotlin.concurrent.fixedRateTimer
/**
* ExposureManager tool to commit logs to aliyun loghub
* TODO handle logs that failed to be committed multiple times
* A handful tool for committing logs to aliyun loghub.
*
* 如何简单地统计列表中每个 item 的曝光事件?
*
* 1. Adapter 实现 IExposable 接口,在 BindView 阶段更新 ExposureEventExposureEvent 供 getEventByPosition(pos) 方法获取用
* 2. 构建一个 ExposureListener 并作为入参添加至 recyclerview 的 Scroll 回调中
* 3. 没了
*/
object ExposureManager {
@ -22,160 +26,115 @@ object ExposureManager {
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 var LOG_STORE = BuildConfig.EXPOSURE_REPO
private val loghubHelper = LoghubHelper.getInstance()
private var loghubHelper = LoghubHelper.getInstance()
private lateinit var db: ExposureEventDao
private val storeSet = hashSetOf<ExposureEvent>()
private val storeOpThread = Executors.newSingleThreadExecutor()
private val gson = Gson()
// exposureCache 用来过滤掉具有相同 id 的曝光事件,避免重复发送事件
private val exposureCache = FixedSizeLinkedHashSet<String>(100)
private val exposureSet = hashSetOf<ExposureEvent>()
private val exposureDao by lazy { ExposureDatabase.buildDatabase(HaloApp.getInstance().application).logHubEventDao() }
private val exposureExecutor = Executors.newSingleThreadExecutor()
private val exposureCache = FixedSizeLinkedHashSet<String>(20)
/**
* Must be called early to init object then real use (for example in Application)
*/
@JvmStatic
fun init(application: Application) {
MetaUtil.init(application)
fun init() {
TimeUtil.init()
loghubHelper.init(ENDPOINT, PROJECT, LOG_STORE) { TimeUtil.currentTimeMillis() }
db = ExposureDatabase.buildDatabase(application).logHubEventDao()
loghubHelper.init(HaloApp.getInstance().application, ENDPOINT, PROJECT, LOG_STORE) { TimeUtil.currentTimeMillis() }
storeOpThread.execute {
val eventList = db.getAll()
storeSet.addAll(eventList)
exposureExecutor.execute {
val eventList = exposureDao.getAll()
exposureSet.addAll(eventList)
}
fixedRateTimer(name = "ExposureManager-Store-Checker", initialDelay = 500, period = STORE_FORCE_UPLOAD_PERIOD) {
checkAndUploadFromDatabase(true)
commitSavedExposureEvent(true)
}
}
/**
* Log an Event
* Log a single exposure event.
*/
fun log(event: ExposureEvent, uploadImmediately: Boolean = false) {
when (uploadImmediately) {
false -> store(event)
true -> upload(event)
}
}
/**
* Log Many Events
*/
fun log(eventList: List<ExposureEvent>, uploadImmediately: Boolean = false) {
when (uploadImmediately) {
false -> store(eventList)
true -> upload(eventList)
}
}
/**
* Store an Event to storeSet, upload when storeSet size exceeds STORE_SIZE
*/
private fun store(event: ExposureEvent) {
storeOpThread.execute {
fun log(event: ExposureEvent) {
exposureExecutor.execute {
if (!exposureCache.contains(event.id)) {
storeSet.add(event)
db.insert(event)
exposureCache.add(event.id)
// Catch `android.database.sqlite.SQLiteFullException: database or disk is full` exception.
try {
exposureSet.add(event)
exposureDao.insert(event)
exposureCache.add(event.id)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
Utils.log("Exposure", "遇到重复曝光事件,自动过滤 ${event.id} - ${event.payload.gameName}")
}
checkAndUploadFromDatabase()
}
}
/**
* Store Many Events to storeSet, upload when storeSet size exceeds STORE_SIZE
* Log a collection of exposure event.
*/
private fun store(eventList: List<ExposureEvent>) {
storeOpThread.execute {
fun log(eventList: List<ExposureEvent>) {
exposureExecutor.execute {
for (event in eventList) {
if (!exposureCache.contains(event.id)) {
storeSet.add(event)
db.insert(event)
exposureCache.add(event.id)
// Catch `android.database.sqlite.SQLiteFullException: database or disk is full` exception.
try {
exposureSet.add(event)
exposureDao.insert(event)
exposureCache.add(event.id)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
Utils.log("Exposure", "遇到重复曝光事件,自动过滤 ${event.id} - ${event.payload.gameName}")
}
}
commitSavedExposureEvent()
}
}
/**
* Upload an Event
*/
private fun upload(event: ExposureEvent) {
storeOpThread.execute {
loghubHelper.uploadLogGroup(buildLogGroup(event))
private fun commitSavedExposureEvent(force: Boolean = false) {
exposureExecutor.execute {
if (exposureSet.size < STORE_SIZE && !force || exposureSet.size == 0) return@execute
val exposureList = exposureSet.toList()
// uploadLogGroup 是一个异步方法LoghubHelper 里面实现了重传功能,所以这里交给它就好了
loghubHelper.uploadLogGroup(buildLogGroup(exposureList))
Utils.log("Exposure", "提交了${exposureList.size}条曝光记录")
exposureSet.removeAll(exposureList)
exposureDao.deleteMany(exposureList)
}
}
/**
* Upload Many Events
*/
private fun upload(eventList: List<ExposureEvent>) {
storeOpThread.execute {
loghubHelper.uploadLogGroup(buildLogGroup(eventList))
}
}
/**
* Upload Events From Store, and removed them
*/
private fun checkAndUploadFromDatabase(isForceUpload: Boolean = false) {
storeOpThread.execute {
if (storeSet.size < STORE_SIZE && !isForceUpload || storeSet.size == 0) return@execute
val uploaded = storeSet.toList()
try {
loghubHelper.uploadLogGroup(buildLogGroup(uploaded))
} catch (exception: LogException) {
// Return to insure no logs lost because of online commit failure
return@execute
}
storeSet.removeAll(uploaded)
db.deleteMany(uploaded)
}
}
private fun buildLog(event: ExposureEvent): LgLOG {
val log = LgLOG(TimeUtil.currentTime())
log.PutContent("id", event.id)
log.PutContent("payload", gson.toJson(event.payload))
log.PutContent("event", event.event.toString())
log.PutContent("source", eliminateMultipleBrackets(gson.toJson(event.source)))
log.PutContent("meta", gson.toJson(event.meta))
log.PutContent("e-traces", if (event.eTrace != null) eliminateMultipleBrackets(gson.toJson(event.eTrace)) else "")
log.PutTime(event.time)
return log
}
private fun eliminateMultipleBrackets(jsonWithMultipleBracket: String): String {
return jsonWithMultipleBracket.replace("[[", "[").replace("]]", "]")
}
private fun buildLogGroup(event: ExposureEvent): LogGroup {
private fun buildLogGroup(eventList: List<ExposureEvent>): LogGroup {
val logGroup = LogGroup("sls android", "no ip")
logGroup.PutLog(buildLog(event))
eventList.forEach { logGroup.PutLog(buildLog(it)) }
return logGroup
}
private fun buildLogGroup(eventList: List<ExposureEvent>): LogGroup {
private fun buildLog(event: ExposureEvent): LgLOG {
val log = LgLOG(TimeUtil.currentTime())
val logGroup = LogGroup("sls android", "no ip")
log.PutContent("id", event.id)
log.PutContent("payload", event.payload.toJson())
log.PutContent("event", event.event.toString())
log.PutContent("source", eliminateMultipleBrackets(event.source.toJson()))
log.PutContent("meta", event.meta.toJson())
log.PutContent("e-traces", if (event.eTrace != null) {
eliminateMultipleBrackets(event.eTrace?.toJson() ?: "")
} else "")
log.PutTime(event.time)
eventList.forEach { event ->
logGroup.PutLog(buildLog(event))
}
return logGroup
return log
}
internal class FixedSizeLinkedHashSet<T>(var maxSize: Int) : LinkedHashSet<T>() {

View File

@ -1,15 +1,16 @@
package com.gh.common.exposure
import com.gh.common.util.toObject
import com.gh.gamecenter.entity.GameEntity
import com.google.gson.Gson
import java.util.*
object ExposureUtils {
val gson = Gson()
@JvmStatic
fun logADownloadExposureEvent(entity: GameEntity, platform: String?, traceEvent: ExposureEvent?, downloadType: DownloadType): ExposureEvent {
fun logADownloadExposureEvent(entity: GameEntity,
platform: String?,
traceEvent: ExposureEvent?,
downloadType: DownloadType): ExposureEvent {
val gameEntity = entity.clone()
gameEntity.platform = platform
gameEntity.downloadType = downloadType.toString()
@ -17,21 +18,24 @@ object ExposureUtils {
source = traceEvent?.source ?: ArrayList(),
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
event = ExposureType.DOWNLOAD)
ExposureManager.log(exposureEvent, false)
ExposureManager.log(exposureEvent)
return exposureEvent
}
@JvmStatic
fun logADownloadCompleteExposureEvent(entity: GameEntity, platform: String?, trace: String?, downloadType: DownloadType) {
fun logADownloadCompleteExposureEvent(entity: GameEntity,
platform: String?,
trace: String?,
downloadType: DownloadType) {
val gameEntity = entity.clone()
gameEntity.platform = platform
gameEntity.downloadCompleteType = downloadType.toString()
val traceEvent = gson.fromJson(trace, ExposureEvent::class.java)
val traceEvent = trace?.toObject<ExposureEvent>()
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
source = traceEvent?.source ?: ArrayList(),
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
event = ExposureType.DOWNLOAD_COMPLETE)
ExposureManager.log(exposureEvent, false)
ExposureManager.log(exposureEvent)
}
enum class DownloadType {

View File

@ -1,7 +1,11 @@
package com.gh.common.exposure
/**
* 统计曝光的列表的 adapter 需要实现这个接口
*/
interface IExposable {
fun getEventByPosition(pos: Int): ExposureEvent?
// 部分列表的 item 内嵌套了 recyclerview 这里获取这个 item 所携带的所有事件
fun getEventListByPosition(pos: Int): List<ExposureEvent>?
}

View File

@ -15,11 +15,11 @@ data class Meta(
val android_sdk: Int? = -1,
val android_version: String? = "",
val network: String? = "",
val ip: String? = "",
val os: String? = "",
val gid: String? = "",
val channel: String? = "",
val appVersion: String? = "",
val userId: String? = "",
val exposureVersion: String? = ""
val exposureVersion: String? = "",
val rom: String? = ""
) : Parcelable

View File

@ -14,22 +14,32 @@ import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.manager.UserManager
import com.halo.assistant.HaloApp
import com.leon.channel.helper.ChannelReaderUtil
import com.walkud.rom.checker.RomIdentifier
import java.io.File
object MetaUtil {
private lateinit var application: Application
private val application: Application = HaloApp.getInstance().application
private var channel = ""
private var m: Meta? = null
fun init(application: Application) {
MetaUtil.application = application
}
fun refreshMeta() {
m = Meta(getMac(), getIMEI(), getModel(), getManufacturer(), getAndroidId(), getAndroidSDK(),
getAndroidVersion(), getNetwork(), getIP(), getOS(), HaloApp.getInstance().gid, getChannel(), BuildConfig.VERSION_NAME, UserManager.getInstance().userId, BuildConfig.EXPOSURE_VERSION)
m = Meta(mac = getMac(),
imei = getIMEI(),
model = getModel(),
manufacturer = getManufacturer(),
android_id = getAndroidId(),
android_sdk = getAndroidSDK(),
android_version = getAndroidVersion(),
network = getNetwork(),
os = getOS(),
gid = HaloApp.getInstance().gid,
channel = getChannel(),
appVersion = BuildConfig.VERSION_NAME,
userId = UserManager.getInstance().userId,
exposureVersion = BuildConfig.EXPOSURE_VERSION,
rom = RomIdentifier.getRom().name + "" + RomIdentifier.getRom().versionName)
}
fun getMeta(): Meta {
@ -141,16 +151,16 @@ object MetaUtil {
val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
if (telephonyManager.simState != TelephonyManager.SIM_STATE_READY) return "unknown"
when (telephonyManager.networkType) {
// Unknown
// Unknown
TelephonyManager.NETWORK_TYPE_UNKNOWN -> "Cellular - Unknown"
// Cellular Data2G
// Cellular Data2G
TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_CDMA,
TelephonyManager.NETWORK_TYPE_IDEN, TelephonyManager.NETWORK_TYPE_1xRTT -> "Cellular - 2G"
// Cellular Data3G
// Cellular Data3G
TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSPA,
TelephonyManager.NETWORK_TYPE_HSPAP, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_EVDO_0,
TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B -> "Cellular - 3G"
// Cellular Data4G
// Cellular Data4G
TelephonyManager.NETWORK_TYPE_LTE -> "Cellular - 4G"
else -> "Cellular - Unknown Generation"
}
@ -161,10 +171,6 @@ object MetaUtil {
}
fun getIP(): String {
return "unknown"
}
fun getOS(): String {
return "android"
}

View File

@ -1,5 +1,7 @@
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
@ -17,11 +19,12 @@ class Corrector {
fixedRateTimer("TimeUtil-Corrector-Checker", initialDelay = 0, period = TIME_CORRECTOR_ADJUST_PERIOD) {
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
.subscribeOn(Schedulers.io())
.subscribe({
val serverTime = java.lang.Long.parseLong(it.string())
delta = serverTime * 1000 - System.currentTimeMillis()
}, Throwable::printStackTrace)
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let { delta = it * 1000 - System.currentTimeMillis() }
}
})
}
}
}

View File

@ -4,6 +4,10 @@ object TimeUtil {
private lateinit var corrector: Corrector
fun init() {
corrector = Corrector()
}
fun currentTimeMillis(): Long {
return corrector.delta + System.currentTimeMillis()
}
@ -16,11 +20,4 @@ object TimeUtil {
}
}
/**
* Must be called early then real use (for example in Application)
*/
fun init() {
corrector = Corrector()
}
}

View File

@ -0,0 +1,43 @@
package com.gh.common.history
import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.arch.persistence.room.TypeConverters
import com.gh.gamecenter.entity.HistoryGameEntity
import com.gh.gamecenter.entity.NewsEntity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.room.converter.*
import com.gh.gamecenter.room.dao.AnswerHistoryDao
import com.gh.gamecenter.room.dao.ArticleHistoryDao
import com.gh.gamecenter.room.dao.GameDao
import com.gh.gamecenter.room.dao.NewsHistoryDao
import com.halo.assistant.HaloApp
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class], version = 2, exportSchema = false)
@TypeConverters(*[
CountConverter::class,
CommunityConverter::class,
TimeConverter::class,
AnswerUserConverter::class,
ThumbnailConverter::class,
TagStyleListConverter::class,
StringArrayListConverter::class])
abstract class HistoryDatabase : RoomDatabase() {
abstract fun answerDao(): AnswerHistoryDao
abstract fun articleDao(): ArticleHistoryDao
abstract fun newsDao(): NewsHistoryDao
abstract fun gameDao(): GameDao
companion object {
val instance by lazy {
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
.fallbackToDestructiveMigration()
.build()
}
}
}

View File

@ -0,0 +1,107 @@
package com.gh.common.history
import com.gh.common.runOnIoThread
import com.gh.common.util.clearHtmlFormatCompletely
import com.gh.common.util.removeInsertedContent
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.HistoryGameEntity
import com.gh.gamecenter.entity.NewsEntity
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
object HistoryHelper {
fun insertAnswerEntity(answerDetailEntity: AnswerDetailEntity) {
val answerEntity = convertAnswerDetailToAnswer(answerDetailEntity)
runOnIoThread { HistoryDatabase.instance.answerDao().addAnswer(answerEntity) }
}
fun insertArticleEntity(articleDetailEntity: ArticleDetailEntity) {
val articleEntity = convertArticleDetailToArticle(articleDetailEntity)
runOnIoThread { HistoryDatabase.instance.articleDao().addArticle(articleEntity) }
}
fun insertGameEntity(gameEntity: GameEntity) {
val historyGameEntity = convertGameEntityToHistoryGameEntity(gameEntity)
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
}
private fun convertGameEntityToHistoryGameEntity(gameEntity: GameEntity): HistoryGameEntity {
val historyGame = HistoryGameEntity()
historyGame.orderTag = System.currentTimeMillis()
historyGame.id = gameEntity.id
historyGame.brief = gameEntity.brief
historyGame.des = gameEntity.des
historyGame.icon = gameEntity.icon
historyGame.name = gameEntity.name
historyGame.tagStyle = gameEntity.tagStyle
historyGame.tag = gameEntity.getTag()
return historyGame
}
@JvmStatic
fun insertNewsEntity(newsEntity: NewsEntity) {
newsEntity.orderTag = System.currentTimeMillis()
runOnIoThread { HistoryDatabase.instance.newsDao().addNews(newsEntity) }
}
@JvmStatic
fun deleteNewsEntity(newsId: String) {
runOnIoThread { HistoryDatabase.instance.newsDao().deleteNews(NewsEntity().apply { id = newsId }) }
}
@JvmStatic
fun deleteGameEntity(gameId: String) {
runOnIoThread { HistoryDatabase.instance.gameDao().deleteGame(HistoryGameEntity(id = gameId)) }
}
@JvmStatic
fun deleteArticleEntity(articleId: String) {
runOnIoThread { HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(id = articleId)) }
}
@JvmStatic
fun deleteAnswerEntity(answerId: String) {
runOnIoThread { HistoryDatabase.instance.answerDao().deleteAnswer(AnswerEntity().apply { primaryKey = answerId }) }
}
@JvmStatic
fun emptyDatabase() {
runOnIoThread { HistoryDatabase.instance.clearAllTables() }
}
private fun convertArticleDetailToArticle(articleDetailEntity: ArticleDetailEntity): ArticleEntity {
val articleEntity = ArticleEntity()
articleEntity.id = articleDetailEntity.id
articleEntity.brief = articleDetailEntity.content.removeInsertedContent().clearHtmlFormatCompletely().replace(" +".toRegex()," ")
articleEntity.count = articleDetailEntity.count
articleEntity.community = articleDetailEntity.community
articleEntity.time = articleDetailEntity.time
articleEntity.title = articleDetailEntity.title
articleEntity.user = articleDetailEntity.user
articleEntity.orderTag = System.currentTimeMillis()
return articleEntity
}
private fun convertAnswerDetailToAnswer(answerDetailEntity: AnswerDetailEntity): AnswerEntity {
val answerEntity = AnswerEntity()
answerEntity.id = answerDetailEntity.id
answerEntity.primaryKey = answerDetailEntity.id
answerEntity.commentCount = answerDetailEntity.commentCount
answerEntity.questions = answerDetailEntity.question
answerEntity.vote = answerDetailEntity.vote
answerEntity.user = answerDetailEntity.user
answerEntity.orderTag = System.currentTimeMillis()
answerEntity.brief = answerDetailEntity.content.removeInsertedContent().clearHtmlFormatCompletely().replace(" +".toRegex(), " ")
answerEntity.time = answerDetailEntity.time
return answerEntity
}
}

View File

@ -5,16 +5,19 @@ import android.app.NotificationManager
import android.content.Context
import com.gh.base.CurrentActivityHolder
import com.gh.common.util.SPUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.MessageActivity
import com.gh.gamecenter.SuggestSelectActivity
import com.gh.gamecenter.manager.UserManager
import com.halo.assistant.HaloApp
import com.m7.imkfsdk.KfStartHelper
import com.m7.imkfsdk.utils.Utils
import com.moor.imkf.ChatListener
import com.moor.imkf.IMChat
import com.moor.imkf.IMChatManager
import com.moor.imkf.IMMessage
import com.moor.imkf.utils.MoorUtils
object ImManager {
@ -25,10 +28,17 @@ object ImManager {
var shouldShowFloatingWindow = false
var shouldShowFloatingWindowDot = false
// 记录当前用户 ID 避免重复初始化
var currentUserId = ""
@JvmStatic
fun attachIm() {
try {
if (UserManager.getInstance().userInfoEntity != null) {
if (UserManager.getInstance().userInfoEntity != null &&
currentUserId != UserManager.getInstance().userId) {
currentUserId = UserManager.getInstance().userId
MoorUtils.init(HaloApp.getInstance().application)
Utils.init(HaloApp.getInstance().application)
IMChatManager.getInstance().init(
HaloApp.getInstance().application,
ImReceiver.UNIQUE_BROADCAST_ACTION,
@ -67,7 +77,8 @@ object ImManager {
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) {
e.printStackTrace()

View File

@ -12,8 +12,8 @@ import android.support.v4.app.NotificationCompat
import com.gh.base.CurrentActivityHolder
import com.gh.gamecenter.R
import com.m7.imkfsdk.chat.ChatActivity
import com.m7.imkfsdk.utils.Utils
import com.moor.imkf.IMChatManager
import com.moor.imkf.utils.Utils
class ImReceiver : BroadcastReceiver() {

View File

@ -32,7 +32,7 @@ class Notifier private constructor() {
@JvmStatic
fun tagNotifierAsShowed(content: String) {
val viewedNotifierCollection = SPUtils.getString(SP_VIEWED_NOTIFIER)
if (viewedNotifierCollection.length > 1000) {
if (viewedNotifierCollection.length > 3000) {
SPUtils.setString(SP_VIEWED_NOTIFIER, content)
} else {
SPUtils.setString(SP_VIEWED_NOTIFIER, viewedNotifierCollection + content)

View File

@ -201,12 +201,16 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
showAnimatorSet.cancel()
hideAnimatorSet.cancel()
removeAllListeners(expandAnimator,
shrinkAnimator,
translateUpAnimator,
translateDownAnimator,
translateToLeftAnimator,
translateToRightAnimator)
try {
removeAllListeners(expandAnimator,
shrinkAnimator,
translateUpAnimator,
translateDownAnimator,
translateToLeftAnimator,
translateToRightAnimator)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun removeAllListeners(vararg ts: Animator) {
@ -227,7 +231,7 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
postDelayed({ shrink() }, duration)
}
fun shrink() {
private fun shrink() {
shrinkAnimator.doOnEnd { hide() }
shrinkAnimator.start()
}

View File

@ -1,5 +1,6 @@
package com.gh.common.repository
import com.gh.common.util.ApkActiveUtils
import com.gh.common.util.RandomUtils
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.retrofit.RetrofitManager
@ -17,6 +18,7 @@ object RemenkapaiRepository {
RetrofitManager.getInstance(getApplication()).api.remenkapai
.map { gameList -> filterEntityWithoutApk(gameList) }
.map { pickRandomSizeEntity(size) }
.map(ApkActiveUtils.filterMapperList)
} else {
Observable.create { emitter -> emitter.onNext(pickRandomSizeEntity(size)) }
}
@ -26,6 +28,8 @@ object RemenkapaiRepository {
* 选择随机数量的热门卡牌
*/
private fun pickRandomSizeEntity(size: Int): List<GameEntity> {
if (size > remenkapaiList.size) return remenkapaiList
val randomGameList = arrayListOf<GameEntity>()
val randomArray = RandomUtils.getRandomArray(size, remenkapaiList.size)
for (i in randomArray) {

View File

@ -0,0 +1,37 @@
package com.gh.common.util
import com.gh.common.constant.Config
import com.gh.gamecenter.entity.SettingsEntity
object AdHelper {
// 搜索为空/求版本/意见反馈-功能收录/发现
const val LOCATION_SEARCH_EMPTY = "search_empty"
const val LOCATION_GAME_REQUEST_VERSION = "game_request_version"
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
const val LOCATION_DISCOVER = "discover"
fun getAd(location: String): SettingsEntity.AD? {
val adList = Config.getSettings()?.adList ?: return null
for (ad in adList) {
if (ad.location == location) return ad
}
return null
}
fun getDiscoverAds(): List<SettingsEntity.AD> {
val adList = Config.getSettings()?.adList ?: return listOf()
val discoverAdList = arrayListOf<SettingsEntity.AD>()
for (ad in adList) {
if (ad.location == LOCATION_DISCOVER) {
discoverAdList.add(ad)
}
}
return discoverAdList
}
}

View File

@ -18,6 +18,7 @@ package com.gh.common.util
import android.animation.Animator
import android.support.annotation.RequiresApi
import android.view.ViewPropertyAnimator
/**
* Since [Android KTX] has not release a stable build yet,
@ -125,4 +126,26 @@ fun Animator.addPauseListener(
}
addPauseListener(listener)
return listener
}
fun ViewPropertyAnimator.doOnEnd(onEnd: ((animator: Animator?) -> Unit)? = null): ViewPropertyAnimator {
val listener = object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {
}
override fun onAnimationEnd(animation: Animator?) {
onEnd?.invoke(animation)
}
override fun onAnimationCancel(animation: Animator?) {
}
override fun onAnimationStart(animation: Animator?) {
}
}
this.setListener(listener)
return this
}

View File

@ -1,31 +1,52 @@
package com.gh.common.util;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.manager.PackageManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.utils.Utils;
import java.util.List;
import io.reactivex.functions.Function;
/**
* Created by khy on 10/05/17.
*/
public class ApkActiveUtils {
// 过滤隐藏apk包
public static void filterHideApk(GameEntity gameEntity) {
if (gameEntity == null || gameEntity.getApk() == null
|| gameEntity.getApk().size() == 0) return;
List<ApkEntity> apkList = gameEntity.getApk();
for (int i = 0; i < apkList.size(); i++) {
ApkEntity apkEntity = apkList.get(i);
String packageName = apkEntity.getPackageName();
String id = gameEntity.getId();
if (!apkEntity.isActive() && !PackageManager.INSTANCE.isCanPluggable(id, packageName)) {
apkList.remove(i);
i--;
try {
if (gameEntity == null || gameEntity.getOriginalApk().size() == 0) return;
List<ApkEntity> apkList = gameEntity.getOriginalApk();
for (int i = 0; i < apkList.size(); i++) {
ApkEntity apkEntity = apkList.get(i);
String packageName = apkEntity.getPackageName();
String id = gameEntity.getId();
if (!apkEntity.isActive() && !PackagesManager.INSTANCE.isCanPluggable(id, packageName)) {
apkList.remove(i);
i--;
}
}
} catch (Exception e) {
if (BuildConfig.DEBUG) {
Utils.log("filter hide game apk throws exception:" + e.toString());
}
}
}
// 过滤隐藏apk包
public static Function<List<GameEntity>, List<GameEntity>> filterMapperList = list -> {
for (GameEntity gameEntity : list) {
ApkActiveUtils.filterHideApk(gameEntity);
}
return list;
};
// 过滤隐藏apk包
public static Function<GameEntity, GameEntity> filterMapper = list -> {
ApkActiveUtils.filterHideApk(list);
return list;
};
}

View File

@ -1,90 +0,0 @@
package com.gh.common.util;
import android.content.Context;
import com.lightgame.utils.Utils;
import org.json.JSONObject;
import retrofit2.HttpException;
/**
* Created by khy on 28/12/17.
*/
public class AskErrorResponseUtils {
public static void errorResponseControl(Context context, HttpException e) {
if (e == null) return;
int code = e.code();
try {
if (code == 403) {
JSONObject object = new JSONObject(e.response().errorBody().string());
int errorCode = object.getInt("code");
switch (errorCode) {
case 403001:
Utils.toast(context, "标签名称太长了");
break;
case 403002:
Utils.toast(context, "已经被邀请了");
break;
case 403003:
Utils.toast(context, "每天最多只能邀请10次");
break;
case 403004:
Utils.toast(context, "客户端提供的ID无效空/无效ID");
break;
case 403005:
Utils.toast(context, "已经回答过了(限制频率)");
break;
case 403006:
Utils.toast(context, "图片数量达到限制点");
break;
case 403007:
Utils.toast(context, "不合法的用户");
break;
case 403008:
Utils.toast(context, "已投票");
break;
case 403009:
Utils.toast(context, "已经收藏过了");
break;
case 403010:
Utils.toast(context, "无效的标签栏");
break;
case 403011:
Utils.toast(context, "标题内容过长");
break;
case 403012:
Utils.toast(context, "描述内容过长");
break;
case 403013:
Utils.toast(context, "无效的标签");
break;
case 403014:
Utils.toast(context, "标签数量太多了");
break;
case 403015:
Utils.toast(context, "已经关注过了");
break;
default:
Utils.toast(context, "网络错误");
break;
}
} else if (code == 401) {
JSONObject object = new JSONObject(e.response().errorBody().string());
int errorCode = object.getInt("code");
if (errorCode == 404001) {
Utils.toast(context, "请求的资源不存在");
}
} else {
Utils.toast(context, "网络错误");
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}

View File

@ -7,6 +7,9 @@ import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.os.Build;
import com.halo.assistant.HaloApp;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
@ -186,15 +189,30 @@ public class BitmapUtils {
/**
* Drawable转Bitmap
* @param isSquare 是否是正方形
*/
public static Bitmap drawableToBitmap(Drawable drawable) {
public static Bitmap drawableToBitmap(Drawable drawable, boolean isSquare) {
if (drawable == null) {
return null;
}
int w,h;
// 取 drawable 的长宽
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
w = drawable.getIntrinsicWidth();
h = drawable.getIntrinsicHeight();
// 在低于 5.1 和运行内存小于 2G 的设备上减小图片大小,避免 OOM128 * 128 又不是不能看
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
|| DeviceUtils.getTotalRamSizeOfDevice(HaloApp.getInstance().getApplication()) < 2000) {
if (isSquare) {
w = w > 128 ? 128 : w;
h = h > 128 ? 128 : h;
} else {
w = w > 128 ? w / 2 : w;
h = h > 128 ? h / 2 : h;
}
}
// 取 drawable 的颜色格式
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565;

View File

@ -14,15 +14,17 @@ import com.lightgame.utils.Utils;
public class CheckLoginUtils {
public static void checkLogin(final Context context, OnLoginListener listener) {
if (TextUtils.isEmpty(UserManager.getInstance().getToken())) {
Utils.toast(context, "需要登录");
LogUtils.login(context, "dialog", null);
LogUtils.login(context, "activity", null);
Intent intent = LoginActivity.getIntent(context);
public static void checkLogin(final Context context, String entrance, OnLoginListener listener) {
if (!isLogin()) {
if (listener != null) Utils.toast(context, "需要登录");
LogUtils.login("dialog", null, entrance);
LogUtils.login("activity", null, entrance);
Intent intent = LoginActivity.getIntent(context, entrance);
context.startActivity(intent);
} else {
listener.onLogin();
if (listener != null) {
listener.onLogin();
}
}
}

View File

@ -46,7 +46,7 @@ object CollectionUtils {
try {
val string = e.response()?.errorBody()?.string()
val errorBody = JSONObject(string)
if (errorBody.getInt("detail") == 403009) {
if (errorBody.getInt("code") == 403009) {
listener.onSuccess()
return
}

View File

@ -1,101 +1,62 @@
package com.gh.common.util
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.support.v4.content.ContextCompat
import android.text.TextUtils
import android.view.Window
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.common.util.CommentUtils.copyText
import com.gh.gamecenter.CommentDetailActivity
import com.gh.gamecenter.MessageDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.OnCommentCallBackListener
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.entity.MeEntity
import com.gh.gamecenter.entity.Permissions
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONException
import org.json.JSONObject
import retrofit2.HttpException
object CommentHelper {
// TODO 合并这两个方法的共同部分
@JvmStatic
fun showCommunityArticleCommentOptions(
context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String,
communityId: String,
listener: OnCommentCallBackListener?) {
val dialogOptions = ArrayList<String>()
if (commentEntity.me == null || !commentEntity.me?.isAnswerCommented!!) {
dialogOptions.add("回复")
}
dialogOptions.add("复制")
dialogOptions.add("举报")
if (commentEntity.parentUser != null && showConversation) {
dialogOptions.add("查看对话")
}
val dialog: Dialog
dialog = createOptionsSelectDialog(context, dialogOptions) {
when (it) {
"回复" -> {
CheckLoginUtils.checkLogin(context) {
if (listener != null) {
listener.onCommentCallback(commentEntity)
} else if (!TextUtils.isEmpty(commentEntity.id)) {
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, commentEntity.id))
} else {
Utils.toast(context, "缺少关键属性")
}
}
}
"复制" -> copyText(commentEntity.content, context)
"举报" -> CheckLoginUtils.checkLogin(context) {
showReportTypeDialog(context) { reportType ->
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType,
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}")
}
}
})
}
}
"查看对话" -> {
context.startActivity(CommentDetailActivity
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
}
}
}
dialog.show();
fun showCommunityArticleCommentOptions(context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String,
communityId: String,
listener: OnCommentCallBackListener?) {
showCommentOptions(context = context,
commentEntity = commentEntity,
showConversation = showConversation,
articleId = articleId,
communityId = communityId,
listener = listener)
}
@JvmStatic
fun showAnswerCommentOptions(
context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
answerId: String,
listener: OnCommentCallBackListener?) {
fun showAnswerCommentOptions(context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
answerId: String,
listener: OnCommentCallBackListener?) {
showCommentOptions(context = context,
commentEntity = commentEntity,
showConversation = showConversation,
answerId = answerId,
listener = listener)
}
private fun showCommentOptions(context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String? = null,
communityId: String? = null,
answerId: String? = null,
listener: OnCommentCallBackListener? = null) {
val dialogOptions = ArrayList<String>()
if (commentEntity.me == null || !commentEntity.me?.isAnswerCommented!!) {
@ -105,16 +66,25 @@ object CommentHelper {
dialogOptions.add("复制")
dialogOptions.add("举报")
commentEntity.me?.let {
if (it.isModerator || (it.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|| it.moderatorPermissions.topAnswerComment > Permissions.GUEST
|| it.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST
|| it.moderatorPermissions.topCommunityArticleComment > Permissions.GUEST)) {
dialogOptions.add("管理")
}
}
if (commentEntity.parentUser != null && showConversation) {
dialogOptions.add("查看对话")
}
val dialog: Dialog
dialog = createOptionsSelectDialog(context, dialogOptions) {
DialogUtils.showListDialog(context, dialogOptions, null) {
when (it) {
"管理" -> showControlDialog(context, answerId, articleId, communityId, commentEntity, commentEntity.me!!)
"回复" -> {
CheckLoginUtils.checkLogin(context) {
context.ifLogin("回答详情-评论-回复") {
if (listener != null) {
listener.onCommentCallback(commentEntity)
} else if (!TextUtils.isEmpty(commentEntity.id)) {
@ -127,83 +97,228 @@ object CommentHelper {
"复制" -> copyText(commentEntity.content, context)
"举报" -> CheckLoginUtils.checkLogin(context) {
showReportTypeDialog(context) { reportType ->
PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType,
object : PostCommentUtils.PostCommentListener {
override fun postSuccess(response: JSONObject?) {
Utils.toast(context, "感谢您的举报")
}
"举报" -> {
context.ifLogin("回答详情-评论-举报") {
showReportTypeDialog(context) { reportType ->
override fun postFailed(error: Throwable?) {
if (error == null) {
Utils.toast(context, "举报失败,请稍后重试")
} else {
Utils.toast(context, "举报失败,${error.message}")
}
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 {
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
}
}
}
}
"查看对话" -> {
context.startActivity(CommentDetailActivity
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
if (answerId != null) {
context.startActivity(CommentDetailActivity
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
} else {
context.startActivity(CommentDetailActivity
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
}
}
}
}
}
dialog.show();
private fun showControlDialog(context: Context,
answerId: String? = null,
articleId: String? = null,
communityId: String? = null,
comment: CommentEntity,
me: MeEntity) {
val dialogOptions = arrayListOf<String>()
val highlight = "置顶评论"
val hide = "隐藏评论"
var canHighlightCommentDirectly = false
var canHideCommentDirectly = false
if (me.moderatorPermissions.topAnswerComment > Permissions.GUEST
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.GUEST) {
dialogOptions.add(highlight)
if (me.moderatorPermissions.topAnswerComment > Permissions.REPORTER
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.REPORTER ) {
canHighlightCommentDirectly = true
}
}
if (me.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST) {
dialogOptions.add(hide)
if (me.moderatorPermissions.hideAnswerComment > Permissions.REPORTER
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.REPORTER ) {
canHideCommentDirectly = true
}
}
val highlightDialogHintContent = if (canHighlightCommentDirectly) {
"你的操作将立即生效,确定提交吗?(你的管理权限为:高级)"
} else {
"你的操作将提交给小编审核,确定提交吗?"
}
val hideDialogHintContent = if (canHideCommentDirectly) {
"你的操作将立即生效,确定提交吗?(你的管理权限为:高级)"
} else {
"你的操作将提交给小编审核,确定提交吗?"
}
val disabledOptions = arrayListOf<String>()
if (comment.priority != 0) {
disabledOptions.add(highlight)
}
comment.me?.let {
if (it.isAnswerCommented) {
disabledOptions.add(highlight)
}
}
DialogUtils.showListDialog(context, dialogOptions, disabledOptions) {
when (it) {
highlight -> {
if (comment.priority != 0) {
Utils.toast(context, "评论已经置顶")
return@showListDialog
}
comment.me?.let { me ->
if (me.isAnswerCommented) {
Utils.toast(context, "不能置顶自己的评论")
return@showListDialog
}
}
val highlightObserver = object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
if (canHighlightCommentDirectly) {
Utils.toast(context, "置顶成功,请刷新列表")
} else {
Utils.toast(context, "提交成功")
}
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
e?.let { httpException ->
if (httpException.code() == 403) {
val string = e.response().errorBody()?.string()
val errorJson = JSONObject(string)
val errorCode = errorJson.getInt("code")
if (errorCode == 403059) {
Utils.toast(getApplication(), "权限错误,请刷新后重试")
return
} else {
Utils.toast(getApplication(), e.message())
}
}
}
}
}
if (answerId != null) {
DialogUtils.showAlertDialog(context, highlight, highlightDialogHintContent,
"确定", "取消", {
RetrofitManager.getInstance(context).api
.highlightAnswerComment(answerId, comment.id)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(highlightObserver)
}, null)
} else {
DialogUtils.showAlertDialog(context, highlight, highlightDialogHintContent,
"确定", "取消", {
RetrofitManager.getInstance(context).api
.highlightCommunityArticleComment(communityId, articleId, comment.id)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(highlightObserver)
}, null)
}
}
hide -> {
val hideObserver = object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
if (canHideCommentDirectly) {
Utils.toast(context, "隐藏成功,请刷新列表")
} else {
Utils.toast(context, "提交成功")
}
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
e?.let { httpException ->
if (httpException.code() == 403) {
val string = e.response().errorBody()?.string()
val errorJson = JSONObject(string)
val errorCode = errorJson.getInt("code")
if (errorCode == 403059) {
Utils.toast(getApplication(), "权限错误,请刷新后重试")
return
} else {
Utils.toast(getApplication(), e.message())
}
}
}
}
}
if (answerId != null) {
DialogUtils.showAlertDialog(context, hide, hideDialogHintContent,
"确定", "取消", {
RetrofitManager.getInstance(context).api
.hideAnswerComment(answerId, comment.id)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(hideObserver)
}, null)
} else {
DialogUtils.showAlertDialog(context, hide, hideDialogHintContent,
"确定", "取消", {
RetrofitManager.getInstance(context).api
.hideCommunityArticleComment(communityId, articleId, comment.id)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(hideObserver)
}, null)
}
}
}
}
}
private fun showReportTypeDialog(context: Context, reportCallback: (reportType: String) -> Unit) {
val reportTypes = arrayListOf("垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它")
val dialog = createOptionsSelectDialog(context, reportTypes) {
DialogUtils.showListDialog(context, reportTypes, null) { text ->
val jsonObject = JSONObject()
try {
jsonObject.put("reason", it)
jsonObject.put("reason", text)
reportCallback.invoke(jsonObject.toString())
} catch (e: JSONException) {
e.printStackTrace()
}
}
dialog.show()
}
private fun createOptionsSelectDialog(
context: Context,
dialogOptions: ArrayList<String>,
clickCallback: (text: String) -> Unit): Dialog {
val dialog = Dialog(context)
val container = LinearLayout(context)
container.orientation = LinearLayout.VERTICAL
container.setBackgroundColor(Color.WHITE)
container.setPadding(0, DisplayUtils.dip2px(context, 12f), 0, DisplayUtils.dip2px(context, 12f))
for (s in dialogOptions) {
val reportTv = TextView(context)
reportTv.text = s
reportTv.textSize = 17f
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title))
reportTv.setBackgroundResource(R.drawable.textview_white_style)
val widthPixels = context.resources.displayMetrics.widthPixels
reportTv.layoutParams = LinearLayout.LayoutParams(widthPixels * 9 / 10,
LinearLayout.LayoutParams.WRAP_CONTENT)
reportTv.setPadding(DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 12f),
0, DisplayUtils.dip2px(context, 12f))
container.addView(reportTv)
reportTv.setOnClickListener {
dialog.cancel()
clickCallback.invoke(reportTv.text.toString())
}
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(container)
return dialog
}
}

View File

@ -4,7 +4,6 @@ import android.app.Dialog;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.View;
@ -20,11 +19,8 @@ import com.gh.gamecenter.adapter.OnCommentCallBackListener;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.MeEntity;
import com.gh.gamecenter.entity.RatingComment;
import com.gh.gamecenter.entity.UserInfoEntity;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.utils.Utils;
import org.json.JSONException;
@ -37,11 +33,6 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
/**
@ -80,112 +71,13 @@ public class CommentUtils {
}
}
public static void showGameCommentOptions(final Context context, final RatingComment comment, final String gameId) {
final Dialog dialog = new Dialog(context);
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setBackgroundColor(Color.WHITE);
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
List<String> dialogType = new ArrayList<>();
dialogType.add("复制");
dialogType.add("举报");
for (String s : dialogType) {
final TextView reportTv = new TextView(context);
reportTv.setText(s);
reportTv.setTextSize(17);
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
reportTv.setBackgroundResource(R.drawable.textview_white_style);
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
LinearLayout.LayoutParams.WRAP_CONTENT));
reportTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
0, DisplayUtils.dip2px(context, 12));
container.addView(reportTv);
reportTv.setOnClickListener(v -> {
dialog.cancel();
switch (reportTv.getText().toString()) {
case "复制":
copyText(comment.getContent(), context);
break;
case "举报":
CheckLoginUtils.checkLogin(context, () -> showGameCommentReportDialog(gameId, comment, context));
break;
}
});
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(container);
dialog.show();
}
private static void showGameCommentReportDialog(final String gameId, final RatingComment comment, final Context context) {
final String[] arrReportType = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息",
"违法有害信息", "其它"};
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
final Dialog reportTypeDialog = new Dialog(context);
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
container.setBackgroundColor(Color.WHITE);
for (final String s : arrReportType) {
TextView reportTypeTv = new TextView(context);
reportTypeTv.setText(s);
reportTypeTv.setTextSize(17);
reportTypeTv.setTextColor(ContextCompat.getColor(context, R.color.title));
reportTypeTv.setBackgroundResource(R.drawable.textview_white_style);
reportTypeTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
LinearLayout.LayoutParams.WRAP_CONTENT));
reportTypeTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
0, DisplayUtils.dip2px(context, 12));
container.addView(reportTypeTv);
reportTypeTv.setOnClickListener(v -> {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("reason", s);
} catch (JSONException e) {
e.printStackTrace();
}
RequestBody body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString());
RetrofitManager.getInstance(context).getApi()
.reportGameComment(gameId, comment.getId(), body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(@Nullable ResponseBody response) {
Utils.toast(context, "感谢您的举报");
}
@Override
public void onFailure(@Nullable HttpException e) {
Utils.toast(context, "举报失败,请先检查网络设置");
}
});
reportTypeDialog.cancel();
});
}
reportTypeDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
reportTypeDialog.setContentView(container);
reportTypeDialog.show();
}
public static void showReportDialog(final CommentEntity commentEntity, final Context context, final boolean showConversation,
final OnCommentCallBackListener listener, final String newsId) {
public static void showReportDialog(final CommentEntity commentEntity,
final Context context,
final boolean showConversation,
final OnCommentCallBackListener listener,
final String newsId,
final String patch) {
final Dialog dialog = new Dialog(context);
LinearLayout container = new LinearLayout(context);
@ -225,7 +117,7 @@ public class CommentUtils {
dialog.cancel();
switch (reportTv.getText().toString()) {
case "回复":
CheckLoginUtils.checkLogin(context, () -> {
CheckLoginUtils.checkLogin(context, patch + "-回复", () -> {
if (listener != null) {
listener.onCommentCallback(commentEntity);
} else if (!TextUtils.isEmpty(newsId)) {
@ -239,7 +131,8 @@ public class CommentUtils {
copyText(commentEntity.getContent(), context);
break;
case "举报":
CheckLoginUtils.checkLogin(context, () -> showReportTypeDialog(commentEntity, context));
CheckLoginUtils.checkLogin(context, patch + "-举报",
() -> showReportTypeDialog(commentEntity, context));
break;
case "查看对话":
@ -256,135 +149,6 @@ public class CommentUtils {
}
// public static void showAnswerCommentOptions(final CommentEntity commentEntity, final Context context,
// final OnCommentCallBackListener listener, final String id,
// boolean showConversation, String answerId, String articleId, String articleCommunityId) {
//
// final Dialog dialog = new Dialog(context);
//
// LinearLayout container = new LinearLayout(context);
// container.setOrientation(LinearLayout.VERTICAL);
// container.setBackgroundColor(Color.WHITE);
// container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
//
// List<String> dialogType = new ArrayList<>();
//
// if (commentEntity.getMe() == null || !commentEntity.getMe().isAnswerCommented()) {
// dialogType.add("回复");
// }
//
// dialogType.add("复制");
// dialogType.add("举报");
//
// if (commentEntity.getParentUser() != null && showConversation) {
// dialogType.add("查看对话");
// }
//
// for (String s : dialogType) {
// final TextView reportTv = new TextView(context);
// reportTv.setText(s);
// reportTv.setTextSize(17);
// reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
// reportTv.setBackgroundResource(R.drawable.textview_white_style);
// int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
// reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
// LinearLayout.LayoutParams.WRAP_CONTENT));
// reportTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
// 0, DisplayUtils.dip2px(context, 12));
// container.addView(reportTv);
//
// reportTv.setOnClickListener(v -> {
// dialog.cancel();
// switch (reportTv.getText().toString()) {
// case "回复":
// CheckLoginUtils.checkLogin(context, () -> {
// if (listener != null) {
// listener.onCommentCallback(commentEntity);
// } else if (!TextUtils.isEmpty(id)) {
// context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, id));
// } else {
// Utils.toast(context, "缺少关键属性");
// }
// });
// break;
// case "复制":
// copyText(commentEntity.getContent(), context);
// break;
// case "举报":
// CheckLoginUtils.checkLogin(context, () -> showAnswerReportDialog(answerId, commentEntity, context));
// break;
// case "查看对话":
// if (TextUtils.isEmpty(articleId)) {
// context.startActivity(CommentDetailActivity.getAnswerCommentIntent(context, commentEntity.getId(), answerId, null));
// } else {
// context.startActivity(CommentDetailActivity.getCommunityArticleCommentIntent(context, articleId, commentEntity.getId(), articleCommunityId, null));
// }
// break;
// }
// });
// }
//
// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// dialog.setContentView(container);
// dialog.show();
// }
// private static void showAnswerReportDialog(final String answerId, final CommentEntity commentEntity, final Context context) {
// final String[] arrReportType = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息",
// "违法有害信息", "其它"};
// int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
//
// final Dialog reportTypeDialog = new Dialog(context);
// LinearLayout container = new LinearLayout(context);
// container.setOrientation(LinearLayout.VERTICAL);
// container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
// container.setBackgroundColor(Color.WHITE);
//
// for (final String s : arrReportType) {
// TextView reportTypeTv = new TextView(context);
// reportTypeTv.setText(s);
// reportTypeTv.setTextSize(17);
// reportTypeTv.setTextColor(ContextCompat.getColor(context, R.color.title));
// reportTypeTv.setBackgroundResource(R.drawable.textview_white_style);
// reportTypeTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
// LinearLayout.LayoutParams.WRAP_CONTENT));
// reportTypeTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
// 0, DisplayUtils.dip2px(context, 12));
// container.addView(reportTypeTv);
//
// reportTypeTv.setOnClickListener(v -> {
// JSONObject jsonObject = new JSONObject();
// try {
// jsonObject.put("reason", s);
// } catch (JSONException e) {
// e.printStackTrace();
// }
//
// PostCommentUtils.postAnswerReportData(context, commentEntity.getId(), answerId, jsonObject.toString(),
// new PostCommentUtils.PostCommentListener() {
// @Override
// public void postSuccess(JSONObject response) {
// Utils.toast(context, "感谢您的举报");
// }
//
// @Override
// public void postFailed(Throwable error) {
// if (error != null) {
// Utils.toast(context, "举报失败" + error.getMessage());
// } else {
// Utils.toast(context, "举报失败,请稍候重试");
// }
// }
// });
// reportTypeDialog.cancel();
// });
// }
//
// reportTypeDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// reportTypeDialog.setContentView(container);
// reportTypeDialog.show();
// }
private static void showReportTypeDialog(final CommentEntity commentEntity, final Context context) {
final String[] arrReportType = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息",
"违法有害信息", "其它"};
@ -442,64 +206,68 @@ public class CommentUtils {
}
public static void postVote(final Context context, final CommentEntity commentEntity,
final TextView commentLikeCountTv, final ImageView commentLikeIv, final OnVoteListener listener) {
CheckLoginUtils.checkLogin(context, () -> {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
Utils.toast(context, "已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
commentLikeIv.setImageResource(R.drawable.vote_icon_select);
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
final TextView commentLikeCountTv, final ImageView commentLikeIv,
final OnVoteListener listener) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
Utils.toast(context, "已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
commentLikeIv.setImageResource(R.drawable.vote_icon_select);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
PostCommentUtils.addCommentVote(context, commentEntity.getId(),
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
if (listener != null) {
listener.onVote();
}
PostCommentUtils.addCommentVote(context, commentEntity.getId(),
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
if (listener != null) {
listener.onVote();
}
}
@Override
public void postFailed(Throwable e) {
commentEntity.setVote(commentEntity.getVote() - 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
commentLikeIv.setImageResource(R.drawable.vote_icon_unselect);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
if (commentEntity.getVote() == 0) {
commentLikeCountTv.setVisibility(View.GONE);
} else {
commentLikeCountTv.setVisibility(View.VISIBLE);
}
@Override
public void postFailed(Throwable e) {
commentEntity.setVote(commentEntity.getVote() - 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
commentLikeIv.setImageResource(R.drawable.vote_icon_unselect);
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
if (commentEntity.getVote() == 0) {
commentLikeCountTv.setVisibility(View.GONE);
} else {
commentLikeCountTv.setVisibility(View.VISIBLE);
}
if (e instanceof HttpException) {
HttpException exception = (HttpException) e;
if (exception.code() == 403) {
try {
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
if ("voted".equals(detail)) {
Utils.toast(context, "已经点过赞啦!");
}
} catch (Exception ex) {
ex.printStackTrace();
if (e instanceof HttpException) {
HttpException exception = (HttpException) e;
if (exception.code() == 403) {
try {
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
if ("voted".equals(detail)) {
Utils.toast(context, "已经点过赞啦!");
}
return;
} catch (Exception ex) {
ex.printStackTrace();
}
return;
}
Utils.toast(context, "网络异常,点赞失败");
}
});
});
Utils.toast(context, "网络异常,点赞失败");
}
});
}
public static void postVoteToAnswerComment(final Context context, String answerId, String articleId,
String articleCommunityId, final CommentEntity commentEntity,
final TextView commentLikeCountTv, final ImageView commentLikeIv, final OnVoteListener listener) {
CheckLoginUtils.checkLogin(context, () -> {
String entrance = "回答详情-评论-点赞";
if (TextUtils.isEmpty(articleId)) {
entrance = "社区文章详情-评论-点赞";
}
CheckLoginUtils.checkLogin(context, entrance, () -> {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
Utils.toast(context, "已经点过赞啦!");
return;
@ -507,7 +275,7 @@ public class CommentUtils {
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
commentLikeIv.setImageResource(R.drawable.vote_icon_select);
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
PostCommentUtils.voteAnswerComment(context, answerId, articleId, articleCommunityId, commentEntity.getId(),
@ -525,7 +293,7 @@ public class CommentUtils {
commentEntity.setVote(commentEntity.getVote() - 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
commentLikeIv.setImageResource(R.drawable.vote_icon_unselect);
commentLikeCountTv.setText(String.valueOf(commentEntity.getVote()));
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
if (commentEntity.getVote() == 0) {
commentLikeCountTv.setVisibility(View.GONE);
} else {

View File

@ -1,45 +1,47 @@
package com.gh.common.util
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.qa.entity.AskGameSelectEntity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
/**
* 用于判断社区跳转前社区是否可用
*/
object CommunityHelper {
private var availableCommunityList = listOf<AskGameSelectEntity>()
/**
* 为已开通的社区排序
* 排序规则为将本地存在已安装游戏或已关联游戏的社区置顶
*/
fun sortOpenedCommunity(rawList: List<AskGameSelectEntity>?): ArrayList<AskGameSelectEntity> {
val sortedList = ArrayList<AskGameSelectEntity>()
rawList?.let {
for (game in rawList) {
var thisGameIsInstalled = false
for (installGame in PackageRepository.gameInstalled) {
if (PackageHelper.downloadPackageNameBlackList.contains(installGame.packageName)) {
continue
}
@JvmStatic
fun getAvailableCommunityList() {
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.getAskGameSelect(HaloApp.getInstance().channel
, UrlFilterUtils.getFilterQuery("status", "opened"), 1, 100)
.subscribeOn(Schedulers.io())
.subscribe(object : Response<List<AskGameSelectEntity>>() {
override fun onResponse(response: List<AskGameSelectEntity>?) {
if (response != null && response.isNotEmpty()) {
availableCommunityList = response
// 判断是否已安装
if (installGame.id == game.game.id) {
thisGameIsInstalled = true
break
}
// 判断是否关联了别游戏
for (relatedGameId in game.game.relation) {
if (installGame.id == relatedGameId) {
thisGameIsInstalled = true
break
}
}
})
}
}
@JvmStatic
fun isCommunityAvailable(communityId: String?): Boolean {
communityId?.let {
if (availableCommunityList.isEmpty()) return true
for (entity in availableCommunityList) {
if (communityId == entity.id) {
return true
// 将已安装的置顶
if (thisGameIsInstalled) {
sortedList.add(0, game)
} else {
sortedList.add(game)
}
}
}
return false
return sortedList
}
}

View File

@ -142,12 +142,11 @@ object CompressImageUtils {
}
fun getImageSetting(): SettingsEntity.Image {
var settings = Config.getSettings()
val settings = Config.getSettings()
if (settings == null && settings?.image != null) {
return settings.image
return settings.image!!
}
settings = SettingsEntity()
val image = settings.Image()
val image = SettingsEntity.Image()
image.processLimitSize = compressLimitSize
image.size = defaultCompressBorder
image.ratio = defaultRatio

View File

@ -2,7 +2,6 @@ package com.gh.common.util;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.widget.LinearLayout;
import com.facebook.drawee.drawable.ScalingUtils;
@ -93,12 +92,9 @@ public class ConcernContentUtils {
ScalingUtils.ScaleType.CENTER_CROP, list.get(position));
break;
}
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent checkIntent = ViewImageActivity.getViewImageIntent(context, (ArrayList<String>) list, position, entrance);
context.startActivity(checkIntent);
}
imageView.setOnClickListener(v -> {
Intent checkIntent = ViewImageActivity.getViewImageIntent(context, (ArrayList<String>) list, position, entrance);
context.startActivity(checkIntent);
});
return imageView;
}

View File

@ -1,6 +1,7 @@
package com.gh.common.util
import android.content.Context
import android.text.TextUtils
import com.gh.gamecenter.eventbus.EBConcernChanged
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.Response
@ -20,9 +21,17 @@ import retrofit2.HttpException
*/
object ConcernUtils {
fun postConcernGameId(context: Context, gameId: String, listener: onConcernListener?) {
RetrofitManager.getInstance(context).getApi()
.postConcern(UserManager.getInstance().userId, gameId)
/**
* autoConcern:是否自动关注'关联关注'
*/
fun postConcernGameId(context: Context, gameId: String, listener: onConcernListener?, autoConcern: Boolean = false) {
val mode = if (autoConcern) "auto" else "manual"
val userId = UserManager.getInstance().userId
if (TextUtils.isEmpty(userId)) return
RetrofitManager.getInstance(context).api
.postConcern(UserManager.getInstance().userId, gameId, mode)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
@ -40,7 +49,7 @@ object ConcernUtils {
}
fun deleteConcernData(context: Context, gameId: String, listener: onConcernListener?) {
RetrofitManager.getInstance(context).getApi()
RetrofitManager.getInstance(context).api
.deleteConcern(UserManager.getInstance().userId, gameId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -61,7 +70,7 @@ object ConcernUtils {
fun updateConcernData(context: Context, data: JSONArray) {
val body = RequestBody.create(MediaType.parse("application/json"),
data.toString())
RetrofitManager.getInstance(context).getApi()
RetrofitManager.getInstance(context).api
.putConcern(UserManager.getInstance().userId, body)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
@ -73,7 +82,7 @@ object ConcernUtils {
}
fun deleteConcernQuestions(context: Context, questionsId: String, listener: onConcernListener?) {
RetrofitManager.getInstance(context).getApi()
RetrofitManager.getInstance(context).api
.deleteConcernQuestions(UserManager.getInstance().userId, questionsId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -86,13 +95,19 @@ object ConcernUtils {
override fun onFailure(e: HttpException?) {
super.onFailure(e)
listener?.onError()
AskErrorResponseUtils.errorResponseControl(context, e)
var errorString: String? = null
try {
errorString = e?.response()?.errorBody()?.string()
} catch (e1: Exception) {
e1.printStackTrace()
}
ErrorHelper.handleError(context, errorString, false)
}
})
}
fun postConcernQuestions(context: Context, questionsId: String, listener: onConcernListener?) {
RetrofitManager.getInstance(context).getApi()
RetrofitManager.getInstance(context).api
.postConcernQuestions(UserManager.getInstance().userId, questionsId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -105,7 +120,13 @@ object ConcernUtils {
override fun onFailure(e: HttpException?) {
super.onFailure(e)
listener?.onError()
AskErrorResponseUtils.errorResponseControl(context, e)
var errorString: String? = null
try {
errorString = e?.response()?.errorBody()?.string()
} catch (e1: Exception) {
e1.printStackTrace()
}
ErrorHelper.handleError(context, errorString, false)
}
})
}

View File

@ -6,7 +6,7 @@ import android.os.Build;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.NewsDetailEntity;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.manager.PackageManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadEntity;
import org.json.JSONArray;
@ -118,7 +118,7 @@ public class DataCollectionUtils {
Map<String, Object> map = new HashMap<>();
map.put("type", Build.MODEL);
map.put("system", Build.VERSION.SDK_INT + "=" + Build.VERSION.RELEASE);
map.put("install", PackageManager.INSTANCE.getInstalledList());
map.put("install", PackagesManager.INSTANCE.getInstalledList());
DataCollectionManager.upsert(context, "user", map);
}

View File

@ -38,7 +38,7 @@ public class DataLogUtils {
// 上传日志
public static void uploadLog(Context context, String topic, Map<String, Object> map) {
String version = PackageUtils.getPatchVersionName();
String version = PackageUtils.getVersionName();
String user = Installation.getUUID(context);
String channel = HaloApp.getInstance().getChannel();
map.put("version", version);

View File

@ -82,12 +82,11 @@ public class DataUtils {
StatConfig.init(context);
StatConfig.setInstallChannel(channel);
StatConfig.setAntoActivityLifecycleStat(true);
StatConfig.setAppVersion(PackageUtils.getPatchVersionName());
StatConfig.setAppVersion(PackageUtils.getVersionName());
// 开启收集服务
StatService.startStatService(context, Config.MTA_APPKEY, com.tencent.stat.common.StatConstants.VERSION);
StatService.registerActivityLifecycleCallbacks(context);
} catch (MtaSDkException e) {
e.printStackTrace();
}
@ -100,7 +99,7 @@ public class DataUtils {
strategy.setEnableANRCrashMonitor(false);
strategy.setEnableNativeCrashMonitor(false);
strategy.setAppChannel(channel);
strategy.setAppVersion(PackageUtils.getPatchVersionName());
strategy.setAppVersion(PackageUtils.getVersionName());
CrashReport.initCrashReport(context, Config.BUGLY_APPID, false, strategy);

View File

@ -9,7 +9,7 @@ import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.manager.PackageManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadEntity;
/**
@ -72,8 +72,9 @@ public class DetailDownloadUtils {
switch (downloadEntity.getStatus()) {
case downloading:
case pause:
case overflow:
viewHolder.mDownloadPb.setText(R.string.downloading);
if (downloadEntity.isPluggable() && PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
if (downloadEntity.isPluggable() && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN);
} else {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL);
@ -84,7 +85,7 @@ public class DetailDownloadUtils {
case waiting:
case subscribe:
viewHolder.mDownloadPb.setText(R.string.waiting);
if (downloadEntity.isPluggable() && PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
if (downloadEntity.isPluggable() && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN);
} else {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL);
@ -93,7 +94,7 @@ public class DetailDownloadUtils {
case done:
viewHolder.mDownloadPb.setText(R.string.install);
if (downloadEntity.isPluggable()
&& PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
&& PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
} else {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);

View File

@ -4,8 +4,9 @@ import android.content.Context
import android.os.Environment
import android.preference.PreferenceManager
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.entity.TimeEntity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.StringResponse
import com.halo.assistant.HaloApp
import com.lightgame.utils.Util_System_Phone_State
import com.lightgame.utils.Utils
@ -13,7 +14,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.io.File
object DeviceTokenUtils {
const val DEVICE_ID = "uuid"
@ -26,18 +26,13 @@ object DeviceTokenUtils {
RetrofitManager.getInstance(context).api.time
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : StringResponse() {
override fun onResponse(response: String) {
if (response.matches("^[0-9]{10}$".toRegex())) {
try {
val editor = sp.edit()
editor.putLong("server_time", java.lang.Long.parseLong(response))
editor.putLong("client_time", System.currentTimeMillis() / 1000)
editor.apply()
} catch (e: NumberFormatException) {
e.printStackTrace()
}
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val editor = sp.edit()
response?.time?.let {
editor.putLong("server_time", it)
editor.putLong("client_time", System.currentTimeMillis() / 1000)
editor.apply()
}
}
})
@ -51,18 +46,18 @@ object DeviceTokenUtils {
if (values.isNotEmpty()) {
for (value in values) {
if (value.key.contains("isNewFirstLaunchV")) {
lunchType = LunchType.update
lunchType = LunchType.UPDATE
break
}
}
}
// 再次重装
if (lunchType == null && !getDeviceId().isNullOrEmpty()) {
lunchType = LunchType.again
lunchType = LunchType.AGAIN
}
// 首次安装
if (lunchType == null) {
lunchType = LunchType.first
lunchType = LunchType.FIRST
}
// 保存deviceId
var deviceId = Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application)
@ -133,7 +128,7 @@ object DeviceTokenUtils {
}
enum class LunchType {
first,
update,
again
FIRST,
UPDATE,
AGAIN
}

View File

@ -1,5 +1,6 @@
package com.gh.common.util;
import android.app.ActivityManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
@ -128,6 +129,20 @@ public class DeviceUtils {
return builder.toString();
}
public static String getUserAgent() {
String userAgent = "";
userAgent = System.getProperty("http.agent");
StringBuffer sb = new StringBuffer();
for (int i = 0, length = userAgent.length(); i < length; i++) {
char c = userAgent.charAt(i);
if (c <= '\u001f' || c >= '\u007f') {
sb.append(String.format("\\u%04x", (int) c));
} else {
sb.append(c);
}
}
return sb.toString();
}
public static String getIPAddress(Context context) {
NetworkInfo info = ((ConnectivityManager) context
@ -224,7 +239,6 @@ public class DeviceUtils {
return "";
}
// ping domain
public static String ping(String domain) {
try {
@ -243,5 +257,13 @@ public class DeviceUtils {
}
}
public static long getTotalRamSizeOfDevice(Context context) {
ActivityManager actManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
if (actManager != null) {
actManager.getMemoryInfo(memInfo);
}
return memInfo.totalMem / (1024 * 1024);
}
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (C) 2015 Baidu, Inc. All Rights Reserved.
*/
package com.gh.common.util;
import android.content.Context;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Created by sunpengfei on 15/11/4.
*/
public class DexUtils {
private static final int BUF_SIZE = 2048;
public static boolean prepareAssetsDex(Context context, File dexInternalStoragePath, String dex_file) {
BufferedInputStream bis = null;
OutputStream dexWriter = null;
try {
bis = new BufferedInputStream(context.getAssets().open(dex_file));
dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath));
byte[] buf = new byte[BUF_SIZE];
int len;
while ((len = bis.read(buf, 0, BUF_SIZE)) > 0) {
dexWriter.write(buf, 0, len);
}
dexWriter.close();
bis.close();
return true;
} catch (IOException e) {
if (dexWriter != null) {
try {
dexWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return false;
}
}
public static boolean prepareDex(File dexInternalStoragePath, File dex_file) {
BufferedInputStream bis = null;
OutputStream dexWriter = null;
try {
bis = new BufferedInputStream(new FileInputStream(dex_file));
dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath));
byte[] buf = new byte[BUF_SIZE];
int len;
while ((len = bis.read(buf, 0, BUF_SIZE)) > 0) {
dexWriter.write(buf, 0, len);
}
dexWriter.close();
bis.close();
return true;
} catch (IOException e) {
if (dexWriter != null) {
try {
dexWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return false;
}
}
}

View File

@ -7,6 +7,7 @@ import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
@ -129,7 +130,7 @@ public class DialogUtils {
ApplicationInfo appInfo = info.applicationInfo;
appInfo.sourceDir = apkPath;
appInfo.publicSourceDir = apkPath;
Bitmap bitmap = BitmapUtils.drawableToBitmap(appInfo.loadIcon(pm));
Bitmap bitmap = BitmapUtils.drawableToBitmap(appInfo.loadIcon(pm), true);
ImageView imageView = new ImageView(activity);
imageView.setLayoutParams(new LinearLayout.LayoutParams(DisplayUtils.dip2px(activity, 25)
@ -328,7 +329,6 @@ public class DialogUtils {
}
public static void showWarningDialog(Context context, String title, CharSequence msg, final ConfirmListener listener) {
//TODO fix this
if (!(context instanceof Activity)) {
return;
}
@ -360,9 +360,16 @@ public class DialogUtils {
} else if (NetworkUtils.isWifiConnected(context) || filter4GorSize(context, size)) {
callBack.onResponse(false);
} else {
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
showDownloadDialog(context,
() -> callBack.onResponse(false),
() -> callBack.onResponse(true));
() -> {
callBack.onResponse(false);
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "立即下载");
},
() -> {
callBack.onResponse(true);
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "连上WiFi后自动下载");
});
}
}
@ -445,7 +452,53 @@ public class DialogUtils {
TextView titleTv = contentView.findViewById(R.id.dialog_title);
TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
if (message.toString().contains("红包奖励")) {//将红包奖励四个字标红
String str = message.toString().substring(0, message.toString().indexOf("红包奖励")) + "<font color='#FF0000'>红包奖励</font>";
contentTv.setText(Html.fromHtml(str));
} else {
contentTv.setText(message);
}
titleTv.setText(title);
negativeTv.setText(negative);
positiveTv.setText(positive);
negativeTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (clListener != null) {
clListener.onCancel();
}
dialog.dismiss();
}
});
positiveTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (cmListener != null) {
cmListener.onConfirm();
}
dialog.dismiss();
}
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
return dialog;
}
public static Dialog showAlertDialog(Context context, String title, Spanned message
, String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
View 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);
TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
contentTv.setText(message);
titleTv.setText(title);
negativeTv.setText(negative);
@ -781,6 +834,62 @@ public class DialogUtils {
dialog.show();
}
public static void showListDialog(Context context,
List<String> selectionList,
DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
String[] selectionArray = new String[selectionList.size()];
selectionArray = selectionList.toArray(selectionArray);
builder.setItems(selectionArray, onClickListener);
AlertDialog dialog = builder.create();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.show();
}
/**
* @param options 供以显示的选项
* @param disabledOptions 显示为灰色的选项(是 options 的子集)
*/
public static void showListDialog(Context context,
List<String> options,
List<String> disabledOptions,
OptionCallback callback) {
Dialog dialog = new Dialog(context);
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setBackgroundColor(Color.WHITE);
container.setPadding(0, DisplayUtils.dip2px(context, 12f), 0, DisplayUtils.dip2px(context, 12f));
for (String option : options) {
TextView reportTv = new TextView(context);
reportTv.setText(option);
reportTv.setTextSize(17f);
if (disabledOptions != null && disabledOptions.contains(option)) {
reportTv.setTextColor(ContextCompat.getColor(context, R.color.btn_gray));
} else {
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
reportTv.setBackgroundResource(R.drawable.textview_white_style);
}
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
reportTv.setLayoutParams(new LinearLayout.LayoutParams(widthPixels * 9 / 10,
LinearLayout.LayoutParams.WRAP_CONTENT));
reportTv.setPadding(DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 12f),
0, DisplayUtils.dip2px(context, 12f));
container.addView(reportTv);
reportTv.setOnClickListener(v -> {
dialog.cancel();
callback.onClicked(reportTv.getText().toString());
});
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(container);
dialog.show();
}
public interface ConfirmListener {
void onConfirm();
}
@ -789,6 +898,9 @@ public class DialogUtils {
void onCancel();
}
public interface OptionCallback {
void onClicked(String text);
}
public interface CheckDownloadCallBack {
void onResponse(boolean isSubscribe);

View File

@ -22,7 +22,7 @@ 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.subject.refactor.SubjectActivity
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.suggest.SuggestType
import com.lightgame.utils.Util_System_ClipboardManager
import com.lightgame.utils.Utils
@ -86,18 +86,20 @@ object DirectUtils {
"community_article" -> context.startActivity(ArticleDetailActivity.getIntent(context, linkEntity.community!!, linkEntity.link!!, entrance, path))
"community_column" -> context.startActivity(CommunitySubjectActivity.getIntent(context, linkEntity.community!!, linkEntity.link, entrance))
"community_column" -> context.startActivity(CommunitySubjectActivity.getIntent(context, linkEntity.community!!, linkEntity.link, entrance, path))
"community_special_column" -> context.startActivity(AskColumnDetailActivity.getIntentByColumnId(context, linkEntity.link, linkEntity.community!!, entrance, path))
"web" -> directToWebView(context, url = linkEntity.link!!, entrance = entrance)
"qq" -> directToQqConversation(context, linkEntity.link)
else -> DialogUtils.showLowVersionDialog(context)
}
}
/**
* 跳转到文章详情
* 跳转到新闻详情
*/
@JvmStatic
fun directToArticle(context: Context, id: String, entrance: String? = null) {
@ -175,7 +177,6 @@ object DirectUtils {
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_PACKAGENAME, packageName)
bundle.putInt(BaseFragment_TabLayout.PAGE_INDEX, INDEX_UPDATE)
bundle.putBoolean(KEY_AUTO_UPDATE, true)
EntranceUtils.jumpActivity(context, bundle)
}

View File

@ -21,6 +21,7 @@ object DownloadHelper {
RetrofitManager.getInstance(HaloApp.getInstance().application)
.api
.getGameDigest(gameId)
.map(ApkActiveUtils.filterMapper)
.subscribeOn(Schedulers.io())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(response: GameEntity?) {

View File

@ -22,7 +22,7 @@ import com.gh.gamecenter.adapter.viewholder.GameViewHolder;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.manager.PackageManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadConfig;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
@ -69,7 +69,7 @@ public class DownloadItemUtils {
// adapter.notifyItemChanged(index);
// }
} else {
if (!queue.contains(platform)) {
if (!queue.contains(platform) && !TextUtils.isEmpty(platform)) {
queue.offer(platform);
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(DownloadItemUtils.class, queue.size(), gameEntity.getBrief(), downloadEntity.getPlatform(), index);
@ -83,7 +83,7 @@ public class DownloadItemUtils {
DownloadManager.getInstance(context).sendMessageDelayed(msg, 3000);
}
}
if (platform.equals(queue.peek())) {
if (platform != null && platform.equals(queue.peek())) {
if (entryMap == null) {
entryMap = new ArrayMap<>();
gameEntity.setEntryMap(entryMap);
@ -96,6 +96,13 @@ public class DownloadItemUtils {
}
}
// 下载按钮显示为查看,并且不提供下载功能
public static void updateItemWithViewOnlyStyle(GameViewHolder holder) {
holder.gameDownloadBtn.setVisibility(View.VISIBLE);
holder.gameDownloadBtn.setText("查看");
holder.gameDownloadBtn.setClickable(false);
}
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
boolean isShowPlatform) {
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game);
@ -159,6 +166,7 @@ public class DownloadItemUtils {
// 更新插件的条目有多个apk包
private static void updatePluginItem(Context context, GameViewHolder holder, GameEntity gameEntity,
boolean isShowPlatform, PluginLocation pluginLocation) {
GameUtils.setDownloadBtnStatus(context, gameEntity, holder.gameDownloadBtn, pluginLocation);
ArrayMap<String, DownloadEntity> entryMap = gameEntity.getEntryMap();
if (entryMap != null && !entryMap.isEmpty()) {
@ -177,8 +185,6 @@ 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);
@ -230,7 +236,8 @@ public class DownloadItemUtils {
} else if (status.equals(DownloadStatus.pause)
|| status.equals(DownloadStatus.timeout)
|| status.equals(DownloadStatus.neterror)
|| status.equals(DownloadStatus.subscribe)) {
|| status.equals(DownloadStatus.subscribe)
|| status.equals(DownloadStatus.overflow)) {
holder.gameProgressbar.setProgress((int) (downloadEntity.getPercent() * 10));
if (isShowPlatform && platform != null) {
holder.gameDownloadSpeed.setText(String.format("%s - 暂停", platform));
@ -240,10 +247,10 @@ public class DownloadItemUtils {
holder.gameDownloadPercentage.setText(downloadEntity.getPercent() + "%");
if (isNormal) {
if (status.equals(DownloadStatus.pause)) {
holder.gameDownloadBtn.setText(R.string.downloading);
} else {
if (status.equals(DownloadStatus.waiting)) {
holder.gameDownloadBtn.setText(R.string.waiting);
} else {
holder.gameDownloadBtn.setText(R.string.downloading);
}
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_downloading_style);
holder.gameDownloadBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style));
@ -258,10 +265,10 @@ public class DownloadItemUtils {
holder.gameDownloadPercentage.setText(R.string.hundred_percent);
if (isNormal) {
holder.gameDownloadBtn.setText("安装");
holder.gameDownloadBtn.setText(R.string.install);
holder.gameDownloadBtn.setTextColor(Color.WHITE);
if (downloadEntity.isPluggable()
&& PackageManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
&& PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
} else {
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
@ -316,43 +323,34 @@ public class DownloadItemUtils {
final String entrance,
final String location,
@Nullable final ExposureEvent traceEvent) {
String str = downloadBtn.getText().toString();
switch (str) {
case "下载":
DialogUtils.checkDownload(context, gameEntity.getApk().get(0).getSize(),
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
break;
case "插件化":
if (entrance.contains("我的游戏")) {
DataUtils.onMtaEvent(context, "我的游戏_启动", "插件化", gameEntity.getName());
}
DialogUtils.checkDownload(context, gameEntity.getApk().get(0).getSize(),
isSubscribe -> plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
break;
case "安装":
install(context, gameEntity, position, adapter);
break;
case "启动":
if (entrance.contains("我的游戏")) {
DataUtils.onMtaEvent(context, "我的游戏_启动", "启动", gameEntity.getName());
}
DataUtils.onGameLaunchEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk().get(0).getPackageName());
break;
case "等待中":
case "下载中":
context.startActivity(
DownloadManagerActivity.getDownloadMangerIntent(context, gameEntity.getApk().get(0).getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
break;
case "更新":
if (entrance.contains("我的游戏")) {
DataUtils.onMtaEvent(context, "我的游戏_启动", "更新", gameEntity.getName());
}
DialogUtils.checkDownload(context, gameEntity.getApk().get(0).getSize(),
isSubscribe -> update(context, gameEntity, entrance, location, isSubscribe, traceEvent));
break;
if (str.equals(context.getString(R.string.download))) {
DialogUtils.checkDownload(context, gameEntity.getApk().get(0).getSize(),
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
} else if (str.equals(context.getString(R.string.pluggable))) {
if (entrance.contains("我的游戏")) {
DataUtils.onMtaEvent(context, "我的游戏_启动", "插件化", gameEntity.getName());
}
DialogUtils.checkDownload(context, gameEntity.getApk().get(0).getSize(),
isSubscribe -> plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
} else if (str.equals(context.getString(R.string.install))) {
install(context, gameEntity, position, adapter);
} else if (str.equals(context.getString(R.string.launch))) {
if (entrance.contains("我的游戏")) {
DataUtils.onMtaEvent(context, "我的游戏_启动", "启动", gameEntity.getName());
}
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,
gameEntity.getApk().get(0).getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
} else if (str.equals(context.getString(R.string.update))) {
if (entrance.contains("我的游戏")) {
DataUtils.onMtaEvent(context, "我的游戏_启动", "更新", gameEntity.getName());
}
DialogUtils.checkDownload(context, gameEntity.getApk().get(0).getSize(),
isSubscribe -> update(context, gameEntity, entrance, location, isSubscribe, traceEvent));
}
}

View File

@ -25,7 +25,7 @@ public class EntranceUtils {
public static final String KEY_URL = "url";
public static final String KEY_GAMENAME = "gameName";
public static final String HOST_ARTICLE = "article";
public static final String HOST_COMMUNITY_ARTICLE = "community.article";
public static final String HOST_COMMUNITY_ARTICLE = "community_article";
public static final String HOST_GAME = "game";
public static final String HOST_GAME_DOWNLOAD = "game_download";
public static final String HOST_COLUMN = "column";
@ -82,7 +82,7 @@ public class EntranceUtils {
public static final String KEY_MESSAGE_TYPE = "messageType";
public static final String KEY_QUESTIONS_SEARCH_KEY = "questionsSearchKey";
public static final String KEY_SHOW_ANSWER_COMMENT = "showAnswerComment";
public static final String KEY_RECOMMENDS_ANSWER = "isRecommendsAnswer";
public static final String KEY_RECOMMENDS_CONTENTS = "isRecommendsContents";
public static final String KEY_VERSION_UPDATE = "versionUpdate";
public static final String KEY_CHECK_QUESTION_CONCERN = "check_question_concern";
public static final String KEY_DRAFT_ID = "draft_id";
@ -98,18 +98,20 @@ public class EntranceUtils {
public static final String KEY_COMMUNITY_DATA = "communityData";
public static final String KEY_TRACE_EVENT = "trace_event";
public static final String KEY_SUBJECT_DATA = "subjectData";
public static final String KEY_SHOW_SELECT_COMMUNITY = "show_select_community";
public static final String KEY_USER_ID = "user_id";
public static final String KEY_QUESTION_TAG = "question_tag";
public static final String KEY_COLUMN_ID = "column_id";
public static final String KEY_AUTO_DOWNLOAD = "auto_download";
public static final String KEY_AUTO_UPDATE = "auto_update";
public static final String KEY_HIDE_SUGGEST_HINT = "hide_suggest_hint";
public static final String KEY_COMMUNITY_ARTICLE_ID = "communityArticleId";
public static final String KEY_ARTICLE_COMMENT_ID = "articleCommentId";
public static final String KEY_DEVICE_NAME = "deviceName";
public static final String KEY_SHOW_ARTICLE_COMMENT = "showArticleComment";
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";
public static final String KEY_OPEN_PLATFORM_WINDOW = "openPlatformWindow";
public static final String KEY_OPEN_KEYBOARD = "openKeyboard";
public static void jumpActivity(Context context, Bundle bundle) {

View File

@ -0,0 +1,138 @@
package com.gh.common.util
import android.content.Context
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.ErrorEntity
import com.lightgame.utils.Utils
/**
* 这个类用来管理一些错误像弹窗、TOAST 什么的
*/
object ErrorHelper {
/**
* 手动匹配处理特定错误码
* [showHighPriorityHint] 用来标识有同样错误码可以触发两种处理时,为 true 时选择重要的
* [customizedHandler] 返回 true 为已处理该错误码false 则交由 [handleError] 处理
*/
fun handleErrorWithCustomizedHandler(context: Context,
errorString: String?,
showHighPriorityHint: Boolean = false,
customizedHandler: (code: Int) -> Boolean) {
val errorEntity = errorString?.toObject<ErrorEntity>()
if (errorEntity == null) {
Utils.toast(context, R.string.post_failure_hint)
return
}
if (!errorEntity.toast.isNullOrEmpty()) {
Utils.toast(context, errorEntity.toast)
return
}
if (customizedHandler(errorEntity.code ?: 0)) {
return
} else {
handleError(context, showHighPriorityHint, errorEntity)
}
}
/**
* [showHighPriorityHint] 用来标识有同样错误码可以触发两种处理时,为 true 时选择重要的
*/
@JvmStatic
fun handleError(context: Context, errorString: String?, showHighPriorityHint: Boolean = false) {
val errorEntity = errorString?.toObject<ErrorEntity>()
if (errorEntity == null) {
Utils.toast(context, R.string.post_failure_hint)
return
}
if (!errorEntity.toast.isNullOrEmpty()) {
Utils.toast(context, errorEntity.toast)
return
}
handleError(context, showHighPriorityHint, errorEntity)
}
/***
* 禁言错误,
*403050 评论回答
*403051 评论资讯文章
*403055 评论社区文章
*403048 发表回答
*403053 发表社区文章
*403049 发布问题
*403046 编辑回答
*403045 编辑答案
*403057 游戏评论
*403054 更新社区文章
*403047 回答点赞
*/
private fun handleError(context: Context, showHighPriorityHint: Boolean = false, errorEntity: ErrorEntity) {
when (errorEntity.code) {
403050,
403051,
403055,
403048,
403053,
403049,
403046,
403045,
403057,
403054,
403047 -> handleErrorWithBannedDialog(context, errorEntity)
403001 -> Utils.toast(context, "标签名称太长了")
403002 -> Utils.toast(context, "已经被邀请了")
403003 -> Utils.toast(context, "每天最多可以邀请10次")
403004 -> Utils.toast(context, "客户端提供的ID无效空/无效ID")
403005 -> Utils.toast(context, "已经回答过了(限制频率)")
403006 -> Utils.toast(context, "图片数量达到限制点")
403007 -> Utils.toast(context, "不合法的用户")
403008 -> Utils.toast(context, "已投票")
403009 -> Utils.toast(context, "已经收藏过了")
403010 -> Utils.toast(context, "无效的标签栏")
403011 -> Utils.toast(context, "标题内容过长")
403012 -> Utils.toast(context, "描述内容过长")
403013 -> Utils.toast(context, "无效的标签")
403014 -> Utils.toast(context, "标签数量太多了")
403015 -> Utils.toast(context, "已经关注过了")
404001 -> Utils.toast(context, "请求的资源不存在")
403016 -> Utils.toast(context, "标签内容可能包含敏感信息,请修改后再提交")
403018 -> Utils.toast(context, R.string.comment_failed_unable)
403020 -> if (showHighPriorityHint) {
DialogUtils.showAlertDialog(context,
"限制提醒",
"提问过于频繁,请先休息一下哦",
"知道了", null, null, null)
} else {
Utils.toast(context, R.string.comment_failed_toofrequent)
}
403021 -> Utils.toast(context, R.string.comment_failed_illegal)
403059 -> Utils.toast(context, "权限错误,请刷新后重试")
else -> Utils.toast(context, R.string.post_failure_hint)
}
}
private fun handleErrorWithBannedDialog(context: Context, errorEntity: ErrorEntity) {
val bannedType = if (errorEntity.data?.alwaysBlock!!) {
""
} else {
"(非永久)"
}
DialogUtils.showAlertDialog(context,
"提示",
"你因违反《问答版块规则》,已被禁言$bannedType如有疑问请联系客服QQ3467475980",
"关闭", null, null, null)
}
}

View File

@ -1,28 +1,42 @@
package com.gh.common.util
import android.app.Activity
import android.app.Application
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.arch.lifecycle.*
import android.content.ClipboardManager
import android.content.Context
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity
import android.support.v4.view.ViewPager
import android.text.Html
import android.text.Spanned
import android.view.View
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import okhttp3.MediaType
import okhttp3.RequestBody
import java.net.URI
/**
* 创建以 activity 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> FragmentActivity.viewModelProvider(
provider: ViewModelProvider.Factory
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(this, provider).get(VM::class.java)
/**
* 创建以 activity 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> Fragment.viewModelProviderFromParent(
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(requireActivity(), provider).get(VM::class.java)
/**
* 创建以 fragment 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> Fragment.viewModelProvider(
provider: ViewModelProvider.Factory
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(this, provider).get(VM::class.java)
@ -50,31 +64,108 @@ fun ViewPager.addOnPageChangeListener(onSelected: ((position: Int) -> Unit)? = n
addOnPageChangeListener(listener)
}
fun Application.ActivityLifecycleCallbacks(callBack: () -> Unit) {
val listener = object : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity?) {
/**
* LiveData Extensions
*/
fun <T> LiveData<T?>.observeNonNull(owner: LifecycleOwner, callback: (T) -> Unit) {
observe(owner, Observer { value ->
if (value != null) {
callback(value)
}
})
}
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
}
/**
* Login related extensions
*/
fun Fragment.ifLogin(entrance: String, action: (() -> Unit)? = null) {
requireContext().ifLogin(entrance, action)
}
override fun onActivityStopped(activity: Activity?) {
}
fun Context.ifLogin(entrance: String, action: (() -> Unit)? = null) {
CheckLoginUtils.checkLogin(this, entrance, action)
}
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
}
override fun onActivityPaused(activity: Activity?) {
}
override fun onActivityResumed(activity: Activity?) {
}
override fun onActivityDestroyed(activity: Activity?) {
}
/**
* Gson related extensions.
*/
inline fun <reified T : Any> String.toObject(): T? {
return try {
GsonUtils.gson.fromJson(this, object : TypeToken<T>() {}.type)
} catch (e: Exception) {
e.printStackTrace()
null
}
registerActivityLifecycleCallbacks(listener)
}
inline fun <reified T : Any> T.toJson(): String {
return GsonUtils.toJson(this)
}
/**
* 在限定 interval 里只触发一次 action
*/
fun debounceActionWithInterval(id: Int, interval: Long = 300, action: (() -> Unit)? = null) {
if (!ClickUtils.isFastDoubleClick(id, interval)) {
action?.invoke()
}
}
fun View.debounceActionWithInterval(interval: Long = 300, action: (() -> Unit)? = null) {
debounceActionWithInterval(this.id, interval, action)
}
/**
* 告诉需要返回 true or false 的外层这个事件已经被消费(即返回 true
*/
inline fun consume(f: () -> Unit): Boolean {
f()
return true
}
/**
* String related
*/
fun String.fromHtml(): Spanned {
return Html.fromHtml(this)
}
// 去掉文章/答案的插入内容
fun String.removeInsertedContent(): String {
val textRegex = "(?s)<div class=\"gh-internal-content content-right\".*?</div>"
return this.replace(textRegex.toRegex(), "")
}
// 完全地清除所有 Html 格式
fun String.clearHtmlFormatCompletely(): String {
return Html.fromHtml(this).toString().replace('\n', 32.toChar())
.replace(160.toChar(), 32.toChar()).replace(65532.toChar(), 32.toChar()).trim { it <= ' ' }
}
// 如果该字符串长度超过固定长度的话,从头开始截取固定长度并返回
fun String.subStringIfPossible(length: Int): String {
return if (this.length > length) {
this.substring(0, length)
} else {
this
}
}
fun String.copyTextAndToast(toastText: String = "复制成功") {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cmb.text = this
Utils.toast(application, toastText)
}
fun Map<String, String>.createRequestBody(): RequestBody {
val json = GsonUtils.toJson(this)
return RequestBody.create(MediaType.parse("application/json"), json)
}
// 对在浏览器(WebView)显示的路径进行转码
fun String.decodeURI(): String {
return URI(null, null, this, null).rawPath
}

View File

@ -0,0 +1,100 @@
package com.gh.common.util
import android.content.Context
import android.text.TextUtils
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.schedulers.Schedulers
/**
* 首页补充游戏库辅助类
*/
object GameRepositoryHelper {
private const val KEY_GAME_REPOSITORY = "game_repository"
var gameCollectionList: List<SubjectEntity> = arrayListOf()
init {
loadSavedRepository()
}
/**
* 获取游戏补充库
*/
@JvmStatic
fun getGameRepository(context: Context) {
RetrofitManager.getInstance(context)
.api
.reserveColumns
.subscribeOn(Schedulers.io())
.subscribe(object : Response<List<SubjectEntity>>() {
override fun onResponse(response: List<SubjectEntity>?) {
super.onResponse(response)
updateGameRepository(response)
}
})
}
/**
* 刷新内存中的游戏库(即从 SP 中再读一次)
*/
@JvmStatic
fun refreshGameRepository() = loadSavedRepository()
private fun loadSavedRepository() {
gameCollectionList = SPUtils.getString(KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
}
fun updateGameRepository(subjects: List<SubjectEntity>?) {
if (subjects == null) return
SPUtils.setString(KEY_GAME_REPOSITORY, subjects.toJson())
gameCollectionList = subjects
}
/**
* 从补充游戏库相应的专题中取出一个与其它游戏都不相同的游戏,为空时即为游戏用完或不存在该相应专题
* @param collectionId 补充游戏库相应专题 ID
* @param gameIdList 该专题里已经包含的游戏 ID 列表
*/
fun getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
collectionId?.let {
val collection = gameCollectionList.find { it.id == collectionId }
collection?.let {
val game = collection.data?.find { game -> isThisGameUnique(game, gameIdList) }
game?.let {
collection.data?.remove(game)
// 产品说要记录补充专题的曝光数,所以这个游戏附带了所在专题的名字
game.subjectName = collection.name
return game
}
}
}
return null
}
private fun isThisGameUnique(game: GameEntity, gameIdList: HashSet<String>): Boolean {
// 若该补充游戏已经存在关联关系,判定为非唯一
for (relatedId in game.relatedGameIds!!) {
gameIdList.contains(relatedId)
return false
}
for (apk in game.getApk()) {
// 检查本地是否已安装该游戏,已过滤那部分框架服务的包名
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
return false
}
}
return !gameIdList.contains(game.id) && !TextUtils.isEmpty(game.id)
}
}

View File

@ -6,14 +6,15 @@ import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.widget.TextView;
import com.gh.common.constant.Config;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameCollectionEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.manager.PackageManager;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.manager.PackagesManager;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
@ -71,15 +72,18 @@ public class GameUtils {
int installCount = 0; // 已安装数量
DownloadEntity downloadEntity;
Object gh_id;
apkFor:
for (ApkEntity apkEntity : gameEntity.getApk()) {
// 去除下载合集判断
boolean isCollection = false;
for (GameCollectionEntity collectionEntity : gameEntity.getCollection()) {
if (collectionEntity.getPackage().contains(apkEntity.getPackageName()))
isCollection = true;
// filter by packageName
SettingsEntity settings = Config.getSettings();
if (settings != null && gameEntity.getApk().size() > 1) {
for (String pkgName : settings.getGameDownloadBlackList()) {
if (pkgName.equals(apkEntity.getPackageName())) {
continue apkFor;
}
}
}
if (isCollection) continue;
downloadEntity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.getUrl());
if (downloadEntity != null) {
@ -91,10 +95,10 @@ public class GameUtils {
updateCount++;
}
}
if (PackageManager.INSTANCE.isCanUpdate(gameEntity.getId(), apkEntity.getPackageName())) {
if (PackagesManager.INSTANCE.isCanUpdate(gameEntity.getId(), apkEntity.getPackageName())) {
updateCount++;
}
if (PackageManager.INSTANCE.isInstalled(apkEntity.getPackageName())) {
if (PackagesManager.INSTANCE.isInstalled(apkEntity.getPackageName())) {
gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
if (gameEntity.getTag() != null && gameEntity.getTag().size() != 0
&& !TextUtils.isEmpty(apkEntity.getGhVersion())
@ -107,19 +111,19 @@ public class GameUtils {
}
}
if (doneCount != 0) {
return "安装";
return context.getString(R.string.install);
} else if (pluginCount != 0) {
return "插件化";
return context.getString(R.string.pluggable);
} else if (updateCount != 0) {
return "更新";
return context.getString(R.string.update);
} else if (installCount != 0) {
if (gameEntity.getApk().size() == 1) {
return "启动";
return context.getString(R.string.launch);
} else {
return "打开";
return context.getString(R.string.open);
}
} else {
return "下载";
return context.getString(R.string.download);
}
}

View File

@ -41,7 +41,7 @@ public class GameViewUtils {
if (i == size - 1) {
view = getGameTagView(context, tag.get(i), 0, tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
} else {
view = getGameTagView(context, tag.get(i), DisplayUtils.dip2px(context, 6), tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
view = getGameTagView(context, tag.get(i), DisplayUtils.dip2px(context, 5), tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
}
if (view != null) {
labelLayout.addView(view);
@ -58,7 +58,7 @@ public class GameViewUtils {
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lparams.rightMargin = rightMargin;
TextView tag = new TextView(context);
tag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
tag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 9);
tag.setSingleLine(true);
tag.setText(tagStr);
if ("官方版".equals(tagStr) || "已关注".equals(tagStr)) {
@ -80,6 +80,7 @@ public class GameViewUtils {
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
tag.setTextColor(Color.WHITE);
}
gradientDrawable.setCornerRadius(DisplayUtils.dip2px(1.5F));
tag.setBackgroundDrawable(gradientDrawable);
} else {
colorStr = TagUtils.getInstance(context).getColor(tagStr);
@ -90,14 +91,15 @@ public class GameViewUtils {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.TRANSPARENT);
gradientDrawable.setStroke(DisplayUtils.dip2px(context, 0.6f), color);
gradientDrawable.setCornerRadius(DisplayUtils.dip2px(1.5F));
tag.setBackgroundDrawable(gradientDrawable);
tag.setTextColor(color);
}
}
tag.setLayoutParams(lparams);
tag.setPadding(DisplayUtils.dip2px(context, 3),
tag.setPadding(DisplayUtils.dip2px(context, 4),
0,
DisplayUtils.dip2px(context, 3),
DisplayUtils.dip2px(context, 4),
DisplayUtils.dip2px(context, 1));
return tag;
}

View File

@ -0,0 +1,51 @@
package com.gh.common.util
import android.app.Application
import android.text.TextUtils
import com.lightgame.utils.Utils
import com.qq.gdt.action.GDTAction
import org.json.JSONObject
/**
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
*/
object GdtHelper {
const val NETWORK_TYPE = "NETWORK_TYPE"
const val PAGE_TYPE = "PAGE_TYPE"
const val CONTENT_TYPE = "CONTENT_TYPE"
const val CONTENT_ID = "CONTENT_ID"
const val KEYWORD = "KEYWORD"
const val GAME_ID = "GAME_ID"
const val SCORE = "SCORE"
const val PLATFORM = "PLATFORM"
fun init(application: Application) {
GDTAction.init(application, "1108222478", "0b2bb2b971c8221be45a8454f05a0b1f")
}
fun logAction(type: String) {
GDTAction.logAction(type)
Utils.log("GDT", type)
}
fun logAction(type: String, vararg kv: String?) {
try {
val actionParam = JSONObject()
for (i in kv.indices) {
if (i % 2 != 0) {
val key = kv[i - 1]
val value = kv[i]
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
actionParam.put(key, value)
}
}
}
Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
GDTAction.logAction(type, actionParam)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@ -16,9 +16,9 @@ import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WbAuthListener;
import com.sina.weibo.sdk.auth.WbConnectErrorMessage;
import com.sina.weibo.sdk.auth.sso.SsoHandler;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.SendAuth;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
@ -56,7 +56,7 @@ public class GetLoginDataUtils {
+ "follow_app_official_microblog," + "invitation_write"; // weiboCode
private GetLoginDataUtils(Context context) {
mContext = context.getApplicationContext();
mContext = context;
mTencent = Tencent.createInstance(Config.TENCENT_APPID, mContext); //初始化QQ分享
mIWXAPI = WXAPIFactory.createWXAPI(mContext, Config.WECHAT_APPID, true); //初始化微信分享
@ -68,7 +68,7 @@ public class GetLoginDataUtils {
public static GetLoginDataUtils getInstance(Context context) {
if (instance == null) {
instance = new GetLoginDataUtils(context);
instance = new GetLoginDataUtils(context.getApplicationContext());
}
return instance;
}
@ -172,7 +172,7 @@ public class GetLoginDataUtils {
}
}
public void WCLofinCallBack(JSONObject content) {
public void WCLoginCallBack(JSONObject content) {
if (mLoginListener != null) {
mLoginListener.OnLoginData(content, LoginTag.wechat);
}

View File

@ -0,0 +1,20 @@
package com.gh.common.util
import android.content.Context
import com.zhihu.matisse.MimeType
import com.zhihu.matisse.filter.Filter
import com.zhihu.matisse.internal.entity.IncapableCause
import com.zhihu.matisse.internal.entity.Item
class GhMatisseFilter : Filter() {
override fun constraintTypes(): MutableSet<MimeType> {
return MimeType.ofVideo()
}
override fun filter(context: Context?, item: Item?): IncapableCause? {
if (!needFiltering(context, item)) return null
return IncapableCause(IncapableCause.TOAST, "暂不支持视频")
}
}

View File

@ -1,45 +1,27 @@
package com.gh.common.util
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
/**
* Created by khy on 11/10/17.
*/
class GsonUtils private constructor() {
val mGson: Gson = Gson()
object GsonUtils {
val gson: Gson = Gson()
companion object {
@JvmStatic
fun getInstance(): GsonUtils {
return Inner.anotherSingle
}
private object Inner {
val anotherSingle = GsonUtils()
}
@JvmStatic
fun <T> fromJson(json: String, t: Class<T>): T {
return gson.fromJson(json, t)
}
fun <T> fromJsonBean(json: String, t: Class<T>): T {
return mGson.fromJson(json, t)
// @JvmStatic
// fun <T> fromJsonList(json: String): List<T> {
// val type = object : TypeToken<List<T>>() {}.type
// return gson.fromJson(json, type)
// }
@JvmStatic
fun toJson(any: Any?): String {
return gson.toJson(any)
}
fun <T> fromJsonList(json: String, t: Class<T>): T {
val type = object : TypeToken<List<T>>() {}.type
return mGson.fromJson(json, type)
}
fun toJson(any: Any): String {
return mGson.toJson(any)
}
}
// Use Kotlin Extension to do the same trick.
inline fun <reified T : Any> String.fromObject(): T {
return GsonUtils.getInstance().mGson.fromJson(this, T::class.java)
}
inline fun <reified T : Any> T.toJson(): String {
return GsonUtils.getInstance().mGson.toJson(this)
}

View File

@ -1,36 +0,0 @@
package com.gh.common.util;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HMACUtils {
public static String encrypt(String data, String key) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
return byte2hex(mac.doFinal(data.getBytes()));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
private static String byte2hex(byte[] ciphertext) {
StringBuilder builder = new StringBuilder();
String stmp;
for (int i = 0; ciphertext != null && i < ciphertext.length; i++) {
stmp = Integer.toHexString(ciphertext[i] & 0XFF);
if (stmp.length() == 1) {
builder.append('0');
}
builder.append(stmp);
}
return builder.toString().toLowerCase();
}
}

View File

@ -1,158 +0,0 @@
/*
* Copyright (C) 2015 Baidu, Inc. All Rights Reserved.
*/
package com.gh.common.util;
import android.annotation.TargetApi;
import android.content.Context;
import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import dalvik.system.DexClassLoader;
import dalvik.system.PathClassLoader;
/* compiled from: ProGuard */
public final class HotFix {
public static void patch(Context context, String patchDexFile, String patchClassName) {
if (patchDexFile != null && new File(patchDexFile).exists()) {
try {
if (hasLexClassLoader()) {
injectInAliyunOs(context, patchDexFile, patchClassName);
} else if (hasDexClassLoader()) {
injectAboveEqualApiLevel14(context, patchDexFile, patchClassName);
} else {
injectBelowApiLevel14(context, patchDexFile, patchClassName);
}
} catch (Throwable th) {
}
}
}
private static boolean hasLexClassLoader() {
try {
Class.forName("dalvik.system.LexClassLoader");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
private static void injectInAliyunOs(Context context, String patchDexFile, String patchClassName)
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException, NoSuchFieldException {
PathClassLoader obj = (PathClassLoader) context.getClassLoader();
String replaceAll = new File(patchDexFile).getName().replaceAll("\\.[a-zA-Z0-9]+", ".lex");
Class cls = Class.forName("dalvik.system.LexClassLoader");
Object newInstance =
cls.getConstructor(new Class[]{String.class, String.class, String.class, ClassLoader.class}).newInstance(
new Object[]{context.getDir("dex", 0).getAbsolutePath() + File.separator + replaceAll,
context.getDir("dex", 0).getAbsolutePath(), patchDexFile, obj});
cls.getMethod("loadClass", new Class[]{String.class}).invoke(newInstance, new Object[]{patchClassName});
setField(obj, PathClassLoader.class, "mPaths",
appendArray(getField(obj, PathClassLoader.class, "mPaths"), getField(newInstance, cls, "mRawDexPath")));
setField(obj, PathClassLoader.class, "mFiles",
combineArray(getField(obj, PathClassLoader.class, "mFiles"), getField(newInstance, cls, "mFiles")));
setField(obj, PathClassLoader.class, "mZips",
combineArray(getField(obj, PathClassLoader.class, "mZips"), getField(newInstance, cls, "mZips")));
setField(obj, PathClassLoader.class, "mLexs",
combineArray(getField(obj, PathClassLoader.class, "mLexs"), getField(newInstance, cls, "mDexs")));
}
private static boolean hasDexClassLoader() {
try {
Class.forName("dalvik.system.BaseDexClassLoader");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
private static void injectAboveEqualApiLevel14(Context context, String str, String str2)
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
PathClassLoader pathClassLoader = (PathClassLoader) context.getClassLoader();
Object a = combineArray(getDexElements(getPathList(pathClassLoader)),
getDexElements(getPathList(
new DexClassLoader(str, context.getDir("dex", 0).getAbsolutePath(), str, context.getClassLoader()))));
Object a2 = getPathList(pathClassLoader);
setField(a2, a2.getClass(), "dexElements", a);
pathClassLoader.loadClass(str2);
}
@TargetApi(14)
private static void injectBelowApiLevel14(Context context, String str, String str2)
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
PathClassLoader obj = (PathClassLoader) context.getClassLoader();
DexClassLoader dexClassLoader =
new DexClassLoader(str, context.getDir("dex", 0).getAbsolutePath(), str, context.getClassLoader());
dexClassLoader.loadClass(str2);
setField(obj, PathClassLoader.class, "mPaths",
appendArray(getField(obj, PathClassLoader.class, "mPaths"), getField(dexClassLoader, DexClassLoader.class,
"mRawDexPath")
));
setField(obj, PathClassLoader.class, "mFiles",
combineArray(getField(obj, PathClassLoader.class, "mFiles"), getField(dexClassLoader, DexClassLoader.class,
"mFiles")
));
setField(obj, PathClassLoader.class, "mZips",
combineArray(getField(obj, PathClassLoader.class, "mZips"), getField(dexClassLoader, DexClassLoader.class,
"mZips")));
setField(obj, PathClassLoader.class, "mDexs",
combineArray(getField(obj, PathClassLoader.class, "mDexs"), getField(dexClassLoader, DexClassLoader.class,
"mDexs")));
obj.loadClass(str2);
}
private static void setField(Object obj, Class cls, String str, Object obj2)
throws NoSuchFieldException, IllegalAccessException {
Field declaredField = cls.getDeclaredField(str);
declaredField.setAccessible(true);
declaredField.set(obj, obj2);
}
private static Object appendArray(Object obj, Object obj2) {
Class componentType = obj.getClass().getComponentType();
int length = Array.getLength(obj);
Object newInstance = Array.newInstance(componentType, length + 1);
Array.set(newInstance, 0, obj2);
for (int i = 1; i < length + 1; i++) {
Array.set(newInstance, i, Array.get(obj, i - 1));
}
return newInstance;
}
private static Object getField(Object obj, Class cls, String str)
throws NoSuchFieldException, IllegalAccessException {
Field declaredField = cls.getDeclaredField(str);
declaredField.setAccessible(true);
return declaredField.get(obj);
}
private static Object combineArray(Object obj, Object obj2) {
Class componentType = obj2.getClass().getComponentType();
int length = Array.getLength(obj2);
int length2 = Array.getLength(obj) + length;
Object newInstance = Array.newInstance(componentType, length2);
for (int i = 0; i < length2; i++) {
if (i < length) {
Array.set(newInstance, i, Array.get(obj2, i));
} else {
Array.set(newInstance, i, Array.get(obj, i - length));
}
}
return newInstance;
}
private static Object getDexElements(Object obj) throws NoSuchFieldException, IllegalAccessException {
return getField(obj, obj.getClass(), "dexElements");
}
private static Object getPathList(Object obj) throws ClassNotFoundException, NoSuchFieldException,
IllegalAccessException {
return getField(obj, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
}
}

View File

@ -9,22 +9,9 @@ import java.util.regex.Pattern;
* Created by khy on 27/12/17.
*/
public class AskUtils {
// public static String voteCountFormat(int voteCount) {
// String vote;
// if (voteCount >= 10000) {
// DecimalFormat df = new DecimalFormat("#.0万");
// vote = df.format(voteCount / 10000f);
// } else {
// vote = String.valueOf(voteCount);
// }
// return vote;
// }
public class HtmlUtils {
public static String stripHtml(String htmlStr) {
if (TextUtils.isEmpty(htmlStr)) return "";
String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
@ -45,5 +32,4 @@ public class AskUtils {
return htmlStr.trim(); //返回文本字符串
}
}

View File

@ -2,9 +2,11 @@ package com.gh.common.util
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.drawable.Animatable
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.support.annotation.DrawableRes
import android.support.v4.content.ContextCompat
import com.facebook.common.executors.CallerThreadExecutor
@ -20,6 +22,7 @@ import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.gh.common.constant.Config
import com.gh.gamecenter.R
import java.io.ByteArrayOutputStream
object ImageUtils {
@ -231,12 +234,23 @@ object ImageUtils {
*/
@JvmStatic
fun display(view: SimpleDraweeView?, url: String?) {
val width = view?.layoutParams?.width
if (width != null && width > 0) {
view.setImageURI(getTransformLimitUrl(url, width, view.context))
} else {
view?.post {
view.setImageURI(getTransformLimitUrl(url, view.width, view.context))
url?.let {
// 图片是以 gif 结尾的就
if (it.endsWith(".gif")) {
val controller = Fresco.newDraweeControllerBuilder()
.setUri(url)
.setAutoPlayAnimations(true)
.build()
view?.controller = controller
} else {
val width = view?.layoutParams?.width
if (width != null && width > 0) {
view.setImageURI(getTransformLimitUrl(url, width, view.context))
} else {
view?.post {
view.setImageURI(getTransformLimitUrl(url, view.width, view.context))
}
}
}
}
}
@ -247,7 +261,10 @@ object ImageUtils {
if (width != null && width > 0) {
val transformUrlX2 = addLimitWidth(url, width * 2)
val transformUrlX1 = addLimitWidth(url, width)
if (NetworkUtils.isWifiOr4GConnected(context)) {
// 当网络为 WIFI 或 4G 且系统版本大于 5.0 && 手机内存大于 1G 才用高清图片
if (NetworkUtils.isWifiOr4GConnected(context)
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP
&& DeviceUtils.getTotalRamSizeOfDevice(context) > 1000) {
transformUrl = transformUrlX2
} else {
// 检查X2大图是否被缓存
@ -278,6 +295,24 @@ object ImageUtils {
}
}
@JvmStatic
fun bmpToByteArray(bmp: Bitmap, needRecycle: Boolean): ByteArray {
val output = ByteArrayOutputStream()
bmp.compress(Bitmap.CompressFormat.PNG, 100, output)
if (needRecycle) {
bmp.recycle()
}
val result = output.toByteArray()
try {
output.close()
} catch (e: Exception) {
e.printStackTrace()
}
return result
}
@JvmStatic
fun display(draweeView: SimpleDraweeView, @DrawableRes res: Int?) {

View File

@ -64,15 +64,13 @@ public class InstallUtils {
keys.add(packageName);
DownloadEntity downloadEntity = DownloadManager.getInstance(context).getDownloadEntityByPackageName(packageName);
String installVersion = PackageUtils.getVersionByPackage(context, packageName);
String installVersion = PackageUtils.getVersionByPackage(packageName);
if (!TextUtils.isEmpty(installVersion) && downloadEntity != null &&
installVersion.equals(downloadEntity.getVersionName())) {
if (!downloadEntity.isPluggable() || PackageUtils.isSignature(context, packageName)) {
EventBus.getDefault().post(new EBPackage("安装", packageName));
}
}
}
}
for (String key : keys) {
@ -109,7 +107,7 @@ public class InstallUtils {
if (mInstance == null) {
synchronized (InstallUtils.class) {
if (mInstance == null) {
mInstance = new InstallUtils(context);
mInstance = new InstallUtils(context.getApplicationContext());
}
}
}

View File

@ -1,32 +0,0 @@
package com.gh.common.util;
import android.support.v4.content.ContextCompat;
import android.widget.TextView;
import com.gh.gamecenter.R;
/**
* Created by khy on 2017/3/19.
*/
public class KaiFuUtils {
public static void setKaiFuType(TextView textView, String type) {
if (type == null) return;
textView.setText(type);
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
// switch (type) {
// case "不删档内测":
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.content));
// break;
// case "删档内测":
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.content));
// break;
// case "公测":
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
// break;
// default:
// textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), R.color.tag_yellow));
// break;
// }
}
}

View File

@ -3,7 +3,6 @@ package com.gh.common.util;
import android.app.Dialog;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
@ -11,20 +10,18 @@ import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.LibaoDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.LibaoDetailAdapter;
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.UserDataLibaoEntity;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBUISwitch;
import com.gh.gamecenter.geetest.GeetestListener;
import com.gh.gamecenter.geetest.GeetestUtils;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.retrofit.JSONObjectResponse;
@ -36,6 +33,7 @@ import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Observable;
@ -86,7 +84,7 @@ public class LibaoUtils {
.subscribe(new JSONObjectResponse() {
@Override
public void onResponse(JSONObject response) {
listener.postSucced(response);
listener.postSucceed(response);
}
@Override
@ -107,7 +105,7 @@ public class LibaoUtils {
.subscribe(new JSONObjectResponse() {
@Override
public void onResponse(JSONObject response) {
listener.postSucced(response);
listener.postSucceed(response);
}
@Override
@ -125,7 +123,7 @@ public class LibaoUtils {
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(ResponseBody response) {
listener.postSucced(response);
listener.postSucceed(response);
}
@Override
@ -142,7 +140,7 @@ public class LibaoUtils {
.subscribe(new Response<List<LibaoStatusEntity>>() {
@Override
public void onResponse(List<LibaoStatusEntity> response) {
listener.postSucced(response);
listener.postSucceed(response);
}
@Override
@ -216,6 +214,10 @@ public class LibaoUtils {
libaoBtn.setText(R.string.libao_unshelve);
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
break;
case "check":
libaoBtn.setText(R.string.libao_check);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
default:
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
libaoBtn.setText("异常");
@ -229,77 +231,166 @@ public class LibaoUtils {
String status = libaoEntity.getStatus();
setLiBaoBtnStatus(libaoBtn, status, context);
libaoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckLoginUtils.checkLogin(context, () -> {
// 领取限制
if ("领取".equals(libaoBtn.getText().toString()) || "淘号".equals(libaoBtn.getText().toString())) {
if (isInstallRequired && !isAppInstalled(context, libaoEntity.getPackageName())) {
String platform;
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
platform = "";
} else {
platform = PlatformUtils.getInstance(context)
.getPlatformName(libaoEntity.getPlatform()) + "";
}
libaoBtn.setOnClickListener(v -> {
String btnStatus = libaoBtn.getText().toString();
CheckLoginUtils.checkLogin(context, "礼包详情-[" + btnStatus + "]", () -> {
// 领取限制
String dialogContent = context.getString(R.string.ling_rules_dialog, libaoEntity.getGame().getName(), platform);
DialogUtils.showWarningDialog(context, "条件不符",
Html.fromHtml(dialogContent), "关闭", "立即安装"
, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
adapter.openDownload();
}
}, null);
if ("领取".equals(btnStatus) || "淘号".equals(btnStatus)) {
if (isInstallRequired && !isAppInstalled(context, libaoEntity.getPackageName())) {
String platform;
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
platform = "";
} else {
platform = PlatformUtils.getInstance(context)
.getPlatformName(libaoEntity.getPlatform());
}
boolean isExistPlatform = false;
ArrayList<ApkEntity> apk = adapter.getGameEntity().getApk();
for (ApkEntity apkEntity : apk) {
if (TextUtils.isEmpty(libaoEntity.getPlatform())) break;
if (libaoEntity.getPlatform().equals(apkEntity.getPlatform())) {
isExistPlatform = true;
break;
}
}
String dialogContent = context.getString(R.string.ling_rules_dialog, libaoEntity.getGame().getName(), platform);
boolean finalIsExistPlatform = isExistPlatform;
DialogUtils.showWarningDialog(context, "条件不符",
Html.fromHtml(dialogContent), isExistPlatform ? "关闭" : null,
isExistPlatform ? "立即安装" : "关闭",
() -> {
if (finalIsExistPlatform) {
adapter.openDownload(libaoEntity.getPlatform());
}
}, null);
return;
}
}
switch (btnStatus) {
case "未开始":
Utils.toast(context, "还没到开始领取时间");
break;
case "查看":
if (!TextUtils.isEmpty(libaoEntity.getDes())) {
DialogUtils.showAlertDialog(v.getContext(), "使用说明",
Html.fromHtml(libaoEntity.getDes()), "关闭", null, null, null);
}
break;
case "再领一个":
case "领取":
if ("repeatLing".equals(status)) {
DialogUtils.showWarningDialog(context, "礼包刷新提醒"
, "礼包每天0点刷新换新区或者换新角色需要继续领取礼包的童鞋请于明天0点之后回来即可[再领一个]"
, null, "知道了", null, null);
} else {
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance);
}
break;
case "再淘一个":
case "淘号":
if ("repeatTao".equals(status)) {
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
return;
}
}
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "淘号中...");
postLibaoTao(context, libaoEntity.getId(), new PostLibaoListener() {
@Override
public void postSucceed(Object response) {
switch (libaoBtn.getText().toString()) {
case "未开始":
Utils.toast(context, "还没到开始领取时间");
break;
case "查看":
Intent intent = LibaoDetailActivity.getIntent(context, libaoEntity, entrance);
context.startActivity(intent);
break;
case "再领一个":
case "领取":
if ("repeatLing".equals(status)) {
DialogUtils.showWarningDialog(context, "礼包刷新提醒"
, "礼包每天0点刷新换新区或者换新角色需要继续领取礼包的童鞋请于明天0点之后回来即可[再领一个]"
, null, "知道了", null, null);
} else {
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance);
}
break;
case "再淘一个":
case "淘号":
if ("repeatTao".equals(status)) {
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
return;
}
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "淘号中...");
postLibaoTao(context, libaoEntity.getId(), new PostLibaoListener() {
@Override
public void postSucced(Object response) {
if (loadingDialog != null) loadingDialog.dismiss();
if (loadingDialog != null) loadingDialog.dismiss();
JSONObject responseBody = (JSONObject) response;
String libaoCode = null;
try {
libaoCode = responseBody.getString("code");
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject responseBody = (JSONObject) response;
String libaoCode = null;
if (TextUtils.isEmpty(libaoCode)) {
try {
libaoCode = responseBody.getString("code");
String detail = responseBody.getString("detail");
switch (detail) {
case "maintaining":
Utils.toast(context, "网络状态异常,请稍后再试");
break;
case "fail to compete":
Utils.toast(context, "淘号失败,稍后重试");
break;
default:
Utils.toast(context, "淘号异常");
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
return;
}
if (TextUtils.isEmpty(libaoCode)) {
Utils.toast(context, "淘号成功");
libaoEntity.setStatus("taoed");
EventBus.getDefault().post(new EBReuse("libaoChanged"));
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "tao", Utils.getTime(context)));
final String finalLibaoCode = libaoCode;
DialogUtils.showWarningDialog(context, "淘号成功"
, Html.fromHtml(context.getString(R.string.taoed_dialog, libaoCode))
, "关闭", " 复制礼包码"
, () -> {
copyLink(finalLibaoCode, context);
if (isInstallRequired) {
libaoBtn.postDelayed(() -> {
Spanned msg = Html.fromHtml(
context.getString(R.string.taoed_copy_dialog
, finalLibaoCode));
lunningAppDialog(context
, msg, libaoEntity);
}, 300);
}
}, null);
}
@Override
public void postFailed(Throwable error) {
Utils.log("---" + error.toString());
if (loadingDialog != null) loadingDialog.dismiss();
if (error instanceof HttpException) {
HttpException exception = (HttpException) error;
if (exception.code() == 403) {
try {
String detail = responseBody.getString("detail");
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
String detail = errorJson.getString("detail");
// Utils.toast(context, "返回::" + detail);
switch (detail) {
case "coming":
Utils.toast(context, "礼包领取时间未开始");
break;
case "finish":
Utils.toast(context, "礼包领取时间已结束");
break;
case "fetched":
Utils.toast(context, "你今天已领过这个礼包了, 不能再淘号");
libaoBtn.setText("已淘号");
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
libaoEntity.setStatus("taoed");
break;
case "try tao":
case "used up":
DialogUtils.showHintDialog(context, "礼包已领光"
, "手速不够快,礼包已经被抢光了,十分抱歉", "知道了");
break;
case "maintaining":
Utils.toast(context, "网络状态异常,请稍后再试");
break;
@ -307,108 +398,25 @@ public class LibaoUtils {
Utils.toast(context, "淘号失败,稍后重试");
break;
default:
Utils.toast(context, "淘号异常");
Utils.toast(context, "操作失败");
break;
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
Utils.toast(context, "礼包处理异常" + ex.toString());
}
return;
} else if (exception.code() == 401) {
return;
}
Utils.toast(context, "淘号成功");
libaoEntity.setStatus("taoed");
EventBus.getDefault().post(new EBReuse("libaoChanged"));
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "tao", Utils.getTime(context)));
final String finalLibaoCode = libaoCode;
DialogUtils.showWarningDialog(context, "淘号成功"
, Html.fromHtml(context.getString(R.string.taoed_dialog, libaoCode))
, "关闭", " 复制礼包码"
, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
copyLink(finalLibaoCode, context);
if (isInstallRequired) {
libaoBtn.postDelayed(new Runnable() {
@Override
public void run() {
Spanned msg = Html.fromHtml(
context.getString(R.string.taoed_copy_dialog
, finalLibaoCode));
lunningAppDialog(context
, msg, libaoEntity);
}
}, 300);
}
}
}, null);
}
@Override
public void postFailed(Throwable error) {
Utils.log("---" + error.toString());
if (loadingDialog != null) loadingDialog.dismiss();
if (error instanceof HttpException) {
HttpException exception = (HttpException) error;
if (exception.code() == 403) {
try {
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
String detail = errorJson.getString("detail");
// Utils.toast(context, "返回::" + detail);
switch (detail) {
case "coming":
Utils.toast(context, "礼包领取时间未开始");
break;
case "finish":
Utils.toast(context, "礼包领取时间已结束");
break;
case "fetched":
Utils.toast(context, "你今天已领过这个礼包了, 不能再淘号");
libaoBtn.setText("已淘号");
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
libaoEntity.setStatus("taoed");
break;
case "try tao":
case "used up":
DialogUtils.showHintDialog(context, "礼包已领光"
, "手速不够快,礼包已经被抢光了,十分抱歉", "知道了");
break;
case "maintaining":
Utils.toast(context, "网络状态异常,请稍后再试");
break;
case "fail to compete":
Utils.toast(context, "淘号失败,稍后重试");
break;
default:
Utils.toast(context, "操作失败");
break;
}
} catch (Exception ex) {
ex.printStackTrace();
Utils.toast(context, "礼包处理异常" + ex.toString());
}
return;
} else if (exception.code() == 401) {
return;
}
}
Utils.toast(context, "发生异常");
}
});
break;
}
});
}
Utils.toast(context, "发生异常");
}
});
break;
}
});
});
}
@ -423,7 +431,7 @@ public class LibaoUtils {
postLibaoLing(context, libaoEntity.getId(), new PostLibaoListener() {
@Override
public void postSucced(Object response) {
public void postSucceed(Object response) {
if (loadingDialog != null) loadingDialog.dismiss();
JSONObject responseBody = (JSONObject) response;
@ -450,20 +458,14 @@ public class LibaoUtils {
final String finalLibaoCode = libaoCode;
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, libaoCode))
, "关闭", " 复制礼包码"
, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
copyLink(finalLibaoCode, context);
if (isInstallRequired) {
libaoBtn.postDelayed(new Runnable() {
@Override
public void run() {
Spanned msg = Html.fromHtml(context.getString(R.string.linged_copy_dialog, finalLibaoCode));
lunningAppDialog(context
, msg, libaoEntity);
}
}, 300);
}
, () -> {
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);
}
@ -524,12 +526,8 @@ public class LibaoUtils {
return;
} else if (exception.code() == 412) {
// 需要验证
GeetestUtils.getInstance().showDialog(context, new GeetestListener() {
@Override
public void onVerified(String captcha) {
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, captcha, entrance);
}
});
GeetestUtils.getInstance().showDialog(context, captcha ->
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, captcha, entrance));
return;
} else if (exception.code() == 401) {
return;
@ -557,17 +555,14 @@ public class LibaoUtils {
public static void lunningAppDialog(final Context context, Spanned msg, final LibaoEntity libaoEntity) {
DialogUtils.showWarningDialog(context, "复制成功", msg
, "关闭", "启动游戏"
, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
if (LibaoUtils.isAppInstalled(context, libaoEntity.getPackageName())) {
PackageUtils.launchApplicationByPackageName(context, libaoEntity.getPackageName());
} else {
Utils.toast(context, "请安装游戏:" + libaoEntity.getGame().getName()
+ PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform()) + "");
}
, () -> {
if (LibaoUtils.isAppInstalled(context, libaoEntity.getPackageName())) {
PackageUtils.launchApplicationByPackageName(context, libaoEntity.getPackageName());
} else {
Utils.toast(context, "请安装游戏:" + libaoEntity.getGame().getName()
+ PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform()) + "");
}
}, null);
}
@ -634,7 +629,7 @@ public class LibaoUtils {
public interface PostLibaoListener {
void postSucced(Object response);
void postSucceed(Object response);
void postFailed(Throwable error);
}

View File

@ -6,7 +6,9 @@ import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.SpecialColumn;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.loghub.LogHubUtils;
@ -22,8 +24,12 @@ import org.json.JSONObject;
*/
public class LogUtils {
public static void uploadCommunityArticle(String tracers, String articleId, String articleTitle,
int readTime, CommunityEntity community) {
public static void uploadCommunityArticle(String tracers,
String articleId,
String articleTitle,
int readTime,
CommunityEntity community,
SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
object.put("subject", "community_article");
@ -33,11 +39,22 @@ public class LogUtils {
object.put("article_name", articleTitle);
object.put("tracers", tracers);
object.put("read", readTime);
JSONObject columnObject = new JSONObject();
if (specialColumn != null) {
columnObject.put("type", specialColumn.getType());
columnObject.put("name", specialColumn.getName());
columnObject.put("tab", specialColumn.getTab());
} else {
columnObject.put("type", "");
columnObject.put("name", "");
columnObject.put("tab", "");
}
object.put("special_column", columnObject);
} catch (JSONException e) {
e.printStackTrace();
}
upload(HaloApp.getInstance().getApplication(), object);
upload(object);
}
public static void uploadDevice(LunchType launchType) {
@ -47,54 +64,84 @@ public class LogUtils {
object.put("subject", "halo_device");
object.put("launch_time", Utils.getTime(application));
object.put("launch_type", launchType.name());
object.put("network", DeviceUtils.getNetwork(application));
object.put("device_model", android.os.Build.MODEL);
object.put("manufacture", Build.MANUFACTURER);
object.put("device_system", android.os.Build.VERSION.RELEASE);
} catch (JSONException e) {
e.printStackTrace();
}
upload(application, object);
upload(object);
}
public static void uploadAnswerReadTime(String tracers, int readTime, String answerId, Questions questions) {
public static void uploadAnswerReadTime(String tracers,
int readTime,
String answerId,
Questions questions,
String communityId,
String CommunityName,
SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
object.put("subject", "answer");
object.put("community_id", UserManager.getInstance().getCommunity().getId());
object.put("community_name", UserManager.getInstance().getCommunity().getName());
object.put("community_id", communityId);
object.put("community_name", CommunityName);
object.put("question_id", questions.getId());
object.put("question_name", questions.getTitle());
object.put("tracers", tracers);
object.put("answer_id", answerId);
object.put("read", readTime);
JSONObject columnObject = new JSONObject();
if (specialColumn != null) {
columnObject.put("type", specialColumn.getType());
columnObject.put("name", specialColumn.getName());
columnObject.put("tab", specialColumn.getTab());
} else {
columnObject.put("type", "");
columnObject.put("name", "");
columnObject.put("tab", "");
}
object.put("special_column", columnObject);
} catch (JSONException e) {
e.printStackTrace();
}
upload(HaloApp.getInstance().getApplication(), object);
upload(object);
}
public static void uploadQuestionReadTime(String tracers, int readTime, Questions questions) {
public static void uploadQuestionReadTime(String tracers,
int readTime,
Questions questions,
String communityId,
String communityName,
SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
object.put("subject", "question");
object.put("community_id", UserManager.getInstance().getCommunity().getId());
object.put("community_name", UserManager.getInstance().getCommunity().getName());
object.put("community_id", communityId);
object.put("community_name", communityName);
object.put("question_id", questions.getId());
object.put("question_name", questions.getTitle());
object.put("tracers", tracers);
object.put("read", readTime);
JSONObject columnObject = new JSONObject();
if (specialColumn != null) {
columnObject.put("type", specialColumn.getType());
columnObject.put("name", specialColumn.getName());
columnObject.put("tab", specialColumn.getTab());
} else {
columnObject.put("type", "");
columnObject.put("name", "");
columnObject.put("tab", "");
}
object.put("special_column", columnObject);
} catch (JSONException e) {
e.printStackTrace();
}
upload(HaloApp.getInstance().getApplication(), object);
upload(object);
}
public static void uploadSearch(Context context, String searchKey) {
if (TextUtils.isEmpty(searchKey) || context == null) return;
public static void uploadSearch(String searchKey) {
if (TextUtils.isEmpty(searchKey)) return;
JSONObject object = new JSONObject();
try {
@ -106,12 +153,11 @@ public class LogUtils {
e.printStackTrace();
}
upload(context, object);
upload(object);
}
public static void communityRefresh(Context context, int dataCount, boolean manualRefresh) {
if (context == null) return;
public static void communityRefresh(int dataCount, boolean manualRefresh) {
JSONObject object = new JSONObject();
try {
object.put("subject", "community_refresh");
@ -119,46 +165,44 @@ public class LogUtils {
object.put("refresh_type", "recommend");
object.put("refresh_way", manualRefresh ? "manual" : "auto");
object.put("data_count", dataCount);
object.put("user_id", UserManager.getInstance().getUserId());
object.put("network", DeviceUtils.getNetwork(context));
object.put("version", PackageUtils.getPatchVersionName());
object.put("channel", HaloApp.getInstance().getChannel());
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
object.put("imei", Util_System_Phone_State.getDeviceId(context));
object.put("device_system", android.os.Build.VERSION.RELEASE);
object.put("device_model", android.os.Build.MODEL);
object.put("time", Utils.getTime(context));
} catch (JSONException e) {
e.printStackTrace();
}
upload(context, object);
upload(object);
}
public static void login(Context context, String loginStep, String loginType) {
if (context == null) return;
public static void login(String loginStep, String loginType, String entrance) {
JSONObject object = new JSONObject();
try {
object.put("entrance", entrance);
object.put("subject", "login");
object.put("step", loginStep);
object.put("login_type", loginType);
object.put("network", DeviceUtils.getNetwork(context));
} catch (JSONException e) {
e.printStackTrace();
}
upload(context, object);
upload(object);
}
private static void upload(Context context, JSONObject object) {
if (context == null) return;
private static void upload(JSONObject object) {
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
Context context = HaloApp.getInstance().getApplication();
try {
object.put("version", PackageUtils.getPatchVersionName());
object.put("version", PackageUtils.getVersionName());
object.put("channel", HaloApp.getInstance().getChannel());
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
object.put("imei", Util_System_Phone_State.getDeviceId(context));
object.put("time", Utils.getTime(context));
object.put("network", DeviceUtils.getNetwork(context));
object.put("user_id", UserManager.getInstance().getUserId());
object.put("device_system", android.os.Build.VERSION.RELEASE);
object.put("device_model", android.os.Build.MODEL);
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance().getApplication()));
object.put("G_ID", UserManager.getInstance().getDeviceId());
} catch (JSONException e) {
e.printStackTrace();
}

View File

@ -1,9 +1,7 @@
package com.gh.common.util;
import android.content.Context;
import android.text.TextUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.retrofit.JSONObjectResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
@ -12,8 +10,6 @@ import com.lightgame.utils.Utils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Iterator;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
@ -106,64 +102,6 @@ public class LoginUtils {
});
}
public static void userPostErrorToast(String errorString, Context context, boolean isQuestion) {
if (TextUtils.isEmpty(errorString)) {
Utils.toast(context, R.string.post_failure_hint);
return;
}
try {
JSONObject errorJson = new JSONObject(errorString);
Iterator<String> iterator = errorJson.keys();
while (iterator.hasNext()) {
String key = iterator.next();
if ("toast".equals(key)) {
Utils.toast(context, errorJson.get(key).toString());
return;
}
}
int errorCode = errorJson.getInt("code");
switch (errorCode) {
case 403018:
Utils.toast(context, R.string.comment_failed_unable);
case 403050:
case 403053:
case 403048:
case 403049:
case 403057:
case 403045:
case 403046:
case 403054:
Utils.toast(context, R.string.comment_failed_userbanned);
break;
case 403051:
Utils.toast(context, R.string.comment_failed_userblocked);
break;
case 403020:
if (isQuestion) {
DialogUtils.showAlertDialog(context, "限制提醒"
, "提问过于频繁,请先休息一下哦", "知道了"
, null, null, null);
} else {
Utils.toast(context, R.string.comment_failed_toofrequent);
}
break;
case 403021:
Utils.toast(context, R.string.comment_failed_illegal);
break;
case 403047:
Utils.toast(context, R.string.deny_vote_answer);
break;
default:
Utils.toast(context, R.string.post_failure_hint);
break;
}
} catch (JSONException e) {
Utils.toast(context, R.string.post_failure_hint);
e.printStackTrace();
}
}
public static void captchaErrorHint(Context context, JSONObject content) {
try {
@ -314,12 +252,18 @@ public class LoginUtils {
case 403016:
Utils.toast(context, "内容违规,请修改后再保存");
break;
case 403021:
Utils.toast(context, "内容可能包含敏感信息,请修改后再提交");
break;
case 403801:
Utils.toast(context, "获取验证码太频繁,请稍后再试");
break;
case 403204:
Utils.toast(context, "获取验证码太频繁,请稍后再试");
break;
case 400212:
Utils.toast(context, "请输入正确的手机号");
break;
default:
Utils.toast(context, code + "");
break;

View File

@ -11,11 +11,11 @@ import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.KeyEvent;
import android.support.v4.content.*;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -28,19 +28,17 @@ import com.gh.common.constant.Config;
import com.gh.gamecenter.R;
import com.lightgame.utils.Utils;
import com.tencent.connect.share.QQShare;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.SendMessageToWX;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.mm.sdk.openapi.WXImageObject;
import com.tencent.mm.sdk.openapi.WXMediaMessage;
import com.tencent.mm.sdk.platformtools.Util;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
@ -255,6 +253,11 @@ public class MessageShareUtils {
private void wechatSahre() {
Utils.toast(mContext, "分享跳转中...");
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
Utils.toast(mContext, "没安装微信,分享失败");
return;
}
//官方分享
// WXImageObject imgObj = new WXImageObject();
// imgObj.setImagePath(mContext.getExternalCacheDir().getPath() + "/ShareImg/" + picName);
@ -286,6 +289,11 @@ public class MessageShareUtils {
private void wechatMomentsSahre() {
Utils.toast(mContext, "分享跳转中...");
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
Utils.toast(mContext, "没安装微信,分享失败");
return;
}
WXImageObject imgObj = new WXImageObject();
imgObj.setImagePath(mContext.getExternalCacheDir().getPath() + "/ShareImg/" + picName);
WXMediaMessage msg = new WXMediaMessage();
@ -298,7 +306,7 @@ public class MessageShareUtils {
req.scene = SendMessageToWX.Req.WXSceneTimeline;
Bitmap compressBp = compressBitmap(shareBm);
msg.thumbData = Util.bmpToByteArray(compressBp, true);
msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true);
mIWXAPI.sendReq(req);
if (mPopupWindow == null) return;
@ -366,7 +374,7 @@ public class MessageShareUtils {
}
}
}
} catch (FileNotFoundException e) {
} catch (Exception e) {
Utils.log("消息分享异常" + e.toString());
e.printStackTrace();
} finally {

View File

@ -5,6 +5,7 @@ import android.text.TextUtils
import com.gh.gamecenter.BuildConfig
import com.halo.assistant.HaloApp
import com.lightgame.utils.Util_System_Phone_State
import com.lightgame.utils.Utils
import com.tencent.stat.StatService
import java.util.*
@ -13,6 +14,12 @@ object MtaHelper {
@JvmStatic
fun onEvent(eventId: String, vararg kv: String?) {
val prop = Properties()
if (kv.size == 1) {
prop.setProperty(kv[0], "")
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
}
for (i in kv.indices) {
if (i % 2 != 0) {
val key = kv[i - 1]
@ -22,9 +29,29 @@ object MtaHelper {
}
}
}
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
}
@JvmStatic
fun onEventWithTime(eventId: String, time: Int, vararg kv: String?) {
val prop = Properties()
for (i in kv.indices) {
if (i % 2 != 0 || i != 0) {
val key = kv[i - 1]
val value = kv[i]
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
prop.setProperty(key, value)
}
}
}
if (prop.size == 0) return
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
}
/**
* 这个方法除了记录传进来的入参还会附带一些基本的设备信息
*/
@ -47,8 +74,11 @@ object MtaHelper {
prop.setProperty("机型", Build.MODEL)
prop.setProperty("厂商", Build.MANUFACTURER)
prop.setProperty("Android版本", Build.VERSION.RELEASE)
prop.setProperty("GID", HaloApp.getInstance().gid)
if (!TextUtils.isEmpty(HaloApp.getInstance().gid)) {
prop.setProperty("GID", HaloApp.getInstance().gid)
}
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
}

View File

@ -3,6 +3,7 @@ package com.gh.common.util;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
public class NetworkUtils {
@ -52,6 +53,12 @@ public class NetworkUtils {
return false;
}
public static boolean isWifiOr4GOr3GConnected(Context context) {
String network = DeviceUtils.getNetwork(context);
return "WIFI".equals(network) || "4G".equals(network) || "3G".equals(network);
}
/**
* 判断MOBILE网络是否可用
*
@ -113,4 +120,48 @@ public class NetworkUtils {
return "NONE";
}
/**
* 获取当前移动网络连接的类型信息(当连接的网络是移动网络时使用)
*
* @param context 上下文
* @return 当前移动网络连接的类型信息
*/
public static String getMobileNetworkType(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info == null) return "unknown";
switch (info.getType()) {
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
return "unknown";
// Cellular Data2G
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_IDEN:
case TelephonyManager.NETWORK_TYPE_1xRTT:
return "2G";
// Cellular Data3G
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
return "3G";
// Cellular Data4G
case TelephonyManager.NETWORK_TYPE_LTE:
return "4G";
default:
return "unknown";
}
}
}

View File

@ -1,18 +1,18 @@
package com.gh.common.util
import java.math.BigDecimal
import java.text.DecimalFormat
object NumberUtils {
@JvmStatic
fun transSimpleCount(count: Int): String {
val s: String
if (count > 10000) {
s = if (count > 100000) {
val number = count / 10000f
val bd = BigDecimal(number.toDouble())
s = bd.setScale(1, BigDecimal.ROUND_DOWN).toString() + "W"
val fmt = DecimalFormat("#")
fmt.format(number) + ""
} else {
s = count.toString()
count.toString()
}
return s
}

View File

@ -0,0 +1,44 @@
package com.gh.common.util
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.support.v4.content.ContextCompat
import android.view.Window
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.gamecenter.R
object OptionDialogHelper {
fun showOptionDialog(context: Context, typeList: List<String>, callback: (String) -> Unit) {
val dialog = Dialog(context)
val container = LinearLayout(context)
container.orientation = LinearLayout.VERTICAL
container.setBackgroundColor(Color.WHITE)
container.setPadding(0, DisplayUtils.dip2px(context, 12f), 0, DisplayUtils.dip2px(context, 12f))
for (type in typeList) {
val reportTv = TextView(context)
reportTv.text = type
reportTv.textSize = 17f
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title))
reportTv.setBackgroundResource(R.drawable.textview_white_style)
val widthPixels = context.resources.displayMetrics.widthPixels
reportTv.layoutParams = LinearLayout.LayoutParams(widthPixels * 9 / 10,
LinearLayout.LayoutParams.WRAP_CONTENT)
reportTv.setPadding(DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 12f),
0, DisplayUtils.dip2px(context, 12f))
container.addView(reportTv)
reportTv.setOnClickListener {
callback.invoke(reportTv.text.toString())
dialog.cancel()
}
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(container)
dialog.show()
}
}

View File

@ -2,45 +2,80 @@ package com.gh.common.util
import android.content.Context
import android.content.pm.ApplicationInfo
import com.gh.common.AppExecutor
import com.gh.common.constant.Config
import com.gh.gamecenter.entity.SettingsEntity
import com.halo.assistant.HaloApp
object PackageHelper {
// 黑名单包名,用于区分像 Xposed Installer 那些工具的包名
var excludePackageNameList = arrayListOf<String>()
// 评论黑名单包名列表,避免用户安装了 Xposed Installer 这样的工具,也能在包含该安装包的游戏详情页评论
var commentPackageNameBlackList = arrayListOf<String>()
// 关闭下载的包列表
var downloadPackageNameBlackList = arrayListOf<String>()
// 本地已安装的包去掉关闭下载的包后的列表
var validLocalPackageNameSet = hashSetOf<String>()
// 游戏包名匹配列表
var relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
// 本地已安装包的列表
var localPackageNameSet = hashSetOf<String>()
get() {
return if (field.isEmpty()) {
field = getAllPackageName(HaloApp.getInstance().application)
field
} else {
field
}
}
@JvmStatic
fun refreshLocalPackageList() {
AppExecutor.ioExecutor.execute {
localPackageNameSet = getAllPackageName(HaloApp.getInstance().application)
}
localPackageNameSet = getAllPackageName(HaloApp.getInstance().application)
updateValidPackageNameList()
}
@JvmStatic
fun initExcludePackageName() {
fun initList() {
Config.getSettings()?.gameCommentBlackList?.let {
excludePackageNameList = ArrayList(it)
commentPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList?.let {
downloadPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gamePackageMatch?.let {
relatedPackageList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList
updateValidPackageNameList()
}
private fun updateValidPackageNameList() {
validLocalPackageNameSet = localPackageNameSet.filterNot { p -> downloadPackageNameBlackList.contains(p) }.toHashSet()
}
/*
* 获取所有已安装的软件的包名、版本(非系统应用)
*/
private fun getAllPackageName(context: Context): HashSet<String> {
val list = HashSet<String>()
val packageInfos = context.applicationContext.packageManager.getInstalledPackages(0)
for (packageInfo in packageInfos) {
if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
if (context.packageName != packageInfo.packageName) {
list.add(packageInfo.packageName)
val set = HashSet<String>()
return try {
val packageInfos = context.applicationContext.packageManager.getInstalledPackages(0)
for (packageInfo in packageInfos) {
if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
if (context.packageName != packageInfo.packageName) {
set.add(packageInfo.packageName)
}
}
}
set
} catch (e: Exception) {
e.printStackTrace()
set
}
return list
}
}

View File

@ -15,11 +15,11 @@ import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import com.g00fy2.versioncompare.Version;
import com.gh.common.constant.Config;
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.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import org.json.JSONArray;
@ -49,12 +49,14 @@ public class PackageUtils {
for (ApkEntity apkEntity : gameEntity.getApk()) {
// 判断是否gh_version是否存在
String gh_version = (String) PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_version");
if (gh_version != null && apkEntity.getGhVersion() != null) {
Object gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
if (gh_version != null && apkEntity.getGhVersion() != null && gh_id != null) {
// 确定这是一个插件游戏
if (!isAPluginGame) isAPluginGame = true;
gh_version = gh_version.substring(2);
if (Long.parseLong(gh_version) < Long.parseLong(apkEntity.getGhVersion()) && apkEntity.getForce()) {
if (Long.parseLong(gh_version) < Long.parseLong(apkEntity.getGhVersion()) && apkEntity.getForce()
&& gh_id.equals(gameEntity.getId())) {
GameUpdateEntity updateEntity = new GameUpdateEntity();
updateEntity.setId(gameEntity.getId());
updateEntity.setName(gameEntity.getName());
@ -78,7 +80,7 @@ public class PackageUtils {
for (ApkEntity apkEntity : gameEntity.getApkNormal()) {
String versionFromRequest = apkEntity.getVersion();
String versionFromInstalledApp = getVersionByPackage(context, apkEntity.getPackageName());
String versionFromInstalledApp = getVersionByPackage(apkEntity.getPackageName());
// 是否需要显示更新
boolean shouldShouldUpdate = apkEntity.getForce();
@ -181,15 +183,15 @@ public class PackageUtils {
* 启动安装应用程序
*/
public static void launchSetup(final Context context, final String path) {
if (isCanLaunchSetup(context, path)) {
context.startActivity(PackageUtils.getInstallIntent(context, path));
} else {
DialogUtils.showPluginDialog(context, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
context.startActivity(PackageUtils.getUninstallIntent(context, 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());
}
}
@ -202,7 +204,7 @@ public class PackageUtils {
if (TextUtils.isEmpty(packageName)) {
return true;
}
boolean isContain = com.gh.gamecenter.manager.PackageManager.INSTANCE.isInstalled(packageName);
boolean isContain = com.gh.gamecenter.manager.PackagesManager.INSTANCE.isInstalled(packageName);
if (!isContain) {
return true;
}
@ -292,16 +294,6 @@ public class PackageUtils {
return 0;
}
/**
* 数据统计或反馈用PatchVersionName
* 判断助手是否是第一次启动或版本更新提交的版本号用AppVersionName{@link PackageUtils#getVersionName()}
*
* @return 补丁包版本号
*/
public static String getPatchVersionName() {
return Config.PATCH_VERSION_NAME;
}
/*
* 返回光环助手的版本信息
*/
@ -312,23 +304,16 @@ public class PackageUtils {
/*
* 返回光环助手的版本code
*/
public static String getVersionCode(Context context) {
try {
PackageInfo pkgInfo = context.getApplicationContext().getPackageManager().getPackageInfo(
context.getPackageName(), 0);
return String.valueOf(pkgInfo.versionCode);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
public static int getVersionCode() {
return BuildConfig.VERSION_CODE;
}
/*
* 获取apk的版本
*/
public static String getVersionByPackage(Context context, String packageName) {
public static String getVersionByPackage(String packageName) {
try {
return context.getApplicationContext().getPackageManager().getPackageInfo(packageName,
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
@ -386,6 +371,25 @@ public class PackageUtils {
return jsonArray;
}
public static JSONObject getAppBasicInfoByPackageName(String packageName) {
JSONObject jsonObject = new JSONObject();
PackageManager pm = HaloApp.getInstance().getApplication().getPackageManager();
try {
PackageInfo packageInfo = HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
jsonObject.put("name", pm.getApplicationLabel(packageInfo.applicationInfo).toString());
jsonObject.put("package", packageName);
jsonObject.put("version", packageInfo.versionName);
}
return jsonObject;
} catch (JSONException | NameNotFoundException e) {
e.printStackTrace();
return jsonObject;
}
}
/*
* 启动应用
*/

View File

@ -133,7 +133,7 @@ public class PlatformUtils {
}
}
updataPlatform(platformMap, platformPicMap, platformPicUrlMap,
updatePlatform(platformMap, platformPicMap, platformPicUrlMap,
platformColorMap);
}
@ -184,7 +184,7 @@ public class PlatformUtils {
}
}
private void updataPlatform(ArrayMap<String, String> pMap,
private void updatePlatform(ArrayMap<String, String> pMap,
ArrayMap<String, Integer> pPMap, ArrayMap<String, String> pUMap,
ArrayMap<String, String> pCMap) {
platformMap = pMap;
@ -236,7 +236,10 @@ public class PlatformUtils {
if (TextUtils.isEmpty(platformName)) {
getPlatform();
}
return platformName;
if (!TextUtils.isEmpty(platformName)) {
return platformName;
}
return platform;
}
public void getPlatform() {

View File

@ -0,0 +1,47 @@
package com.gh.common.util
import android.content.Context
import com.gh.gamecenter.receiver.UmengMessageReceiver
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
object PushHelper {
/**
* 提交推送点击事件,会尝试从 SP 读取之前失败的一并提交
*/
@JvmStatic
fun postPushClickAction(context: Context, clickEvent: UmengMessageReceiver.ClickEvent? = null) {
val clickEventList = arrayListOf<UmengMessageReceiver.ClickEvent>()
clickEvent?.let { clickEventList.add(it) }
val failedClickEventList = SPUtils.getString(UmengMessageReceiver.SP_CLICK_EVENT)
.toObject<ArrayList<UmengMessageReceiver.ClickEvent>>()
failedClickEventList?.let { clickEventList.addAll(it) }
// 没有要提交的事件
if (clickEventList.size == 0) return
val body = RequestBody.create(MediaType.parse("application/json"), clickEventList.toJson())
RetrofitManager.getInstance(context)
.api
.postUmengReceiveInfo(body)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
SPUtils.setString(UmengMessageReceiver.SP_CLICK_EVENT, "")
}
override fun onFailure(exception: Exception) {
SPUtils.setString(UmengMessageReceiver.SP_CLICK_EVENT, clickEventList.toJson())
}
})
}
}

View File

@ -0,0 +1,20 @@
package com.gh.common.util
import android.app.ActivityManager
import android.content.Context
object ServiceUtils {
fun isServiceRunningInForeground(context: Context, serviceClass: Class<*>): Boolean {
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.name == service.service.className) {
if (service.foreground) {
return true
}
}
}
return false
}
}

View File

@ -37,12 +37,11 @@ import com.sina.weibo.sdk.WbSdk;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.tencent.connect.share.QQShare;
import com.tencent.connect.share.QzoneShare;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.SendMessageToWX;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.mm.sdk.openapi.WXMediaMessage;
import com.tencent.mm.sdk.openapi.WXWebpageObject;
import com.tencent.mm.sdk.platformtools.Util;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
@ -251,6 +250,12 @@ public class ShareUtils {
//微信好友分享
private void wechatShare() {
Utils.toast(mContext, R.string.share_skip);
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
Utils.toast(mContext, "没安装微信,分享失败");
return;
}
WXWebpageObject webpage = new WXWebpageObject();
WXMediaMessage msg = new WXMediaMessage(webpage);
webpage.webpageUrl = shareUrl;
@ -290,10 +295,10 @@ public class ShareUtils {
protected void onNewResultImpl(Bitmap bitmap) {
Bitmap compressBp = compressBitmap(bitmap);
if (mShareType == ShareType.askNormal || mShareType == ShareType.askInvite) {
msg.thumbData = Util.bmpToByteArray(compressBp, true);
msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true);
} else {
Bitmap resultBp = addBackGround(compressBp);
msg.thumbData = Util.bmpToByteArray(resultBp, true);
msg.thumbData = ImageUtils.bmpToByteArray(resultBp, true);
}
mIWXAPI.sendReq(req);
}
@ -387,6 +392,12 @@ public class ShareUtils {
//微信朋友圈分享
private void wechatMomentsShare() {
Utils.toast(mContext, R.string.share_skip);
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
Utils.toast(mContext, "没安装微信,分享失败");
return;
}
WXWebpageObject webpage = new WXWebpageObject();
WXMediaMessage msg = new WXMediaMessage(webpage);

View File

@ -0,0 +1,54 @@
package com.gh.common.util
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.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException
/**
* 可以在此类发送一些无关页面操作的请求
*/
object SimpleRequestHelper {
private val mApi = RetrofitManager.getInstance(HaloApp.getInstance().application).api
fun reportGameComment(gameId: String, commentId: String, type: String) {
val map = HashMap<String, String>()
map["reason"] = type
mApi.reportGameComment(gameId, commentId, map.createRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
Utils.toast(HaloApp.getInstance().application, "感谢您的举报")
}
override fun onFailure(e: HttpException?) {
ErrorHelper.handleError(HaloApp.getInstance().application, e?.response()?.errorBody()?.string())
}
})
}
fun reportGameCommentReply(gameId: String, commentId: String, replyId: String, type: String) {
val map = HashMap<String, String>()
map["reason"] = type
mApi.reportGameCommentReply(gameId, commentId, replyId, map.createRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
Utils.toast(HaloApp.getInstance().application, "感谢您的举报")
}
override fun onFailure(e: HttpException?) {
ErrorHelper.handleError(HaloApp.getInstance().application, e?.response()?.errorBody()?.string())
}
})
}
}

View File

@ -1,84 +0,0 @@
package com.gh.common.util;
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
/**
* 用于解决因为沉浸式状态栏(自定义)时键盘不遮挡输入框
*/
public class SoftInputHidWidgetUtils {
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private int contentHeight;
private boolean isfirst = true;
private int statusBarHeight;
public static void assistActivity(Activity activity) {
if (Build.VERSION.SDK_INT >= 19) {
new SoftInputHidWidgetUtils(activity);
}
}
private SoftInputHidWidgetUtils(Activity activity) {
statusBarHeight = getStatusBarHeight(activity);
FrameLayout content = (FrameLayout)activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
//界面出现变动都会调用这个监听事件
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (isfirst) {
contentHeight = mChildOfContent.getHeight();//兼容华为等机型
isfirst = false;
}
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
//重新调整跟布局的高度
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
//当前可见高度和上一次可见高度不一致 布局变动
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
} else {
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
}
} else {
frameLayoutParams.height = contentHeight;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
/**
* 获取改变之后界面的可用高度(可以为开发者显示内容的高度)
* @return
*/
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);//获取到的rect就是界面除去标题栏、除去软键盘挡住部分所剩下的域
return (r.bottom - r.top);
}
public static int getStatusBarHeight(Activity activity) {
//获取状态栏的高度
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
return activity.getResources().getDimensionPixelSize(resourceId);
}
}

View File

@ -45,6 +45,16 @@ object SPUtils {
return sp.getInt(key, defaultValue)
}
@JvmStatic
fun getLong(key: String, defaultValue: Long): Long {
return sp.getLong(key, defaultValue)
}
@JvmStatic
fun setLong(key: String, value: Long) {
return sp.edit().putLong(key, value).apply()
}
@JvmStatic
fun setBoolean(key: String, value: Boolean) {
sp.edit().putBoolean(key, value).apply()
@ -54,4 +64,22 @@ object SPUtils {
fun getBoolean(key: String): Boolean {
return sp.getBoolean(key, false)
}
@JvmStatic
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
return sp.getBoolean(key, defaultValue)
}
@JvmStatic
fun setString(sp: SharedPreferences, key: String, value: String? = null) {
try {
val commitStatus = sp.edit().putString(key, value).commit()
if (!commitStatus) {
sp.edit().putString(key, value).apply()
}
} catch (e: Exception) {
e.printStackTrace()
sp.edit().putString(key, value).apply()
}
}
}

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