Compare commits

..

95 Commits

Author SHA1 Message Date
5a826234d0 fix 2020-12-03 14:55:02 +08:00
9f5ffb084a 修复APP更新逻辑,以VersionName为准
修复App更新无法下载安装包问题
2020-11-23 18:38:01 +08:00
b5d4cbe718 更新启动弹窗隐私协议和用户协议内容 2020-11-20 14:20:49 +08:00
b39a47c0bd 光环马甲包4.3.8修改 2020-11-20 14:18:39 +08:00
5ea6647bf7 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into video_only
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/LoginActivity.java
#	app/src/main/java/com/gh/gamecenter/MainActivity.java
#	app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java
#	app/src/main/java/com/gh/gamecenter/collection/CollectionWrapperFragment.java
#	app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java
#	app/src/main/java/com/gh/gamecenter/history/HistoryWrapperFragment.kt
#	app/src/main/java/com/gh/gamecenter/personal/PersonalViewModel.kt
#	app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
#	app/src/main/res/layout/fragment_home.xml
#	app/src/main/res/layout/fragment_login.xml
#	app/src/main/res/layout/fragment_personal.xml
2020-11-13 16:04:36 +08:00
lyr
6fcd8397b6 修复"模拟器游戏创建桌面快捷方式时,由于图片过大而闪退"的Bug 2020-11-04 17:34:53 +08:00
3478aaba2f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-11-04 10:24:53 +08:00
1f0b9a95e2 尝试修复后台开启前台服务闪退 https://gitlab.ghzs.com/halo/assistant-android/-/issues/7 2020-11-04 10:15:16 +08:00
5cdc1635ca 正式环境接口改为 4.4 2020-11-03 18:11:18 +08:00
3db784509b 更新依赖库 hash 2020-11-02 10:46:50 +08:00
e8f63ea99f 调整 jenkins 打包脚本 2020-11-02 10:46:30 +08:00
97ac4b03a3 处理合并异常 2020-11-02 10:27:30 +08:00
883a948b7b Merge branch 'feature-sdk-free' into dev
# Conflicts:
#	app/src/main/java/com/gh/common/LocalBroadcastReceiver.kt
#	app/src/main/java/com/gh/common/im/ImManager.kt
#	app/src/main/java/com/gh/common/im/ImReceiver.kt
#	app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameDetailCustomColumnAdapter.kt
#	app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingCommentItemViewHolder.kt
#	app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyAdapter.kt
#	app/src/main/java/com/gh/gamecenter/personalhome/background/PersonalityBackgroundViewModel.kt
#	app/src/main/java/com/gh/gamecenter/user/UserRepository.java
#	app/src/main/java/com/halo/assistant/HaloApp.java
#	dependencies.gradle
2020-11-02 10:03:28 +08:00
lyr
261e0cc45a 搜索页-未登录状态点击预约按钮也上传"search_click"点击事件 2020-10-30 15:01:21 +08:00
0357a0a71e 处理跳转模拟器传递meta格式错误 2020-10-30 10:30:04 +08:00
lyr
d87de59427 光环助手V4.4.0-个人主页优化(第2期)-> 1029 UI反馈 -> 第2点 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1037#note_74645 2020-10-29 22:37:11 +08:00
lyr
d5ee01a2e1 光环助手V4.4.0-游戏搜索功能强化(第6期)-> 20201028测试问题/搜索快捷按钮交互优化 2020-10-29 22:08:30 +08:00
lyr
3563637919 光环助手V4.4.0-游戏搜索数据 -> 20201029测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1035#note_74631 2020-10-29 21:32:34 +08:00
lyr
d881e08aee 光环助手V4.4.0-我的光环-新增[模拟器游戏] -> 1029测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1031 2020-10-29 21:24:32 +08:00
f5ff838d2f 更换背景默认透明度改为1 2020-10-29 20:57:26 +08:00
52c1b08e59 修复自动搜索曝光统计问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1035 2020-10-29 17:42:44 +08:00
lyr
652972f49d 光环助手V4.4.0-我的光环-新增[模拟器游戏] -> 1028测试 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1031 2020-10-29 16:16:02 +08:00
0d122cf8ba 光环助手V4.4.0-单机模拟器1028测试(4) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1030 2020-10-29 09:27:01 +08:00
lyr
2b115c4058 第一次打开App删除所有模拟器游戏记录 2020-10-28 18:17:52 +08:00
lyr
cfca7db4ef 补充游戏搜索页-"搜索-点击"事件的埋点数据 2020-10-28 15:41:05 +08:00
lyr
5f66c029fb 光环助手V4.4.0-游戏搜索数据 —> 20201028测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1035#note_74338 2020-10-28 14:52:39 +08:00
lyr
8635652fe2 优化"个人主页"代码逻辑 2020-10-28 11:22:57 +08:00
lyr
a890ad532c 光环助手V4.4.0-游戏搜索功能强化(第6期)-> 20201027测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1025#note_74281 2020-10-28 11:18:03 +08:00
lyr
65c9d2be2a 光环助手V4.4.0-我的光环-新增[模拟器游戏] -> 1027测试/201027UI反馈 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1031 2020-10-27 18:22:49 +08:00
9620e26f6a 删除模拟器游戏时上传记录 2020-10-27 16:57:34 +08:00
e4ca1d8406 光环助手V4.4.0-单机模拟器 1027测试(6,7,8,10) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1030 2020-10-27 16:19:00 +08:00
74ebaa592b 修改模拟器下载完成埋点 2020-10-27 11:09:35 +08:00
f9b689efdb 更新 LGLibrary 2020-10-27 10:13:42 +08:00
ed458f08ad debug mode 接入简单的闪退日志显示插件 2020-10-27 10:06:26 +08:00
lyr
9822646acc 光环助手V4.4.0-游戏搜索数据->前端埋点 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1035 2020-10-26 18:38:56 +08:00
4259078420 完成光环前端优化汇总(2020年10月第1周)(10,11) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1028 2020-10-26 18:21:13 +08:00
3b9db4e964 恢复模拟器游戏保存路径 2020-10-26 18:11:42 +08:00
b7e6cd08fd 修改通知弹窗闪退问题 2020-10-26 16:49:12 +08:00
bba1e6f10c 处理一些闪退异常 2020-10-26 14:23:44 +08:00
3fe2973968 修改模拟器下载日志 2020-10-26 14:15:37 +08:00
b16d33d9fa Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-10-26 09:22:18 +08:00
e1a7ed9049 修改更换背景获取bitmap方式 2020-10-26 09:21:59 +08:00
lyr
11354030e8 光环助手V4.4.0-游戏搜索功能强化(第6期)三 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1025 2020-10-26 09:21:42 +08:00
ee109060fc 更改首页横向自滚动专题的实现 2020-10-23 18:19:49 +08:00
lyr
eebc0c1096 提交遗漏代码 2020-10-23 17:09:28 +08:00
lyr
4ec45e2a27 Merge remote-tracking branch 'origin/dev' into dev 2020-10-23 17:08:10 +08:00
lyr
12143f7f95 优化"模拟器游戏"模块代码逻辑 2020-10-23 17:06:19 +08:00
7025dc45bd 优化获取图片 bitmap 的逻辑 2020-10-23 17:05:13 +08:00
772e7861e2 更换模拟器游戏文件夹名 2020-10-23 15:58:25 +08:00
ff71c9a3e8 优化模拟器下载 2020-10-23 11:50:52 +08:00
b7001cc996 Merge branch 'dev_4.4.0' into dev
# Conflicts:
#	app/src/main/java/com/gh/base/GHActivityLifecycleCallbacksImpl.java
#	app/src/main/java/com/gh/common/util/DownloadObserver.kt
#	app/src/main/java/com/gh/gamecenter/user/UserRepository.java
#	app/src/main/java/com/halo/assistant/HaloApp.java
2020-10-23 10:47:40 +08:00
83658e47f8 特殊渠道隐藏首页视频tab https://gitlab.ghzs.com/pm/issues-Inbox/-/issues/3090 2020-10-23 10:21:05 +08:00
lyr
0699d3ccc4 调整"模拟器游戏"列表-下载按钮UI 2020-10-22 18:19:11 +08:00
f80b998e98 处理当前链接没有下载记录并且文件已经存在下载异常问题 2020-10-22 17:26:04 +08:00
91e84be708 尝试排除分片检测下载进度数据上传的无用数据 2020-10-22 17:07:54 +08:00
f589c286c6 提交LGLibrary 2020-10-22 16:42:20 +08:00
379650a0f5 Merge branch 'emulator' into dev_4.4.0
# Conflicts:
#	app/src/main/java/com/gh/common/util/EntranceUtils.java
#	app/src/main/java/com/gh/common/util/LogUtils.java
#	app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java
#	app/src/main/java/com/halo/assistant/HaloApp.java
#	app/src/main/res/values/colors.xml
2020-10-22 16:12:24 +08:00
3796eb46bd 启动模拟器游戏 2020-10-22 15:46:49 +08:00
c240048c5e 处理延迟初始化视频播放闪退 2020-10-22 14:52:13 +08:00
lyr
2f81c9240d 完善"模拟器游戏"快捷方式的处理逻辑 2020-10-22 10:58:40 +08:00
lyr
da0dc3df97 完成"模拟器游戏"模块UI 2020-10-21 17:45:47 +08:00
d73c0f2044 Merge branch 'emulator' of gitlab.ghzs.com:halo/assistant-android into emulator
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorGameFragment.kt
2020-10-21 17:18:58 +08:00
a6f9e12082 光环助手V4.4.0-数据统计需求(单机模拟器)(一、1,二) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1033 2020-10-21 17:16:24 +08:00
lyr
1086574b33 "模拟器游戏"空数据页面增加广告位链接 2020-10-21 16:21:41 +08:00
lyr
58631d540c "模拟器游戏"顶部Tab增加筛选,增加无数据显示页面 2020-10-21 15:25:28 +08:00
lyr
08763aeb2d 上传遗漏代码 2020-10-21 11:36:46 +08:00
lyr
039d0ca06c 去掉多余代码 2020-10-21 11:31:45 +08:00
lyr
f39574c8b3 大致完成"模拟器游戏"模块UI 2020-10-21 11:26:44 +08:00
6067a52fb1 光环助手V4.4.0-数据统计需求(单机模拟器)(二、2) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1033 2020-10-21 10:01:36 +08:00
a1298547d1 版本号升级为4.4.0 2020-10-20 18:38:14 +08:00
6a6378f635 【光环助手V4.4.0】论坛数据埋点需求 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1019 2020-10-20 09:16:34 +08:00
920050efc8 Merge dev_4.4.0 into dev_4.4.0 2020-10-19 18:35:25 +08:00
103ecc10d3 完成游戏下载状态新增"更新中" https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1021 2020-10-19 18:30:05 +08:00
f90e9a8085 视频流支持下载、启动模拟器游戏 2020-10-19 16:46:17 +08:00
caa37ead4b 光环助手V4.4.0-个人主页优化(第2期)(2-⑦、3) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1037 2020-10-19 15:07:42 +08:00
d18eeaf346 已下载的模拟器游戏显示在 已安装、玩过的游戏 等位置 2020-10-19 10:35:04 +08:00
lyr
b98d287843 光环助手V4.4.0-个人主页优化(第2期)https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1037#note_73008 2020-10-18 16:36:27 +08:00
66fb57f708 记录模拟器游戏下载完成、启动 2020-10-16 18:19:50 +08:00
8001ce2603 大致完成模拟器游戏下载、模拟器下载与安装 2020-10-16 17:16:24 +08:00
b1079e84d8 大致完成模拟器游戏下载、模拟器下载与安装 2020-10-16 17:15:51 +08:00
93126517b6 模拟器游戏下载记录使用本地数据库保存 2020-10-14 19:53:24 +08:00
9687ddcd54 光环前端优化汇总(2020年10月第1周)(7) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1028 2020-10-14 09:24:54 +08:00
04c49cbad7 测试环境api更新为v4d4d0 2020-10-13 18:12:08 +08:00
lyr
229eaa0859 光环前端优化汇总(2020年10月第1周)第4/5点 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1028 2020-10-13 17:48:42 +08:00
b2100fe0e5 修改模拟器游戏保存路径 2020-10-13 17:18:08 +08:00
fefe29a0b8 模拟器下载弹窗(未完) 2020-10-13 09:21:34 +08:00
6efc1e06bb 下载模拟器游戏 2020-10-12 16:21:11 +08:00
e51439d584 完成光环前端优化汇总(10月第一周第8点删掉七陌客服) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1028 2020-10-12 15:52:51 +08:00
lyr
658fb8579c 光环前端优化汇总(2020年10月第1周)第9点 https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1028 2020-10-12 14:14:14 +08:00
f21d86c8a7 光环前端优化汇总(2020年10月第1周)(3) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1028 2020-10-10 16:24:17 +08:00
798c4a2089 update 2020-04-29 10:59:39 +08:00
0686f70df6 更新到3.7.6 2020-04-29 10:51:28 +08:00
3c30564ab6 update 2020-04-10 19:10:11 +08:00
f04070e846 update 2020-04-02 18:39:01 +08:00
fc279839fa 光环助手马甲包——视频 https://gitlab.ghzs.com/pm/yunying/issues/1051 2020-04-02 15:07:11 +08:00
233 changed files with 4758 additions and 2227 deletions

View File

