Compare commits
95 Commits
v4.3.8-218
...
video_only
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a826234d0 | |||
| 9f5ffb084a | |||
| b5d4cbe718 | |||
| b39a47c0bd | |||
| 5ea6647bf7 | |||
| 6fcd8397b6 | |||
| 3478aaba2f | |||
| 1f0b9a95e2 | |||
| 5cdc1635ca | |||
| 3db784509b | |||
| e8f63ea99f | |||
| 97ac4b03a3 | |||
| 883a948b7b | |||
| 261e0cc45a | |||
| 0357a0a71e | |||
| d87de59427 | |||
| d5ee01a2e1 | |||
| 3563637919 | |||
| d881e08aee | |||
| f5ff838d2f | |||
| 52c1b08e59 | |||
| 652972f49d | |||
| 0d122cf8ba | |||
| 2b115c4058 | |||
| cfca7db4ef | |||
| 5f66c029fb | |||
| 8635652fe2 | |||
| a890ad532c | |||
| 65c9d2be2a | |||
| 9620e26f6a | |||
| e4ca1d8406 | |||
| 74ebaa592b | |||
| f9b689efdb | |||
| ed458f08ad | |||
| 9822646acc | |||
| 4259078420 | |||
| 3b9db4e964 | |||
| b7e6cd08fd | |||
| bba1e6f10c | |||
| 3fe2973968 | |||
| b16d33d9fa | |||
| e1a7ed9049 | |||
| 11354030e8 | |||
| ee109060fc | |||
| eebc0c1096 | |||
| 4ec45e2a27 | |||
| 12143f7f95 | |||
| 7025dc45bd | |||
| 772e7861e2 | |||
| ff71c9a3e8 | |||
| b7001cc996 | |||
| 83658e47f8 | |||
| 0699d3ccc4 | |||
| f80b998e98 | |||
| 91e84be708 | |||
| f589c286c6 | |||
| 379650a0f5 | |||
| 3796eb46bd | |||
| c240048c5e | |||
| 2f81c9240d | |||
| da0dc3df97 | |||
| d73c0f2044 | |||
| a6f9e12082 | |||
| 1086574b33 | |||
| 58631d540c | |||
| 08763aeb2d | |||
| 039d0ca06c | |||
| f39574c8b3 | |||
| 6067a52fb1 | |||
| a1298547d1 | |||
| 6a6378f635 | |||
| 920050efc8 | |||
| 103ecc10d3 | |||
| f90e9a8085 | |||
| caa37ead4b | |||
| d18eeaf346 | |||
| b98d287843 | |||
| 66fb57f708 | |||
| 8001ce2603 | |||
| b1079e84d8 | |||
| 93126517b6 | |||
| 9687ddcd54 | |||
| 04c49cbad7 | |||
| 229eaa0859 | |||
| b2100fe0e5 | |||
| fefe29a0b8 | |||
| 6efc1e06bb | |||
| e51439d584 | |||
| 658fb8579c | |||
| f21d86c8a7 | |||
| 798c4a2089 | |||
| 0686f70df6 | |||
| 3c30564ab6 | |||
| f04070e846 | |||
| fc279839fa |
@ -192,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}"
|
||||
|
||||
@ -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,6 +583,14 @@
|
||||
android:name=".personalhome.excellentcomments.ExcellentCommentsActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".simulatorgame.SimulatorGameActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".simulatorgame.SimulatorManagementActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.PushProxyActivity"
|
||||
@ -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
@ -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
|
||||
不得故意避开或者破坏著作权人为保护本软件著作权而采取的技术措施;
|
||||
</p>
|
||||
<p>3.6.3 用户不得利用本软件误导、欺骗他人; </p>
|
||||
<p>
|
||||
3.6.4
|
||||
违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行;
|
||||
</p>
|
||||
<p>3.6.5 未经允许,进入计算机信息网络或者使用计算机信息网络资源; </p>
|
||||
<p>3.6.6 未经允许,对计算机信息网络功能进行删除、修改或者增加; </p>
|
||||
<p>
|
||||
3.6.7
|
||||
未经允许,对计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加;
|
||||
</p>
|
||||
<p>
|
||||
3.6.8
|
||||
破坏本软件系统或网站的正常运行,故意传播计算机病毒等破坏性程序;
|
||||
</p>
|
||||
<p>3.6.9 其他任何危害计算机信息网络安全的行为。 </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>
|
||||
1) 首次启动光环game 2) 评论详情-发送评论功能 3)
|
||||
视频投稿-上传视频功能 4) 视频详情-关注up主功能
|
||||
</p>
|
||||
<p><b>七、其他</b></p>
|
||||
<p>
|
||||
7.1
|
||||
本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。
|
||||
</p>
|
||||
<p>
|
||||
7.2
|
||||
如果本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,或违反任何适用的法律,则该条款被视为删除,但本协议的其余条款仍应有效并且有约束力。
|
||||
</p>
|
||||
<p>
|
||||
7.3
|
||||
光环有权随时根据有关法律、法规的变化以及公司经营状况和经营策略的调整等修改本协议。修改后的协议会在软件设置内发布。
|
||||
当发生有关争议时,以最新的协议文本为准。如果不同意改动的内容,用户可以自行删除本软件。如果用户继续使用本软件,则视为您接受本协议的变动。
|
||||
</p>
|
||||
<p> 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>
|
||||
@ -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
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -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()
|
||||
// }
|
||||
//}
|
||||
@ -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("模拟器游戏-模拟器管理")
|
||||
}
|
||||
}
|
||||
@ -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())
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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)));
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -304,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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取应用第一次安装的时间
|
||||
*/
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -563,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(
|
||||
@ -591,8 +596,6 @@ public class ShareUtils {
|
||||
smsBody = mTitle + shareUrl;
|
||||
break;
|
||||
case plugin:
|
||||
smsBody = "向你推荐:" + mTitle + "(光环加速版)_光环助手:" + shareUrl;
|
||||
break;
|
||||
case game:
|
||||
smsBody = "向你推荐:" + mTitle + "_光环助手:" + shareUrl;
|
||||
break;
|
||||
@ -606,6 +609,9 @@ public class ShareUtils {
|
||||
case communityArticle:
|
||||
smsBody = mTitle + " - 光环助手" + shareUrl;
|
||||
break;
|
||||
case qaDetail:
|
||||
smsBody = "向你推荐:" + mTitle + " @光环助手 " + shareUrl;
|
||||
break;
|
||||
default:
|
||||
smsBody = mTitle;
|
||||
break;
|
||||
@ -619,7 +625,7 @@ public class ShareUtils {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (mShareEntrance != ShareEntrance.shareGh ) {
|
||||
if (mShareEntrance != ShareEntrance.shareGh) {
|
||||
safelyDismiss();
|
||||
}
|
||||
}
|
||||
@ -746,7 +752,7 @@ public class ShareUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void safelyDismiss() {
|
||||
if (popupWindow.get() != null) {
|
||||
popupWindow.get().dismiss();
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
146
app/src/main/java/com/gh/common/view/ZoomCoordinatorLayout.java
Normal file
146
app/src/main/java/com/gh/common/view/ZoomCoordinatorLayout.java
Normal 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){
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
@ -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,6 +54,9 @@ 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, PackageManager.GET_ACTIVITIES)
|
||||
if (packageInfo == null) {
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,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(),()->{
|
||||
@ -230,7 +231,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
public void onSuccess(PrivacyPolicyEntity data) {
|
||||
DialogUtils.showPrivacyPolicyDialog(
|
||||
SplashScreenActivity.this,
|
||||
data, callback);
|
||||
PrivacyPolicyEntity.createDefaultData(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
data class EmulatorGameEntity(
|
||||
var gameName: String = "",
|
||||
var filePath: String = ""
|
||||
)
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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
|
||||
@ -160,6 +160,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
|
||||
MtaHelper.onEvent("论坛详情", getKeyValue(mLastPosition), getKeyValue(it))
|
||||
mLastPosition = it
|
||||
}
|
||||
LogUtils.uploadAccessToBbs(bbsId, "论坛详情")
|
||||
}
|
||||
|
||||
private fun getKeyValue(position: Int): String {
|
||||
|
||||
@ -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,"关注板块")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)}")
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
// 强制更改标签颜色
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -64,9 +64,13 @@ object MessageUnreadRepository {
|
||||
Observable.zip(getMessageUnread(), getDiscoveryData(), getAddonsData(), getAddonsUnreadCount(),
|
||||
Function4<Int, Int, Int, Int, Boolean> { t1, t2, t3, t4 ->
|
||||
zixunConcern.postValue(t2 > 0)
|
||||
if (isRecordData) addUnreadRecord(t1, t2, t3, t4)
|
||||
if (isRecordData) {
|
||||
addUnreadRecord(t1, t2, t3, t4)
|
||||
SPUtils.setString(Constants.SP_PRIVACY_MINE_MD5, SPUtils.getString(Constants.SP_PRIVACY_CURRENT_MD5))
|
||||
}
|
||||
val isSameAsLast = checkDataIsSameAsLast(t1, t2, t3, t4)
|
||||
unreadMessageTotal.postValue(!isSameAsLast)
|
||||
val privacyIsSame = checkPrivacyIsSame()
|
||||
unreadMessageTotal.postValue(!isSameAsLast || !privacyIsSame)
|
||||
t1 > 0 || t2 > 0 || t3 > 0 || t4 > 0
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -184,6 +188,12 @@ object MessageUnreadRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkPrivacyIsSame(): Boolean {
|
||||
val currentMd5 = SPUtils.getString(Constants.SP_PRIVACY_CURRENT_MD5)
|
||||
val mineMd5 = SPUtils.getString(Constants.SP_PRIVACY_MINE_MD5)
|
||||
return currentMd5 == mineMd5
|
||||
}
|
||||
|
||||
private fun checkDataIsSameAsLast(t1: Int, t2: Int, t3: Int, t4: Int): Boolean {
|
||||
val lastRecord = SPUtils.getString(Constants.SP_GH_RED_POINT_REMIND, "")
|
||||
val lastRecordList = if (!lastRecord.isNullOrEmpty()) {
|
||||
|
||||
@ -7,8 +7,10 @@ import com.gh.base.BaseActivity_TabLayout
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.common.util.UsageStatsHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.baselist.ListAdapter
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.GameInstall
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.personalhome.InstalledGameDialog
|
||||
|
||||
@ -36,6 +38,10 @@ class MyPlayedGameFragment : PlayedGameFragment() {
|
||||
override fun onChanged(ts: MutableList<GameEntity>?) {
|
||||
super.onChanged(ts)
|
||||
val installedList = PackagesManager.filterSameApk(PackagesManager.filterDownloadBlackPackage(PackagesManager.getInstalledList()))
|
||||
val simulatorDownloadEntityList = DownloadManager.getInstance(requireContext()).allSimulatorDownloadEntity
|
||||
simulatorDownloadEntityList.forEach { entity ->
|
||||
installedList.add(GameInstall(entity.gameId, packageName = entity.packageName, name = entity.name, icon = entity.icon))
|
||||
}
|
||||
// val count = SPUtils.getInt(Constants.SP_MARK_INSTALLED_GAME, 0)
|
||||
val isCancel = SPUtils.getBoolean(Constants.SP_MARK_INSTALLED_GAME_MY_GAME, false)
|
||||
val tabCheckIndex = activity?.intent?.getIntExtra(BaseActivity_TabLayout.PAGE_INDEX, 0) ?: 0
|
||||
|
||||
@ -320,7 +320,7 @@ public class PersonalFragment extends BaseLazyFragment {
|
||||
mPersonalBadgeIcon.setImageURI("");
|
||||
|
||||
if (badgeEntities.isEmpty()) {
|
||||
mPersonalBadgeTv.setText("领取徽章");
|
||||
mPersonalBadgeTv.setText("我的徽章");
|
||||
} else {
|
||||
mPersonalBadgeTv.setText(String.format(Locale.CHINA, "%d枚徽章", badgeEntities.size()));
|
||||
|
||||
@ -721,7 +721,7 @@ public class PersonalFragment extends BaseLazyFragment {
|
||||
mUserInfoEntity.getIcon(), mUserInfoEntity.getAuth() == null ? "" : mUserInfoEntity.getAuth().getIcon());
|
||||
ImageUtils.displayIcon(mUserIconSmall, mUserInfoEntity.getIcon());
|
||||
mPersonalUserName.setVisibility(View.VISIBLE);
|
||||
mPersonalBadge.setVisibility(View.VISIBLE);
|
||||
// mPersonalBadge.setVisibility(View.VISIBLE);
|
||||
mPersonalHome.setVisibility(View.VISIBLE);
|
||||
mPersonalLogin.setVisibility(View.GONE);
|
||||
mPersonalUserName.setText(mUserInfoEntity.getName());
|
||||
@ -736,7 +736,7 @@ public class PersonalFragment extends BaseLazyFragment {
|
||||
mPersonalBackgroundShadow.setVisibility(View.GONE);
|
||||
mUserIcon.display("", "", "");
|
||||
mUserIconSmall.setImageURI("");
|
||||
mPersonalBadgeTv.setText("领取徽章");
|
||||
mPersonalBadgeTv.setText("我的徽章");
|
||||
mPersonalUserNameSmall.setText("立即登录");
|
||||
mPersonalUserName.setVisibility(View.GONE);
|
||||
mPersonalHome.setVisibility(View.GONE);
|
||||
|
||||
@ -25,6 +25,7 @@ import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
import com.gh.gamecenter.mygame.MyGameActivity
|
||||
import com.gh.gamecenter.qa.myqa.MyAskActivity
|
||||
import com.gh.gamecenter.security.SecurityActivity
|
||||
import com.gh.gamecenter.simulatorgame.SimulatorGameActivity
|
||||
import com.gh.gamecenter.user.UserViewModel
|
||||
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
@ -56,13 +57,6 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
|
||||
ImageUtils.display(addIconIv, linkEntity.icon)
|
||||
}
|
||||
nameTv.text = linkEntity.name
|
||||
/* updateHintIv.visibility = if (linkEntity.message == "新版本") {
|
||||
mDisplayUpdateHint = true
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}*/
|
||||
|
||||
messageTips.visibility = View.GONE
|
||||
updateHintIv.visibility = View.GONE
|
||||
|
||||
@ -83,6 +77,9 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
|
||||
if (linkEntity.remind) {
|
||||
messageTips.visibility = View.VISIBLE
|
||||
}
|
||||
if (linkEntity.type == "设置" && !checkPrivacyIsSame()) {
|
||||
messageTips.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
setOnClickListener {
|
||||
directPage(linkEntity)
|
||||
@ -90,6 +87,12 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkPrivacyIsSame(): Boolean {
|
||||
val currentMd5 = SPUtils.getString(Constants.SP_PRIVACY_CURRENT_MD5)
|
||||
val settingMd5 = SPUtils.getString(Constants.SP_PRIVACY_SETTING_MD5)
|
||||
return currentMd5 == settingMd5
|
||||
}
|
||||
|
||||
private fun directPage(linkEntity: FunctionalLinkEntity) {
|
||||
if (linkEntity.remind) {
|
||||
val haveReadRecord: HashSet<String> = SPUtils.getStringSet(Constants.SP_ADDONS_FUNCS_HAVE_READ) as HashSet<String>
|
||||
@ -158,6 +161,10 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
|
||||
CheckLoginUtils.checkLogin(context, "我的光环-账号安全") {}
|
||||
}
|
||||
}
|
||||
"模拟器游戏" -> {
|
||||
MtaHelper.onEvent("我的光环", "模拟器游戏")
|
||||
context.startActivity(SimulatorGameActivity.getIntent(context))
|
||||
}
|
||||
"游戏评论" -> {
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
context.startActivity(MyRatingActivity.getIntent(context, "", "我的光环-游戏评论"))
|
||||
@ -192,6 +199,10 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
|
||||
context.startActivity(ShareGhActivity.getIntent(context))
|
||||
}
|
||||
"设置" -> {
|
||||
if (!checkPrivacyIsSame()) {
|
||||
SPUtils.setString(Constants.SP_PRIVACY_SETTING_MD5, SPUtils.getString(Constants.SP_PRIVACY_CURRENT_MD5))
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
MtaHelper.onEvent("我的光环", "设置图标")
|
||||
DataCollectionUtils.uploadClick(context, "设置图标", "我的光环")
|
||||
context.startActivity(SettingActivity.getIntent(context, mDisplayUpdateHint, "(我的光环)"))
|
||||
|
||||
@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.FunctionalGroupEntity
|
||||
import com.gh.gamecenter.entity.FunctionalLinkEntity
|
||||
@ -16,13 +18,14 @@ class PersonalViewModel(application: Application) : AndroidViewModel(application
|
||||
|
||||
var haloAddData = MutableLiveData<ArrayList<FunctionalGroupEntity>>()
|
||||
private val commonFuncs = arrayListOf(
|
||||
Triple("我的游戏", R.drawable.personal_my_game, "我的游戏"),
|
||||
Triple("游戏评论", R.drawable.personal_game_comment, "游戏评论"),
|
||||
Triple("我的问答", R.drawable.personal_my_questions, "我的问答"),
|
||||
// Triple("我的游戏", R.drawable.personal_my_game, "我的游戏"),
|
||||
// Triple("游戏评论", R.drawable.personal_game_comment, "游戏评论"),
|
||||
// Triple("我的问答", R.drawable.personal_my_questions, "我的问答"),
|
||||
Triple("视频投稿", R.drawable.personal_video_submission, "视频投稿"),
|
||||
Triple("我的收藏", R.drawable.personal_my_collect, "我的收藏"),
|
||||
Triple("浏览记录", R.drawable.personal_browsing_history, "浏览记录"),
|
||||
Triple("账号安全", R.drawable.personal_account_security, "账号安全")
|
||||
// Triple("模拟器游戏", R.drawable.personal_simulator_game, "模拟器游戏")
|
||||
)
|
||||
private val contentCenterFuncs = arrayListOf(
|
||||
Triple("游戏动态", R.drawable.personal_game_dynamic, "游戏动态"),
|
||||
@ -31,10 +34,10 @@ class PersonalViewModel(application: Application) : AndroidViewModel(application
|
||||
Triple("工具箱", R.drawable.personal_tools, "工具箱")
|
||||
)
|
||||
private val otherFuncs = arrayListOf(
|
||||
Triple("帮助与反馈", R.drawable.personal_feedback, "帮助与反馈"),
|
||||
// Triple("帮助与反馈", R.drawable.personal_feedback, "帮助与反馈"),
|
||||
Triple("实名认证", R.drawable.personal_verified, "实名认证"),
|
||||
Triple("微信提醒", R.drawable.personal_wechat_remind, "微信提醒"),
|
||||
Triple("安装包清理", R.drawable.personal_package_chean, "安装包清理"),
|
||||
// Triple("微信提醒", R.drawable.personal_wechat_remind, "微信提醒"),
|
||||
// Triple("安装包清理", R.drawable.personal_package_chean, "安装包清理"),
|
||||
Triple("分享光环", R.drawable.personal_share, "分享光环"),
|
||||
Triple("设置", R.drawable.personal_setting, "设置")
|
||||
)
|
||||
@ -45,15 +48,24 @@ class PersonalViewModel(application: Application) : AndroidViewModel(application
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getHaloAddons() {
|
||||
RetrofitManager.getInstance(getApplication())
|
||||
.api.haloAddons
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ArrayList<FunctionalGroupEntity>>() {
|
||||
override fun onSuccess(data: ArrayList<FunctionalGroupEntity>) {
|
||||
haloAddData.postValue(data)
|
||||
}
|
||||
})
|
||||
// RetrofitManager.getInstance(getApplication())
|
||||
// .api.haloAddons
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(object : BiResponse<ArrayList<FunctionalGroupEntity>>() {
|
||||
// override fun onSuccess(data: ArrayList<FunctionalGroupEntity>) {
|
||||
// haloAddData.postValue(data)
|
||||
// data.forEach loop@{
|
||||
// it.addons.forEach { link ->
|
||||
// if (link.type == "设置") {
|
||||
// SPUtils.setString(Constants.SP_PRIVACY_CURRENT_MD5, link.checkSum?.privacyPolicy
|
||||
// ?: "")
|
||||
// return@loop
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
private fun initDefaultData() {
|
||||
@ -68,14 +80,14 @@ class PersonalViewModel(application: Application) : AndroidViewModel(application
|
||||
}
|
||||
datas.add(groupEntity1)
|
||||
|
||||
val groupEntity2 = FunctionalGroupEntity(name = "内容中心")
|
||||
contentCenterFuncs.forEach {
|
||||
groupEntity2.addons.add(FunctionalLinkEntity(iconRes = it.second).apply {
|
||||
name = it.first
|
||||
type = it.third
|
||||
})
|
||||
}
|
||||
datas.add(groupEntity2)
|
||||
// val groupEntity2 = FunctionalGroupEntity(name = "内容中心")
|
||||
// contentCenterFuncs.forEach {
|
||||
// groupEntity2.addons.add(FunctionalLinkEntity(iconRes = it.second).apply {
|
||||
// name = it.first
|
||||
// type = it.third
|
||||
// })
|
||||
// }
|
||||
// datas.add(groupEntity2)
|
||||
|
||||
val groupEntity3 = FunctionalGroupEntity(name = "其它功能")
|
||||
otherFuncs.forEach {
|
||||
|
||||
@ -7,9 +7,7 @@ import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.dialog.TrackableDialog
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.view.SpacingItemDecoration
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.GameInstall
|
||||
@ -51,14 +49,16 @@ class InstalledGameDialog(val mContext: Context, val games: ArrayList<GameInstal
|
||||
dismiss()
|
||||
}
|
||||
view.dialog_ok.setOnClickListener {
|
||||
MtaHelper.onEvent(mEvent, mKey, "点击确定")
|
||||
// SPUtils.setInt(Constants.SP_MARK_INSTALLED_GAME, 2)
|
||||
if (mEvent == "个人主页详情") {
|
||||
SPUtils.setBoolean(Constants.SP_MARK_INSTALLED_GAME_USER_HOME,true)
|
||||
} else {
|
||||
SPUtils.setBoolean(Constants.SP_MARK_INSTALLED_GAME_MY_GAME,true)
|
||||
debounceActionWithInterval(it.id, 2000L) {
|
||||
MtaHelper.onEvent(mEvent, mKey, "点击确定")
|
||||
// SPUtils.setInt(Constants.SP_MARK_INSTALLED_GAME, 2)
|
||||
if (mEvent == "个人主页详情") {
|
||||
SPUtils.setBoolean(Constants.SP_MARK_INSTALLED_GAME_USER_HOME, true)
|
||||
} else {
|
||||
SPUtils.setBoolean(Constants.SP_MARK_INSTALLED_GAME_MY_GAME, true)
|
||||
}
|
||||
postPlayedGames()
|
||||
}
|
||||
postPlayedGames()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
package com.gh.gamecenter.personalhome
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CheckedTextView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
@ -20,6 +22,7 @@ import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DirectUtils.directToBadgeWall
|
||||
import com.gh.common.view.HorizontalItemDecoration
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.*
|
||||
import com.gh.gamecenter.databinding.FragmentHomeBinding
|
||||
import com.gh.gamecenter.entity.*
|
||||
@ -56,6 +59,7 @@ class UserHomeFragment : NormalFragment() {
|
||||
private lateinit var mMessageUnreadViewModel: MessageUnreadViewModel
|
||||
private lateinit var mDialog: InstalledGameDialog
|
||||
private lateinit var mPersonalEntity: PersonalEntity
|
||||
private lateinit var mBitmap: Bitmap
|
||||
private var mBadgeCount = 0
|
||||
private var mPlayGameCount = 0
|
||||
|
||||
@ -85,7 +89,8 @@ class UserHomeFragment : NormalFragment() {
|
||||
getUserPlayedGameCount()
|
||||
}
|
||||
|
||||
mHomeBinding?.userBadge?.visibleIf(mUserHomeViewModel.userId == UserManager.getInstance().userId)
|
||||
mHomeBinding?.container?.setZoomView(mHomeBinding?.userBackgroundContainer)
|
||||
// mHomeBinding?.userBadge?.visibleIf(mUserHomeViewModel.userId == UserManager.getInstance().userId)
|
||||
|
||||
mUserHomeViewModel.userInfo.observeNonNull(this) {
|
||||
// 区分是数据初始化还是数据更新
|
||||
@ -114,6 +119,7 @@ class UserHomeFragment : NormalFragment() {
|
||||
mBadgeCount = it.size
|
||||
|
||||
if (it.isNotEmpty()) {
|
||||
mHomeBinding?.badgeContainer?.visibility = View.VISIBLE
|
||||
mHomeBinding?.badgeTv?.text = String.format(Locale.CHINA, "%d枚徽章", it.size)
|
||||
run outside@{
|
||||
it.forEach { badge ->
|
||||
@ -129,7 +135,7 @@ class UserHomeFragment : NormalFragment() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mHomeBinding?.badgeTv?.text = "领取徽章"
|
||||
mHomeBinding?.badgeContainer?.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (mUserHomeViewModel.userId == UserManager.getInstance().userId) {
|
||||
@ -174,6 +180,10 @@ class UserHomeFragment : NormalFragment() {
|
||||
showPlayedGames(it)
|
||||
}
|
||||
val installedList = PackagesManager.filterSameApk(PackagesManager.filterDownloadBlackPackage(PackagesManager.getInstalledList()))
|
||||
val simulatorDownloadEntityList = DownloadManager.getInstance(requireContext()).allSimulatorDownloadEntity
|
||||
simulatorDownloadEntityList.forEach { entity ->
|
||||
installedList.add(GameInstall(entity.gameId, packageName = entity.packageName, name = entity.name, icon = entity.icon))
|
||||
}
|
||||
//val count = SPUtils.getInt(Constants.SP_MARK_INSTALLED_GAME, 0)
|
||||
val isCancel = SPUtils.getBoolean(Constants.SP_MARK_INSTALLED_GAME_USER_HOME, false)
|
||||
if (mUserHomeViewModel.userId == UserManager.getInstance().userId
|
||||
@ -218,18 +228,22 @@ class UserHomeFragment : NormalFragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mHomeBinding?.run {
|
||||
val statusBarHeight = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) 0 else DisplayUtils.getStatusBarHeight(resources)
|
||||
val params: ViewGroup.LayoutParams = toolbar.layoutParams
|
||||
params.height = DisplayUtils.dip2px(50f) + statusBarHeight
|
||||
toolbar.layoutParams = params
|
||||
|
||||
appbar.addOnOffsetChangedListener(OnOffsetChangedListener { _: AppBarLayout?, verticalOffset: Int ->
|
||||
val statusBarHeight = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) 0 else DisplayUtils.getStatusBarHeight(resources)
|
||||
val absOffset = abs(verticalOffset)
|
||||
val invisibleOffset = DisplayUtils.dip2px(240f - statusBarHeight)
|
||||
if (absOffset <= invisibleOffset) {
|
||||
val invisibleOffset = 264f.dip2px() - 50f.dip2px() - 2f.dip2px() - statusBarHeight
|
||||
if (absOffset < invisibleOffset) {
|
||||
toolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.transparent))
|
||||
toolbarContainer.background = null
|
||||
userSmallContainer.visibility = View.GONE
|
||||
} else {
|
||||
toolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.theme))
|
||||
if (this@UserHomeFragment::mBitmap.isInitialized) {
|
||||
toolbar.setBackgroundColor(R.color.white.toColor())
|
||||
toolbarContainer.background = BitmapDrawable(resources, mBitmap)
|
||||
} else {
|
||||
toolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.theme))
|
||||
}
|
||||
userSmallContainer.visibility = View.VISIBLE
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -299,7 +313,7 @@ class UserHomeFragment : NormalFragment() {
|
||||
|
||||
val adapter = UserHomePlayedGameAdapter(playedGames)
|
||||
|
||||
playedGameContainer.visibility = View.VISIBLE
|
||||
playedGameContainer.visibility = View.GONE
|
||||
playedGameRecyclerView.adapter = adapter
|
||||
playedGameRecyclerView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
||||
playedGameRecyclerView.addItemDecoration(HorizontalItemDecoration(requireContext(), 24, playedGames.size, true))
|
||||
@ -333,6 +347,27 @@ class UserHomeFragment : NormalFragment() {
|
||||
// }
|
||||
// }
|
||||
|
||||
// 截取背景图片,供toolbar使用
|
||||
if (!personalData.background?.url.isNullOrEmpty()) {
|
||||
ImageUtils.getBitmap(personalData.background?.url ?: "", object : BiCallback<Bitmap, Boolean> {
|
||||
override fun onFirst(first: Bitmap) {
|
||||
userBackground.postDelayed({
|
||||
if (!requireActivity().isFinishing && !isStateSaved) {
|
||||
val statusBarHeight = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) 0 else DisplayUtils.getStatusBarHeight(resources)
|
||||
val bitmap = getBitmapFromView(userBackground)
|
||||
bitmap?.let {
|
||||
mBitmap = Bitmap.createBitmap(it, 0, it.height - statusBarHeight - 50f.dip2px(), it.width, statusBarHeight + 50f.dip2px())
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
override fun onSecond(second: Boolean) {
|
||||
Utils.log("获取背景图片失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 设置有边框挂件的头像
|
||||
userIcon.display(personalData.iconBorder?.url, personalData.icon, personalData.auth?.icon)
|
||||
|
||||
@ -468,4 +503,11 @@ class UserHomeFragment : NormalFragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getBitmapFromView(view: View): Bitmap? {
|
||||
var bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
|
||||
var canvas = Canvas(bitmap)
|
||||
view.draw(canvas)
|
||||
return bitmap
|
||||
}
|
||||
}
|
||||
@ -3,11 +3,22 @@ package com.gh.gamecenter.personalhome.background
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.facebook.binaryresource.BinaryResource
|
||||
import com.facebook.binaryresource.FileBinaryResource
|
||||
import com.facebook.cache.common.CacheKey
|
||||
import com.facebook.imagepipeline.cache.DefaultCacheKeyFactory
|
||||
import com.facebook.imagepipeline.core.ImagePipelineFactory
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
||||
import com.gh.common.util.BiCallback
|
||||
import com.gh.common.util.BitmapUtils
|
||||
import com.gh.common.util.ImageUtils
|
||||
import com.gh.gamecenter.entity.BackgroundImageEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
@ -19,7 +30,7 @@ import java.io.File
|
||||
|
||||
class PersonalityBackgroundViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
val loadingLiveData= MutableLiveData<Boolean>()
|
||||
val loadingLiveData = MutableLiveData<Boolean>()
|
||||
val backgroundImagesLiveData = MutableLiveData<ArrayList<BackgroundImageEntity>>()
|
||||
|
||||
init {
|
||||
@ -45,13 +56,16 @@ class PersonalityBackgroundViewModel(application: Application) : AndroidViewMode
|
||||
fun downLoadImage(context: Context, entity: BackgroundImageEntity) {
|
||||
loadingLiveData.postValue(true)
|
||||
Single.just(entity.url)
|
||||
.map {
|
||||
Picasso.with(getApplication()).load(Uri.parse(it)).priority(Picasso.Priority.HIGH).get()
|
||||
.flatMap {
|
||||
getBitmapFormCache(it)
|
||||
}
|
||||
.map {
|
||||
val fileName = entity.url.substring(entity.url.lastIndexOf("/") + 1)
|
||||
val filePath: String = "${context.cacheDir.absolutePath}${File.separator}$fileName"
|
||||
BitmapUtils.saveBitmap(it, filePath)
|
||||
val filePath = "${context.cacheDir.absolutePath}${File.separator}$fileName"
|
||||
val file = File(filePath)
|
||||
if (!file.exists()) {
|
||||
BitmapUtils.saveBitmap(it, filePath)
|
||||
}
|
||||
filePath
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -65,4 +79,19 @@ class PersonalityBackgroundViewModel(application: Application) : AndroidViewMode
|
||||
loadingLiveData.postValue(false)
|
||||
})
|
||||
}
|
||||
|
||||
private fun getBitmapFormCache(url: String): Single<Bitmap> {
|
||||
return Single.create {
|
||||
ImageUtils.getBitmap(url, object : BiCallback<Bitmap, Boolean> {
|
||||
override fun onFirst(first: Bitmap) {
|
||||
it.onSuccess(first)
|
||||
}
|
||||
|
||||
override fun onSecond(second: Boolean) {
|
||||
it.onError(Throwable("获取bitmap失败"))
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,8 +44,6 @@ class UserCommentHistoryViewModel(application: Application, var userId: String)
|
||||
|
||||
val itemDataList = arrayListOf<UserCommentHistoryItemData>()
|
||||
|
||||
mResultLiveData.postValue(itemDataList)
|
||||
|
||||
if (mExcellentComments == null) {
|
||||
mApi.getExcellentComments(userId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -96,6 +96,7 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
|
||||
forumNameTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), if (entity.bbs.name.isEmpty()) entity.community.name else entity.bbs.name)
|
||||
itemView.context.startActivity(ForumDetailActivity.getIntent(itemView.context, entity.community.id, entrance))
|
||||
LogUtils.uploadAccessToBbs(entity.community.id, "文章外所属论坛")
|
||||
}
|
||||
|
||||
commentCountContainer.setOnClickListener {
|
||||
|
||||
@ -282,6 +282,7 @@ class ArticleDetailContentViewHolder(var binding: ItemArticleDetailContentBindin
|
||||
tagTv.setOnClickListener {
|
||||
MtaHelper.onEvent("帖子详情", "内容区域", tag)
|
||||
DirectUtils.directForumDetail(tagTv.context, viewModel.detailEntity?.communityId, "帖子详情")
|
||||
LogUtils.uploadAccessToBbs(viewModel.detailEntity?.communityId, "文章内所属论坛")
|
||||
}
|
||||
} else {
|
||||
tagTv.setPadding(14F.dip2px(), 5F.dip2px(), 14F.dip2px(), 5F.dip2px())
|
||||
|
||||
@ -59,6 +59,7 @@ import com.gh.gamecenter.entity.ServersGameCategory;
|
||||
import com.gh.gamecenter.entity.SettingsEntity;
|
||||
import com.gh.gamecenter.entity.SignEntity;
|
||||
import com.gh.gamecenter.entity.SimpleGameEntity;
|
||||
import com.gh.gamecenter.entity.SimulatorEntity;
|
||||
import com.gh.gamecenter.entity.SubjectEntity;
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity;
|
||||
import com.gh.gamecenter.entity.SubjectRefreshEntity;
|
||||
@ -2672,4 +2673,51 @@ public interface ApiService {
|
||||
@GET("users/icon_borders")
|
||||
Observable<ArrayList<AvatarBorderEntity>> getPendants();
|
||||
|
||||
/**
|
||||
* 记录设备下载的模拟器游戏
|
||||
*/
|
||||
@POST("devices/{device_id}/download_simulator_games")
|
||||
Single<ResponseBody> downloadSimulatorGames(@Path("device_id") String deviceId, @Body RequestBody body);
|
||||
|
||||
/**
|
||||
* 删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@DELETE("devices/{device_id}/download_simulator_games/{game_id}")
|
||||
Single<ResponseBody> deleteSimulatorGame(@Path("device_id") String deviceId, @Path("game_id") String gameId);
|
||||
|
||||
/**
|
||||
* 批量删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@POST("devices/{device_id}/download_simulator_games:batch_delete")
|
||||
Single<ResponseBody> deleteSimulatorGames(@Path("device_id") String deviceId, @Body RequestBody body);
|
||||
|
||||
/**
|
||||
* 删除设备所有模拟器游戏的记录
|
||||
*/
|
||||
@POST("devices/{device_id}/download_simulator_games:batch_delete?type=all")
|
||||
Single<ResponseBody> deleteAllSimulatorGame(@Path("device_id") String deviceId);
|
||||
|
||||
/**
|
||||
* 启动设备上的模拟器游戏
|
||||
*/
|
||||
@POST("devices/{device_id}/played_simulator_games")
|
||||
Single<ResponseBody> playedSimulatorGames(@Path("device_id") String deviceId, @Body RequestBody body);
|
||||
|
||||
/**
|
||||
* 获取后台模拟器列表
|
||||
*/
|
||||
@GET("games/simulators")
|
||||
Single<List<SimulatorEntity>> getSimulators();
|
||||
|
||||
/**
|
||||
* 获取设备下载的模拟器游戏的类型
|
||||
*/
|
||||
@GET("devices/{device_id}/simulator_types")
|
||||
Single<List<String>> getDeviceSimulatorTypes(@Path("device_id") String deviceId);
|
||||
|
||||
/**
|
||||
* 获取设备下载的模拟器游戏列表
|
||||
*/
|
||||
@GET("devices/{device_id}/download_simulator_games")
|
||||
Single<List<GameEntity>> getSimulatorGames(@Path("device_id") String deviceId, @Query("page") int page, @Query("filter") String filter);
|
||||
}
|
||||
@ -79,7 +79,9 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
mHotSearchList = Config.getSettings()?.search?.hotSearch?.apply {
|
||||
for (hotSearch in this) {
|
||||
hotSearch.exposureEvent = ExposureEvent.createEvent(hotSearch.toGameEntity(), listOf(ExposureSource("首页搜索"), ExposureSource("热门搜索")))
|
||||
hotSearch.name = hotSearch.name.removeSuffix(".") + (hotSearch.nameSuffix ?: "")
|
||||
if (!hotSearch.name.endsWith(hotSearch.nameSuffix ?: "")) {
|
||||
hotSearch.name = hotSearch.name.removeSuffix(".") + (hotSearch.nameSuffix ?: "")
|
||||
}
|
||||
ExposureManager.log(hotSearch.exposureEvent!!)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.util.ImageUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.SearchDefaultHotItemBinding
|
||||
import com.gh.gamecenter.entity.SettingsEntity
|
||||
@ -31,6 +30,10 @@ class SearchDefaultHotAdapter(context: Context,
|
||||
|
||||
icon.displayGameIcon(hotSearch.rawIcon ?: hotSearch.icon, hotSearch.iconSubscript)
|
||||
|
||||
if (!name.isSelected) {
|
||||
name.postDelayed({ name.isSelected = true }, 500)
|
||||
}
|
||||
|
||||
index.text = (position + 1).toString()
|
||||
when (position) {
|
||||
0 -> {
|
||||
|
||||
@ -29,8 +29,7 @@ import com.gh.gamecenter.game.GameItemViewHolder
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
|
||||
class SearchGameIndexAdapter(context: Context,
|
||||
val fragment: SearchGameIndexFragment,
|
||||
@ -118,12 +117,14 @@ class SearchGameIndexAdapter(context: Context,
|
||||
|
||||
GameDetailActivity.startGameDetailActivity(mContext, gameEntity,
|
||||
StringUtils.buildString(entrance, "+(搜索-列表[", key, "=", "$type=",
|
||||
(holder.getAdapterPosition() + 1).toString(), "])"))
|
||||
(holder.getAdapterPosition() + 1).toString(), "])"), exposureEvent)
|
||||
|
||||
dao.add(gameEntity.nameWithoutSuffix)
|
||||
|
||||
LogUtils.uploadSearchClick("search_click", "搜索页", key, SearchType.fromString(type).toChinese(), gameEntity.id, gameEntity.name)
|
||||
}
|
||||
|
||||
DownloadItemUtils.setOnClickListener(
|
||||
DownloadItemUtils.setOnClickListenerWithInvokeCallbackForAllState(
|
||||
mContext,
|
||||
binding.downloadBtn,
|
||||
gameEntity,
|
||||
@ -143,6 +144,8 @@ class SearchGameIndexAdapter(context: Context,
|
||||
if (SearchType.fromString(type) == SearchType.AUTO) {
|
||||
// MtaHelper.onEvent("游戏搜索", "自动搜索", key)
|
||||
}
|
||||
|
||||
LogUtils.uploadSearchClick("search_click", "搜索页", key, SearchType.fromString(type).toChinese(), gameEntity.id, gameEntity.name)
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -163,6 +166,8 @@ class SearchGameIndexAdapter(context: Context,
|
||||
StringUtils.buildString(entrance, "+(搜索-列表[", key, "=", type, "=",
|
||||
(holder.getAdapterPosition() + 1).toString(), "])"), exposureEvent)
|
||||
dao.add(gameEntity.nameWithoutSuffix)
|
||||
|
||||
LogUtils.uploadSearchClick("search_click", "搜索页", key, SearchType.fromString(type).toChinese(), gameEntity.id, gameEntity.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.common.xapk.XapkUnzipStatus
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchType
|
||||
import com.gh.gamecenter.SuggestionActivity
|
||||
import com.gh.gamecenter.baselist.ListFragment
|
||||
import com.gh.gamecenter.baselist.NormalListViewModel
|
||||
@ -131,8 +132,14 @@ class SearchGameIndexFragment : ListFragment<GameEntity, NormalListViewModel<Gam
|
||||
@OnClick(R.id.reuse_no_connection, R.id.reuse_nodata_skip_function, R.id.reuse_nodata_skip_game)
|
||||
override fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.reuse_nodata_skip_function -> SuggestionActivity.startSuggestionActivity(context, SuggestType.functionSuggest, "求功能:")
|
||||
R.id.reuse_nodata_skip_game -> SuggestionActivity.startSuggestionActivity(context, SuggestType.gameCollect, " 求游戏:")
|
||||
R.id.reuse_nodata_skip_function -> {
|
||||
LogUtils.uploadSearchGame("ask_more_func", "搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(context, SuggestType.functionSuggest, "求功能:")
|
||||
}
|
||||
R.id.reuse_nodata_skip_game -> {
|
||||
LogUtils.uploadSearchGame("ask_more_games", "搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(context, SuggestType.gameCollect, " 求游戏:")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,6 +168,7 @@ class SearchGameIndexFragment : ListFragment<GameEntity, NormalListViewModel<Gam
|
||||
val clickableSpan = object : ClickableSpan() {
|
||||
override fun onClick(widget: View?) {
|
||||
MtaHelper.onEvent("广告位统计", "搜索结果为空", ad.title)
|
||||
LogUtils.uploadSearchGame("click_ad", " 搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
DirectUtils.directToLinkPage(requireContext(), ad.toLinkEntity(), "(搜索结果为空-广告位)", "")
|
||||
}
|
||||
|
||||
|
||||
@ -96,8 +96,14 @@ class SearchGameResultAdapter(context: Context,
|
||||
}
|
||||
|
||||
private fun bindFooterItem(holder: SearchGameFooterViewHolder) {
|
||||
holder.binding.skipFunction.setOnClickListener { SuggestionActivity.startSuggestionActivity(mContext, SuggestType.functionSuggest, "求功能:") }
|
||||
holder.binding.skipGame.setOnClickListener { SuggestionActivity.startSuggestionActivity(mContext, SuggestType.gameCollect, "求游戏:") }
|
||||
holder.binding.skipFunction.setOnClickListener {
|
||||
LogUtils.uploadSearchGame("ask_more_func", " 搜索页", key, SearchType.fromString(type).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(mContext, SuggestType.functionSuggest, "求功能:")
|
||||
}
|
||||
holder.binding.skipGame.setOnClickListener {
|
||||
LogUtils.uploadSearchGame("ask_more_games", " 搜索页", key, SearchType.fromString(type).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(mContext, SuggestType.gameCollect, "求游戏:")
|
||||
}
|
||||
fragment.showAd(holder.binding.hintText, true)
|
||||
}
|
||||
|
||||
@ -131,12 +137,14 @@ class SearchGameResultAdapter(context: Context,
|
||||
exposureEvent)
|
||||
mDao.add(gameEntity.nameWithoutSuffix)
|
||||
|
||||
LogUtils.uploadSearchClick("search_click", "搜索页", key, SearchType.fromString(type).toChinese(), gameEntity.id, gameEntity.name)
|
||||
|
||||
if (SearchType.fromString(type) == SearchType.AUTO) {
|
||||
// MtaHelper.onEvent("游戏搜索", "自动搜索", key)
|
||||
}
|
||||
|
||||
}
|
||||
DownloadItemUtils.setOnClickListener(
|
||||
DownloadItemUtils.setOnClickListenerWithInvokeCallbackForAllState(
|
||||
mContext,
|
||||
binding.downloadBtn,
|
||||
gameEntity,
|
||||
@ -154,6 +162,8 @@ class SearchGameResultAdapter(context: Context,
|
||||
searchMap[gameEntity.id] = gameEntity.name
|
||||
}
|
||||
|
||||
LogUtils.uploadSearchClick("search_click", "搜索页", key, SearchType.fromString(type).toChinese(), gameEntity.id, gameEntity.name)
|
||||
|
||||
if (SearchType.fromString(type) == SearchType.AUTO) {
|
||||
// MtaHelper.onEvent("游戏搜索", "自动搜索", key)
|
||||
}
|
||||
|
||||
@ -10,7 +10,11 @@ import android.text.style.ClickableSpan
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.TranslateAnimation
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
@ -24,6 +28,7 @@ import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.common.xapk.XapkUnzipStatus
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchType
|
||||
import com.gh.gamecenter.SuggestionActivity
|
||||
import com.gh.gamecenter.baselist.ListFragment
|
||||
import com.gh.gamecenter.baselist.NormalListViewModel
|
||||
@ -43,18 +48,30 @@ class SearchGameResultFragment : ListFragment<GameEntity, NormalListViewModel<Ga
|
||||
|
||||
@BindView(R.id.reuse_none_data)
|
||||
lateinit var mSearchNoData: LinearLayout
|
||||
|
||||
@BindView(R.id.reuse_tv_none_data)
|
||||
lateinit var mSearchNoDataTv: TextView
|
||||
|
||||
@BindView(R.id.search_move_button)
|
||||
lateinit var mMoveButton: TextView
|
||||
@BindView(R.id.container_menu_close)
|
||||
lateinit var mCloseMenuContainer: RelativeLayout
|
||||
@BindView(R.id.container_menu_open)
|
||||
lateinit var mOpenMenuContainer: RelativeLayout
|
||||
@BindView(R.id.blank)
|
||||
lateinit var mBlankView: View
|
||||
@BindView(R.id.seek_game_btn)
|
||||
lateinit var mSeekGameBtn: TextView
|
||||
@BindView(R.id.seek_function_btn)
|
||||
lateinit var mSeekFunctionBtn: TextView
|
||||
@BindView(R.id.menu_view)
|
||||
lateinit var mMenuView: ImageView
|
||||
|
||||
private var mAdapter: SearchGameResultAdapter? = null
|
||||
private var mExposureListener: ExposureListener? = null
|
||||
private lateinit var mShowAction: Animation
|
||||
private lateinit var mHideAction: Animation
|
||||
|
||||
private var mKey: String = ""
|
||||
private var mType: String = ""
|
||||
private var mLoadingAnimation = false
|
||||
private var mScrollIng = false
|
||||
|
||||
private var mOnGlobalLayoutListener: ViewTreeObserver.OnGlobalLayoutListener? = null
|
||||
|
||||
@ -116,20 +133,106 @@ class SearchGameResultFragment : ListFragment<GameEntity, NormalListViewModel<Ga
|
||||
mExposureListener = ExposureListener(this, mAdapter!!)
|
||||
mListRv!!.addOnScrollListener(mExposureListener!!)
|
||||
mListRv!!.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
mScrollIng = false
|
||||
mCloseMenuContainer.alpha = 1F
|
||||
} else {
|
||||
mScrollIng = true
|
||||
if (mCloseMenuContainer.visibility == View.VISIBLE) {
|
||||
mCloseMenuContainer.alpha = 0.5F
|
||||
} else {
|
||||
mCloseMenuContainer.postDelayed({
|
||||
mCloseMenuContainer.alpha = 0.5F
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
if (mOpenMenuContainer.visibility == View.VISIBLE && !mLoadingAnimation) {
|
||||
showCloseMenuView()
|
||||
}
|
||||
val position = mLayoutManager!!.findLastVisibleItemPosition()
|
||||
if (position == mAdapter!!.itemCount - 1) {
|
||||
val child = mLayoutManager!!.findViewByPosition(position)
|
||||
if (child != null && recyclerView.bottom - child.bottom > -DisplayUtils.dip2px(50f) && mAdapter?.isLoadOver() == true) {
|
||||
mMoveButton.visibility = View.GONE
|
||||
mCloseMenuContainer.visibility = View.GONE
|
||||
} else {
|
||||
mMoveButton.visibility = View.VISIBLE
|
||||
mCloseMenuContainer.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
mMoveButton.visibility = View.VISIBLE
|
||||
if (!mLoadingAnimation) mCloseMenuContainer.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
initAnimation()
|
||||
}
|
||||
|
||||
private fun initAnimation() {
|
||||
mShowAction = TranslateAnimation(Animation.RELATIVE_TO_SELF,
|
||||
1.0F, Animation.RELATIVE_TO_SELF, 0.0F,
|
||||
Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,
|
||||
0.0F)
|
||||
mShowAction.duration = 300
|
||||
mShowAction.setAnimationListener(object : Animation.AnimationListener {
|
||||
override fun onAnimationStart(animation: Animation?) {
|
||||
mLoadingAnimation = true
|
||||
mCloseMenuContainer.background = null
|
||||
mBlankView.visibility = View.VISIBLE
|
||||
mMenuView.setImageResource(R.drawable.ic_search_menu_selected)
|
||||
}
|
||||
|
||||
override fun onAnimationRepeat(animation: Animation?) {}
|
||||
|
||||
override fun onAnimationEnd(animation: Animation?) {
|
||||
mLoadingAnimation = false
|
||||
mCloseMenuContainer.visibility = View.GONE
|
||||
mSeekFunctionBtn.postDelayed({
|
||||
mSeekFunctionBtn.visibility = View.VISIBLE
|
||||
}, 100)
|
||||
mSeekGameBtn.postDelayed({
|
||||
mSeekGameBtn.visibility = View.VISIBLE
|
||||
}, 130)
|
||||
}
|
||||
})
|
||||
|
||||
mHideAction = TranslateAnimation(Animation.RELATIVE_TO_SELF,
|
||||
0.0F, Animation.RELATIVE_TO_SELF, 1.0F,
|
||||
Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,
|
||||
0.0F)
|
||||
mHideAction.duration = 300
|
||||
mHideAction.setAnimationListener(object : Animation.AnimationListener {
|
||||
override fun onAnimationStart(animation: Animation?) {
|
||||
mLoadingAnimation = true
|
||||
|
||||
mCloseMenuContainer.visibility = View.VISIBLE
|
||||
mSeekGameBtn.visibility = View.INVISIBLE
|
||||
mSeekFunctionBtn.visibility = View.INVISIBLE
|
||||
mCloseMenuContainer.postDelayed({
|
||||
mBlankView.visibility = View.GONE
|
||||
mCloseMenuContainer.setBackgroundResource(R.drawable.bg_search_menu)
|
||||
mMenuView.setImageResource(R.drawable.ic_search_menu_unselect)
|
||||
mOpenMenuContainer.visibility = View.GONE
|
||||
}, 200)
|
||||
}
|
||||
|
||||
override fun onAnimationRepeat(animation: Animation?) {}
|
||||
|
||||
override fun onAnimationEnd(animation: Animation?) {
|
||||
mLoadingAnimation = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun showOpenMenuView() {
|
||||
mOpenMenuContainer.startAnimation(mShowAction)
|
||||
mOpenMenuContainer.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun showCloseMenuView() {
|
||||
mOpenMenuContainer.startAnimation(mHideAction)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -137,20 +240,46 @@ class SearchGameResultFragment : ListFragment<GameEntity, NormalListViewModel<Ga
|
||||
activity?.window?.decorView?.viewTreeObserver?.removeOnGlobalLayoutListener(mOnGlobalLayoutListener)
|
||||
}
|
||||
|
||||
@OnClick(R.id.reuse_nodata_skip_function, R.id.reuse_nodata_skip_game, R.id.search_move_button)
|
||||
@OnClick(R.id.reuse_nodata_skip_function, R.id.reuse_nodata_skip_game, R.id.container_menu_close,
|
||||
R.id.seek_game_btn, R.id.seek_function_btn, R.id.container_menu_open)
|
||||
override fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.reuse_nodata_skip_function -> {
|
||||
MtaHelper.onEvent("游戏搜索", "求功能", mKey)
|
||||
LogUtils.uploadSearchGame("ask_more_func", "搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(context, SuggestType.functionSuggest, "求功能:")
|
||||
}
|
||||
|
||||
R.id.reuse_nodata_skip_game -> {
|
||||
MtaHelper.onEvent("游戏搜索", "求游戏", mKey)
|
||||
LogUtils.uploadSearchGame("ask_more_games", "搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(context, SuggestType.gameCollect, "求游戏:")
|
||||
}
|
||||
R.id.search_move_button -> {
|
||||
MtaHelper.onEvent("游戏搜索", "找不到想要的游戏", mKey)
|
||||
mListRv.smoothScrollToPosition(mAdapter!!.itemCount - 1)
|
||||
|
||||
R.id.container_menu_close -> {
|
||||
if (mScrollIng) return
|
||||
LogUtils.uploadSearchGame("open_floating_window", "搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
showOpenMenuView()
|
||||
}
|
||||
|
||||
R.id.container_menu_open -> {
|
||||
if (mScrollIng) return
|
||||
LogUtils.uploadSearchGame("close_floating_window", "搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
showCloseMenuView()
|
||||
}
|
||||
|
||||
R.id.seek_game_btn -> {
|
||||
MtaHelper.onEvent("游戏搜索", "求游戏", mKey)
|
||||
LogUtils.uploadSearchGame("ask_more_games", " 搜索页-悬浮按钮", mKey, SearchType.fromString(mType).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(context, SuggestType.gameCollect, "求游戏:")
|
||||
showCloseMenuView()
|
||||
}
|
||||
|
||||
R.id.seek_function_btn -> {
|
||||
MtaHelper.onEvent("游戏搜索", "求功能", mKey)
|
||||
LogUtils.uploadSearchGame("ask_more_func", " 搜索页-悬浮按钮", mKey, SearchType.fromString(mType).toChinese())
|
||||
SuggestionActivity.startSuggestionActivity(context, SuggestType.functionSuggest, "求功能:")
|
||||
showCloseMenuView()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,6 +321,7 @@ class SearchGameResultFragment : ListFragment<GameEntity, NormalListViewModel<Ga
|
||||
override fun onClick(widget: View?) {
|
||||
MtaHelper.onEvent("广告位统计", "搜索结果为空", ad.title)
|
||||
MtaHelper.onEvent("游戏搜索", ad.title, mKey)
|
||||
LogUtils.uploadSearchGame("click_ad", " 搜索页", mKey, SearchType.fromString(mType).toChinese())
|
||||
DirectUtils.directToLinkPage(requireContext(), ad.toLinkEntity(), "(搜索结果为空-广告位)", "")
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.NormalActivity
|
||||
|
||||
class SimulatorGameActivity : NormalActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setNavigationTitle("模拟器游戏")
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context): Intent {
|
||||
return getTargetIntent(context, SimulatorGameActivity::class.java, SimulatorGameFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.view.TabIndicatorView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.normal.NormalFragment
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import kotterknife.bindView
|
||||
|
||||
class SimulatorGameFragment : NormalFragment() {
|
||||
|
||||
private val mTabContainer by bindView<View>(R.id.fragment_tab_container)
|
||||
private val mViewPager by bindView<ViewPager>(R.id.fragment_view_pager)
|
||||
private val mTabLayout by bindView<TabLayout>(R.id.fragment_tab_layout)
|
||||
private val mTabIndicatorView by bindView<TabIndicatorView>(R.id.fragment_tab_indicator)
|
||||
private val mReuseNoData by bindView<LinearLayout>(R.id.reuse_none_data)
|
||||
private val mAdTv by bindView<TextView>(R.id.tv_ad)
|
||||
|
||||
private lateinit var mViewModel: SimulatorGameViewModel
|
||||
private var mFragmentsList = ArrayList<Fragment>()
|
||||
private var mTypeAliasList = ArrayList<String>()
|
||||
private var mCurrentPage = 0
|
||||
|
||||
override fun getLayoutId() = R.layout.fragment_simulator_game
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
mViewModel = viewModelProvider()
|
||||
mViewModel.getSimulators()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
initMenu(R.menu.menu_simulator_manager)
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
mViewModel.getSimulators()
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(menuItem: MenuItem) {
|
||||
super.onMenuItemClick(menuItem)
|
||||
if (menuItem.itemId == R.id.menu_simulator_manager) {
|
||||
startActivity(SimulatorManagementActivity.getIntent(requireContext()))
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击模拟器管理")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mViewModel.simulators.observe(viewLifecycleOwner, Observer { list ->
|
||||
mTypeAliasList.clear()
|
||||
mFragmentsList.clear()
|
||||
if (list.isEmpty()) {
|
||||
// 只剩一个tab然后删除了该tab所有游戏后刷新adapter
|
||||
mViewPager.adapter?.notifyDataSetChanged()
|
||||
|
||||
mReuseNoData.visibility = View.VISIBLE
|
||||
AdHelper.getAdForLocation(AdHelper.LOCATION_SIMULATOR_GAME)?.let { ad ->
|
||||
mAdTv.run {
|
||||
visibility = View.VISIBLE
|
||||
text = ad.title
|
||||
paint.flags = Paint.UNDERLINE_TEXT_FLAG
|
||||
paint.isAntiAlias = true
|
||||
setOnClickListener {
|
||||
MtaHelper.onEvent("广告位统计", "模拟器游戏", ad.title)
|
||||
directToLinkPage(requireContext(), ad.toLinkEntity(), "(模拟器游戏-广告位)", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
list.forEachIndexed { index, entity ->
|
||||
mTabContainer.goneIf(list.size == 1)
|
||||
mTypeAliasList.add(entity.typeAlias)
|
||||
mFragmentsList.add(childFragmentManager.findFragmentByTag("android:switcher:${mViewPager.id}:$index") ?:
|
||||
SimulatorGameListFragment().apply { with(bundleOf(EntranceUtils.KEY_SIMULATOR to entity)) })
|
||||
}
|
||||
|
||||
if (mViewPager.adapter != null) {
|
||||
// 删除了一个tab里面所有游戏后刷新adapter
|
||||
mViewPager.adapter?.notifyDataSetChanged()
|
||||
} else {
|
||||
initViewPager()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initViewPager() {
|
||||
mViewPager.run {
|
||||
offscreenPageLimit = mFragmentsList.size
|
||||
adapter = object : FragmentStatePagerAdapter(childFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||
override fun getItem(position: Int) = mFragmentsList[position]
|
||||
|
||||
override fun getCount() = mFragmentsList.size
|
||||
|
||||
override fun getItemPosition(`object`: Any) = PagerAdapter.POSITION_NONE
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
return if (mTypeAliasList.size > position) {
|
||||
mTypeAliasList[position]
|
||||
} else super.getPageTitle(position)
|
||||
}
|
||||
}
|
||||
doOnPageSelected {
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${mTypeAliasList[it]}")
|
||||
|
||||
if (mCurrentPage != it) {
|
||||
(mFragmentsList[mCurrentPage] as SimulatorGameListFragment).resetPage()
|
||||
mCurrentPage = it
|
||||
}
|
||||
}
|
||||
}
|
||||
mTabLayout.setupWithViewPager(mViewPager)
|
||||
mTabIndicatorView.run {
|
||||
setupWithTabLayout(mTabLayout)
|
||||
setupWithViewPager(mViewPager)
|
||||
setIndicatorWidth(20)
|
||||
}
|
||||
|
||||
for (i in 0 until mTabLayout.tabCount) {
|
||||
val tab = mTabLayout.getTabAt(i) ?: continue
|
||||
val tabTitle = if (tab.text != null) tab.text.toString() else ""
|
||||
val tabView = BaseFragment_TabLayout.createDefaultTabCustomView(tabTitle)
|
||||
tab.customView = tabView
|
||||
}
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mViewPager.currentItem)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,374 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Matrix
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.PopupWindow
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.constant.ItemViewType
|
||||
import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.view.BugFixedPopupWindow
|
||||
import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.adapter.viewholder.SimulatorHeaderViewHolder
|
||||
import com.gh.gamecenter.baselist.ListAdapter
|
||||
import com.gh.gamecenter.databinding.SimulatorGameItemBinding
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SimulatorEntity
|
||||
|
||||
class SimulatorGameListAdapter(context: Context, var simulator: SimulatorEntity, var fragment: SimulatorGameListFragment) : ListAdapter<GameEntity>(context) {
|
||||
|
||||
private var mCurrentOption = OPTION_MANAGER
|
||||
private var mShowSelectFlag = false
|
||||
private var mSelectList = ArrayList<Boolean>()
|
||||
private val mEntrance = "模拟器游戏"
|
||||
private lateinit var mPopWindow: PopupWindow
|
||||
var mLaunchGameFlag = false
|
||||
|
||||
override fun setListData(updateData: MutableList<GameEntity>?) {
|
||||
mSelectList.clear()
|
||||
updateData?.forEach { _ ->
|
||||
mSelectList.add(false)
|
||||
}
|
||||
super.setListData(updateData)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 2
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return when (viewType) {
|
||||
ItemViewType.ITEM_HEADER -> {
|
||||
SimulatorHeaderViewHolder(mLayoutInflater.inflate(R.layout.simulator_header_view, parent, false))
|
||||
}
|
||||
|
||||
ItemViewType.GAME_NORMAL -> {
|
||||
SimulatorGameViewHolder(SimulatorGameItemBinding.bind(mLayoutInflater.inflate(R.layout.simulator_game_item, parent, false)))
|
||||
}
|
||||
|
||||
else -> {
|
||||
FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is SimulatorHeaderViewHolder -> {
|
||||
holder.managerBtn.run {
|
||||
text = when (mCurrentOption) {
|
||||
OPTION_MANAGER -> "管理"
|
||||
OPTION_ALL_SELECT -> "全选"
|
||||
OPTION_CANCEL_SELECT -> "取消全选"
|
||||
else -> "管理"
|
||||
}
|
||||
setOnClickListener {
|
||||
when (mCurrentOption) {
|
||||
OPTION_MANAGER -> {
|
||||
mShowSelectFlag = true
|
||||
showOptionWindow()
|
||||
notifyDataSetChanged()
|
||||
mCurrentOption = OPTION_ALL_SELECT
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${simulator.typeAlias}+管理")
|
||||
}
|
||||
|
||||
OPTION_ALL_SELECT -> {
|
||||
resetSelectList(true)
|
||||
notifyDataSetChanged()
|
||||
mCurrentOption = OPTION_CANCEL_SELECT
|
||||
}
|
||||
|
||||
OPTION_CANCEL_SELECT -> {
|
||||
resetSelectList(false)
|
||||
notifyDataSetChanged()
|
||||
mCurrentOption = OPTION_ALL_SELECT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
holder.simulatorBtn.run {
|
||||
if (PackageUtils.isInstalledFromAllPackage(context, simulator.apk?.packageName)) {
|
||||
val versionFromInstalledApp = PackageUtils.getVersionByPackage(simulator.apk?.packageName)
|
||||
val shouldShowUpdate = Version(simulator.apk?.version).isHigherThan(versionFromInstalledApp)
|
||||
text = if (shouldShowUpdate) "更新模拟器" else "模拟器已安装"
|
||||
setTextColor(if (shouldShowUpdate) R.color.theme.toColor() else R.color.text_999999.toColor())
|
||||
if (shouldShowUpdate) {
|
||||
setOnClickListener {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(context, simulator, SimulatorDownloadManager.SimulatorLocation.SIMULATOR_GAME)
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${simulator.typeAlias}+更新模拟器")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (simulator.active) {
|
||||
text = "安装模拟器"
|
||||
setTextColor(R.color.theme.toColor())
|
||||
setOnClickListener {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(context, simulator, SimulatorDownloadManager.SimulatorLocation.SIMULATOR_GAME)
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${simulator.typeAlias}+下载模拟器")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is SimulatorGameViewHolder -> {
|
||||
val gameEntity = mEntityList[position - 1]
|
||||
holder.binding.run {
|
||||
gameItemIncluded.game = gameEntity
|
||||
(gameItemIncluded.downloadBtn.layoutParams as LinearLayout.LayoutParams).apply {
|
||||
gravity = Gravity.BOTTOM
|
||||
bottomMargin = DisplayUtils.dip2px(4F)
|
||||
}
|
||||
(gameItemIncluded.gameName.layoutParams as LinearLayout.LayoutParams).apply {
|
||||
width = LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
gameItemIncluded.recentPlayedTag.goneIf(!gameEntity.isRecentlyPlayed)
|
||||
gameItemIncluded.selectIv.goneIf(!mShowSelectFlag)
|
||||
gameItemIncluded.selectIv.isChecked = mSelectList[position - 1]
|
||||
gameItemIncluded.selectIv.setOnClickListener {
|
||||
gameItemIncluded.selectIv.isChecked = !gameItemIncluded.selectIv.isChecked
|
||||
mSelectList[position - 1] = gameItemIncluded.selectIv.isChecked
|
||||
|
||||
when (mCurrentOption) {
|
||||
OPTION_CANCEL_SELECT -> {
|
||||
if (mSelectList.contains(false)) {
|
||||
mCurrentOption = OPTION_ALL_SELECT
|
||||
notifyItemChanged(0)
|
||||
}
|
||||
}
|
||||
|
||||
OPTION_ALL_SELECT -> {
|
||||
if (!mSelectList.contains(false)) {
|
||||
mCurrentOption = OPTION_CANCEL_SELECT
|
||||
notifyItemChanged(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DownloadItemUtils.setOnClickListener(mContext,
|
||||
gameItemIncluded.downloadBtn,
|
||||
gameEntity,
|
||||
position,
|
||||
this@SimulatorGameListAdapter,
|
||||
"(${mEntrance})",
|
||||
StringUtils.buildString(mEntrance, ":", gameEntity.name),
|
||||
null,
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
// 若当前点击为启动模拟器游戏,且当前item不是近期玩过的游戏(即未显示"近期玩过"标签),则将标志位mLaunchGameFlag置为true
|
||||
if (gameItemIncluded.downloadBtn.text == R.string.launch.toResString()
|
||||
&& gameItemIncluded.recentPlayedTag.visibility == View.GONE) {
|
||||
mLaunchGameFlag = true
|
||||
}
|
||||
}
|
||||
})
|
||||
DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding.gameItemIncluded), true)
|
||||
|
||||
optionsIv.setOnClickListener {
|
||||
showSingleOptionWindow(optionsIv, gameEntity, gameItemIncluded.downloadBtn.text == mContext.getString(R.string.launch))
|
||||
}
|
||||
|
||||
root.setOnClickListener {
|
||||
GameDetailActivity.startGameDetailActivity(mContext, gameEntity.id, "(${mEntrance})")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is FooterViewHolder -> {
|
||||
holder.initItemPadding()
|
||||
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetSelectList(value: Boolean) {
|
||||
for (i in 0 until mSelectList.size) {
|
||||
mSelectList[i] = value
|
||||
}
|
||||
}
|
||||
|
||||
private fun showOptionWindow() {
|
||||
val contentView = View.inflate(mContext, R.layout.popup_simulator_option, null)
|
||||
contentView.isFocusable = true
|
||||
contentView.isFocusableInTouchMode = true
|
||||
val deleteItem = contentView.findViewById<LinearLayout>(R.id.item_delete)
|
||||
val completeItem = contentView.findViewById<LinearLayout>(R.id.item_complete)
|
||||
|
||||
mPopWindow = PopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
mPopWindow.showAtLocation(fragment.requireActivity().window.decorView, Gravity.BOTTOM, 0, 0)
|
||||
|
||||
completeItem.setOnClickListener {
|
||||
mPopWindow.dismiss()
|
||||
resetStatus()
|
||||
notifyDataSetChanged()
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${simulator.typeAlias}+管理+完成")
|
||||
}
|
||||
|
||||
deleteItem.setOnClickListener {
|
||||
val list = ArrayList<String>()
|
||||
val ids = ArrayList<String>()
|
||||
mSelectList.forEachIndexed { index, b ->
|
||||
if (b) {
|
||||
list.add(mEntityList[index]?.name ?: "")
|
||||
ids.add(mEntityList[index]?.id ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
if (list.isEmpty()) {
|
||||
ToastUtils.showToast("请选择游戏")
|
||||
} else {
|
||||
DialogUtils.showNewAlertDialog(mContext, "删除游戏", "即将删除游戏记录和本地文件,是否确定删除", "取消", "确定", null) {
|
||||
mPopWindow.dismiss()
|
||||
resetStatus()
|
||||
SimulatorGameManager.deleteLocalGames(list)
|
||||
SimulatorGameManager.deleteSimulatorGames(ids) {
|
||||
if (list.size == mEntityList.size) {
|
||||
(fragment.parentFragment as SimulatorGameFragment).refresh()
|
||||
} else {
|
||||
fragment.onLoadRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${simulator.typeAlias}+管理+删除游戏")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSingleOptionWindow(view: View, gameEntity: GameEntity, isShowShortCut: Boolean) {
|
||||
val gameName = gameEntity.name ?: ""
|
||||
val inflater = LayoutInflater.from(mContext)
|
||||
val layout = inflater.inflate(R.layout.popup_simulator_option_single, null)
|
||||
val popupWindow = BugFixedPopupWindow(
|
||||
layout,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
|
||||
val container = layout.findViewById<LinearLayout>(R.id.container)
|
||||
val shortCutItem = container.findViewById<LinearLayout>(R.id.item_shortcut)
|
||||
val deleteGameItem = container.findViewById<LinearLayout>(R.id.item_delete_game)
|
||||
|
||||
shortCutItem.goneIf(!isShowShortCut)
|
||||
|
||||
shortCutItem.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
DialogUtils.showShortCutPermissionDialog(mContext)
|
||||
createShortcut(gameEntity)
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${gameName}+添加到桌面")
|
||||
}
|
||||
|
||||
deleteGameItem.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
MtaHelper.onEvent("我的光环_新", "模拟器游戏", "点击${gameName}+删除游戏")
|
||||
DialogUtils.showNewAlertDialog(mContext, "删除游戏", "即将删除游戏记录和本地文件,是否确定删除", "取消", "确定", null) {
|
||||
SimulatorGameManager.deleteLocalGame(gameName)
|
||||
SimulatorGameManager.deleteSimulatorGame(gameEntity.id) {
|
||||
if (mEntityList.size == 1) {
|
||||
(fragment.parentFragment as SimulatorGameFragment).refresh()
|
||||
} else {
|
||||
fragment.onLoadRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
popupWindow.isTouchable = true
|
||||
popupWindow.isFocusable = true
|
||||
|
||||
popupWindow.showAutoOrientation(view)
|
||||
}
|
||||
|
||||
fun resetPageFromFragment() {
|
||||
if (mShowSelectFlag) {
|
||||
resetStatus()
|
||||
notifyDataSetChanged()
|
||||
if (::mPopWindow.isInitialized && mPopWindow.isShowing) {
|
||||
mPopWindow.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetStatus() {
|
||||
mShowSelectFlag = false
|
||||
mCurrentOption = OPTION_MANAGER
|
||||
resetSelectList(false)
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when (position) {
|
||||
0 -> ItemViewType.ITEM_HEADER
|
||||
itemCount - 1 -> ItemViewType.ITEM_FOOTER
|
||||
else -> ItemViewType.GAME_NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun createShortcut(gameEntity: GameEntity) {
|
||||
val gameName = gameEntity.name ?: ""
|
||||
val gameIcon = gameEntity.icon ?: ""
|
||||
if (ShortcutManagerCompat.isRequestPinShortcutSupported(mContext)) {
|
||||
ImageUtils.getBitmap(gameIcon, object : BiCallback<Bitmap, Boolean> {
|
||||
override fun onFirst(first: Bitmap) {
|
||||
// 要先压缩图片,不然图片过大再调用requestPinShortcut后,可能会报TransactionTooLargeException异常
|
||||
val bitmap = compressImage(first)
|
||||
val shortcutInfoIntent = Intent(mContext, MainActivity::class.java)
|
||||
shortcutInfoIntent.run {
|
||||
action = Intent.ACTION_VIEW
|
||||
putExtra(EntranceUtils.KEY_REQUIRE_REDIRECT, true)
|
||||
putExtra(EntranceUtils.KEY_TO, EntranceUtils.HOST_LAUNCH_SIMULATOR_GAME)
|
||||
putExtra(EntranceUtils.KEY_GAME, gameEntity.toJson())
|
||||
val info = ShortcutInfoCompat.Builder(mContext, gameName)
|
||||
.setIcon(IconCompat.createWithBitmap(bitmap))
|
||||
.setShortLabel(gameName)
|
||||
.setIntent(this)
|
||||
.build()
|
||||
ShortcutManagerCompat.requestPinShortcut(mContext, info, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSecond(second: Boolean) {
|
||||
ToastUtils.showToast("创建快捷方式失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Bitmap尺寸超过300*300就压缩
|
||||
fun compressImage(bitmap: Bitmap): Bitmap {
|
||||
return if (bitmap.byteCount > 300 * 300 * 4) {
|
||||
val width = bitmap.width.toFloat()
|
||||
val height = bitmap.height.toFloat()
|
||||
val matrix = Matrix()
|
||||
val scaleWidth = 300 / width
|
||||
val scaleHeight = 300 / height
|
||||
matrix.postScale(scaleWidth, scaleHeight)
|
||||
Bitmap.createBitmap(bitmap, 0, 0, width.toInt(), height.toInt(), matrix, true)
|
||||
} else bitmap
|
||||
}
|
||||
|
||||
class SimulatorGameViewHolder(var binding: SimulatorGameItemBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
companion object {
|
||||
const val OPTION_MANAGER = 100
|
||||
const val OPTION_ALL_SELECT = 101
|
||||
const val OPTION_CANCEL_SELECT = 102
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.os.Bundle
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.viewModelProvider
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.baselist.ListFragment
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.game.GameAndPosition
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import java.util.ArrayList
|
||||
|
||||
class SimulatorGameListFragment : ListFragment<GameEntity, SimulatorGameListViewModel>() {
|
||||
|
||||
private lateinit var mSimulatorEntity: SimulatorEntity
|
||||
private var mAdapter: SimulatorGameListAdapter? = null
|
||||
|
||||
private val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
val data = getGameEntityByPackage(downloadEntity.packageName)
|
||||
for (gameAndPosition in data) {
|
||||
if (gameAndPosition.entity != null && gameAndPosition.entity.name == downloadEntity.name) {
|
||||
val entryMap = gameAndPosition.entity.getEntryMap()
|
||||
entryMap[downloadEntity.platform] = downloadEntity
|
||||
}
|
||||
mAdapter?.notifyItemChanged(gameAndPosition.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGameEntityByPackage(packageName: String): List<GameAndPosition> {
|
||||
val positionList = ArrayList<GameAndPosition>()
|
||||
val positionMap = mListViewModel.positionAndPackageMap
|
||||
for (key in positionMap.keys) {
|
||||
if (key.contains(packageName)) {
|
||||
val position = positionMap[key]!!
|
||||
val game = mAdapter?.entityList?.get(position - 1)
|
||||
if (game != null) {
|
||||
positionList.add(GameAndPosition(game, position))
|
||||
}
|
||||
}
|
||||
}
|
||||
return positionList
|
||||
}
|
||||
|
||||
//安装、卸载事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if ("安装" == busFour.type || "卸载" == busFour.type) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun resetPage() {
|
||||
mAdapter?.resetPageFromFragment()
|
||||
}
|
||||
|
||||
override fun getItemDecoration() = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
arguments?.apply {
|
||||
mSimulatorEntity = getParcelable(EntranceUtils.KEY_SIMULATOR) ?: SimulatorEntity()
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun provideListAdapter() = mAdapter
|
||||
?: SimulatorGameListAdapter(requireContext(), mSimulatorEntity, this).apply { mAdapter = this }
|
||||
|
||||
|
||||
override fun provideListViewModel(): SimulatorGameListViewModel {
|
||||
return viewModelProvider(SimulatorGameListViewModel.Factory(HaloApp.getInstance().application, mSimulatorEntity.type))
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
DownloadManager.getInstance(context).addObserver(dataWatcher)
|
||||
|
||||
// 启动模拟器游戏后,返回本页面若mLaunchGameFlag为true,则刷新页面(主要是为了更新游戏item的"近期玩过"标签)
|
||||
if (mAdapter?.mLaunchGameFlag == true) {
|
||||
onLoadRefresh()
|
||||
mAdapter?.mLaunchGameFlag = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
DownloadManager.getInstance(context).removeObserver(dataWatcher)
|
||||
}
|
||||
|
||||
override fun onChanged(ts: MutableList<GameEntity>?) {
|
||||
super.onChanged(ts)
|
||||
if (ts.isNullOrEmpty()) {
|
||||
(parentFragment as SimulatorGameFragment).refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.common.simulator.SimulatorGameManager.findDownloadEntityByUrl
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import java.io.File
|
||||
|
||||
class SimulatorGameListViewModel(application: Application, var type: String) : ListViewModel<GameEntity, GameEntity>(application) {
|
||||
|
||||
private val mApi = RetrofitManager.getInstance(getApplication()).api
|
||||
|
||||
var positionAndPackageMap = HashMap<String, Int>() // key: packageName + position, value: position
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource<List<GameEntity>>(mListLiveData) {
|
||||
positionAndPackageMap.clear()
|
||||
val newList = ArrayList<GameEntity>()
|
||||
it.forEachIndexed { index, gameEntity ->
|
||||
addGamePositionAndPackage(gameEntity, index + 1)
|
||||
val downloadEntity = findDownloadEntityByUrl(gameEntity.getApk()[0].url)
|
||||
// 后台设置为隐藏且本次文件被删除,则不显示该游戏且删除该记录
|
||||
if (!gameEntity.active && downloadEntity != null && !File(downloadEntity.path).exists()) {
|
||||
SimulatorGameManager.deleteSimulatorGame(gameEntity.id) {}
|
||||
} else {
|
||||
newList.add(gameEntity)
|
||||
}
|
||||
}
|
||||
mResultLiveData.postValue(newList)
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<MutableList<GameEntity>>? = null
|
||||
|
||||
override fun provideDataSingle(page: Int): Single<MutableList<GameEntity>> {
|
||||
return mApi.getSimulatorGames(HaloApp.getInstance().gid, page, getFilter())
|
||||
}
|
||||
|
||||
private fun getFilter(): String {
|
||||
return UrlFilterUtils.getFilterQuery("type", type)
|
||||
}
|
||||
|
||||
private fun addGamePositionAndPackage(game: GameEntity, position: Int) {
|
||||
var packages = ""
|
||||
for (apkEntity in game.getApk()) {
|
||||
packages += apkEntity.packageName
|
||||
}
|
||||
packages += game.simulator?.apk?.packageName
|
||||
positionAndPackageMap[packages + position] = position
|
||||
game.gameLocation = GameEntity.GameLocation.INDEX
|
||||
game.setEntryMap(DownloadManager.getInstance(getApplication()).getEntryMap(game.name))
|
||||
}
|
||||
|
||||
|
||||
class Factory(private val mApplication: Application,
|
||||
private val mType: String) : ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return SimulatorGameListViewModel(mApplication, mType) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.gamecenter.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class SimulatorGameViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
private var mSimulatorsList: List<SimulatorEntity>? = null
|
||||
private var mTypeList: List<String>? = null
|
||||
private var mResultSimulatorsList = ArrayList<SimulatorEntity>()
|
||||
private val api = RetrofitManager.getInstance(getApplication()).api
|
||||
var simulators = MutableLiveData<List<SimulatorEntity>>()
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getSimulators() {
|
||||
mSimulatorsList = null
|
||||
mTypeList = null
|
||||
mResultSimulatorsList.clear()
|
||||
val simulatorsSingle = api.simulators
|
||||
val deviceSimulatorTypesSingle = api.getDeviceSimulatorTypes(HaloApp.getInstance().gid)
|
||||
Single.merge(simulatorsSingle, deviceSimulatorTypesSingle)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
if (it.isNotEmpty()) {
|
||||
when (it[0]) {
|
||||
is SimulatorEntity -> mSimulatorsList = it as List<SimulatorEntity>
|
||||
|
||||
is String -> mTypeList = it as List<String>
|
||||
}
|
||||
}
|
||||
}, {
|
||||
simulators.postValue(mResultSimulatorsList)
|
||||
}, {
|
||||
if (mSimulatorsList != null && mTypeList != null) {
|
||||
mSimulatorsList?.forEach {
|
||||
if (mTypeList!!.contains(it.type)) mResultSimulatorsList.add(it)
|
||||
}
|
||||
}
|
||||
simulators.postValue(mResultSimulatorsList)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.NormalActivity
|
||||
|
||||
class SimulatorManagementActivity : NormalActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setNavigationTitle("模拟器管理")
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context): Intent {
|
||||
return getTargetIntent(context, SimulatorManagementActivity::class.java, SimulatorManagementFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user