@ -125,11 +125,15 @@ android {
}
}
flavorDimensions ("env")
flavorDimensions "nonsense"
/**
* 多渠道打包,渠道请参考"channel.txt"文件所有渠道值均通过java code设置
*/
productFlavors {
// publish release host
publish {
dimension "env"
dimension "nonsense"
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "SENSITIVE_API_HOST", "\"${SENSITIVE_API_HOST}\""
@ -138,8 +142,9 @@ android {
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${UMENG_MESSAGE_SECRET}\""
buildConfigField "String", "BUGLY_APPID", "\"${BUGLY_APPID}\""
}
// internal test dev host
internal {
dimension "env"
dimension "nonsense"
versionNameSuffix "-debug"
buildConfigField "String", "API_HOST", "\"${DEV_API_HOST}\""
@ -187,6 +192,7 @@ dependencies {
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stetho}"
debugImplementation "com.squareup.okhttp3:logging-interceptor:${okHttp}"
debugImplementation "com.gu.android:toolargetool:${toolargetool}"
debugImplementation "com.github.nichbar:WhatTheStack:$whatTheStack"
implementation "androidx.core:core:${core}"
implementation "androidx.fragment:fragment:${fragment}"

View File

@ -27,6 +27,8 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- 修改系统设置的权限 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- 创建快捷方式的权限 -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
@ -45,13 +47,13 @@
<uses-sdk tools:overrideLibrary="com.shuyu.gsyvideoplayer,
com.shuyu.gsyvideoplayer.lib,
com.haroldadmin.whatthestack,
com.shuyu.gsyvideoplayer.armv7a,
com.shuyu.gsyvideoplayer.x86,
com.shuyu.gsy.base,
com.google.android.exoplayer2,
tv.danmaku.ijk.media.exo2,
pl.droidsonroids.gif,
com.donkingliang.consecutivescroller" />
pl.droidsonroids.gif" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -581,12 +583,20 @@
android:name=".personalhome.excellentcomments.ExcellentCommentsActivity"
android:screenOrientation="portrait" />
<!-- &lt;!&ndash; 使用小米/华为推送弹窗功能提高推送成功率&ndash;&gt;-->
<!-- <activity-->
<!-- android:name="com.gh.gamecenter.PushProxyActivity"-->
<!-- android:exported="true"-->
<!-- android:launchMode="singleTask"-->
<!-- android:theme="@android:style/Theme.Translucent" />-->
<activity
android:name=".simulatorgame.SimulatorGameActivity"
android:screenOrientation="portrait" />
<activity
android:name=".simulatorgame.SimulatorManagementActivity"
android:screenOrientation="portrait" />
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
<activity
android:name="com.gh.gamecenter.PushProxyActivity"
android:exported="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name="com.gh.gamecenter.SkipActivity"
@ -670,14 +680,14 @@
<!-- </intent-filter>-->
<!-- </receiver>-->
<receiver
android:name="com.gh.common.im.ImReceiver"
android:enabled="true">
<intent-filter android:priority="2147483647">
<action android:name="com.gh.im" />
<action android:name="action_finish" />
</intent-filter>
</receiver>
<!-- <receiver-->
<!-- android:name="com.gh.common.im.ImReceiver"-->
<!-- android:enabled="true">-->
<!-- <intent-filter android:priority="2147483647">-->
<!-- <action android:name="com.gh.im" />-->
<!-- <action android:name="action_finish" />-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<!-- <meta-data-->
<!-- android:name="com.huawei.hms.client.appid"-->

File diff suppressed because it is too large Load Diff

View File

@ -1,493 +1,161 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>光环助手软件许可及服务协议</title>
</head>
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>光环助手软件许可及服务协议</title>
<style>
* {
margin: 0;
padding: 0;
font-size: 14px;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
* {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
font-size: 16px;
}
</style>
</head>
<body>
<div class="content-area">
<p><b></b></p>
<p>
<b>光环</b>
<b>game</b>
<b>软件许可及服务协议</b>
</p>
<p><b>更新日期2020年11月20日</b></p>
<p><b>生效日期2020年11月30日</b></p>
<p><b>首部及导言</b></p>
<p>欢迎使用光环game软件许可及服务</p>
<p>
各位用户在使用光环game前请您务必审慎阅读、并充分理解本协议中的各项条款
<b>
特别是免除或者限制责任的条款,以及开通或使用某项服务的单独协议,并选择接受或不接受。
</b>
除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本软件及相关服务。您的下载、安装、使用、登录等行为即视为您已阅读并同意上述协议的约束。
</p>
<p>如果您未满18周岁请在法定监护人的陪同下阅读本协议及其他上述协议。</p>
<p><b>一、权利声明</b></p>
<p>
“光环game”的一切知识产权以及与“光环game”相关的所有信息内容包括但不限于文字表述及其组合、图标、图饰、图像、图表、色彩、界面设计、版面框架、有关数据、附加程序、印刷材料或电子文档等均为光环game所有受著作权法和国际著作权条约以及其他知识产权法律法规的保护。
</p>
<p><b>二、软件使用规范</b></p>
<p>
2.1
本软件是基于Android安卓系统手机、平板电脑(PAD)等设备开发的一款软件,提供注册登录、观看视频、视频投稿等功能
</p>
<p>2.2 软件的下载、安装和使用</p>
<p>
本软件为免费软件用户可以非商业性、无限制数量地从光环game授权的渠道下载、安装及使用本软件。
</p>
<p>
<b>如果您从未经光环</b>
<b>game</b>
<b>授权的第三方获取本软件或与本软件名称相同的安装程序,光环</b>
<b>game</b>
<b>无法保证该软件能够正常使用,并对因此给您造成的损失不予负责。</b>
</p>
<p>2.3 软件的复制、分发和传播</p>
<p>
本产品以研究交流为目的。用户可以非商业性、无限制数量地复制、分发和传播本软件产品。但必须保证每一份复制、分发和传播都是完整和真实的,
包括所有有关本软件产品的软件、电子文档, 版权和商标,亦包括本协议。
</p>
<p>2.4 软件的更新</p>
<p>
为了改善用户体验、完善服务内容光环game将不断努力开发新的服务并为您不时提供软件更新这些更新可能会采取软件替换、修改、功能强化、版本升级等形式。为了保证本软件及服务的安全性和功能的一致性光环game有权不经向您特别通知而对软件进行更新或者对软件的部分功能效果进行改变或限制。本软件新版本发布后旧版本的软件可能无法使用。光环game不保证旧版本软件继续可用及相应的客户服务请您随时核对并下载最新版本。
</p>
<p><b>三、用户使用须知</b></p>
<p>3.1 您理解并同意:</p>
<p>
为了向您提供有效的服务,本软件会利用您移动通讯终端的处理器和带宽等资源。本软件使用过程中可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担相关费用.
</p>
<p>3.2您理解并同意:</p>
<p>
<b>
如果因您不正当使用本软件造成了不良影响,或因使用本软件造成的包括但不限于数据异常等问题,均由使用者自行承担,光环团队不对任意类型的使用结果承担责任;
</b>
</p>
<p>3.3您理解并同意:</p>
<p>
本软件不含任何破坏用户移动通讯设备数据和获取用户隐私信息的恶意代码,不会泄露用户的个人信息和隐私;
</p>
<p>3.4您理解并同意:</p>
<p>
<b>
对于包括但不限于互联网网络故障、计算机故障、手机故障或病毒、信息损坏或丢失、计算机系统问题,或其它任何基于不可抗力原因而产生的损失,光环团队不承担任何责任。
</b>
</p>
<p>3.5您理解并同意:</p>
<p>光环game发布、收录的视频均不代表光环立场。</p>
<p>3.6您理解并同意:</p>
<p>
用户应在遵守法律及本协议的前提下使用本软件。用户无权实施包括但不限于下列行为:
</p>
<p>3.6.1 不得删除或者改变本软件上的所有权利管理电子信息</p>
<p>
3.6.2
不得故意避开或者破坏著作权人为保护本软件著作权而采取的技术措施;&nbsp;
</p>
<p>3.6.3 用户不得利用本软件误导、欺骗他人;&nbsp;</p>
<p>
3.6.4
违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行;&nbsp;
</p>
<p>3.6.5 未经允许,进入计算机信息网络或者使用计算机信息网络资源;&nbsp;</p>
<p>3.6.6 未经允许,对计算机信息网络功能进行删除、修改或者增加;&nbsp;</p>
<p>
3.6.7
未经允许,对计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加;&nbsp;
</p>
<p>
3.6.8
破坏本软件系统或网站的正常运行,故意传播计算机病毒等破坏性程序;&nbsp;
</p>
<p>3.6.9 其他任何危害计算机信息网络安全的行为。&nbsp;</p>
<p>3.7 您理解并同意:</p>
<p>
本软件经过详细的测试,但不能保证与所有的软硬件系统完全兼容,不能保证本软件完全没有错误。如果出现不兼容及软件错误的情况,用户可通过各反馈途径将情况告知光环团队,获得技术支持。如果无法解决兼容性问题,用户可以删除本软件。
</p>
<p><b>四、争议解决处理</b></p>
<p>
本《协议》的解释、效力及纠纷的解决适用于中华人民共和国法律。若用户和光环game之间发生任何纠纷或争议首先应友好协商解决协商不成的用户在此完全同意将纠纷或争议提交光环game所在地法院管辖
</p>
<p>
<b></b>
<b>、关于获取手机设备信息的说明</b>
</p>
<p>
1为方便区分每个用户的个人信息等本软件需获取用户的手机设备信息用于用户登录、视频评论互动交流等用户相关的行为
</p>
<p>
2为了保障软件与服务的安全运行我们会收集您的硬件型号、操作系统版本号、国际移动设备识别码、唯一设备标识符、网络设备硬件地址、IP
地址、WLAN接入点、蓝牙、基站、软件版本号、网络接入方式、类型、状态、网络质量数据、操作、使用、服务日志。
</p>
<p>
3为了预防恶意程序及安全运营所必需我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据、应用来源。
</p>
<p>
4我们可能使用您的账户信息、设备信息、服务日志信息以及我们关联公司、合作方在获得您授权或依法可以共享的信息用于判断账户安全、进行身份验证、检测及防范安全事件。
</p>
<p>5具体会发生获取手机设备信息场景如下说明</p>
<p>
&nbsp;&nbsp;1) 首次启动光环game&nbsp;2) 评论详情-发送评论功能&nbsp;3)
视频投稿-上传视频功能&nbsp;4) 视频详情-关注up主功能
</p>
<p><b>七、其他</b></p>
<p>
7.1
本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。
</p>
<p>
&nbsp;7.2
如果本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,或违反任何适用的法律,则该条款被视为删除,但本协议的其余条款仍应有效并且有约束力。
</p>
<p>
&nbsp;7.3
光环有权随时根据有关法律、法规的变化以及公司经营状况和经营策略的调整等修改本协议。修改后的协议会在软件设置内发布。
当发生有关争议时,以最新的协议文本为准。如果不同意改动的内容,用户可以自行删除本软件。如果用户继续使用本软件,则视为您接受本协议的变动。
</p>
<p>&nbsp;7.4 光环在法律允许的最大范围内对本协议拥有解释权与修改权。</p>
</div>
body {
margin: 10px;
}
.top {
margin-left: 0;
margin-right: 0;
padding: 10px 0 10px 0;
}
.title {
font-weight: 700;
}
p {
font-size: 14px;
word-break: break-all;
}
.bold {
font-weight: 700;
}
.margintop {
margin-top: 10px;
}
.left-indent {
margin-left: 20px;
}
.red-style {
color: red;
}
.bold-font {
font-weight: bold;
}
span.bold {
font-weight: bold;
}
.link-text {
color: #005ad0;
text-decoration: underline;
}
</style>
<body>
<h3 class="top">光环助手软件许可及服务协议</h3>
<h5 class="title">首部及导言</h5>
<p>欢迎使用光环助手软件许可及服务</p>
<p>
各位用户在使用光环助手前,请您务必审慎阅读、并充分理解本协议中的各项条款,
<span class="bold">
特别是免除或者限制责任的条款,以及开通或使用某项服务的单独协议,并选择接受或不接受。
</span>
除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本软件及相关服务。您的下载、安装、使用、登录等行为即视为您已阅读并同意上述协议的约束。
</p>
<p>如果您未满18周岁请在法定监护人的陪同下阅读本协议及其他上述协议。</p>
<h5 class="title margintop">一、权利声明</h5>
<p>
“光环助手”的一切知识产权,以及与“光环助手”相关的所有信息内容,包括但不限于:文字表述及其组合、图标、图饰、图像、图表、色彩、界面设计、版面框架、有关数据、附加程序、印刷材料或电子文档等均为光环助手所有,受著作权法和国际著作权条约以及其他知识产权法律法规的保护。
</p>
<h5 class="title margintop">二、软件使用规范</h5>
<p>
2.1
本软件是基于Android安卓系统手机、平板电脑(PAD)等设备开发的一款软件,提供注册登录、手机游戏管理、游戏推荐、文章阅读等功能
</p>
<p>2.2 软件的下载、安装和使用</p>
<p>
本软件为免费软件,用户可以非商业性、无限制数量地从光环授权的渠道下载、安装及使用本软件。
</p>
<p>
<span class="bold">
如果您从未经光环授权的第三方获取本软件或与本软件名称相同的安装程序,光环无法保证该软件能够正常使用,并对因此给您造成的损失不予负责。
</span>
</p>
<p>2.3 软件的复制、分发和传播</p>
<p>
本产品以学习、研究交流为目的。用户可以非商业性、无限制数量地复制、分发和传播本软件产品。但必须保证每一份复制、分发和传播都是完整和真实的,
包括所有有关本软件产品的软件、电子文档, 版权和商标,亦包括本协议。
</p>
<p>2.4 软件的更新</p>
<p>
为了改善用户体验、完善服务内容,光环将不断努力开发新的服务,并为您不时提供软件更新(这些更新可能会采取软件替换、修改、功能强化、版本升级等形式)。为了保证本软件及服务的安全性和功能的一致性,光环有权不经向您特别通知而对软件进行更新,或者对软件的部分功能效果进行改变或限制。本软件新版本发布后,旧版本的软件可能无法使用。光环不保证旧版本软件继续可用及相应的客户服务,请您随时核对并下载最新版本。
</p>
<h5 class="title margintop">三、用户使用须知</h5>
<p>3.1 您理解并同意:</p>
<p>
为了向您提供有效的服务,本软件会利用您移动通讯终端的处理器和带宽等资源。本软件使用过程中可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担相关费用.
</p>
<p>3.2 您理解并同意:</p>
<p>
由本软件进行收录、推荐并提供下载、升级服务的第三方软件,由第三方享有一切合法权利,光环并不能识别用户利用本软件下载、安装的第三方软件是否有合法来源。
<span class="bold">
因第三方软件引发的任何纠纷,由该第三方负责解决,光环不承担任何责任。
</span>
同时光环不对第三方软件或技术提供客服支持,若用户需要获取支持,请与该软件或技术提供商联系,若您为有关软件的权利人,不愿本软件为您的软件提供用户下载、安装、使用的服务,也可按本协议约定的联系方式联系我们,我们将会积极配合进行处理。
</p>
<p>3.3 您理解并同意:</p>
<p>
<span class="bold">
如果因您不正当使用本软件造成了不良影响,或因使用本软件造成的包括但不限于数据异常等问题,均由使用者自行承担,光环团队不对任意类型的使用结果承担责任;
</span>
</p>
<p>3.4 您理解并同意:</p>
<p>
本软件不含任何破坏用户移动通讯设备数据和获取用户隐私信息的恶意代码,不会泄露用户的个人信息和隐私;
</p>
<p>3.5 您理解并同意:</p>
<p>
<span class="bold">
对于包括但不限于互联网网络故障、计算机故障、手机故障或病毒、信息损坏或丢失、计算机系统问题,或其它任何基于不可抗力原因而产生的损失,光环团队不承担任何责任。
</span>
</p>
<p>3.6 您理解并同意:</p>
<p>光环发布、收录的文章均不代表光环立场。</p>
<p>3.7 您理解并同意:</p>
<p>
为实现软件包括但不限于集中展示、下载、安装、卸载等游戏管理功能以及文章优先推荐功能,本软件会检测用户手机中已安装游戏的包名、版本号、版本名、游戏名称信息。除征得用户明确同意和法律明确规定外,光环不会向第三方泄露任何的用户信息
</p>
<p>3.8 您理解并同意:</p>
<p>
用户应在遵守法律及本协议的前提下使用本软件。用户无权实施包括但不限于下列行为:
</p>
3.8.1 不得删除或者改变本软件上的所有权利管理电子信息
<br />
3.8.2 不得故意避开或者破坏著作权人为保护本软件著作权而采取的技术措施;
<br />
3.8.3 用户不得利用本软件误导、欺骗他人;
<br />
3.8.4
违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行;
<br />
3.8.5 未经允许,进入计算机信息网络或者使用计算机信息网络资源;
<br />
3.8.6 未经允许,对计算机信息网络功能进行删除、修改或者增加;
<br />
3.8.7
未经允许,对计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加;
<br />
3.8.8 破坏本软件系统或网站的正常运行,故意传播计算机病毒等破坏性程序;
<br />
3.8.9 其他任何危害计算机信息网络安全的行为。
<br />
<p>3.9 您理解并同意:</p>
<p>
本软件经过详细的测试,但不能保证与所有的软硬件系统完全兼容,不能保证本软件完全没有错误。如果出现不兼容及软件错误的情况,用户可通过各反馈途径将情况告知光环团队,获得技术支持。如果无法解决兼容性问题,用户可以删除本软件。
</p>
<h5 class="title margintop">四、争议解决处理</h5>
<p>
本《协议》的解释、效力及纠纷的解决,适用于中华人民共和国法律。若用户和光环助手之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户在此完全同意将纠纷或争议提交光环助手所在地法院管辖
</p>
<p class="title margintop"><b>五、第三方SDK接入说明</b></p>
<p>
为保障光环助手App相关功能的实现与应用安全稳定的运行我们会接入由第三方提供的软件开发包SDK实现相关功能。
<br />
我们会对合作方获取有关信息的软件工具开发包SDK进行严格的安全检测并与授权合作伙伴约定严格的数据保护措施令其按照我们的委托目的、服务说明、本隐私权政策以及其他任何相关的保密和安全措施来处理个人信息。
<br />
<span class="red-style">
下方为整个光环助手
<span class="bold">所有版本</span>
内接入的所有信息收集类第三方SDK的权限说明因隐私政策会因光环助手版本迭代而新接入SDK或停止合作部分SDK方便照顾
<span class="bold">所有版本</span>
的用户查看自己SDK第三方权限说明。
<br />
我们对涉及用户信息使用的SDK相关情况进行了逐项列举具体如下
</span>
</p>
<p class="margintop red-style bold-font"><b>1数据统计类</b></p>
<p>1.头条推广</p>
<p>
SDK官网
<span class="link-text">
https://ad.oceanengine.com/openapi/index.html
</span>
</p>
<p>SDK包名com.bytedance</p>
<p>企业主体:北京有竹居网络技术有限公司</p>
<p>使用目的:用于广告流量统计相关服务</p>
<p>
收集信息类型设备品牌、型号、软件系统相关信息、安卓oaid、无线网SSID名称、WiFi路由器MAC地址、设备MAC地址、IMEI、地理位置
</p>
<p>
隐私政策链接:
<span class="link-text">
https://ad.oceanengine.com/openapi/register/protocol.html?rid=vo25p8sfqde
</span>
</p>
<p>2.talkingdata统计</p>
<p>
SDK官网
<span class="link-text">http://www.talkingdata.com/</span>
</p>
<p>SDK包名com.tendcloud</p>
<p>企业主体:北京腾云天下科技有限公司</p>
<p>使用目的:用于统计数据和效果分析,以便为用户提供更好的服务</p>
<p>收集信息类型:设备信息、网络信息、位置信息、应用信息</p>
<p>
隐私政策链接:
<span class="link-text">
http://www.talkingdata.com/privacy.jsp?languagetype=zh_cn
</span>
</p>
<p>3.腾讯MTA</p>
<p>
SDK官网
<span class="link-text">https://mta.qq.com/mta/</span>
</p>
<p>SDK包名com.tencent</p>
<p>企业主体:深圳市腾讯计算机系统有限公司</p>
<p>使用目的:用于统计数据和效果分析</p>
<p>
收集信息类型Mac地址、唯一设备识别码IMEI、android
ID、IDFA、OPENUDID、GUID/SIM卡IMSI信息、地理位置信息
</p>
<p>
隐私政策链接:
<span class="link-text">
https://mta.qq.com/mta/ctr_index/protocol_v2/
</span>
</p>
<p>4.腾讯广点通</p>
<p>
SDK官网
<span class="link-text">https://developers.e.qq.com/</span>
</p>
<p>SDK包名com.tencent</p>
<p>企业主体:深圳市腾讯计算机系统有限公司</p>
<p>使用目的:用于广告流量统计相关服务</p>
<p>
收集信息类型:
个人常用设备信息IMEI、AndroidID、位置信息IP地址、软件版本号
</p>
<p>
隐私政策链接:
<span class="link-text">https://e.qq.com/optout.html</span>
</p>
<p class="margintop red-style bold-font"><b>2社交登录类</b></p>
<p>5.微信登录分享</p>
<p>
SDK官网
<span class="link-text">https://open.weixin.qq.com/</span>
</p>
<p>SDK包名com.tencent.mm.opensdk</p>
<p>企业主体:深圳市腾讯计算机系统有限公司</p>
<p>使用目的:用于支持微信登录、分享</p>
<p>
收集信息类型个人常用设备信息MAC地址、IMEI、AndroidID、硬件型号、操作系统类型、软件信息软件版本号、浏览器类型、IP地址、服务日志信息、通讯日志信息
</p>
<p>
隐私政策链接:
<span class="link-text">https://privacy.tencent.com/</span>
</p>
<p>6.QQ登录分享</p>
<p>
SDK官网
<span class="link-text">https://connect.qq.com/</span>
</p>
<p>SDK包名com.tentcent</p>
<p>企业主体:深圳市腾讯计算机系统有限公司</p>
<p>使用目的用于支持QQ登录、分享</p>
<p>
收集信息类型个人常用设备信息MAC地址、IMEI、AndroidID、IMSI、ICCID、序列号、设备型号、操作系统版本、软件信息软件版本号、浏览器类型、网络信息、IP地址、服务日志信息、通讯日志信息 
</p>
<p>
隐私政策链接:
<span class="link-text">
https://wiki.connect.qq.com/qq互联sdk隐私保护声明
</span>
</p>
<p>7.微博登录分享</p>
<p>
SDK官网
<span class="link-text">http://open.weibo.com/authentication</span>
</p>
<p>SDK包名com.sina.weibo.sdk</p>
<p>企业主体:北京微梦创科网络技术有限公司</p>
<p>使用目的:用于支持微博登录、分享</p>
<p>
收集信息类型个人常用设备信息MAC地址、IMEI、AndroidID、IMSI、ICCID、序列号、网络信息、应用列表硬件型号、操作系统类型、软件信息软件版本号、浏览器类型、IP地址、服务日志信息、通讯日志信息
</p>
<p>
隐私政策链接:
<span class="link-text">https://open.weibo.com/wiki/开发者协议</span>
</p>
<p>8.头条抖音登录</p>
<p>
SDK官网
<span class="link-text">https://open.douyin.com/platform</span>
</p>
<p>SDK包名com.bytedance.sdk</p>
<p>企业主体:北京字节跳动科技有限公司</p>
<p>使用目的:用于支持抖音登录</p>
<p>
收集信息类型个人常用设备信息MAC地址、IMEI、AndroidID、硬件型号、操作系统类型、软件信息软件版本号、浏览器类型、IP地址、服务日志信息、通讯日志信息
</p>
<p>
隐私政策链接:
<span class="link-text">
https://www.douyin.com/agreements/?id=6773901168964798477
</span>
</p>
<p class="margintop red-style bold-font"><b>3推送通知类</b></p>
<p>9.友盟推送</p>
<p>
SDK官网
<span class="link-text">https://www.umeng.com/push</span>
</p>
<p>SDK包名com.umeng</p>
<p>企业主体:北京友盟网络科技有限公司</p>
<p>使用目的:用于游戏相关信息的提醒通知</p>
<p>
收集信息类型Mac地址、唯一设备识别码IMEI、android
ID、IDFA、OPENUDID、GUID/SIM卡IMSI信息、地理位置信息
</p>
<p>
隐私政策链接:
<span class="link-text">
https://www.umeng.com/page/policy?spm=a213m0.14063960.0.0.7f626e72hx3nnv
</span>
</p>
<p class="margintop red-style bold-font"><b>4其他功能类</b></p>
<p>10.阿里云反爬虫</p>
<p>
SDK官网
<span class="link-text">https://www.aliyun.com/product/antibot</span>
</p>
<p>SDK包名com.alibaba.wireless</p>
<p>企业主体:阿里巴巴网络技术有限公司</p>
<p>使用目的为APP提供网络应用安全防护</p>
<p>
收集信息类型设备相关信息例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息、设备所在位置相关信息例如IP地址、GPS位置以及能够提供相关信息的Wi-Fi接入点、蓝牙和基站等传感器信息
</p>
<p>
隐私政策链接:
<span class="link-text">
http://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html?spm=a2c4g.11186623.J_9220772140.81.b7574832gmk0vr
</span>
</p>
<p>11.腾讯bugly</p>
<p>
SDK官网
<span class="link-text">https://bugly.qq.com/v2/</span>
</p>
<p>SDK包名com.tencent.bugly</p>
<p>企业主体:深圳市腾讯计算机系统有限公司</p>
<p>使用目的APP异常上报</p>
<p>
收集信息类型:设备及应用信息。如:设备名称、设备识别符、硬件型号、操作系统版本、应用程序版本
</p>
<p>
隐私政策链接:
<span class="link-text">https://bugly.qq.com/v2/contract</span>
</p>
<p>12.阿里云文件上传</p>
<p>
SDK官网
<span class="link-text">https://www.alibabacloud.com/zh</span>
</p>
<p>SDK包名com.alibaba.sdk.android</p>
<p>SDK包名com.alibaba.sdk.android</p>
<p>企业主体:阿里巴巴网络技术有限公司</p>
<p>使用目的:用于支持用户上传视频等相关内容</p>
<p>
收集信息类型设备相关信息例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息、设备所在位置相关信息例如IP地址、GPS位置以及能够提供相关信息的Wi-Fi接入点、蓝牙和基站等传感器信息
</p>
<p>
隐私政策链接:
<span class="link-text">
http://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html?spm=a2c4g.11186623.J_9220772140.81.b7574832gmk0vr
</span>
</p>
<p>13.阿里云日志上传</p>
<p>
SDK官网
<span class="link-text">https://www.alibabacloud.com/zh</span>
</p>
<p>SDK包名com.aliyun.sls.android.sdk</p>
<p>企业主体:阿里巴巴网络技术有限公司</p>
<p>
使用目的:通过网络日志分析这些信息以便更及时响应您的帮助请求,以及用于改进服务
</p>
<p>
收集信息类型设备相关信息例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息、设备所在位置相关信息例如IP地址、GPS位置以及能够提供相关信息的Wi-Fi接入点、蓝牙和基站等传感器信息
</p>
<p>
隐私政策链接:
<span class="link-text">
http://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html?spm=a2c4g.11186623.J_9220772140.81.b7574832gmk0vr
</span>
</p>
<p>14.容联七陌</p>
<p>
SDK官网
<span class="link-text">https://www.7moor.com/developer</span>
</p>
<p>SDK包名com.m7.imkfsdk</p>
<p>企业主体:北京七陌科技有限公司</p>
<p>使用目的:用于提供对应在线客服功能</p>
<p>
收集信息类型:设备相关信息(设备名称、设备型号、硬件序列号、操作系统和应用程序版本及类型、语言设置、分辨率、移动终端随机存储内存、摄像头/相册、通讯录权限等)
</p>
<p>
隐私政策链接:
<span class="link-text">http://m.7moor.com/72/57/p5077783560e807/</span>
</p>
<h5 class="title margintop">六、关于获取手机设备信息的说明</h5>
<div>
1为方便区分每个用户的个人信息等本软件需获取用户的手机设备信息用于游戏主动预约、论坛互动交流后进行推送等用户相关的行为
<br />
2为了保障软件与服务的安全运行我们会收集您的硬件型号、操作系统版本号、国际移动设备识别码、唯一设备标识符、网络设备硬件地址、IP
地址、WLAN接入点、蓝牙、基站、软件版本号、网络接入方式、类型、状态、网络质量数据、操作、使用、服务日志。
<br />
3为了预防恶意程序及安全运营所必需我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据、应用来源。
<br />
4我们可能使用您的账户信息、设备信息、服务日志信息以及我们关联公司、合作方在获得您授权或依法可以共享的信息用于判断账户安全、进行身份验证、检测及防范安全事件。
<br />
5具体会发生获取手机设备信息场景如下说明
<br />
<p class="left-indent">
1) 首次启动光环助手
<br />
2) 游戏列表/游戏详情/资讯文章详情/搜索结果页-预约功能
<br />
3) 礼包中心/礼包详情-领取功能
<br />
4) 评论详情-发送评论功能
<br />
5) 回答/问题详情-我来回答功能
<br />
6) 问答首页-提问功能
<br />
7) 个人主页-发文章功能
<br />
8) 帖子草稿/我的草稿-编辑功能
<br />
9) 游戏投稿功能
<br />
10) 视频投稿-上传视频功能
<br />
11) 游戏详情-关注游戏功能
</p>
</div>
<h5 class="title margintop">七、其他</h5>
<p>
7.1
本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。
<br />
7.2
如果本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,或违反任何适用的法律,则该条款被视为删除,但本协议的其余条款仍应有效并且有约束力。
<br />
7.3
光环有权随时根据有关法律、法规的变化以及公司经营状况和经营策略的调整等修改本协议。修改后的协议会在软件设置内发布。
当发生有关争议时,以最新的协议文本为准。如果不同意改动的内容,用户可以自行删除本软件。如果用户继续使用本软件,则视为您接受本协议的变动。
<br />
<span class="bold">
7.4 光环在法律允许的最大范围内对本协议拥有解释权与修改权。
</span>
</p>
</body>
</html>
</body></html>

View File

@ -4,7 +4,6 @@ import android.app.Activity;
import android.app.Application.ActivityLifecycleCallbacks;
import android.os.Bundle;
import com.gh.common.im.ImManager;
import com.gh.common.notifier.Notifier;
import com.gh.common.util.DataUtils;
import com.gh.download.DownloadManager;
@ -39,7 +38,6 @@ public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallba
if (HaloApp.isUserAcceptPrivacyPolicy(activity)) {
DataUtils.onResume(activity);
ImManager.updateFloatingWindow();
//FIXME 这里应该只是部分Activity需要
try {
// 初始化gameMap

View File

@ -81,13 +81,8 @@ public class WaitingDialogFragment extends BaseDialogFragment {
@Override
public void dismiss() {
dismissAllowingStateLoss();
}
@Override
public void dismissAllowingStateLoss() {
mBackListener = null;
super.dismissAllowingStateLoss();
super.dismiss();
}
public static class WaitingDialogData {

View File

@ -51,6 +51,9 @@ public class Constants {
public static final String EXTRA_DOWNLOAD_TYPE = "extra_download_type";
public static final String SILENT_UPDATE = "静默更新";
public static final String SIMULATOR_DOWNLOAD = "下载模拟器";
public static final String SIMULATOR_GAME = "simulator_game";
public static final String SIMULATOR_DOWNLOAD_START_TIME = "simulator_download_start_time";
public static final String LAST_GHZS_UPDATE_FILE_SIZE = "last_ghzs_update_file_size";
// 新用户首次启动光环的时间
@ -118,6 +121,11 @@ public class Constants {
public static final String SP_WECHAT_SHOW_BIND_PHONE_TIME = "wechat_show_bind_phone_time" + HaloApp.getInstance().getGid();
public static final String SP_WEIBO_SHOW_BIND_PHONE_TIME = "weibo_show_bind_phone_time" + HaloApp.getInstance().getGid();
public static final String SP_DOUYIN_SHOW_BIND_PHONE_TIME = "douyin_show_bind_phone_time" + HaloApp.getInstance().getGid();
//隐私政策是否有更新
public static final String SP_PRIVACY_CURRENT_MD5 = "sp_privacy_current_md5";
public static final String SP_PRIVACY_MINE_MD5 = "sp_privacy_mine_md5";
public static final String SP_PRIVACY_SETTING_MD5 = "sp_privacy_setting_md5";
public static final String SP_PRIVACY_MD5 = "sp_privacy_md5";
public static final String SP_IS_USER_ACCEPTED_PRIVACY_STATEMENT = "has_user_accepted_privacy_statement";
public static final String SP_BRAND_NEW_USER = "brand_new_user";

View File

@ -14,12 +14,6 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.OnViewClickListener;
import com.gh.common.constant.Config;
@ -28,6 +22,8 @@ import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.history.HistoryHelper;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorDownloadManager;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
@ -72,11 +68,18 @@ import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
/**
* Created by khy on 12/02/18.
*/
@ -436,6 +439,15 @@ public class BindingAdapters {
case PLUGIN:
if (gameEntity.getApk().size() == 1) {
ApkEntity apk = gameEntity.getApk().get(0);
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
if (gameEntity.getSimulator() != null) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(v.getContext(), gameEntity.getSimulator().getApk().getPackageName());
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
SimulatorDownloadManager.getInstance().showDownloadDialog(v.getContext(), gameEntity.getSimulator(),
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(), null);
return;
}
}
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
@ -461,6 +473,20 @@ public class BindingAdapters {
break;
case LAUNCH_OR_OPEN:
if (gameEntity.getApk().size() == 1) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
download(progressBar, gameEntity, traceEvent, false, entrance, location);
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
}
return;
}
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
} else {
@ -516,9 +542,12 @@ public class BindingAdapters {
HistoryHelper.insertGameEntity(gameEntity);
}
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton()));
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton()));
progressBar.getContext().startActivity(i);
break;
case UPDATING:
Utils.toast(progressBar.getContext(), "正在加急更新版本,敬请后续留意");
break;
}
});
@ -548,10 +577,14 @@ public class BindingAdapters {
} else {
if (offStatus != null && "dialog".equals(offStatus)) {
progressBar.setText("查看");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
} else if ("updating".equals(offStatus)) {
progressBar.setText("更新中");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.UPDATING);
} else {
progressBar.setText("暂无");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
}
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
}
} else {

View File

@ -48,7 +48,7 @@ class GameOffServiceDialogFragment
siteTv.setOnClickListener {
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
dismissAllowingStateLoss()
dismiss()
}
container.addView(siteTv)

View File

@ -2,7 +2,6 @@ package com.gh.common.dialog
import android.annotation.SuppressLint
import android.content.Intent
import android.content.res.AssetManager
import android.os.Build
import android.os.Bundle
import android.provider.Settings

View File

@ -102,11 +102,11 @@ class PrivacyDialogFragment : BaseDialogFragment() {
containerView?.findViewById<View>(R.id.refuseTv)?.setOnClickListener {
mCallBack?.invoke(false)
dismissAllowingStateLoss()
dismiss()
}
containerView?.findViewById<View>(R.id.agreeTv)?.setOnClickListener {
mCallBack?.invoke(true)
dismissAllowingStateLoss()
dismiss()
}
}

View File

@ -24,7 +24,6 @@ object MetaUtil {
private var m: Meta? = null
private var imei: String? = null
private var base64EncodedImei: String? = null
private var androidId: String? = null
fun refreshMeta() {
@ -105,20 +104,6 @@ object MetaUtil {
}
@JvmStatic
fun getBase64EncodedIMEI(): String {
if (TextUtils.isEmpty(base64EncodedImei) && imei != null) {
try {
base64EncodedImei = android.util.Base64.encodeToString(getIMEI().trim().toByteArray(), android.util.Base64.NO_WRAP)
} catch (e: java.lang.Exception) {
e.printStackTrace()
return ""
}
}
return base64EncodedImei ?: ""
}
fun getModel(): String? {
return Build.MODEL
}

View File

@ -4,7 +4,6 @@ import com.gh.common.runOnIoThread
import com.gh.common.util.clearHtmlFormatCompletely
import com.gh.common.util.removeInsertedContent
import com.gh.common.util.removeVideoContent
import com.gh.common.util.tryCatchInRelease
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
import com.gh.gamecenter.qa.entity.AnswerEntity
@ -15,28 +14,27 @@ object HistoryHelper {
fun insertAnswerEntity(answerDetailEntity: AnswerDetailEntity) {
val answerEntity = convertAnswerDetailToAnswer(answerDetailEntity)
// 偶尔有设备会出现磁盘满了写不进数据库的问题 database or disk is full 异常,毕竟只是插入个本地历史,这里直接捕抓
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.answerDao().addAnswer(answerEntity) } }
runOnIoThread { HistoryDatabase.instance.answerDao().addAnswer(answerEntity) }
}
fun insertArticleEntity(articleDetailEntity: ArticleDetailEntity) {
val articleEntity = convertArticleDetailToArticle(articleDetailEntity)
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.articleDao().addArticle(articleEntity) } }
runOnIoThread { HistoryDatabase.instance.articleDao().addArticle(articleEntity) }
}
@JvmStatic
fun insertGameEntity(gameEntity: GameEntity) {
val historyGameEntity = convertGameEntityToHistoryGameEntity(gameEntity)
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) } }
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
}
@JvmStatic
fun insertGameEntity(updateEntity: GameUpdateEntity) {
val historyGameEntity = convertGameUpdateEntityToHistoryGameEntity(updateEntity)
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) } }
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
}
private fun convertGameUpdateEntityToHistoryGameEntity(updateEntity: GameUpdateEntity): HistoryGameEntity {
private fun convertGameUpdateEntityToHistoryGameEntity(updateEntity: GameUpdateEntity): HistoryGameEntity{
val historyGame = HistoryGameEntity()
historyGame.orderTag = System.currentTimeMillis()

View File

@ -1,67 +1,67 @@
package com.gh.common.im
import android.app.Activity
import androidx.core.view.ViewCompat
import android.view.View
import android.view.ViewGroup
object ImHintHelper {
@JvmStatic
fun show(activity: Activity?) {
activity?.let {
var hintView = retrieveHintViewFromActivity(it)
if (hintView == null) {
hintView = ImHintView(it)
hintView.showDot(ImManager.shouldShowFloatingWindowDot)
val decorView = it.window.decorView as ViewGroup
it.runOnUiThread {
decorView.addView(hintView)
}
} else {
hintView.showDot(ImManager.shouldShowFloatingWindowDot)
}
}
}
@JvmStatic
fun dismiss(activity: Activity?) {
activity?.let {
clearCurrent(it)
}
}
private fun retrieveHintViewFromActivity(activity: Activity?) : ImHintView? {
(activity?.window?.decorView as? ViewGroup)?.let {
for (i in 0..it.childCount) {
val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
if (childView != null && childView.windowToken != null) {
return childView
}
}
return null
}
return null
}
private fun clearCurrent(activity: Activity?) {
(activity?.window?.decorView as? ViewGroup)?.let {
for (i in 0..it.childCount) {
val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
if (childView != null && childView.windowToken != null) {
ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView))
}
}
}
}
private fun getRemoveViewRunnable(childView: View?): Runnable {
return Runnable {
childView?.let {
(childView.parent as? ViewGroup)?.removeView(childView)
}
}
}
}
//package com.gh.common.im
//
//import android.app.Activity
//import androidx.core.view.ViewCompat
//import android.view.View
//import android.view.ViewGroup
//
//object ImHintHelper {
//
// @JvmStatic
// fun show(activity: Activity?) {
// activity?.let {
// var hintView = retrieveHintViewFromActivity(it)
// if (hintView == null) {
// hintView = ImHintView(it)
// hintView.showDot(ImManager.shouldShowFloatingWindowDot)
//
// val decorView = it.window.decorView as ViewGroup
// it.runOnUiThread {
// decorView.addView(hintView)
// }
// } else {
// hintView.showDot(ImManager.shouldShowFloatingWindowDot)
// }
// }
// }
//
// @JvmStatic
// fun dismiss(activity: Activity?) {
// activity?.let {
// clearCurrent(it)
// }
// }
//
// private fun retrieveHintViewFromActivity(activity: Activity?) : ImHintView? {
// (activity?.window?.decorView as? ViewGroup)?.let {
// for (i in 0..it.childCount) {
// val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
// if (childView != null && childView.windowToken != null) {
// return childView
// }
// }
// return null
// }
// return null
// }
//
// private fun clearCurrent(activity: Activity?) {
// (activity?.window?.decorView as? ViewGroup)?.let {
// for (i in 0..it.childCount) {
// val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
// if (childView != null && childView.windowToken != null) {
// ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView))
// }
// }
// }
// }
//
// private fun getRemoveViewRunnable(childView: View?): Runnable {
// return Runnable {
// childView?.let {
// (childView.parent as? ViewGroup)?.removeView(childView)
// }
// }
// }
//
//}

View File

@ -1,45 +1,45 @@
package com.gh.common.im
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.widget.RelativeLayout
import androidx.core.view.ViewCompat
import com.gh.common.util.DisplayUtils
import com.gh.gamecenter.R
import kotlinx.android.synthetic.main.view_im_hint.view.*
class ImHintView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
: RelativeLayout(context, attrs, defStyle) {
init {
inflate(context, R.layout.view_im_hint, this)
ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat() - 1)
ivContainer.setOnClickListener {
if (context is Activity) {
ImManager.startChatActivity(context)
ImManager.removeNotification()
}
}
val lp = ivContainer.layoutParams as RelativeLayout.LayoutParams
lp.setMargins(0, 0, dp2px(30f), dp2px(106f) + DisplayUtils.retrieveNavigationHeight(context))
}
fun showDot(show: Boolean) {
if (show) {
unreadDot.visibility = View.VISIBLE
} else {
unreadDot.visibility = View.GONE
}
}
private fun dp2px(dp: Float): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.applicationContext.resources.displayMetrics).toInt()
}
}
//package com.gh.common.im
//
//import android.app.Activity
//import android.content.Context
//import android.util.AttributeSet
//import android.util.TypedValue
//import android.view.View
//import android.widget.RelativeLayout
//import androidx.core.view.ViewCompat
//import com.gh.common.util.DisplayUtils
//import com.gh.gamecenter.R
//import kotlinx.android.synthetic.main.view_im_hint.view.*
//
//class ImHintView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
// : RelativeLayout(context, attrs, defStyle) {
//
// init {
// inflate(context, R.layout.view_im_hint, this)
//
// ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat() - 1)
//
// ivContainer.setOnClickListener {
// if (context is Activity) {
// ImManager.startChatActivity(context)
// ImManager.removeNotification()
// }
// }
//
// val lp = ivContainer.layoutParams as RelativeLayout.LayoutParams
//
// lp.setMargins(0, 0, dp2px(30f), dp2px(106f) + DisplayUtils.retrieveNavigationHeight(context))
// }
//
// fun showDot(show: Boolean) {
// if (show) {
// unreadDot.visibility = View.VISIBLE
// } else {
// unreadDot.visibility = View.GONE
// }
// }
//
// private fun dp2px(dp: Float): Int {
// return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.applicationContext.resources.displayMetrics).toInt()
// }
//}

View File

@ -4,7 +4,6 @@ import android.content.Context
import android.database.ContentObserver
import android.media.AudioManager
import android.os.Handler
import com.gh.common.util.tryCatchInRelease
class VolumeObserver(var context: Context, handler: Handler, var callback: MuteCallback? = null)
: ContentObserver(handler) {
@ -12,8 +11,7 @@ class VolumeObserver(var context: Context, handler: Handler, var callback: MuteC
init {
val audio = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
// 部分设备的 audioManager getStreamVolume 内部会触发空指针 :(
tryCatchInRelease { previousVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC) }
previousVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
}
override fun onChange(selfChange: Boolean) {

View File

@ -0,0 +1,243 @@
package com.gh.common.simulator
import android.app.Dialog
import android.content.Context
import android.view.View
import android.view.Window
import android.widget.ProgressBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.g00fy2.versioncompare.Version
import com.gh.common.AppExecutor.uiExecutor
import com.gh.common.constant.Constants
import com.gh.common.dialog.TrackableDialog
import com.gh.common.util.*
import com.gh.common.util.PackageInstaller.getDownloadPath
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.ApkEntity
import com.gh.gamecenter.entity.SimulatorEntity
import com.gh.gamecenter.entity.TrackableEntity
import com.halo.assistant.HaloApp
import com.lightgame.download.*
import com.lightgame.utils.Utils
import java.text.DecimalFormat
class SimulatorDownloadManager private constructor() {
private var app_pb_progress: ProgressBar? = null
private var appProgressSize: TextView? = null
private var appProgressRemain: TextView? = null
private var appProgressPercent: TextView? = null
private var appProgressFilling: View? = null
private var appProgressAnchor: View? = null
private var downloadDialog: Dialog? = null
private var simulatorLocation: SimulatorLocation? = null
private var simulator: SimulatorEntity? = null
private var gameId: String = ""
private var gameName: String = ""
private var downloadType: String = ""
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity?) {
if (downloadEntity?.isSimulatorDownload() == true) {
val size = downloadEntity.progress.toFloat() / 1024 / 1024
val df = DecimalFormat("0.00")
appProgressSize!!.text = "${df.format(size.toDouble())}MB"
appProgressRemain!!.text = String.format("剩余%s", SpeedUtils.getRemainSecondTime(downloadEntity.size,
downloadEntity.progress, downloadEntity.speed * 1024))
app_pb_progress!!.progress = (downloadEntity.percent * 10).toInt()
val width = app_pb_progress!!.width
val marLeft = (downloadEntity.percent / 100 * width).toInt()
val anchorLp = appProgressAnchor!!.layoutParams
if (anchorLp is ConstraintLayout.LayoutParams) {
anchorLp.leftMargin = marLeft
appProgressAnchor!!.layoutParams = anchorLp
}
val fillingLp = appProgressFilling!!.layoutParams
fillingLp.width = marLeft + DisplayUtils.dip2px(5f)
appProgressFilling!!.layoutParams = fillingLp
appProgressPercent?.text = if (downloadEntity.percent != 100.0) "${downloadEntity.percent}%" else "100%"
when {
DownloadStatus.done == downloadEntity.status -> {
val locationStr = if (simulatorLocation == SimulatorLocation.LAUNCH) "${simulatorLocation?.value}${gameName}" else simulatorLocation?.value
val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk")
val startTime = downloadEntity.getMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME)
LogUtils.uploadSimulatorDownload("simulator_download_complete", fileName, simulator?.id, downloadEntity.name, gameId, locationStr, downloadType, startTime)
DownloadManager.getInstance(HaloApp.getInstance().application).cancel(downloadEntity.url, false, true)
downloadDialog?.dismiss()
}
DownloadStatus.neterror == downloadEntity.status -> {
ToastUtils.showToast("网络不稳定,下载任务已暂停")
}
DownloadStatus.timeout == downloadEntity.status -> {
ToastUtils.showToast("网络不稳定,下载任务已暂停")
}
DownloadStatus.notfound == downloadEntity.status -> {
ToastUtils.showToast("下载链接异常,请稍后重试")
}
DownloadStatus.hijack == downloadEntity.status -> {
ToastUtils.showToast("网络劫持,请稍后重试")
}
}
}
}
}
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation) {
showDownloadDialog(context, simulator, location, "", "", null)
}
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation, gameId: String = "", gameName: String = "", cancelCallback: (() -> Unit)? = null) {
this.simulatorLocation = location
this.simulator = simulator
this.gameId = gameId
this.gameName = gameName
//判断是否隐藏
if (simulator?.active == false) {
showNoneEmulatorDialog(context)
return
}
val isInstalled = PackageUtils.isInstalledFromAllPackage(context, simulator?.apk?.packageName)
val versionFromInstalledApp = PackageUtils.getVersionByPackage(simulator?.apk?.packageName)
val shouldShowUpdate = Version(simulator?.apk?.version).isHigherThan(versionFromInstalledApp)
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message = if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText = if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
val trackableEntity = TrackableEntity("模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, {
if (shouldShowUpdate && isInstalled){
cancelCallback?.invoke()
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
}
}, {
showDownloadingDialog(context, simulator)
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载")
})
}
private fun showDownloadingDialog(context: Context, simulator: SimulatorEntity?) {
val msg = FileUtils.isCanDownload(context, simulator?.apk?.size)
if (!msg.isNullOrEmpty()) {
Utils.toast(context, msg)
return
}
if (NetworkUtils.isMobileConnected(context)) {
Utils.toast(context, "当前使用移动数据进行下载")
}
downloadDialog = TrackableDialog(context, R.style.GhAlertDialog, "模拟器下载", "下载中弹窗")
downloadDialog?.window?.setBackgroundDrawableResource(R.color.transparent)
val view = View.inflate(context, R.layout.download_simulator_dialog, null)
app_pb_progress = view.findViewById(R.id.progress)
appProgressSize = view.findViewById(R.id.size)
appProgressRemain = view.findViewById(R.id.remain)
appProgressAnchor = view.findViewById(R.id.progress_anchor)
appProgressPercent = view.findViewById(R.id.percent)
appProgressFilling = view.findViewById(R.id.progress_filling)
view.findViewById<View>(R.id.app_tv_cancel).setOnClickListener {
DownloadManager.getInstance(context).pause(simulator?.apk?.url)
MtaHelper.onEvent("模拟器下载", "下载中弹窗", "点击关闭")
downloadDialog?.dismiss()
}
downloadDialog?.setOnDismissListener {
DownloadManager.getInstance(context).removeObserver(dataWatcher)
}
downloadDialog?.setCanceledOnTouchOutside(false)
downloadDialog?.setCancelable(false)
downloadDialog?.closeOptionsMenu()
downloadDialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
downloadDialog?.setContentView(view)
val params = downloadDialog?.window?.attributes
params?.width = context.resources.displayMetrics.widthPixels - DisplayUtils.dip2px(60f)
downloadDialog?.window?.attributes = params
download(context, simulator)
}
private fun showNoneEmulatorDialog(context: Context) {
val dialog = DialogUtils.showNewAlertDialog(context, "安装模拟器", "模拟器游戏需要先下载安装对应的模拟器,才可以运行", "取消", "暂无下载", null, {
ToastUtils.showToast("该模拟器暂未提供下载")
})
dialog?.window?.findViewById<TextView>(R.id.confirm)?.setTextColor(ContextCompat.getColor(context, R.color.text_cccccc))
}
private fun download(context: Context, simulator: SimulatorEntity?) {
val apkEntity = simulator?.apk ?: return
DownloadManager.getInstance(context).pauseAll()
val entity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.url)
if (entity != null) {
when (entity.status) {
DownloadStatus.pause, DownloadStatus.subscribe,
DownloadStatus.neterror, DownloadStatus.timeout -> {
DownloadManager.getInstance(context).addObserver(dataWatcher)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance(context).resume(entity, true) }, 200)
downloadDialog?.show()
}
DownloadStatus.done -> DataChanger.notifyDataChanged(entity)
else -> createDownload(context, apkEntity, simulator)
}
} else {
createDownload(context, apkEntity, simulator)
}
}
private fun createDownload(context: Context, apkEntity: ApkEntity, simulator: SimulatorEntity) {
DownloadManager.getInstance(context).addObserver(dataWatcher)
val downloadEntity = DownloadEntity()
downloadEntity.url = apkEntity.url
downloadEntity.name = simulator.name
downloadEntity.path = getDownloadPath(simulator.name, apkEntity.format)
downloadEntity.platform = apkEntity.getPlatform()
downloadEntity.packageName = apkEntity.packageName
downloadEntity.versionName = apkEntity.version
downloadEntity.addMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE, Constants.SIMULATOR_DOWNLOAD)
downloadEntity.addMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME, (System.currentTimeMillis() / 1000).toString())
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance(context).add(downloadEntity) }, 200)
val locationStr = if (simulatorLocation == SimulatorLocation.LAUNCH) "${simulatorLocation?.value}${gameName}" else simulatorLocation?.value
val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk")
LogUtils.uploadSimulatorDownload("simulator_download", fileName, simulator.id, simulator.name, gameId, locationStr, downloadType, "")
downloadDialog?.show()
}
companion object {
@Volatile
private var instance: SimulatorDownloadManager? = null
@JvmStatic
fun getInstance(): SimulatorDownloadManager {
return instance ?: synchronized(this) {
instance ?: SimulatorDownloadManager().also { instance = it }
}
}
}
enum class SimulatorLocation(val value: String) {
LAUNCH("启动"),
SIMULATOR_GAME("模拟器游戏"),
SIMULATOR_MANAGE("模拟器游戏-模拟器管理")
}
}

View File

@ -0,0 +1,219 @@
package com.gh.common.simulator
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import com.g00fy2.versioncompare.Version
import com.gh.common.util.*
import com.gh.download.DownloadManager
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.EmptyResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadDao
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import java.io.File
object SimulatorGameManager {
private val gamePath = FileUtils.getDownloadPath(HaloApp.getInstance().application, "emulator_game")
@JvmStatic
fun getPathByType(type: String) = "${gamePath}/${type}"
@JvmStatic
fun deleteLocalGames(names: List<String>) {
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
names.forEach { name ->
val downloadEntity = downloadEntityList.find { it.name == name }
if (downloadEntity != null) {
val file = File(downloadEntity.path)
if (file.exists()) {
file.delete()
DownloadDao.getInstance(HaloApp.getInstance().application).delete(downloadEntity.url)
}
}
}
}
@JvmStatic
fun deleteLocalGame(name: String) {
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
val downloadEntity = downloadEntityList.find { it.name == name }
if (downloadEntity != null) {
val file = File(downloadEntity.path)
if (file.exists()) {
file.delete()
DownloadDao.getInstance(HaloApp.getInstance().application).delete(downloadEntity.url)
}
}
}
@JvmStatic
fun findDownloadEntityByUrl(url: String?): DownloadEntity? {
val downloadEntity = DownloadDao.getInstance(HaloApp.getInstance().application).get(url)
if (downloadEntity != null) {
val isFileCompleted = DownloadManager.getInstance(HaloApp.getInstance().application).isFileCompleted(url)
if (downloadEntity.isSimulatorGame() && isFileCompleted) {
return downloadEntity
}
}
return null
}
@JvmStatic
fun isSimulatorGame(gameEntity: GameEntity) = gameEntity.category == "simulator"
@JvmStatic
fun launchSimulatorGame(downloadEntity: DownloadEntity, gameEntity: GameEntity) {
val versionFromInstalledApp = PackageUtils.getVersionByPackage(gameEntity.simulator?.apk?.packageName)
val shouldShowUpdate = Version(gameEntity.simulator?.apk?.version).isHigherThan(versionFromInstalledApp)
if (shouldShowUpdate) {
SimulatorDownloadManager.getInstance().showDownloadDialog(AppManager.getInstance().recentActiveActivity, gameEntity.simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
?: "") {
jumpToSimulator(downloadEntity, gameEntity)
}
} else {
jumpToSimulator(downloadEntity, gameEntity)
}
}
private fun jumpToSimulator(downloadEntity: DownloadEntity, gameEntity: GameEntity) {
val intent = Intent()
intent.data = Uri.fromFile(File(downloadEntity.path))
if (gameEntity.simulatorType == "FBA") {
val apkEntity = gameEntity.getApk()[0]
intent.putExtra("rom_name", apkEntity.packageName)
}
intent.putExtra("default_path", downloadEntity.path.substring(0, downloadEntity.path.lastIndexOf('/')))
intent.putExtra("game_type", gameEntity.simulatorType)
intent.putExtra("title", downloadEntity.name)
intent.putExtra("icon", gameEntity.icon ?: "")
intent.putExtra("meta", LogUtils.getMetaObject().toString())
intent.putExtra("simulatorId", gameEntity.simulator?.id)
intent.putExtra("simulatorName", gameEntity.simulator?.name)
intent.putExtra("gameId", gameEntity.id)
val destActivity = "com.gh.emu.RequestPermissionActivity"
intent.setClassName(gameEntity.simulator?.apk?.packageName ?: "", destActivity)
try {
AppManager.getInstance().recentActiveActivity.startActivity(intent)
} catch (e: ActivityNotFoundException) {
ToastUtils.showToast("模拟器安装错误")
}
recordPlaySimulatorGames(gameEntity.id)
}
/**
* 记录设备下载的模拟器游戏
*/
@SuppressLint("CheckResult")
@JvmStatic
fun recordDownloadSimulatorGames(gameId: String) {
val requestMap = hashMapOf<String, Any>()
requestMap["game_id"] = gameId
requestMap["package"] = "-"
val body = requestMap.createRequestBodyAny()
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.downloadSimulatorGames(HaloApp.getInstance().gid, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(EmptyResponse())
}
/**
* 标记已玩过
*/
@SuppressLint("CheckResult")
fun postPlayedGame(gameId: String, packageName: String) {
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn) {
val requestMap = hashMapOf<String, Any>()
requestMap["game_id"] = gameId
requestMap["package"] = packageName
val body = requestMap.toRequestBody()
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.postPlayedGame(UserManager.getInstance().userId, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(EmptyResponse())
}
}
/**
* 记录启动设备上的模拟器游戏
*/
@SuppressLint("CheckResult")
fun recordPlaySimulatorGames(gameId: String) {
val requestMap = hashMapOf<String, Any>()
requestMap["game_id"] = gameId
requestMap["package"] = "-"
val body = requestMap.createRequestBodyAny()
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.playedSimulatorGames(HaloApp.getInstance().gid, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(EmptyResponse())
}
/**
* 删除设备下载模拟器游戏的记录
*/
@SuppressLint("CheckResult")
fun deleteSimulatorGame(gameId: String, callback: () -> Unit) {
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.deleteSimulatorGame(HaloApp.getInstance().gid, gameId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
callback.invoke()
}
})
}
/**
* 批量删除设备下载模拟器游戏的记录
*/
@SuppressLint("CheckResult")
fun deleteSimulatorGames(gameIds: List<String>, callback: () -> Unit) {
val requestMap = hashMapOf<String, Any>()
requestMap["game_ids"] = gameIds
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.deleteSimulatorGames(HaloApp.getInstance().gid, requestMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
callback.invoke()
}
})
}
/**
* 批量删除设备下载模拟器游戏的记录
*/
@JvmStatic
@SuppressLint("CheckResult")
fun deleteAllSimulatorGame() {
RetrofitManager.getInstance(HaloApp.getInstance().application).api
.deleteAllSimulatorGame(HaloApp.getInstance().gid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(EmptyResponse())
}
}

View File

@ -5,11 +5,12 @@ 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"
const val LOCATION_SIMULATOR_GAME = "simulator_game"
fun getAd(location: String): SettingsEntity.AD? {
val adList = Config.getSettings()?.adList ?: return null
@ -34,4 +35,19 @@ object AdHelper {
return discoverAdList
}
fun getAdForLocation(location: String): SettingsEntity.AD? {
val adList = Config.getSettings()?.adList ?: return null
var result: SettingsEntity.AD? = null
run outside@ {
for (ad in adList) {
if (ad.location == location) {
result = ad
return@outside
}
}
}
return result
}
}

View File

@ -57,6 +57,9 @@ public class DataLogUtils {
map.put("channel", channel);
Map<String, String> params = new HashMap<>();
if ("search-hot-tag".equals(topic) || "game".equals(topic) || "slide".equals(topic)) {
params.put("meta", LogUtils.getMetaObject().toString());
}
params.put("topic", topic);
params.put("source", "GH-ASSIST-Client");
params.put("time", String.valueOf(Utils.getTime(context)));

View File

@ -3,13 +3,11 @@ package com.gh.common.util;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.BuildConfig;
import com.gh.gid.GidCallback;
import com.gh.gid.GidHelper;
import com.halo.assistant.HaloApp;
@ -191,36 +189,36 @@ public class DataUtils {
// 游戏下载
public static void onGameDownloadEvent(Context context, String gameName, String platform, String entrance, String status, String method) {
Map<String, Object> kv = new HashMap<>();
platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
kv.put("版本", platform);
kv.put("用户机型", Build.MODEL);
kv.put("设备IMEI", MetaUtil.getIMEI());
kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
kv.put("光环助手版本", BuildConfig.VERSION_NAME);
kv.put("位置", entrance);
kv.put("类型", method);
kv.put("厂商", Build.MANUFACTURER);
kv.put("Android版本", Build.VERSION.RELEASE);
onEvent(context, "游戏下载", gameName, kv);
Map<String, Object> kv2 = new HashMap<>();
kv2.put("状态", status);
kv2.put("位置", entrance);
if (status.equals("开始")) {
kv2.put("版本", entrance + "-开始");
kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
} else {
kv2.put("版本", platform);
kv2.put("游戏分平台", gameName + "-" + platform);
kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
}
onEvent(context, "游戏下载位置", gameName, kv2);
// Map<String, Object> kv = new HashMap<>();
//
// platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
//
// kv.put("版本", platform);
// kv.put("用户机型", Build.MODEL);
// kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
// kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
// kv.put("光环助手版本", BuildConfig.VERSION_NAME);
// kv.put("位置", entrance);
// kv.put("类型", method);
// kv.put("厂商", Build.MANUFACTURER);
// kv.put("Android版本", Build.VERSION.RELEASE);
// onEvent(context, "游戏下载", gameName, kv);
//
// Map<String, Object> kv2 = new HashMap<>();
// kv2.put("状态", status);
// kv2.put("位置", entrance);
//
// if (status.equals("开始")) {
// kv2.put("版本", entrance + "-开始");
// kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
// } else {
// kv2.put("版本", platform);
// kv2.put("游戏分平台", gameName + "-" + platform);
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
// }
//
// onEvent(context, "游戏下载位置", gameName, kv2);
}
// 游戏更新

View File

@ -5,6 +5,7 @@ import android.view.View;
import com.gh.common.constant.Config;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.view.DownloadProgressBar;
import com.gh.common.xapk.XapkInstaller;
import com.gh.common.xapk.XapkUnzipStatus;
@ -66,6 +67,9 @@ public class DetailDownloadUtils {
if ("dialog".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "查看详情" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE_WITH_HINT);
} else if ("updating".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "更新中" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.UPDATING);
} else {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "暂无下载" : viewHolder.gameEntity.getDownloadOffText());
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
@ -148,13 +152,25 @@ public class DetailDownloadUtils {
}
break;
case done:
viewHolder.mDownloadPb.setText(R.string.install);
if (downloadEntity.isPluggable()
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
} else {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
if (SimulatorGameManager.isSimulatorGame(viewHolder.gameEntity)){
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(viewHolder.context, viewHolder.gameEntity.getSimulator().getApk().getPackageName());
if (isInstalled){
viewHolder.mDownloadPb.setText(R.string.launch);
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
}else{
viewHolder.mDownloadPb.setText(R.string.install);
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
}
}else{
viewHolder.mDownloadPb.setText(R.string.install);
if (downloadEntity.isPluggable()
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
} else {
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
}
}
break;
case cancel:
case hijack:

View File

@ -4,12 +4,15 @@ import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.CountDownTimer;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@ -32,6 +35,13 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.AppExecutor;
@ -71,13 +81,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
public class DialogUtils {
public static Dialog showWaitDialog(Context context, String msg) {
@ -347,10 +350,21 @@ public class DialogUtils {
* @param cmListener 确认按钮监听
*/
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
, String negative, String positive, final CancelListener clListener, final ConfirmListener cmListener) {
, String negative, String positive, TrackableEntity trackableEntity, final CancelListener clListener, final ConfirmListener cmListener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
final Dialog dialog;
if (trackableEntity != null) {
dialog = new TrackableDialog(context,
R.style.GhAlertDialog,
trackableEntity.getEvent(),
trackableEntity.getKey(),
trackableEntity.getValue(),
trackableEntity.getCancelValue(),
trackableEntity.getKeyBackValue(),
trackableEntity.getLogShowEvent());
} else {
dialog = new Dialog(context, R.style.GhAlertDialog);
}
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_new_alert, null);
@ -395,6 +409,11 @@ public class DialogUtils {
return dialog;
}
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
, String negative, String positive, final CancelListener clListener, final ConfirmListener cmListener) {
return showNewAlertDialog(context, title, message, negative, positive, null, clListener, cmListener);
}
/**
* Material Design 风格弹窗
*
@ -1859,6 +1878,30 @@ public class DialogUtils {
dialog.show();
}
public static void showShortCutPermissionDialog(Context context) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_shortcut_permission, null);
Context finalContext = context;
contentView.findViewById(R.id.dialog_positive).setOnClickListener(v -> {
dialog.dismiss();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + finalContext.getPackageName()));
finalContext.startActivity(intent);
});
contentView.findViewById(R.id.dialog_negative).setOnClickListener(v -> {
dialog.dismiss();
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
/**
* @param context may be is application context
* @return activity context

View File

@ -575,7 +575,7 @@ object DirectUtils {
@JvmStatic
fun directToExternalBrowser(context: Context, url: String) {
if (url.isEmpty()) return
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Uri.decode(url)))
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
if (context !is AppCompatActivity) {
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

View File

@ -15,6 +15,8 @@ import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.history.HistoryHelper;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorDownloadManager;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.xapk.XapkInstaller;
import com.gh.common.xapk.XapkUnzipStatus;
import com.gh.download.DownloadManager;
@ -34,6 +36,7 @@ import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import java.io.File;
import java.util.concurrent.LinkedBlockingQueue;
import androidx.annotation.Nullable;
@ -195,6 +198,10 @@ public class DownloadItemUtils {
holder.gameDownloadBtn.setText("查看");
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
} else if ("updating".equals(offStatus)) {
holder.gameDownloadBtn.setText("更新中");
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
holder.gameDownloadBtn.setBackgroundResource(R.drawable.download_button_updating_style);
} else {
holder.gameDownloadBtn.setText("暂无");
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
@ -223,9 +230,18 @@ public class DownloadItemUtils {
if (entryMap != null && !entryMap.isEmpty()) {
DownloadEntity downloadEntity = entryMap.get(apkEntity.getPlatform());
if (downloadEntity != null) {
// 更改进度条和提示文本的状态
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
return;
if (ExtensionsKt.isSimulatorGame(downloadEntity)) {
if (downloadEntity.getStatus() != DownloadStatus.done) {
// 更改进度条和提示文本的状态
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
return;
}
} else {
// 更改进度条和提示文本的状态
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
return;
}
}
}
@ -468,7 +484,7 @@ public class DownloadItemUtils {
HistoryHelper.insertGameEntity(gameEntity);
}
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton());
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton());
context.startActivity(i);
});
} else if (gameEntity.getApk().size() == 1) {
@ -506,7 +522,115 @@ public class DownloadItemUtils {
});
});
}
}
/**
* @param clickCallback 供那些需要知道点击回调的地方使用,只要触发了点击事件就响应回调(未登录状态下点击预约也要响应回调)
*/
public static void setOnClickListenerWithInvokeCallbackForAllState(final Context context,
final TextView downloadBtn,
final GameEntity gameEntity,
final int position,
final RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter,
final String entrance,
final String location,
final ExposureEvent traceEvent,
@Nullable final EmptyCallback clickCallback) {
if (gameEntity.isReservable()) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
downloadBtn.setOnClickListener(v -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
CheckLoginUtils.checkLogin(context, entrance, () -> {
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(context, () -> {
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
gameEntity,
() -> {
LogUtils.logReservation(gameEntity, traceEvent);
adapter.notifyItemChanged(position);
}
);
dialogFragment.show(((AppCompatActivity) context).getSupportFragmentManager(), "reserve");
});
});
});
} else {
downloadBtn.setOnClickListener(v -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
if ("download".equals(gameEntity.getReserveStatus())) {
ReservationHelper.showDeleteReservationDialog(context, () -> {
ReservationHelper.deleteReservation(gameEntity, () -> {
adapter.notifyItemChanged(position);
});
});
} else {
ReservationHelper.showCancelReservationDialog(context, () -> {
ReservationHelper.cancelReservation(gameEntity, () -> {
adapter.notifyItemChanged(position);
});
});
}
});
}
return;
}
if (gameEntity.getApk().size() == 0 && gameEntity.getH5Link() != null) {
downloadBtn.setOnClickListener(v -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
LinkEntity linkEntity = gameEntity.getH5Link();
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
if (isPlay) {
HistoryHelper.insertGameEntity(gameEntity);
}
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton());
context.startActivity(i);
});
} else if (gameEntity.getApk().size() == 1) {
downloadBtn.setOnClickListener(v -> {
EmptyCallback clickRunnable = () -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent);
};
// 启动不需要请求存储权限
if (downloadBtn.getText().toString().equals(context.getString(R.string.launch))) {
clickRunnable.onCallback();
} else {
PermissionHelper.checkStoragePermissionBeforeAction(context, clickRunnable);
}
});
} else {
downloadBtn.setOnClickListener(v -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
PermissionHelper.checkStoragePermissionBeforeAction(context, () -> {
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
DownloadDialog.showDownloadDialog(
v.getContext(),
gameEntity,
traceEvent,
entrance,
location);
});
});
});
});
}
}
public static void onNormalClick(final Context context,
@ -541,6 +665,7 @@ public class DownloadItemUtils {
});
});
DataLogUtils.uploadGameLog(context, gameEntity.getId(), gameEntity.getName(), entrance);
} else if (str.equals(context.getString(R.string.attempt))) {
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
@ -570,8 +695,30 @@ public class DownloadItemUtils {
});
}
} else if (str.equals(context.getString(R.string.install))) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
if (gameEntity.getSimulator() != null) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
SimulatorDownloadManager.getInstance().showDownloadDialog(context, gameEntity.getSimulator(),
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(),null);
return;
}
}
install(context, gameEntity, position, adapter);
} else if (str.equals(context.getString(R.string.launch))) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
download(context, gameEntity, downloadBtn, entrance, location, false, traceEvent);
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
}
return;
}
if (entrance.contains("我的游戏")) {
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.getName());
}

View File

@ -45,6 +45,7 @@ object DownloadNotificationHelper {
val xapkStatus = entity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SILENT_UPDATE) return
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SIMULATOR_DOWNLOAD) return
val intent = Intent()
if (entity.status == DownloadStatus.done && xapkStatus != XapkUnzipStatus.FAILURE.name) {
@ -114,7 +115,8 @@ object DownloadNotificationHelper {
|| entity.status == DownloadStatus.overflow
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty()
&& xapkStatus != XapkUnzipStatus.FAILURE.name)) {
&& xapkStatus != XapkUnzipStatus.FAILURE.name)
||entity.status == DownloadStatus.done && entity.isSimulatorGame()) {//模拟器游戏下载完需要cancel掉通知
requireUpdateNotificationGroupDelay = true
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
} else {

View File

@ -6,6 +6,8 @@ import android.preference.PreferenceManager
import com.gh.base.BaseActivity
import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureUtils
import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.common.exposure.meta.MetaUtil
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadDataHelper
@ -133,20 +135,36 @@ object DownloadObserver {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
if (!downloadEntity.isPluggable) {
// 是否是自动安装
if (PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)) {
if (FileUtils.isEmptyFile(downloadEntity.path)) {
Utils.toast(mApplication, R.string.install_failure_hint)
downloadManager.cancel(downloadEntity.url)
} else {
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
tryWithDefaultCatch {
PackageInstaller.install(mApplication, downloadEntity, false)
}
if (downloadEntity.isSimulatorGame()) {
val gameEntity = HaloApp.get(GameEntity::class.java.simpleName, true) as? GameEntity
if (gameEntity?.simulator != null) {
val isInstalled = PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance().application, gameEntity.simulator!!.apk!!.packageName)
if (!isInstalled) {
SimulatorDownloadManager.getInstance().showDownloadDialog(AppManager.getInstance().currentActivity(), gameEntity.simulator,
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
?: "", null)
}
SimulatorGameManager.recordDownloadSimulatorGames(gameEntity.id)
SimulatorGameManager.postPlayedGame(gameEntity.id, downloadEntity.packageName)
}
} else {
val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
// 是否是自动安装
val isAutoInstall = PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)
if (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall) {
if (FileUtils.isEmptyFile(downloadEntity.path)) {
Utils.toast(mApplication, R.string.install_failure_hint)
downloadManager.cancel(downloadEntity.url)
} else {
// 弹出卸载提示框
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
tryWithDefaultCatch {
PackageInstaller.install(mApplication, downloadEntity, false)
}
} else {
// 弹出卸载提示框
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
}
}
}
}
@ -157,15 +175,15 @@ object DownloadObserver {
}
// 下载过程分析统计
// val pm = mApplication.packageManager
// val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, 0)
// if (packageInfo == null) {
val pm = mApplication.packageManager
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
if (packageInfo == null) {
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
// "游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
//
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
// "游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
// }
}
}
if (downloadEntity.status == DownloadStatus.done) {

View File

@ -90,6 +90,7 @@ public class EntranceUtils {
public static final String HOST_FORUM_DETAIL = "forum_detail";
public static final String HOST_GAME_RATING_DETAIL = "game_rating_detail";
public static final String HOST_HELP_AND_FEEDBACK = "help_and_feedback";
public static final String HOST_LAUNCH_SIMULATOR_GAME = "launch_simulator_game";
public static final String KEY_DATA = "data";
public static final String KEY_MESSAGE = "message";
public static final String KEY_MESSAGE_ID = "message_id";
@ -212,6 +213,8 @@ public class EntranceUtils {
public static final String KEY_CONFLICT_PHONE = "conflictPhone";
public static final String KEY_CONFLICT_USER = "conflictUser";
public static final String KEY_BBS_ID = "bbs_id";
public static final String KEY_DIAGNOSIS = "diagnosis";
public static final String KEY_SIMULATOR = "simulator";
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);

View File

@ -255,23 +255,23 @@ fun String.containHtmlTag(): Boolean {
* 用户行为相关
*/
fun Fragment.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
DialogUtils.showRegulationTestDialog(requireContext(),
{ DirectUtils.directToRegulationTestPage(requireContext()) },
{ action.invoke() })
} else {
// if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
// DialogUtils.showRegulationTestDialog(requireContext(),
// { DirectUtils.directToRegulationTestPage(requireContext()) },
// { action.invoke() })
// } else {
action()
}
// }
}
fun Context.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
DialogUtils.showRegulationTestDialog(this,
{ DirectUtils.directToRegulationTestPage(this) },
{ action.invoke() })
} else {
// if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
// DialogUtils.showRegulationTestDialog(this,
// { DirectUtils.directToRegulationTestPage(this) },
// { action.invoke() })
// } else {
action()
}
// }
}
/**
@ -662,6 +662,14 @@ fun DownloadEntity.isSilentUpdate(): Boolean {
return Constants.SILENT_UPDATE == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
}
fun DownloadEntity.isSimulatorDownload(): Boolean {
return Constants.SIMULATOR_DOWNLOAD == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
}
fun DownloadEntity.isSimulatorGame(): Boolean {
return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty()
}
/**
* Process related
*/

View File

@ -5,9 +5,8 @@ import android.graphics.Color;
import android.text.TextUtils;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.gh.common.constant.Config;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.ApkEntity;
@ -24,6 +23,8 @@ import com.lightgame.download.DownloadStatus;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
public class GameUtils {
/**
@ -116,16 +117,27 @@ public class GameUtils {
installCount++;
}
}
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
DownloadEntity simulatorDownloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apkEntity.getUrl());
if (simulatorDownloadEntity != null && gameEntity.getSimulator() != null) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
if (isInstalled) {
installCount++;
} else {
doneCount++;
}
}
}
}
if (doneCount != 0) {
return context.getString(R.string.install);
} else if (pluginCount != 0) {
return context.getString(R.string.pluggable);
} else if (updateCount != 0) {
return context.getString(R.string.update);
} else if (installCount != 0) {
if (installCount != 0) {
return context.getString(R.string.launch);
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen()) {
} else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
return context.getString(R.string.pluggable);
} else if (updateCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
return context.getString(R.string.update);
} else if (doneCount != 0) {
return context.getString(R.string.install);
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen() && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
return context.getString(R.string.attempt);
} else {
return context.getString(R.string.download);
@ -238,7 +250,7 @@ public class GameUtils {
}
}
}
collectionEntity.setSaveApkEntity(saveApkEntity);
return collectionEntity;
}

View File

@ -1,9 +1,6 @@
package com.gh.common.util
import android.app.Application
import android.text.TextUtils
import com.halo.assistant.HaloApp
import java.util.*
/**
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
@ -22,22 +19,18 @@ object GdtHelper {
const val PLATFORM = "PLATFORM"
fun init(application: Application, channel: String) {
// if (shouldUseGdtHelper()) {
// if (channel == "GH_728") {
// GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
// } else if (channel == "GH_729") {
// GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
// } else {
// GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
// }
// if (channel == "GH_728") {
// GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
// } else if (channel == "GH_729") {
// GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
// } else {
// GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
// }
}
fun logAction(type: String) {
// if (shouldUseGdtHelper()) {
// GDTAction.logAction(type)
// Utils.log("GDT", type)
// }
// GDTAction.logAction(type)
// Utils.log("GDT", type)
}
fun logAction(type: String, vararg kv: String?) {
@ -59,12 +52,4 @@ object GdtHelper {
// }
}
// TODO 确认开启的渠道条件
private fun shouldUseGdtHelper(): Boolean {
return true
val channel = HaloApp.getInstance().channel
return !(TextUtils.isEmpty(channel) || channel.contains("GDT".toLowerCase(Locale.CHINA)))
}
}

View File

@ -10,6 +10,8 @@ import org.json.JSONArray
* Created by khy on 11/10/17.
*/
object GsonUtils {
@JvmStatic
val gson: Gson = Gson()
val gsonThatIgnoreNull: Gson = GsonBuilder().serializeNulls().create()

View File

@ -15,7 +15,7 @@ object HomePluggableHelper {
if (apkList.isNotEmpty()) {
val apk = apkList.first()
val tag = if (isNever) "never" else apk.version ?: ""
tryCatchInRelease { mHomePluggableFilterDao.addData(HomePluggableFilterEntity(pkgName = apk.packageName, tag = tag, active = isNever)) }
mHomePluggableFilterDao.addData(HomePluggableFilterEntity(pkgName = apk.packageName, tag = tag, active = isNever))
}
}
@ -44,7 +44,7 @@ object HomePluggableHelper {
for (entity in filterList) {
entity.active = true
}
tryCatchInRelease { mHomePluggableFilterDao.addData(filterList) }
mHomePluggableFilterDao.addData(filterList)
}
}
}

View File

@ -10,14 +10,20 @@ import android.net.Uri
import android.os.Build
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import com.facebook.common.executors.CallerThreadExecutor
import com.facebook.common.references.CloseableReference
import com.facebook.datasource.DataSource
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.controller.ControllerListener
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.gh.common.constant.Config
import com.gh.common.structure.FixedSizeLinkedHashSet
import com.gh.gamecenter.R
@ -223,11 +229,44 @@ object ImageUtils {
.build()
}
// 获取bitmap (使用 fresco 获取 gif bitmap 会为空https://github.com/facebook/fresco/issues/241)
// 所以这里换用 picasso
/**
* 获取bitmap (使用 fresco 获取 gif 的 bitmap 会为空https://github.com/facebook/fresco/issues/241)
* 所以当 url 以 .gif 结尾时换用 picasso 获取
* 优先使用 fresco 是因为可能已经有了缓存
*/
@SuppressLint("CheckResult")
@JvmStatic
fun getBitmap(url: String, callback: BiCallback<Bitmap, Boolean>) {
if (url.endsWith(".gif")) {
getBitmapWithPicasso(url, callback)
} else {
getBitmapWithFresco(url, callback)
}
}
private fun getBitmapWithFresco(url: String, callback: BiCallback<Bitmap, Boolean>) {
val imageRequest = ImageRequestBuilder
.newBuilderWithSource(Uri.parse(url))
.build()
Fresco.getImagePipeline()
.fetchDecodedImage(imageRequest, HaloApp.getInstance().application)
.subscribe(object : BaseBitmapDataSubscriber() {
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
callback.onSecond(true)
}
override fun onNewResultImpl(bitmap: Bitmap?) {
if (bitmap != null) {
callback.onFirst(bitmap)
} else {
callback.onSecond(true)
}
}
}, CallerThreadExecutor.getInstance())
}
@SuppressLint("CheckResult")
private fun getBitmapWithPicasso(url: String, callback: BiCallback<Bitmap, Boolean>) {
Single.just(url)
.map { Picasso.with(HaloApp.getInstance().application).load(url).priority(Picasso.Priority.HIGH).get() }
.subscribeOn(Schedulers.io())

View File

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

View File

@ -458,7 +458,7 @@ public class LibaoUtils {
adapter.notifyDataSetChanged();
final String finalLibaoCode = libaoCode;
NotificationHelper.showNotificationHintDialog(NotificationUgc.GIFT, isShow -> {
if (!isShow) {
if (!isShow){
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, finalLibaoCode))
, "关闭", " 复制礼包码"
, () -> {
@ -547,7 +547,8 @@ public class LibaoUtils {
}
public static boolean isAppInstalled(Context context, String packageName) {
List<PackageInfo> pinfo = PackageUtils.getInstalledPackages(context, 0);
final android.content.pm.PackageManager packageManager = context.getPackageManager();
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;

View File

@ -6,8 +6,6 @@ import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.ExposureEntity;
import com.gh.common.exposure.ExposureEvent;
@ -34,6 +32,7 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
@ -518,4 +517,124 @@ public class LogUtils {
.subscribeOn(Schedulers.io())
.subscribe(new EmptyResponse<>());
}
public static JSONObject getMetaObject() {
Meta meta = MetaUtil.INSTANCE.getMeta();
JSONObject metaObject = new JSONObject();
try {
metaObject.put("android_id", meta.getAndroid_id());
metaObject.put("android_sdk", meta.getAndroid_sdk());
metaObject.put("android_version", meta.getAndroid_version());
metaObject.put("appVersion", meta.getAppVersion());
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("imei", meta.getImei());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
metaObject.put("model", meta.getModel());
metaObject.put("network", meta.getNetwork());
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
} catch (JSONException e) {
e.printStackTrace();
}
return metaObject;
}
private static void uploadCommunity(JSONObject object) {
try {
object.put("meta", getMetaObject());
object.put("timestamp", System.currentTimeMillis() / 1000);
} catch (JSONException e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
LoghubUtils.log(object, "community", false);
}
public static void uploadAccessToBbs(String bbsId, String location) {
JSONObject object = new JSONObject();
JSONObject payload = new JSONObject();
try {
payload.put("location", location);//关注板块/文章外所属论坛/游戏详情/文章内所属论坛
payload.put("bbs_id", bbsId);
object.put("event", "access_to_bbs");
object.put("payload", payload);
} catch (JSONException e) {
e.printStackTrace();
}
uploadCommunity(object);
}
public static void uploadAccessBbsTab() {
JSONObject object = new JSONObject();
try {
object.put("event", "main_tab[bbs]");
} catch (JSONException e) {
e.printStackTrace();
}
uploadCommunity(object);
}
public static void uploadSimulatorDownload(String event, String fileName, String simulatorId, String simulatorName, String gameId, String location, String downloadType, String startTime) {
JSONObject object = new JSONObject();
JSONObject payload = new JSONObject();
try {
object.put("event", event);// 取值有[开始, 完成] [simulator_download, simulator_download_complete]
object.put("meta", getMetaObject());
object.put("timestamp", System.currentTimeMillis() / 1000);
payload.put("filename", fileName);// 下载模拟器文件名,每次新创建的下载任务文件名都不同,可以用来关联同一次的下载开始与完成
payload.put("simulator_id", simulatorId);
payload.put("simulator_name", simulatorName);
payload.put("location", location);//启动《具体的游戏名称》/模拟器游戏/模拟器游戏-模拟器管理
payload.put("game_id", gameId);//如果是 启动《游戏名称》 这种方式, 记录这个游戏具体的游戏ID
payload.put("download_type", downloadType);// update/download 下载类型(更新/下载)
if (!TextUtils.isEmpty(startTime) && event.equals("simulator_download_complete")) {
payload.put("simulator_download_timestamp", startTime);// 对应的下载开始时间
}
object.put("payload", payload);
} catch (JSONException e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
LoghubUtils.log(object, "event", false);
}
public static void uploadSearchGame(String event, String location, String key, String searchType) {
uploadSearchClick(event, location, key, searchType, "", "");
}
public static void uploadSearchClick(String event, String location, String key, String searchType, String gameId, String gameName) {
JSONObject object = new JSONObject();
JSONObject payload = new JSONObject();
try {
object.put("event", event);
object.put("location", location);
object.put("meta", getMetaObject());
object.put("timestamp", System.currentTimeMillis() / 1000);
payload.put("key", key); //搜索关键词
payload.put("search_type", searchType); //搜索类型, 有四种取值 默认搜索/历史搜索/自动搜索/主动搜索
payload.put("game_id", gameId); //event为search_click才取值
payload.put("game_name", gameName); //event为search_click才取值
object.put("payload", payload);
} catch (JSONException e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
LoghubUtils.log(object, "event", false);
}
}

View File

@ -1,13 +1,5 @@
package com.gh.common.util
import android.os.Build
import android.text.TextUtils
import com.gh.common.exposure.meta.MetaUtil
import com.gh.gamecenter.BuildConfig
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.util.*
object MtaHelper {
@JvmStatic
@ -17,7 +9,7 @@ object MtaHelper {
// if (kv.size == 1) {
// prop.setProperty(kv[0], kv[0])
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}]")
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
// return
// }
//
@ -31,7 +23,7 @@ object MtaHelper {
// }
// }
//
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}]")
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
}
@ -53,7 +45,7 @@ object MtaHelper {
// }
//
// if (prop.size == 0) return
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
// StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
}
@ -83,7 +75,7 @@ object MtaHelper {
// prop.setProperty("GID", HaloApp.getInstance().gid)
// }
//
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}]")
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
}

View File

@ -5,15 +5,10 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationManagerCompat
import com.gh.common.constant.Constants
import com.gh.common.dialog.NotificationHintDialogFragment
import com.gh.gamecenter.entity.NotificationHint
import com.gh.gamecenter.entity.NotificationUgc
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
object NotificationHelper {
@ -159,7 +154,8 @@ object NotificationHelper {
callBack?.invoke(false)
} else {
callBack?.invoke(true)
NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
// if (activity.supportFragmentManager.isStateSaved) return
// NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
}
}

View File

@ -63,7 +63,7 @@ object PackageHelper {
private fun getAllPackageName(context: Context): HashSet<String> {
val set = HashSet<String>()
return try {
val packageInfos = PackageUtils.getInstalledPackages(context, 0)
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) {

View File

@ -1,6 +1,5 @@
package com.gh.common.util
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
@ -114,9 +113,6 @@ object PackageInstaller {
val uninstallIntent = Intent()
uninstallIntent.action = Intent.ACTION_DELETE
uninstallIntent.addCategory(Intent.CATEGORY_DEFAULT)
if (context !is Activity) {
uninstallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
val packageName = PackageUtils.getPackageNameByPath(context, path)
uninstallIntent.data = Uri.parse("package:$packageName")
InstallUtils.getInstance(context).addUninstall(packageName)

View File

@ -30,11 +30,8 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@ -289,7 +286,7 @@ public class PackageUtils {
*/
public static String getPackageNameByPath(Context context, String path) {
PackageManager packageManager = context.getApplicationContext().getPackageManager();
PackageInfo info = packageManager.getPackageArchiveInfo(path, 0);
PackageInfo info = packageManager.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
if (info != null) {
ApplicationInfo appInfo = info.applicationInfo;
return appInfo.packageName;
@ -307,6 +304,11 @@ public class PackageUtils {
return intent != null;
}
public static boolean isInstalledFromAllPackage(Context context, String packageName) {
ArrayList<String> allPackageName = getAllPackageName(context);
return allPackageName.contains(packageName);
}
/*
* 获取应用第一次安装的时间
*/
@ -368,7 +370,7 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageName(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = context.getApplicationContext().getPackageManager().getInstalledPackages(0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
@ -383,7 +385,7 @@ public class PackageUtils {
JSONArray jsonArray = new JSONArray();
try {
PackageManager pm = context.getPackageManager();
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
JSONObject jsonObject = new JSONObject();
@ -555,42 +557,4 @@ public class PackageUtils {
}
/**
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-to-get-a-list-of-applications-installed/30062632#30062632
*/
public static List<PackageInfo> getInstalledPackages(Context context, int flags) {
final PackageManager pm = context.getPackageManager();
try {
return pm.getInstalledPackages(flags);
} catch (Exception ignored) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
Process process;
List<PackageInfo> result = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
process = Runtime.getRuntime().exec("pm list packages");
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
final String packageName = line.substring(line.indexOf(':') + 1);
final PackageInfo packageInfo = pm.getPackageInfo(packageName, flags);
result.add(packageInfo);
}
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bufferedReader != null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
}

View File

@ -8,7 +8,6 @@ import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.fragment.app.FragmentActivity
import com.tbruyelle.rxpermissions2.RxPermissions

View File

@ -24,9 +24,6 @@ import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.constant.Config;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WeiBoShareActivity;
@ -53,6 +50,9 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
/**
@ -91,7 +91,8 @@ public class ShareUtils {
communityArticle("文章详情"),
video("视频"),
web("web链接"),
userHome("个人主页");
userHome("个人主页"),
qaDetail("QA内容详情");
private String name;
@ -158,7 +159,8 @@ public class ShareUtils {
//检查是否安装手机QQ
public static boolean isQQClientAvailable(Context context) {
List<PackageInfo> pinfo = PackageUtils.getInstalledPackages(context, 0);
final PackageManager packageManager = context.getPackageManager();
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;
@ -562,6 +564,10 @@ public class ShareUtils {
private void sinaWeiboShare() {
WbSdk.install(mContext, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
if (mShareEntrance == ShareEntrance.qaDetail) {
mTitle = "向你推荐:" + mTitle + " @光环助手 " + shareUrl;
mSummary = "";
}
Activity activity = mActivity.get();
if (activity != null) {
Intent intent = WeiBoShareActivity.getWeiboshareIntent(
@ -590,8 +596,6 @@ public class ShareUtils {
smsBody = mTitle + shareUrl;
break;
case plugin:
smsBody = "向你推荐:" + mTitle + "光环加速版_光环助手" + shareUrl;
break;
case game:
smsBody = "向你推荐:" + mTitle + "_光环助手" + shareUrl;
break;
@ -605,6 +609,9 @@ public class ShareUtils {
case communityArticle:
smsBody = mTitle + " - 光环助手" + shareUrl;
break;
case qaDetail:
smsBody = "向你推荐:" + mTitle + " @光环助手 " + shareUrl;
break;
default:
smsBody = mTitle;
break;

View File

@ -22,10 +22,11 @@ object TimeUtils {
return formatter.format(date)
}
@JvmStatic
fun getFormatTime(time: Long, pattern: String = "yyyy-MM-dd"): String {
val f = SimpleDateFormat(pattern, Locale.CHINA)
f.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
return f.format(Date(time * 1000))
return f.format(Date(getJavaTimestamp(time)))
}
fun getFormatDate(timestamp: Long): String {

View File

@ -56,4 +56,10 @@ object ToastUtils {
}
mOneTime = mTwoTime
}
fun toast(message: String) {
if (mToast != null) mToast?.cancel()
mToast = ToastHandler.INSTANCE.getToastInstance(HaloApp.getInstance().application, message, Toast.LENGTH_SHORT)
mToast?.show()
}
}

View File

@ -4,7 +4,9 @@ import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.LinearLayout
import androidx.annotation.Nullable
import androidx.core.view.children
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
@ -12,13 +14,15 @@ import androidx.recyclerview.widget.RecyclerView
import java.lang.ref.WeakReference
import java.util.*
class AutoScrollRecyclerView(context: Context, @Nullable attrs: AttributeSet?) : RecyclerView(context, attrs), LifecycleObserver {
class AutoScrollRecyclerViewContainerView(context: Context, @Nullable attrs: AttributeSet?)
: LinearLayout(context, attrs), LifecycleObserver {
var autoScrollTask: AutoScrollTask?
private var mIsScrolling = false
private var mIsScrollable = false
private var mOnItemTouchListener: OnItemTouchListener? = null
private var mOnItemTouchListener: RecyclerView.OnItemTouchListener? = null
init {
autoScrollTask = AutoScrollTask(this)
@ -28,20 +32,23 @@ class AutoScrollRecyclerView(context: Context, @Nullable attrs: AttributeSet?) :
super.onAttachedToWindow()
if (mOnItemTouchListener == null) {
mOnItemTouchListener = object : OnItemTouchListener {
mOnItemTouchListener = object : RecyclerView.OnItemTouchListener {
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent) = rv.scrollState == SCROLL_STATE_DRAGGING
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent) = rv.scrollState == RecyclerView.SCROLL_STATE_DRAGGING
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}
}
removeOnItemTouchListener(mOnItemTouchListener!!)
addOnItemTouchListener(mOnItemTouchListener!!)
for (child in children) {
if (child is RecyclerView) {
child.removeOnItemTouchListener(mOnItemTouchListener!!)
child.addOnItemTouchListener(mOnItemTouchListener!!)
}
}
resumeScrolling()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
@ -72,20 +79,24 @@ class AutoScrollRecyclerView(context: Context, @Nullable attrs: AttributeSet?) :
private const val AUTO_SCROLL_INTERVAL: Long = 10
}
class AutoScrollTask(reference: AutoScrollRecyclerView?) : Runnable {
private val mReference: WeakReference<AutoScrollRecyclerView?>?
class AutoScrollTask(reference: AutoScrollRecyclerViewContainerView?) : Runnable {
private val mReference: WeakReference<AutoScrollRecyclerViewContainerView?>?
private val mScrollSlop = if (Build.MODEL.toLowerCase(Locale.getDefault()) == "mumu") 1 else 2
override fun run() {
val recyclerView: AutoScrollRecyclerView? = mReference?.get()
if (recyclerView != null && recyclerView.mIsScrolling && recyclerView.mIsScrollable) {
recyclerView.scrollBy(mScrollSlop, mScrollSlop)
recyclerView.postDelayed(recyclerView.autoScrollTask, AUTO_SCROLL_INTERVAL)
}
}
init {
mReference = WeakReference(reference)
}
override fun run() {
val containerView: AutoScrollRecyclerViewContainerView? = mReference?.get()
if (containerView != null && containerView.mIsScrolling && containerView.mIsScrollable) {
for (child in containerView.children) {
if (child is RecyclerView) {
child.scrollBy(mScrollSlop, mScrollSlop)
}
}
containerView.postDelayed(containerView.autoScrollTask, AUTO_SCROLL_INTERVAL)
}
}
}
}

View File

@ -29,6 +29,7 @@ class AvatarBorderView : ConstraintLayout {
private var mBadgeWidth = 30f
private var mAvatarBorderColor = Color.parseColor("#ffffff")
private var mAvatarBorderWidth = 2f.dip2px().toFloat()
private var mRatio = 0f
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
@ -50,6 +51,9 @@ class AvatarBorderView : ConstraintLayout {
if (ta.hasValue(R.styleable.AvatarBorderView_border_width)) {
mAvatarBorderWidth = ta.getDimension(R.styleable.AvatarBorderView_border_width, mAvatarBorderWidth)
}
if (ta.hasValue(R.styleable.AvatarBorderView_border_ratio)) {
mRatio = ta.getFloat(R.styleable.AvatarBorderView_border_ratio, 0f)
}
mAvatarBorderColor = ta.getColor(R.styleable.AvatarBorderView_border_color, mAvatarBorderColor)
ta.recycle()
@ -74,8 +78,13 @@ class AvatarBorderView : ConstraintLayout {
}
borderView?.apply {
val params = layoutParams
params.width = (mAvatarWidth * 3 / 2).toInt()
params.height = (mAvatarWidth * 3 / 2).toInt()
if (mRatio > 0) {
params.width = (mAvatarWidth * mRatio).toInt()
params.height = (mAvatarWidth * mRatio).toInt()
} else {
params.width = (mAvatarWidth * 3 / 2).toInt()
params.height = (mAvatarWidth * 3 / 2).toInt()
}
layoutParams = params
}
badgeView?.apply {

View File

@ -39,6 +39,7 @@ public class DownloadProgressBar extends ProgressBar {
RESERVABLE,
RESERVED,
H5_GAME,
UPDATING,
XAPK_UNZIPPING,
XAPK_SUCCESS,
@ -212,17 +213,21 @@ public class DownloadProgressBar extends ProgressBar {
break;
case RESERVABLE:
setProgressDrawable(getResources().getDrawable(R.drawable.button_reserve));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.all_white);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
case UPDATING:
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_updating_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
case RESERVED:
setProgressDrawable(getResources().getDrawable(R.drawable.game_item_btn_pause_dn));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.all_white);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
case XAPK_FAILURE:
case XAPK_SUCCESS:
case XAPK_UNZIPPING:
setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_xapk_detail_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.all_white);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
break;
}

View File

@ -32,7 +32,7 @@ class ReserveDialog : BaseDialogFragment() {
binding.more.setOnClickListener {
val intent = MyGameActivity.getIntentWithConfig(requireContext(), 2)
startActivity(intent)
dismissAllowingStateLoss()
dismiss()
}
binding.recyclerView.layoutManager = if (mReserveList.size > 4) {
GridLayoutManager(context, 4)
@ -54,7 +54,7 @@ class ReserveDialog : BaseDialogFragment() {
holder.binding.game = entity
holder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(mContext, entity.id, "(预约弹窗)")
dismissAllowingStateLoss()
dismiss()
}
}
}

View File

@ -86,7 +86,7 @@ class WelcomeDialog : BaseDialogFragment() {
mDismissByClickImage = true
dismissAllowingStateLoss()
dismiss()
}
binding.ivOpeningCover.loadingCallback = object : WrapContentDraweeView.LoadingCallback {
@ -102,24 +102,15 @@ class WelcomeDialog : BaseDialogFragment() {
}
binding.ivCloseBackup.setOnClickListener {
dismissAllowingStateLoss()
dismiss()
}
binding.ivClose.setOnClickListener {
dismissAllowingStateLoss()
dismiss()
}
binding.welcome = mWelcomeEntity
return binding.root
}
override fun dismissAllowingStateLoss() {
try {
mDismissByClickImage = false
super.dismissAllowingStateLoss()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun dismiss() {
try {
mDismissByClickImage = false

View File

@ -0,0 +1,146 @@
package com.gh.common.view;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
public class ZoomCoordinatorLayout extends CoordinatorLayout {
private View mZoomView;
private int mZoomViewWidth;
private int mZoomViewHeight;
private float firstPosition;//记录第一次按下的位置
private boolean isScrolling;//是否正在缩放
private boolean isScrollDown;//是否下滑
private float mScrollRate = 0.6f;//缩放系数,缩放系数越大,变化的越大
private float mReplyRate = 0.3f;//回调系数,越大,回调越慢
private View mMoveView;
private View mMoveView2;
private int height,height2;
/**
* 初始坐标
*/
private float mInitialY, mInitialX;
public ZoomCoordinatorLayout(Context context) {
super(context);
}
public ZoomCoordinatorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ZoomCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setZoomView(View mZoomView) {
this.mZoomView = mZoomView;
}
public void setMoveView(View mMoveView1, View mMoveView2) {
this.mMoveView = mMoveView1;
this.mMoveView2 = mMoveView2;
height = mMoveView.getMeasuredHeight();
height2 = mMoveView2.getMeasuredHeight();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int[] location = new int[2];
mZoomView.getLocationOnScreen(location);
int y = location[1];
if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0) {
mZoomViewWidth = mZoomView.getMeasuredWidth();
mZoomViewHeight = mZoomView.getMeasuredHeight();
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialX = ev.getX();
mInitialY = ev.getY();
break;
case MotionEvent.ACTION_UP:
if(isScrollDown) break;
//手指离开后恢复图片
isScrolling = false;
replyImage();
break;
case MotionEvent.ACTION_MOVE:
if(y != 0 || (ev.getY() - mInitialY) < 0) return super.dispatchTouchEvent(ev);
isScrollDown = false;
if (!isScrolling) {
if (getScrollY() == 0) {
firstPosition = ev.getY();// 滚动到顶部时记录位置,否则正常返回
} else {
break;
}
}
int distance = (int) ((ev.getY() - firstPosition) * mScrollRate); // 滚动距离乘以一个系数
if (distance < 0) { // 当前位置比记录位置要小,正常返回
isScrollDown = true;
break;
}
// 处理放大
isScrolling = true;
setZoom(distance);
return super.dispatchTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
private void scrollDown(float zoom) {
mMoveView2.setScrollY(-(int)(height2 * ((height2 + zoom) / height2)));
}
//回弹动画
private void replyImage() {
float distance = mZoomView.getMeasuredWidth() - mZoomViewWidth;
ValueAnimator valueAnimator = ValueAnimator.ofFloat(distance, 0f).setDuration((long) (distance * mReplyRate));
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setZoom((Float) animation.getAnimatedValue());
}
});
valueAnimator.start();
// mMoveView.setScrollY(height);
// mMoveView2.setScrollY(height2);
}
public void setZoom(float zoom) {
if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0) {
return;
}
ViewGroup.LayoutParams lp = mZoomView.getLayoutParams();
lp.width = (int) (mZoomViewWidth * ((mZoomViewWidth + zoom) / mZoomViewWidth));
lp.height = (int) (mZoomViewHeight * ((mZoomViewWidth + zoom) / mZoomViewWidth));
mZoomView.setLayoutParams(lp);
int margin = (lp.width - mZoomViewWidth) / 2;
mZoomView.setTranslationX(-margin);
// try {
// CollapsingToolbarLayout parent = (CollapsingToolbarLayout) (mMoveView.getParent());
// ViewGroup.LayoutParams layoutParams = parent.getLayoutParams();
// layoutParams.height = lp.height;
// parent.setLayoutParams(layoutParams);
// }catch (Exception e){
//
// }
}
}

View File

@ -142,14 +142,7 @@ object XapkInstaller : IXapkUnzipListener {
mXapkUnzipThreadMap.remove(downloadEntity.path)
AppExecutor.uiExecutor.execute {
val pkgPath = downloadEntity.meta[XAPK_PACKAGE_PATH_TAG]
if (pkgPath == null) {
Utils.toast(mContext, "下载出错,请重新下载!")
return@execute
}
val pkgPath = checkNotNull(downloadEntity.meta[XAPK_PACKAGE_PATH_TAG])
PackageInstaller.install(mContext, pkgPath)
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"

View File

@ -1,11 +1,16 @@
package com.gh.download
import android.content.pm.PackageManager
import com.gh.common.constant.Constants
import com.gh.common.exposure.meta.MetaUtil.getMeta
import com.gh.common.loghub.LoghubUtils
import com.gh.common.util.DeviceUtils
import com.gh.common.util.getMetaExtra
import com.gh.common.util.isSimulatorDownload
import com.gh.common.util.isSimulatorGame
import com.gh.gamecenter.BuildConfig
import com.halo.assistant.HaloApp
import com.lightgame.download.DataChanger
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.Utils
@ -49,8 +54,11 @@ object DownloadDataHelper {
} else if (status == DownloadStatus.subscribe || status == DownloadStatus.neterror || status == DownloadStatus.timeout) {
"暂停下载-连上WiFi自动下载"
} else if (status == DownloadStatus.done) {
if(downloadEntity.isSimulatorGame()){
return "下载完成"
}
val pm = HaloApp.getInstance().application.applicationContext.packageManager
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, 0)
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
if (packageInfo == null) {
"解析包错误"
} else {
@ -66,7 +74,7 @@ object DownloadDataHelper {
"解析包错误-下载过程中"
} else if (status == DownloadStatus.hijack || status == DownloadStatus.notfound) {
"下载失败"
} else if (status == DownloadStatus.redirected) {
} else if (status == DownloadStatus.redirected) {
"重定向至最终地址"
} else {
"未知状态"
@ -272,7 +280,12 @@ object DownloadDataHelper {
fun uploadDownloadHeartbeat(upload: Boolean) {
val allDownloadEntity = DownloadManager.getInstance(HaloApp.getInstance().application).allDownloadEntity
for (downloadEntity in allDownloadEntity) {
if (downloadEntity.status == DownloadStatus.downloading) {
/**
* 在后台唤醒的情况下 下载状态可能无法修正
* see [DownloadManager.initDownloadService]
*/
if (downloadEntity.status == DownloadStatus.downloading && DataChanger.downloadingTasks[downloadEntity.url] != null) {
var sheet = mDownloadHeartbeatSheet[downloadEntity.url]
if (sheet == null) {
sheet = JSONObject()

View File

@ -18,6 +18,7 @@ import com.gh.common.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.history.HistoryHelper;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.AppDebugConfig;
import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.DeviceUtils;
@ -244,10 +245,24 @@ public class DownloadManager implements DownloadStatusListener {
}
}
String path;
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
path = SimulatorGameManager.getPathByType(gameEntity.getSimulatorType()) + "/" + gameEntity.getName() + "." + apkEntity.getFormat();
} else {
path = PackageInstaller.getDownloadPath(gameEntity.getName(), apkEntity.getFormat());
}
File file = new File(path);
DownloadEntity entity = DownloadDao.getInstance(context).get(apkEntity.getUrl());
//判断当前链接没有下载记录并且文件已经存在则删除这个文件
if (entity == null && file.exists()) {
file.delete();
}
DownloadEntity downloadEntity = new DownloadEntity();
downloadEntity.setUrl(apkEntity.getUrl());
downloadEntity.setName(gameEntity.getName());
downloadEntity.setPath(PackageInstaller.getDownloadPath(gameEntity.getName(), apkEntity.getFormat()));
downloadEntity.setPath(path);
downloadEntity.setETag(apkEntity.getEtag());
downloadEntity.setIcon(gameEntity.getIcon());
downloadEntity.setPlatform(apkEntity.getPlatform());
@ -258,6 +273,10 @@ public class DownloadManager implements DownloadStatusListener {
downloadEntity.setVersionName(apkEntity.getVersion());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.RAW_GAME_ICON, gameEntity.getRawIcon());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript());
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR_GAME, apkEntity.getFormat());
HaloApp.put(GameEntity.class.getSimpleName(), gameEntity);
}
int installed = 0;
for (ApkEntity apk : gameEntity.getApk()) {
if (PackagesManager.INSTANCE.isInstalled(apk.getPackageName())) {
@ -305,6 +324,16 @@ public class DownloadManager implements DownloadStatusListener {
// GdtHelper.PLATFORM, downloadEntity.getPlatform());
}
public void removeAllTaskThatFileDoesNotExist() {
for (DownloadEntity entity : getAllDownloadEntity()) {
if (entity.getStatus() == DownloadStatus.done) {
if (FileUtils.isEmptyFile(entity.getPath())) {
cancel(entity.getUrl());
}
}
}
}
/**
* 添加一个下载任务
*
@ -509,6 +538,17 @@ public class DownloadManager implements DownloadStatusListener {
return all != null ? all : new ArrayList<>();
}
public List<DownloadEntity> getAllSimulatorDownloadEntity() {
List<DownloadEntity> downloadEntityList = mDownloadDao.getAll();
ArrayList<DownloadEntity> filteredDownloadEntityList = new ArrayList<>();
for (DownloadEntity downloadEntity : downloadEntityList) {
if (ExtensionsKt.isSimulatorGame(downloadEntity) && downloadEntity.getStatus() == DownloadStatus.done) {
filteredDownloadEntityList.add(downloadEntity);
}
}
return filteredDownloadEntityList;
}
/**
* 获取所有下载列表中的任务排除静默更新
*/
@ -526,9 +566,18 @@ public class DownloadManager implements DownloadStatusListener {
if (downloadEntityList == null) return filteredDownloadEntityList;
for (DownloadEntity downloadEntity : downloadEntityList) {
if (!Constants.SILENT_UPDATE.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE))) {
filteredDownloadEntityList.add(downloadEntity);
if (!ExtensionsKt.isSimulatorGame(downloadEntity)) {
if (!Constants.SILENT_UPDATE.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE)) &&
!Constants.SIMULATOR_DOWNLOAD.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE))) {
filteredDownloadEntityList.add(downloadEntity);
}
} else {
if (downloadEntity.getStatus() != DownloadStatus.done) {
filteredDownloadEntityList.add(downloadEntity);
}
}
}
return filteredDownloadEntityList;
@ -943,7 +992,7 @@ public class DownloadManager implements DownloadStatusListener {
map.put(HttpDnsManager.GID, HaloApp.getInstance().getGid());
map.put(HttpDnsManager.OAID, HaloApp.getInstance().getOAID());
map.put(HttpDnsManager.USER_ID, UserManager.getInstance().getUserId());
map.put(HttpDnsManager.IMEI, MetaUtil.getBase64EncodedIMEI());
map.put(HttpDnsManager.IMEI, MetaUtil.INSTANCE.getIMEI());
HttpDnsManager.metaMap = map;
}

View File

@ -140,7 +140,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
}
})
mViewModel.dismissLiveData.observe(this, Observer {
dismissAllowingStateLoss()
dismiss()
})
mElapsedHelper = TimeElapsedHelper()
@ -173,7 +173,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
postBrowseMta()
mViewModel.collectionLiveData.postValue(null)
} else {
dismissAllowingStateLoss()
dismiss()
}
}
mGestureDetector = GestureDetector(requireContext(), SingleTapConfirm())
@ -332,7 +332,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
MotionEvent.ACTION_UP,
MotionEvent.ACTION_OUTSIDE -> {
if (mBinding.root.y >= mBinding.root.height / 2) {
dismissAllowingStateLoss()
dismiss()
} else {
resetDialogPosition(300)
}

View File

@ -28,7 +28,7 @@ class DownloadLinkDialog : BaseDialogFragment() {
mLinkEntity.content, "text/html", "utf-8", null)
binding.confirm.setOnClickListener {
dismissAllowingStateLoss()
dismiss()
}
return binding.root
}

View File

@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.fragment.LoginFragment;
import com.halo.assistant.HaloApp;
/**
* Created by khy on 14/08/17.

View File

@ -30,9 +30,9 @@ import com.gh.common.avoidcallback.AvoidOnResultManager;
import com.gh.common.constant.Config;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.im.ImManager;
import com.gh.common.loghub.LoghubUtils;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.ActivationHelper;
import com.gh.common.util.ClassUtils;
import com.gh.common.util.ConcernUtils;
@ -44,6 +44,8 @@ import com.gh.common.util.DialogUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
@ -55,11 +57,13 @@ import com.gh.common.util.PlatformUtils;
import com.gh.common.util.SPUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.ThirdPartyPackageHelper;
import com.gh.common.util.ToastUtils;
import com.gh.common.util.UrlFilterUtils;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.download.DownloadFragment;
import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.GameDigestEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
import com.gh.gamecenter.entity.NotificationUgc;
import com.gh.gamecenter.eventbus.EBNetworkState;
@ -80,6 +84,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.suggest.SuggestSelectFragment;
import com.gh.gamecenter.suggest.SuggestType;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.halo.assistant.HaloApp;
import com.halo.assistant.fragment.SettingsFragment;
import com.lightgame.download.DownloadEntity;
@ -115,6 +120,7 @@ import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import static com.gh.common.util.EntranceUtils.ENTRANCE_BROWSER;
import static com.gh.common.util.EntranceUtils.HOST_LAUNCH_SIMULATOR_GAME;
import static com.gh.common.util.EntranceUtils.HOST_QQ;
import static com.gh.common.util.EntranceUtils.HOST_QQ_GROUP;
import static com.gh.common.util.EntranceUtils.HOST_WEB;
@ -158,6 +164,10 @@ public class MainActivity extends BaseActivity {
} else if (getIntent() != null) {
mMainWrapperFragment.setArguments(getIntent().getExtras());
}
Bundle arguments = mMainWrapperFragment.getArguments();
if (arguments == null) arguments = new Bundle();
arguments.putInt(BaseFragment_ViewPager.ARGS_INDEX, MainWrapperFragment.INDEX_VIDEO);
mMainWrapperFragment.setArguments(arguments);
replaceFragment(mMainWrapperFragment);
mSp = PreferenceManager.getDefaultSharedPreferences(this);
@ -170,6 +180,8 @@ public class MainActivity extends BaseActivity {
if (!this.isFinishing()) {
LogUtils.uploadDevice(lunchType);
ActivationHelper.sendActivationInfo();
// 第一次打开App删除模拟器游戏记录
SimulatorGameManager.deleteAllSimulatorGame();
}
}, 2000L);
getPluginUpdate();
@ -210,10 +222,10 @@ public class MainActivity extends BaseActivity {
checkNotificationPermission();
// 初始化 IM只有在 APP 刚启动时执行
if (HaloApp.get(SHOULD_INIT_IM, false) != null) {
HaloApp.put(SHOULD_INIT_IM, false);
handler.postDelayed(ImManager::attachIm, 1000);
}
// if (HaloApp.get(SHOULD_INIT_IM, false) != null) {
// HaloApp.put(SHOULD_INIT_IM, false);
// handler.postDelayed(ImManager::attachIm, 1000);
// }
ReservationRepository.refreshReservations();
@ -258,7 +270,6 @@ public class MainActivity extends BaseActivity {
HomePluggableHelper.activationFilterData();
});
//启动app删除视频缓存文件
AppExecutor.getIoExecutor().execute(() -> {
try {
@ -378,6 +389,20 @@ public class MainActivity extends BaseActivity {
DirectUtils.directToExternalBrowser(this, url);
}
break;
case HOST_LAUNCH_SIMULATOR_GAME:
String json = getIntent().getStringExtra(EntranceUtils.KEY_GAME);
GameEntity gameEntity = GsonUtils.getGson().fromJson(json, new TypeToken<GameEntity>(){}.getType());
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
ToastUtils.INSTANCE.showToast("文件已被删除,无法启动");
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
}
break;
}
}
}
@ -422,6 +447,7 @@ public class MainActivity extends BaseActivity {
|| PackageUtils.isSignedByGh(getApplicationContext(), entity.getPackageName()))) {
continue;
}
if (ExtensionsKt.isSimulatorGame(entity)) continue;
if (downloadEntity == null) {
downloadEntity = entity;
} else if (entity.getEnd() > downloadEntity.getEnd()) {

View File

@ -18,10 +18,7 @@ import android.webkit.WebViewClient
import android.widget.ScrollView
import android.widget.TextView
import com.gh.base.ToolBarActivity
import com.gh.common.util.CommentUtils
import com.gh.common.util.DeviceUtils
import com.gh.common.util.DialogUtils
import com.gh.common.util.tryCatchInRelease
import com.gh.common.util.*
import com.gh.gamecenter.retrofit.Response
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
@ -44,6 +41,7 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
private val mProgress by bindView<TextView>(R.id.network_diagnosis_progress)
private val mWebView by bindView<WebView>(R.id.network_diagnosis_web)
private val mScrollView by bindView<ScrollView>(R.id.network_diagnosis_scrollview)
private val mSuggestBtn by bindView<TextView>(R.id.network_diagnosis_suggest)
private val builder = SpannableStringBuilder()
@ -163,9 +161,9 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
fun setResultProgress(progress: Int) {
mProgress.text = "正在进行网络诊断 $progress%"
mBaseHandler.post(Runnable {
mBaseHandler.post {
mScrollView.fullScroll(ScrollView.FOCUS_DOWN)
})
}
mProgressData = progress
}
@ -208,6 +206,12 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
builder.append("\n")
builder.append("\n")
builder.append(mSuccessHint)
mSuggestBtn.run {
visibility = View.VISIBLE
setOnClickListener {
startActivity(SuggestionActivity.getIntentFromNetworkDiagnosis(this@NetworkDiagnosisActivity, builder.toString().replace(mSuccessHint, "")))
}
}
builder.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
@ -222,7 +226,7 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
}, builder.length - mSuccessHint.length, builder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
mResult.text = builder
mResult.setMovementMethod(LinkMovementMethod.getInstance())
mResult.movementMethod = LinkMovementMethod.getInstance()
setResultProgress(100)
}
}, 1000)
@ -237,14 +241,14 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
+ ".jpg"
)
if (!file.exists()) {
file.getParentFile().mkdirs()
file.parentFile.mkdirs()
file.createNewFile()
}
val fos = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)
fos.flush()
fos.close()
return file.getAbsolutePath();
return file.absolutePath;
} catch (e: IOException) {
e.printStackTrace()
}
@ -252,14 +256,14 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
}
override fun handleBackPressed(): Boolean {
if (mProgressData < 100) {
return if (mProgressData < 100) {
DialogUtils.showAlertDialog(this, "确认退出", "网络诊断还未完成,退出会终止所有诊断进程,确定退出吗?"
, "确定", "取消", DialogUtils.ConfirmListener {
finish()
}, null)
return true
true
} else {
return false
false
}
}

View File

@ -10,10 +10,7 @@ import android.view.inputmethod.EditorInfo
import androidx.core.widget.doAfterTextChanged
import androidx.core.widget.doOnTextChanged
import com.gh.base.BaseActivity
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.EntranceUtils
import com.gh.common.util.TextHelper
import com.gh.common.util.goneIf
import com.gh.common.util.*
import com.gh.gamecenter.DisplayType.*
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
@ -82,7 +79,7 @@ open class SearchActivity : BaseActivity() {
} else if (!TextUtils.isEmpty(hint)) {
searchEt.hint = hint
if (searchImmediately) {
mDisplayType = DisplayType.GAME_DETAIL
mDisplayType = GAME_DETAIL
mDao?.add(hint)
search(SearchType.DEFAULT, hint)
}
@ -136,26 +133,29 @@ open class SearchActivity : BaseActivity() {
when (type) {
SearchType.AUTO -> {
mSearchKey = key
updateDisplayType(DisplayType.GAME_DIGEST)
updateDisplayType(GAME_DIGEST)
LogUtils.uploadSearchGame("searching", "搜索页", key, "自动搜索")
}
SearchType.DEFAULT -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.GAME_DETAIL)
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "默认搜索")
// MtaHelper.onEvent("游戏搜索", "默认搜索", key)
}
SearchType.HOT -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.GAME_DETAIL)
updateDisplayType(GAME_DETAIL)
}
SearchType.HISTORY -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.GAME_DETAIL)
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "历史搜索")
// MtaHelper.onEvent("游戏搜索", "历史搜索", key)
}
SearchType.MANUAL -> {
@ -166,15 +166,16 @@ open class SearchActivity : BaseActivity() {
mDao?.add(hint)
search(SearchType.DEFAULT, hint)
}
} else if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) {
} else if (newSearchKey != mSearchKey || mDisplayType != GAME_DETAIL) {
mSearchKey = newSearchKey
if (!TextUtils.isEmpty(mSearchKey)) {
mDao?.add(mSearchKey)
updateDisplayType(DisplayType.GAME_DETAIL)
updateDisplayType(GAME_DETAIL)
} else {
toast("请输入搜索内容")
}
}
LogUtils.uploadSearchGame("searching", "搜索页", newSearchKey, "主动搜索")
// MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey)
}
}

View File

@ -15,12 +15,6 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.g00fy2.versioncompare.Version;
import com.gh.base.BaseActivity;
import com.gh.common.AppExecutor;
@ -62,6 +56,11 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
@ -132,9 +131,10 @@ public class SplashScreenActivity extends BaseActivity {
if (isSuccess) {
showPrivacyPolicy(() -> {
// Dialog dismiss 后的回调
guideLayout.setVisibility(View.VISIBLE);
// guideLayout.setVisibility(View.VISIBLE);
SPUtils.setBoolean(Constants.SP_BRAND_NEW_USER, false);
requestPermission();
// requestPermission();
launchMainActivity();
});
} else {
DialogUtils.showPrivacyPolicyDisallowDialog(this, PrivacyPolicyEntity.createDefaultData(),()->{
@ -231,7 +231,7 @@ public class SplashScreenActivity extends BaseActivity {
public void onSuccess(PrivacyPolicyEntity data) {
DialogUtils.showPrivacyPolicyDialog(
SplashScreenActivity.this,
data, callback);
PrivacyPolicyEntity.createDefaultData(), callback);
}
@Override

View File

@ -40,7 +40,6 @@ import com.gh.common.AppExecutor;
import com.gh.common.dialog.TrackableDialog;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.im.ImManager;
import com.gh.common.util.AdHelper;
import com.gh.common.util.ApkActiveUtils;
import com.gh.common.util.CheckLoginUtils;
@ -56,6 +55,7 @@ import com.gh.common.util.NotificationHelper;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.TextHelper;
import com.gh.common.util.TimeUtils;
import com.gh.common.util.ToastUtils;
import com.gh.common.util.UploadImageUtils;
import com.gh.common.util.UrlFilterUtils;
@ -230,6 +230,8 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
private String mHideHint;
private String mSuggestContent;
private String mSuggestHintType;
private String mDiagnosisResult;
private String mDiagnosisMessage;
private boolean mAgreePostPic;
private boolean fromRating = false;
@ -292,6 +294,14 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
return intent;
}
public static Intent getIntentFromNetworkDiagnosis(Context context, String diagnosis) {
Intent intent = new Intent(context, SuggestionActivity.class);
intent.putExtra(EntranceUtils.KEY_SUGGESTTYPE, SuggestType.normal);
intent.putExtra(EntranceUtils.KEY_CONTENT, "网络诊断结果" + TimeUtils.getFormatTime(System.currentTimeMillis(), "yyyy.MM.dd"));
intent.putExtra(EntranceUtils.KEY_DIAGNOSIS, diagnosis);
return intent;
}
@Override
protected int getLayoutId() {
return R.layout.activity_suggest;
@ -357,6 +367,10 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
mFunctionTypeName = getResources().getStringArray(R.array.suggest_function_type);
mGameEntity = extras.getParcelable(SimpleGameEntity.class.getSimpleName());
fromRating = extras.getBoolean(FROM_RATING_KEY, false);
mDiagnosisResult = extras.getString(EntranceUtils.KEY_DIAGNOSIS, "");
if (!mDiagnosisResult.isEmpty()) {
mDiagnosisMessage = mSuggestContent;
}
setNavigationTitle("意见反馈-" + mSuggestType.getType());
@ -945,9 +959,7 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
mSuggestEmailEt.requestFocus();
mSuggestEmailEt.postDelayed(() -> Util_System_Keyboard.showSoftKeyboard(getApplicationContext(), mSuggestEmailEt), 300);
},
() -> {
postSuggestion(email);
});
() -> postSuggestion(email));
}
private void postPic(final String email) {
@ -1043,11 +1055,11 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
params.put("suggestion_type", "版权申诉");
sendSuggestion(new JSONObject(params));
if (CheckLoginUtils.isLogin()) {
// 创建一条信息至七陌客服
String feedbackType = "意见反馈-" + mSuggestType.getType();
ImManager.sendFeedbackMessage(feedbackType + ": " + mExplanationEt.getText().toString());
}
// if (CheckLoginUtils.isLogin()) {
// // 创建一条信息至七陌客服
// String feedbackType = "意见反馈-" + mSuggestType.getType();
// ImManager.sendFeedbackMessage(feedbackType + ": " + mExplanationEt.getText().toString());
// }
}
private void initPostData(String email, JSONArray picArray) {
@ -1067,9 +1079,12 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
if (fromRating) {
params.put("suggestion_type", mSuggestType.getType() + "(评论)");
} else if (!mDiagnosisResult.isEmpty()){
params.put("suggestion_type", "网络诊断");
} else {
params.put("suggestion_type", mSuggestType.getType());
}
if (mGameEntity != null) {
params.put("game_id", mGameEntity.getId());
}
@ -1092,6 +1107,9 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
} else {
message = mSuggestGameName.getText() + "-" + mPlatformEt.getText() + "" + content;
}
} else if (mSuggestType == SuggestType.normal && !mDiagnosisResult.isEmpty()) {
message = mDiagnosisMessage;
params.put("log", mDiagnosisResult);
} else {
message = content;
if (mSuggestType == SuggestType.crash) {
@ -1116,11 +1134,11 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
sendSuggestion(jsonObject);
if (CheckLoginUtils.isLogin()) {
// 创建一条信息至七陌客服
String feedbackType = "意见反馈-" + mSuggestType.getType();
ImManager.sendFeedbackMessage(feedbackType + ": " + message);
}
// if (CheckLoginUtils.isLogin()) {
// // 创建一条信息至七陌客服
// String feedbackType = "意见反馈-" + mSuggestType.getType();
// ImManager.sendFeedbackMessage(feedbackType + ": " + message);
// }
}
private void sendSuggestion(JSONObject jsonObject) {

View File

@ -223,6 +223,18 @@ public class WebActivity extends NormalActivity {
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getIntent(Context context, String url, String title, int qaType) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_URL, url);
bundle.putString(EntranceUtils.KEY_GAMENAME, title);
bundle.putBoolean(WebFragment.KEY_COMPLETION_TITLE, false);
bundle.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_TITLE, false);
bundle.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false);
bundle.putInt(WebFragment.KEY_QA_TYPE, qaType);
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getIntentByUrl(Context context, String url) {
return getIntentByUrl(context, url, false);

View File

@ -17,7 +17,6 @@ import androidx.core.content.ContextCompat;
import com.gh.common.util.BitmapUtils;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
import com.gh.gamecenter.entity.InstallGameEntity;
@ -107,7 +106,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
for (String apk_path : mApkPath) {
InstallGameEntity apkEntity = new InstallGameEntity();
PackageManager pm = mContext.getApplicationContext().getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(apk_path, 0);
PackageInfo packageInfo = pm.getPackageArchiveInfo(apk_path, PackageManager.GET_ACTIVITIES);
if (packageInfo == null) continue;
ApplicationInfo appInfo = packageInfo.applicationInfo;
@ -133,7 +132,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
/**安装处理类型*/
/** 得到包名 */
String packageName = packageInfo.packageName;
int type = doType(packageName);
int type = doType(pm, packageName);
apkEntity.setInstallStatus(type);
mApkList.add(apkEntity);
@ -177,8 +176,8 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
}
}
private int doType(String packageName) {
List<PackageInfo> pakageinfos = PackageUtils.getInstalledPackages(mContext, 0);
private int doType(PackageManager pm, String packageName) {
List<PackageInfo> pakageinfos = pm.getInstalledPackages(0);
for (PackageInfo pi : pakageinfos) {
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
String pi_packageName = pi.packageName;

View File

@ -11,6 +11,8 @@ import com.gh.common.dialog.GameOffServiceDialogFragment;
import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.history.HistoryHelper;
import com.gh.common.simulator.SimulatorDownloadManager;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DataLogUtils;
import com.gh.common.util.DataUtils;
@ -41,6 +43,8 @@ import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentActivity;
@ -187,6 +191,20 @@ public class DetailViewHolder {
break;
case LAUNCH_OR_OPEN:
if (mGameEntity.getApk().size() == 1) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(mGameEntity)) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(mGameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
download(false);
return;
}
SimulatorGameManager.launchSimulatorGame(downloadEntity, mGameEntity);
}
return;
}
DataUtils.onGameLaunchEvent(mViewHolder.context, mGameEntity.getName(), mGameEntity.getApk().get(0).getPlatform(), mName);
PackageUtils.launchApplicationByPackageName(mViewHolder.context, mGameEntity.getApk().get(0).getPackageName());
} else {
@ -202,12 +220,29 @@ public class DetailViewHolder {
break;
case INSTALL_PLUGIN:
case INSTALL_NORMAL:
ApkEntity apk = mGameEntity.getApk().get(0);
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
if (mGameEntity.getSimulator() != null) {
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(mViewHolder.context, mGameEntity.getSimulator().getApk().getPackageName());
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(mGameEntity) && !isInstalled) {
SimulatorDownloadManager.getInstance().showDownloadDialog(mViewHolder.context, mGameEntity.getSimulator(),
SimulatorDownloadManager.SimulatorLocation.LAUNCH, mGameEntity.getId(), mGameEntity.getName(), null);
return;
}
}
PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> {
if (mDownloadEntity == null) {
mDownloadEntity = DownloadManager.getInstance(mViewHolder.context).getDownloadEntityByUrl(mGameEntity.getApk().get(0).getUrl());
}
if (mDownloadEntity != null) {
PackageInstaller.install(mViewHolder.context, mDownloadEntity);
final String path = mDownloadEntity.getPath();
if (FileUtils.isEmptyFile(path)) {
Utils.toast(mViewHolder.context, R.string.install_failure_hint);
DownloadManager.getInstance(mViewHolder.context).cancel(mDownloadEntity.getUrl());
} else {
PackageInstaller.install(mViewHolder.context, mDownloadEntity);
}
}
});
break;
@ -251,7 +286,9 @@ public class DetailViewHolder {
Intent i = new Intent(WebActivity.getIntentForWebGame(mViewHolder.context, linkEntity.getLink(), mGameEntity.getName(), isPlay, linkEntity.getCloseButton()));
mViewHolder.context.startActivity(i);
break;
case UPDATING:
Utils.toast(mViewHolder.context, "正在加急更新版本,敬请后续留意");
break;
default:
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(mViewHolder.context,
mGameEntity.getApk().get(0).getUrl(),

View File

@ -0,0 +1,12 @@
package com.gh.gamecenter.adapter.viewholder
import android.view.View
import android.widget.TextView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.gamecenter.R
import kotterknife.bindView
class SimulatorHeaderViewHolder(view: View) : BaseRecyclerViewHolder<Any>(view) {
val managerBtn by bindView<TextView>(R.id.btn_manager)
val simulatorBtn by bindView<TextView>(R.id.btn_simulator)
}

View File

@ -0,0 +1,12 @@
package com.gh.gamecenter.adapter.viewholder
import android.view.View
import android.widget.TextView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.gamecenter.R
import kotterknife.bindView
class SimulatorManagementViewHolder(view: View) : BaseRecyclerViewHolder<Any>(view) {
val simulatorName by bindView<TextView>(R.id.simulator_name)
val simulatorInstallBtn by bindView<TextView>(R.id.simulator_install_btn)
}

View File

@ -31,19 +31,19 @@ public class CollectionWrapperFragment extends BaseFragment_TabLayout {
@Override
protected void initTabTitleList(List<String> tabTitleList) {
tabTitleList.add(getString(R.string.answer));
tabTitleList.add(getString(R.string.collection_article));
tabTitleList.add(getString(R.string.collection_toolkit));
tabTitleList.add(getString(R.string.collection_info));
// tabTitleList.add(getString(R.string.answer));
// tabTitleList.add(getString(R.string.collection_article));
// tabTitleList.add(getString(R.string.collection_toolkit));
// tabTitleList.add(getString(R.string.collection_info));
tabTitleList.add(getString(R.string.video));
}
@Override
protected void initFragmentList(List<Fragment> fragments) {
fragments.add(new AnswerFragment().with(getArguments()));
fragments.add(new CommunityArticleFragment().with(getArguments()));
fragments.add(new ToolsFragment().with(getArguments()));
fragments.add(new ArticleFragment().with(getArguments()));
// fragments.add(AnswerFragment.getInstance(AnswerFragment.Type.COLLECTION).with(getArguments()));
// fragments.add(CommunityArticleFragment.getInstance(CommunityArticleFragment.Type.COLLECTION).with(getArguments()));
// fragments.add(new ToolsFragment().with(getArguments()));
// fragments.add(ArticleFragment.getInstance(ArticleFragment.Type.COLLECTION).with(getArguments()));
Bundle arguments = getArguments();
if (arguments != null)

View File

@ -17,7 +17,7 @@ public class DataCollectionDao {
try {
helper = DatabaseHelper.getHelper(context);
dao = helper.getDao(DataCollectionInfo.class);
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -28,7 +28,7 @@ public class DataCollectionDao {
public List<DataCollectionInfo> findByType(String type) {
try {
return dao.queryForEq("type", type);
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return null;
@ -40,8 +40,7 @@ public class DataCollectionDao {
public void add(DataCollectionInfo entity) {
try {
dao.create(entity);
} catch (SQLException | IllegalStateException e) {
// java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -52,8 +51,7 @@ public class DataCollectionDao {
public void delete(String id) {
try {
dao.deleteById(id);
} catch (SQLException | IllegalStateException e) {
// java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -64,7 +62,7 @@ public class DataCollectionDao {
public void delete(List<String> ids) {
try {
dao.deleteIds(ids);
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -75,7 +73,7 @@ public class DataCollectionDao {
public DataCollectionInfo find(String id) {
try {
return dao.queryForId(id);
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return null;
@ -87,7 +85,7 @@ public class DataCollectionDao {
public List<DataCollectionInfo> getAll() {
try {
return dao.queryForAll();
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return null;
@ -99,7 +97,7 @@ public class DataCollectionDao {
public List<DataCollectionInfo> getClickData() {
try {
return dao.queryForEq("type", "click-item");
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return null;
@ -111,7 +109,7 @@ public class DataCollectionDao {
public void update(DataCollectionInfo entity) {
try {
dao.update(entity);
} catch (SQLException | IllegalStateException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}

View File

@ -1,7 +1,6 @@
package com.gh.gamecenter.db;
import android.content.Context;
import android.database.sqlite.SQLiteException;
import com.gh.gamecenter.db.info.PackageInfo;
import com.j256.ormlite.dao.Dao;
@ -19,7 +18,7 @@ public class FilterDao {
try {
helper = DatabaseHelper.getHelper(context);
dao = helper.getDao(PackageInfo.class);
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -32,7 +31,7 @@ public class FilterDao {
if (list != null && list.size() != 0) {
return list.get(0).getTime();
}
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
@ -44,7 +43,7 @@ public class FilterDao {
if (filterEntity != null) {
return true;
}
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return false;
@ -56,7 +55,7 @@ public class FilterDao {
public void add(PackageInfo entity) {
try {
dao.create(entity);
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -68,7 +67,7 @@ public class FilterDao {
public void addAll(List<PackageInfo> list) {
try {
dao.create(list);
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -76,7 +75,7 @@ public class FilterDao {
public void deleteAll(List<PackageInfo> list) {
try {
dao.delete(list);
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -87,7 +86,7 @@ public class FilterDao {
public void delete(String packageName) {
try {
dao.deleteById(packageName);
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
}
@ -98,7 +97,7 @@ public class FilterDao {
public List<PackageInfo> getAll() {
try {
return dao.queryForAll();
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return null;
@ -110,7 +109,7 @@ public class FilterDao {
public long getCount() {
try {
return dao.countOf();
} catch (SQLiteException | SQLException e) {
} catch (SQLException e) {
e.printStackTrace();
}
return 0;

View File

@ -7,12 +7,6 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.fragment.BaseFragment;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.EntranceUtils;
@ -41,6 +35,11 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.OnClick;
@ -85,6 +84,14 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
return;
}
if (downloadEntity.getStatus().equals(DownloadStatus.done) && ExtensionsKt.isSimulatorGame(downloadEntity)) {
adapter.initMap();
adapter.notifyDataSetChanged();
int listSize = adapter.getDownloadingList().size() + adapter.getDoneList().size();
mNoDataSkip.setVisibility(listSize > 0 ? View.GONE : View.VISIBLE);
EventBus.getDefault().post(new EBDownloadChanged("download", View.GONE, listSize));
}
if (downloadEntity.getStatus().equals(DownloadStatus.downloading)
|| downloadEntity.getStatus().equals(DownloadStatus.pause)
|| downloadEntity.getStatus().equals(DownloadStatus.waiting)) {
@ -178,6 +185,10 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
if (ExtensionsKt.isSilentUpdate(downloadEntity)) {
return;
}
//下载模拟器任务不需要添加
if (ExtensionsKt.isSimulatorDownload(downloadEntity)) {
return;
}
if (adapter.getDownloadingList().isEmpty()) {
adapter.getDownloadingList().add(0, downloadEntity);

View File

@ -9,11 +9,6 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.common.constant.Constants;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
@ -48,6 +43,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
/**
* Created by LGT on 2016/8/15.
*/
@ -640,9 +640,11 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
for (DownloadEntity downloadEntity : DownloadManager.getInstance(mContext).getAllDownloadEntityExcludeSilentUpdate()) {
statusMap.put(downloadEntity.getUrl(), downloadEntity.getStatus().name());
if (DownloadStatus.done.equals(downloadEntity.getStatus())) {
urlMap.put(PackageUtils.getPackageNameByPath(mContext,
downloadEntity.getPath()), downloadEntity.getUrl());
doneList.add(downloadEntity);
if(!ExtensionsKt.isSimulatorGame(downloadEntity)) {
urlMap.put(PackageUtils.getPackageNameByPath(mContext,
downloadEntity.getPath()), downloadEntity.getUrl());
doneList.add(downloadEntity);
}
} else {
downloadingList.add(downloadEntity);
}

View File

@ -14,6 +14,7 @@ import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.base.OnRequestCallBackListener
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.isSimulatorGame
import com.gh.common.view.FixLinearLayoutManager
import com.gh.common.view.VerticalItemDecoration
import com.gh.download.DownloadManager
@ -29,6 +30,7 @@ import com.gh.gamecenter.normal.NormalFragment
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -37,12 +39,16 @@ class InstalledGameFragment : NormalFragment(), OnRequestCallBackListener<Any> {
@BindView(R.id.fm_install_rv_show)
lateinit var mInstallRv: RecyclerView
@BindView(R.id.reuse_nodata_skip)
lateinit var mNoDataSkip: LinearLayout
@BindView(R.id.reuse_nodata_skip_tv_hint)
lateinit var mNoDataSkipHint: TextView
@BindView(R.id.reuse_nodata_skip_tv_btn)
lateinit var mNoDataSkipBtn: TextView
@BindView(R.id.list_skeleton)
lateinit var mListSkeleton: View
@ -56,6 +62,13 @@ class InstalledGameFragment : NormalFragment(), OnRequestCallBackListener<Any> {
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.status == DownloadStatus.done && downloadEntity.isSimulatorGame()) {
DownloadManager.getInstance(requireContext()).getEntryMap(downloadEntity.name)[downloadEntity.platform] = downloadEntity
mPackageViewModel?.getGameInstalledLiveData()?.value?.let {
mAdapter?.initData(PackagesManager.filterSameApk(PackagesManager.filterDownloadBlackPackage(it as MutableList<GameInstall>?)))
}
return
}
val locationList = mAdapter!!.locationMap[downloadEntity.packageName]
if (locationList != null && locationList.size != 0) {
var gameEntity: GameEntity?

View File

@ -4,10 +4,6 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.common.AppExecutor;
import com.gh.common.constant.ItemViewType;
import com.gh.common.exposure.ExposureEvent;
@ -15,6 +11,7 @@ import com.gh.common.exposure.ExposureSource;
import com.gh.common.exposure.ExposureType;
import com.gh.common.exposure.IExposable;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.ApkActiveUtils;
import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.DownloadItemUtils;
@ -39,11 +36,15 @@ import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.download.DownloadEntity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -84,6 +85,13 @@ public class InstalledGameFragmentAdapter extends BaseRecyclerAdapter<ViewHolder
}
public void initData(List<GameInstall> list) {
List<DownloadEntity> downloadEntityList = DownloadManager.getInstance(mContext).getAllSimulatorDownloadEntity();
for (DownloadEntity entity : downloadEntityList) {
GameInstall gameInstall = new GameInstall();
gameInstall.setId(entity.getGameId());
list.add(gameInstall);
}
for (GameInstall gameInstall : list) {
Object gh_id = PackageUtils.getMetaData(mContext, gameInstall.getPackageName(), "gh_id");
if (gh_id != null && !gh_id.equals(gameInstall.getId())) {
@ -287,7 +295,11 @@ public class InstalledGameFragmentAdapter extends BaseRecyclerAdapter<ViewHolder
PlatformUtils.getInstance(mContext).getPlatformName(gameEntity.getApk().get(0).getPlatform()));
binding.gameIconIv.setImageDrawable(PackageUtils.getIconByPackage(mContext, gameEntity.getApk().get(0).getPackageName()));
binding.gameIconDecoratorIv.setVisibility(View.GONE);
binding.gameDes.setText(String.format("V%s", PackageUtils.getVersionByPackage(gameEntity.getApk().get(0).getPackageName())));
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
binding.gameDes.setText(String.format("V%s", gameEntity.getApk().get(0).getVersion()));
} else {
binding.gameDes.setText(String.format("V%s", PackageUtils.getVersionByPackage(gameEntity.getApk().get(0).getPackageName())));
}
} else {
name = gameEntity.getName();
ImageUtils.display(binding.gameIconIv, gameEntity.getRawIconInAdvanced());
@ -295,6 +307,9 @@ public class InstalledGameFragmentAdapter extends BaseRecyclerAdapter<ViewHolder
ExtensionsKt.goneIf(binding.gameIconDecoratorIv, TextUtils.isEmpty(gameEntity.getIconSubscript()));
binding.gameDes.setText(gameEntity.getBrief());
}
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
ImageUtils.display(binding.gameIconIv, gameEntity.getIcon());
}
binding.gameName.setText(name);

View File

@ -0,0 +1,6 @@
package com.gh.gamecenter.entity
data class EmulatorGameEntity(
var gameName: String = "",
var filePath: String = ""
)

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import androidx.annotation.DrawableRes
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@ -22,9 +23,17 @@ data class FunctionalLinkEntity(
var iconRes: Int = 0, // 客户端展示的icon
@SerializedName("remind_switch")
var remind: Boolean = false,//分组提醒
var message: FunctionalMessageType? = null
var message: FunctionalMessageType? = null,
@SerializedName("checksum")
var checkSum: CheckSumEntity? = null // addons.$.type为 设置 时存在该字段
) : LinkEntity()
@Parcelize
data class CheckSumEntity(
@SerializedName("privacy_policy")
var privacyPolicy: String = "" //隐私政策网页md5值用于判断是否有更新
) : Parcelable
enum class FunctionalMessageType {
NEW_VERSION,
NEW_MESSAGE

View File

@ -153,7 +153,7 @@ data class GameEntity(
@SerializedName("show_comment")
var showComment: Boolean = false, // 游戏评论是否打开
// 分类,取值有 online (网络游戏) , local (单机游戏) welfare (福利游戏)
// 分类,取值有 online (网络游戏) , local (单机游戏) welfare (福利游戏)simulator模拟器游戏
@SerializedName("category")
private var mCategory: String? = "",
// 7天下载量
@ -217,6 +217,12 @@ data class GameEntity(
var ignoreComment: Boolean = false,
@SerializedName("overseas_address_dialog")
var overseasAddressDialog: OverseasAddressDialog? = null,
var simulator: SimulatorEntity? = null,
@SerializedName("simulator_type")
var simulatorType: String = "",
@SerializedName("is_recently_played")
var isRecentlyPlayed: Boolean = false,
var active: Boolean = true,
// 本地字段,使用镜像信息
var useMirrorInfo: Boolean = false,
@ -502,6 +508,9 @@ data class GameEntity(
gameEntity.gameVersion = gameVersion
gameEntity.welcomeDialogId = welcomeDialogId
gameEntity.welcomeDialogTitle = welcomeDialogTitle
gameEntity.mCategory = mCategory
gameEntity.simulator = simulator
gameEntity.simulatorType = simulatorType
return gameEntity
}

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.entity
import com.gh.gamecenter.R
import com.google.gson.annotations.SerializedName
import com.halo.assistant.HaloApp
data class PrivacyPolicyEntity(
var title: String = "",
@ -15,8 +16,8 @@ data class PrivacyPolicyEntity(
@JvmStatic
fun createDefaultData(): PrivacyPolicyEntity {
val data = PrivacyPolicyEntity()
data.title = "欢迎来到光环助手"
data.topContent = "为提供完整的功能与稳定的服务,光环助手将向你申请开启以下权限:"
data.title = "欢迎来到" + HaloApp.getInstance().application.getString(R.string.app_name)
data.topContent = "为提供完整的功能与稳定的服务," + HaloApp.getInstance().application.getString(R.string.app_name) + "将向你申请开启以下权限:"
data.bottomContent = "你可以在系统设置中关闭授权,但可能会影响部分功能的正常使用"
val permissions = arrayListOf<PermissionsEntity>()
permissions.add(PermissionsEntity(

View File

@ -0,0 +1,19 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class SimulatorEntity(
@SerializedName("_id")
var id: String = "",
var active: Boolean = false,
var name: String = "",
var type: String = "",
@SerializedName("type_alias")
var typeAlias: String = "",
@SerializedName("file_type")
var fileType: List<String> = listOf(),
var apk: ApkEntity? = null
) : Parcelable

View File

@ -160,6 +160,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
MtaHelper.onEvent("论坛详情", getKeyValue(mLastPosition), getKeyValue(it))
mLastPosition = it
}
LogUtils.uploadAccessToBbs(bbsId, "论坛详情")
}
private fun getKeyValue(position: Int): String {

View File

@ -6,10 +6,7 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DisplayUtils
import com.gh.common.util.ImageUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.dip2px
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemForumFollowBinding
import com.gh.gamecenter.entity.ForumEntity
@ -82,6 +79,7 @@ class ForumFollowAdapter(context: Context) : BaseRecyclerAdapter<RecyclerView.Vi
holder.itemView.setOnClickListener {
MtaHelper.onEvent("论坛首页", "关注的论坛", forumEntity.name)
mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, "论坛"))
LogUtils.uploadAccessToBbs(forumEntity.id,"关注板块")
}
}
}

View File

@ -1,6 +1,5 @@
package com.gh.gamecenter.fragment;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Animatable;
import android.net.Uri;
@ -29,15 +28,13 @@ import com.gh.base.OnDoubleTapListener;
import com.gh.base.fragment.BaseFragment_ViewPager_Checkable;
import com.gh.common.constant.Config;
import com.gh.common.syncpage.SyncPageRepository;
import com.gh.common.util.BiCallback;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.HomeBottomBarHelper;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.LogUtils;
import com.gh.common.view.ReserveDialog;
import com.gh.common.view.WelcomeDialog;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
@ -51,7 +48,6 @@ import com.gh.gamecenter.message.MessageUnreadRepository;
import com.gh.gamecenter.message.MessageUnreadViewModel;
import com.gh.gamecenter.personal.PersonalFragment;
import com.gh.gamecenter.video.detail.HomeVideoFragment;
import com.halo.assistant.HaloApp;
import com.lightgame.listeners.OnBackPressedListener;
import com.lightgame.view.CheckableImageView;
import com.lightgame.view.CheckableLinearLayout;
@ -164,7 +160,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
if (TextUtils.isEmpty(defaultGameBarData.getLink())) {
mGameTab.setVisibility(View.GONE);
} else {
mGameTab.setVisibility(View.VISIBLE);
mGameTab.setVisibility(View.GONE);
mTabGameName.setText(defaultGameBarData.getName());
Picasso.with(getContext())
.load(Uri.parse(defaultGameBarData.getIconUnselect()))
@ -192,37 +188,40 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
});
// 判断是否是第一次启动应用,不是的话不弹启动弹窗
if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false);
mViewModel.requestOpeningData();
mViewModel.getOpeningDialog().observe(this, it -> {
if (it != null) {
ImageUtils.getBitmap(it.getIcon(), new BiCallback<Bitmap, Boolean>() {
@Override
public void onFirst(Bitmap bitmap) {
WelcomeDialog welcomeDialog = WelcomeDialog.getInstance(it);
welcomeDialog.setOnDismissListener(() -> {
mViewModel.requestReserveDialog();
return null;
});
welcomeDialog.show(getChildFragmentManager(), "openingDialog");
}
@Override
public void onSecond(Boolean aBoolean) {
mViewModel.requestReserveDialog();
}
});
} else {
mViewModel.requestReserveDialog();
}
});
}
// if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
// HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false);
// mViewModel.requestOpeningData();
// mViewModel.getOpeningDialog().observe(this, it -> {
// if (it != null) {
// ImageUtils.getBitmap(it.getIcon(), new BiCallback<Bitmap, Boolean>() {
// @Override
// public void onFirst(Bitmap bitmap) {
// // 网络速度追不上用户操作的时候可能会出现要弹启动弹窗但用户已经不停留在 MainActivity 的情况
// if (isStateSaved()) return;
//
// WelcomeDialog welcomeDialog = WelcomeDialog.getInstance(it);
// welcomeDialog.setOnDismissListener(() -> {
// mViewModel.requestReserveDialog();
// return null;
// });
// welcomeDialog.show(getChildFragmentManager(), "openingDialog");
// }
//
// @Override
// public void onSecond(Boolean aBoolean) {
// mViewModel.requestReserveDialog();
// }
// });
// } else {
// mViewModel.requestReserveDialog();
// }
// });
// }
}
private void updateGameBarContent(SubjectRecommendEntity navBarEntity) {
if (navBarEntity != null) {
mGameTab.setVisibility(View.VISIBLE);
mGameTab.setVisibility(View.GONE);
mTabGameName.setText(navBarEntity.getName());
Picasso.with(getContext())
.load(Uri.parse(navBarEntity.getIconUnselect()))
@ -274,6 +273,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
}
});
}
changeColor(mCheckedIndex);
}
@Override
@ -448,7 +449,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
DataUtils.onMtaEvent(getContext(), "顶级页面", "BottomBar", "游戏库");
break;
case INDEX_ASK:
DataUtils.onMtaEvent(getContext(), "顶级页面", "BottomBar", "问答");
DataUtils.onMtaEvent(getContext(), "顶级页面", "BottomBar", "论坛");
LogUtils.uploadAccessBbsTab();
break;
case INDEX_VIDEO:
DisplayUtils.setLightStatusBar(requireActivity(), false);
@ -491,7 +493,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
if (settings != null && !settings.showCommunityEntrance()) {
mTabCommunity.setVisibility(View.GONE);
} else {
mTabCommunity.setVisibility(View.VISIBLE);
mTabCommunity.setVisibility(View.GONE);
}
}
}

View File

@ -14,6 +14,8 @@ import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.game.GameFragment;
import com.gh.gamecenter.home.HomeFragment;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@ -50,6 +52,14 @@ public class SearchToolWrapperFragment extends BaseLazyFragment {
}
String className = Objects.requireNonNull(arguments.getString(WRAPPER_FRAGMENT_NAME));
mContentFragment = (Fragment) Class.forName(className).newInstance();
Bundle bundle = new Bundle();
if (HomeFragment.class.getName().equals(className)) {
bundle.putString(EntranceUtils.KEY_LOCATION, "首页");
} else if (GameFragment.class.getName().equals(className)) {
bundle.putString(EntranceUtils.KEY_LOCATION, "游戏库");
}
mSearchToolbarFragment.setArguments(bundle);
}
} catch (Exception e) {
e.printStackTrace();

View File

@ -25,6 +25,7 @@ import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.LogUtils;
import com.gh.common.util.MtaHelper;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.DownloadManagerActivity;
@ -70,6 +71,7 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
private static final int REQUEST_MESSAGE = 198;
private ArrayList<String> mHintList;
private int mHintIndex;
private String mLocation;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
@ -171,6 +173,9 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null && getArguments().getString(EntranceUtils.KEY_LOCATION) != null) {
mLocation = getArguments().getString(EntranceUtils.KEY_LOCATION);
}
mHintIndex = 0;
if (savedInstanceState != null) {
mHintList = savedInstanceState.getStringArrayList(EntranceUtils.KEY_HINT);
@ -245,6 +250,9 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
DataUtils.onEvent(getActivity(), "主页", "搜索框");
MtaHelper.onEvent("首页_点击", "顶栏", "搜索");
DataCollectionUtils.uploadClick(getActivity(), "搜索框", "主页");
if ("首页".equals(mLocation) || "游戏库".equals(mLocation)) {
LogUtils.uploadSearchGame("access_to_search", mLocation, "", "");
}
intent = SearchActivity.getIntent(requireContext(), false, mSearchHintTv.getHint().toString(), "(工具栏)");
startActivity(intent);

View File

@ -9,7 +9,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureSource
import com.gh.common.view.AutoScrollRecyclerView
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.GameGallerySlideItemBinding
@ -22,7 +21,7 @@ class GameGallerySlideViewHolder(val binding: GameGallerySlideItemBinding)
: BaseRecyclerViewHolder<Any>(binding.root) {
private var mCachedSubject: SubjectEntity? = null
private var mRecyclerViewList: ArrayList<AutoScrollRecyclerView>? = null
private var mRecyclerViewList: ArrayList<RecyclerView>? = null
private var mEntrance = ""
private var mExposureClosure: ((ExposureEvent) -> Unit)? = null
@ -48,11 +47,10 @@ class GameGallerySlideViewHolder(val binding: GameGallerySlideItemBinding)
for ((index, recyclerView) in mRecyclerViewList!!.withIndex()) {
recyclerView.layoutManager = LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false)
recyclerView.adapter = GameGallerySlideAdapter(binding.root.context, getDividedGameList()[index])
recyclerView.resumeScrolling()
if (binding.root.context is ComponentActivity) {
recyclerView.setLifeCycleOwner((binding.root.context as ComponentActivity).lifecycle)
}
}
binding.container.resumeScrolling()
binding.container.setLifeCycleOwner((binding.root.context as ComponentActivity).lifecycle)
}
private fun getDividedGameList(): ArrayList<ArrayList<GameEntity>> {
@ -67,19 +65,11 @@ class GameGallerySlideViewHolder(val binding: GameGallerySlideItemBinding)
}
fun resumeScrolling() {
mRecyclerViewList?.let {
for (recyclerView in it) {
recyclerView.resumeScrolling()
}
}
binding.container.resumeScrolling()
}
fun pauseScrolling() {
mRecyclerViewList?.let {
for (recyclerView in it) {
recyclerView.pauseScrolling()
}
}
binding.container.pauseScrolling()
}
inner class GameGallerySlideAdapter(context: Context, var gameList: ArrayList<GameEntity>) : BaseRecyclerAdapter<GameGallerySlideAdapter.GameGallerySlideItemViewHolder>(context) {

View File

@ -61,12 +61,12 @@ class GameResourcePolicyDialogFragment : BaseDialogFragment() {
mVebView?.loadUrl(requireContext().getString(R.string.upload_game_policy_url))
containerView?.findViewById<View>(R.id.refuseTv)?.setOnClickListener {
MtaHelper.onEvent("游戏上传", "开发者弹窗", "不同意")
dismissAllowingStateLoss()
dismiss()
requireActivity().finish()
}
containerView?.findViewById<View>(R.id.agreeTv)?.setOnClickListener {
MtaHelper.onEvent("游戏上传", "开发者弹窗", "同意")
dismissAllowingStateLoss()
dismiss()
}
}

View File

@ -322,6 +322,7 @@ class GameDetailFragment : NormalFragment() {
if (mNewGameDetailEntity?.bbsTab != null && position == tabTitleList.size - 1) {
DirectUtils.directToLinkPage(requireContext(), mNewGameDetailEntity?.bbsTab!!, "游戏详情", "")
LogUtils.uploadAccessToBbs(mNewGameDetailEntity?.bbsTab?.link, "游戏详情")
} else {
mCurVpPosition = position
}
@ -905,7 +906,7 @@ class GameDetailFragment : NormalFragment() {
for ((packageName) in mGameEntity!!.getApk()) {
if (busFour.packageName == packageName) {
ApkActiveUtils.filterHideApk(mGameEntity)
DetailDownloadUtils.detailInitDownload(detailViewHolder, false)
DetailDownloadUtils.detailInitDownload(detailViewHolder, true)
}
}
}

View File

@ -10,8 +10,8 @@ import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.DisplayUtils
import com.gh.common.util.SpanBuilder
import com.gh.common.util.dip2px
import com.gh.common.util.tryWithDefaultCatch
import com.gh.common.view.CenterImageSpan
import com.gh.common.view.CustomLinkMovementMethod
@ -77,7 +77,7 @@ class GameDetailCustomColumnAdapter(context: Context)
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({
val bitmapDrawable = BitmapDrawable(mContext.resources, it)
bitmapDrawable.setBounds(0, 0, DisplayUtils.dip2px(16F), DisplayUtils.dip2px(16F))
bitmapDrawable.setBounds(0, 0, 16F.dip2px(), 16F.dip2px())
spannable.setSpan(CenterImageSpan(bitmapDrawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
viewHolder.contentTv.movementMethod = CustomLinkMovementMethod.getInstance()
viewHolder.contentTv.text = spannable

View File

@ -112,7 +112,7 @@ class RatingCommentItemViewHolder(val binding: RatingCommentItemBinding) : BaseR
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
val bitmapDrawable = BitmapDrawable(context.resources, it)
bitmapDrawable.setBounds(0, 0, DisplayUtils.dip2px(16F), DisplayUtils.dip2px(16F))
bitmapDrawable.setBounds(0, 0, 16F.dip2px(), 16F.dip2px())
contentSpan.setSpan(CenterImageSpan(bitmapDrawable), commentData.replyData?.user?.name!!.length + 2, commentData.replyData?.user?.name!!.length + 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
contentSpan.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {

View File

@ -189,6 +189,10 @@ class RatingReplyAdapter(context: Context,
if ("dialog" == offStatus) {
text = "查看"
setTextColor(ContextCompat.getColor(mContext, R.color.white))
} else if ("updating" == offStatus) {
text = "更新中"
setTextColor(ContextCompat.getColor(mContext, R.color.white))
setBackgroundResource(R.drawable.download_button_updating_style)
} else {
text = "暂无"
setTextColor(ContextCompat.getColor(mContext, R.color.button_gray))
@ -454,7 +458,7 @@ class RatingReplyAdapter(context: Context,
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
val bitmapDrawable = BitmapDrawable(mContext.resources, it)
bitmapDrawable.setBounds(0, 0, DisplayUtils.dip2px(16F), DisplayUtils.dip2px(16F))
bitmapDrawable.setBounds(0, 0, 16F.dip2px(), 16F.dip2px())
replyNameSpannable.setSpan(CenterImageSpan(bitmapDrawable), startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
replyNameSpannable.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {

View File

@ -91,7 +91,7 @@ class HelpContentAdapter(context: Context,
} else {
Constants.HELP_ADDRESS
}
mContext.startActivity(WebActivity.getIntent(mContext, "${url}${entity.id}", mNavigationTitle, false, false))
mContext.startActivity(WebActivity.getIntent(mContext, "${url}${entity.id}", mNavigationTitle, if (!mQaCollectionId.isNullOrEmpty())0 else 1))
}
val category = mFragment.getHelpCategory()
val activity = mFragment.activity

View File

@ -46,7 +46,7 @@ class HelpQaAdapter(val context: Context, val helpCategoryEntity: HelpCategoryEn
} else {
Constants.HELP_ADDRESS
}
context.startActivity(WebActivity.getIntent(context, "${url}${helpEntity.id}", helpCategoryEntity.name, false, false))
context.startActivity(WebActivity.getIntent(context, "${url}${helpEntity.id}", helpCategoryEntity.name, if (!mQaCollectionId.isNullOrEmpty())0 else 1))
}
if (!mQaCollectionId.isNullOrEmpty()) {
MtaHelper.onEvent("QA", "QA合集点击", "点击首页+${HtmlUtils.stripHtml(helpEntity.title)}")

View File

@ -3,7 +3,6 @@ package com.gh.gamecenter.history
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.gh.base.fragment.BaseFragment_TabLayout
import com.gh.common.util.EntranceUtils
import com.gh.common.util.MtaHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.collection.AnswerFragment
@ -14,21 +13,21 @@ import com.gh.gamecenter.collection.VideoFragment
class HistoryWrapperFragment : BaseFragment_TabLayout() {
override fun initTabTitleList(tabTitleList: MutableList<String>) {
tabTitleList.add(getString(R.string.main_game))
// tabTitleList.add(getString(R.string.answer))
// tabTitleList.add(getString(R.string.collection_article))
// tabTitleList.add(getString(R.string.collection_info))
// tabTitleList.add(getString(R.string.main_game))
tabTitleList.add(getString(R.string.video))
tabTitleList.add(getString(R.string.answer))
tabTitleList.add(getString(R.string.collection_article))
tabTitleList.add(getString(R.string.collection_info))
}
override fun initFragmentList(fragments: MutableList<Fragment>) {
fragments.add(HistoryGameListFragment().with(arguments))
// fragments.add(AnswerFragment.getInstance(AnswerFragment.Type.HISTORY).with(arguments))
// fragments.add(CommunityArticleFragment.getInstance(CommunityArticleFragment.Type.HISTORY).with(arguments))
// fragments.add(ArticleFragment.getInstance(ArticleFragment.Type.HISTORY).with(arguments))
// fragments.add(HistoryGameListFragment().with(arguments))
fragments.add(VideoFragment().with(arguments?.apply {
putString("videoStyle", VideoFragment.VideoStyle.BROWSING_HISTORY.value)
}))
fragments.add(AnswerFragment().with(arguments?.apply { putString(EntranceUtils.KEY_TYPE, AnswerFragment.HISTORY) }))
fragments.add(CommunityArticleFragment().with(arguments?.apply { putString(EntranceUtils.KEY_TYPE, CommunityArticleFragment.Type.HISTORY.value) }))
fragments.add(ArticleFragment().with(arguments?.apply { putString(EntranceUtils.KEY_TYPE, ArticleFragment.HISTORY) }))
}
override fun onPageSelected(position: Int) {

View File

@ -38,6 +38,10 @@ class HomeSlideListItemViewHolder(val binding: HomeSlideListItemBinding) : BaseR
}
val linkGame = homeSlide.linkGame ?: return
// 轮播图的标题不需要游戏后缀
linkGame.nameSuffix = ""
if (homeSlide.text.isNotEmpty()) linkGame.name = homeSlide.text
// 强制更改标签颜色

View File

@ -5,6 +5,7 @@ import android.content.Context;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.loghub.LoghubUtils;
import com.gh.common.util.Installation;
import com.gh.common.util.LogUtils;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.db.DataCollectionDao;
import com.gh.gamecenter.db.info.DataCollectionInfo;
@ -59,6 +60,9 @@ public class DataCollectionManager {
map.put("type", type);
Map<String, Object> paramsWrapper = new HashMap<>();
if ("news".equals(type) || "download".equals(type) || "search".equals(type)) {
paramsWrapper.put("meta", LogUtils.getMetaObject().toString());
}
paramsWrapper.put("topic", type);
paramsWrapper.put("content", new JSONObject(map).toString());
paramsWrapper.put("time", Utils.getTime(HaloApp.getInstance().getApplication()));

View File

@ -27,7 +27,7 @@ object PackagesManager {
*/
val updateListSize: Int get() = updateAndPluginList.size
fun initInstallPkgList(list: List<String>) {
fun initInstallPkgList(list: ArrayList<String>) {
installedPkgList.clear()
installedPkgList.addAll(list)
}

View File

@ -16,6 +16,7 @@ import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.NotificationManagerCompat;
import com.g00fy2.versioncompare.Version;
import com.gh.common.AppExecutor;
import com.gh.common.constant.Constants;
import com.gh.common.util.DataLogUtils;
@ -127,7 +128,7 @@ public class UpdateManager {
downloadDialog.dismiss();
}
if (appEntity != null && appEntity.isForce()) {
exitApp();
AppExecutor.getUiExecutor().executeWithDelay(() -> exitApp(), 1000);
}
} else if (DownloadStatus.neterror.equals(downloadEntity.getStatus())) {
Utils.toast(mContext, "网络错误,请稍后重试");
@ -190,8 +191,7 @@ public class UpdateManager {
RetrofitManager.getInstance(mContext).getApi().getUpdate(PackageUtils.getVersionName(), PackageUtils.getVersionCode(), channel)
.map(appEntity -> {
boolean isShowUpdateDialog = false;
if (appEntity.getVersionCode() > PackageUtils.getVersionCode()) {
if (new Version(appEntity.getVersion()).isHigherThan(PackageUtils.getVersionName())) {
// 助手有更新
UpdateManager.this.appEntity = appEntity;
@ -269,7 +269,7 @@ public class UpdateManager {
handler.sendEmptyMessage(1);
}
if (e != null && (e.code() == 304 || e.code() == 404)) {
Utils.toast(mContext, "您的光环助手已是最新版本");
Utils.toast(mContext, "您的" + mContext.getString(R.string.app_name) + "已是最新版本");
return;
}

View File

@ -12,7 +12,6 @@ import com.gh.base.BaseActivity;
import com.gh.common.PushManager;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.im.ImManager;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DeviceUtils;
@ -195,7 +194,7 @@ public class UserManager {
// 更新 Access Token 后更新推送别名
PushManager.getAndSetAlias();
ImManager.attachIm();
// ImManager.attachIm();
// 更新用户预约的游戏列表
ReservationRepository.refreshReservations();

View File

@ -18,7 +18,6 @@ import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.OnListClickListener;
import com.gh.common.constant.Constants;
import com.gh.common.constant.ItemViewType;
import com.gh.common.im.ImManager;
import com.gh.common.util.CommentUtils;
import com.gh.common.util.DialogHelper;
import com.gh.common.util.DirectUtils;
@ -330,7 +329,9 @@ public class KeFuFragmentAdapter extends ListAdapter<MessageKeFuEntity> {
break;
case "7moor":
if (mContext instanceof Activity) {
ImManager.startChatActivity((Activity) mContext, null, null);
// 去掉七陌支持,跳转到企点
// ImManager.startChatActivity((Activity) mContext, null, null);
DirectUtils.directToWebView(mContext, Constants.TENCENT_QIDIAN_ADDRESS, mEntrance);
}
break;
case "问题":
@ -399,14 +400,10 @@ public class KeFuFragmentAdapter extends ListAdapter<MessageKeFuEntity> {
MtaHelper.onEvent("消息中心", "系统_二级列表", "点击链接");
switch (type) {
case "7moor":
if (mContext instanceof Activity) {
ImManager.startChatActivity((Activity) mContext, null, null);
}
break;
case "home":
DirectUtils.directToHomeActivity(mContext, UserManager.getInstance().getUserId(), mEntrance, "(消息-客服)");
break;
case "7moor":
case "qidian":
DirectUtils.directToWebView(mContext, Constants.TENCENT_QIDIAN_ADDRESS, mEntrance);
break;

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