Compare commits
198 Commits
video_only
...
v4.5.3-253
| Author | SHA1 | Date | |
|---|---|---|---|
| 69e248b389 | |||
| 43f6bfc4c2 | |||
| c8b81ab56a | |||
| aa41fd98e8 | |||
| ee8ce87e28 | |||
| a944a7f730 | |||
| 165ba01afd | |||
| a39a8c2cce | |||
| e4765089fa | |||
| 721e73ca1e | |||
| e406c90027 | |||
| e7c4886219 | |||
| 0d9a4baf32 | |||
| 3a9132ff8c | |||
| 02a6ec9f7d | |||
| c779d775e3 | |||
| 3fbcd33f98 | |||
| dbcdd7f3cc | |||
| 69d9854b44 | |||
| 5246d6e743 | |||
| b20d598751 | |||
| 85e9799f20 | |||
| 6b533c8d09 | |||
| 2797135db4 | |||
| 7507a027da | |||
| 9873ae8946 | |||
| a5ef80ba33 | |||
| dfdd12bf18 | |||
| 9daf01d9a5 | |||
| ee7ed1fed2 | |||
| 08474a660e | |||
| d8dfe00057 | |||
| 6bd175f72b | |||
| 72b6b3042a | |||
| 3317b178ac | |||
| c86e7ba6ee | |||
| 14c5e4e963 | |||
| 6db8179f4d | |||
| 65c2571329 | |||
| 4810803988 | |||
| f3f030edb1 | |||
| 2ac2a3bf48 | |||
| cd104e4688 | |||
| e2de8cfb47 | |||
| c9f9451dee | |||
| 73c39edd3f | |||
| 7f739798ab | |||
| e41cf76d26 | |||
| 113d446e47 | |||
| 882ac7d67d | |||
| d94be8092b | |||
| b9138ae810 | |||
| 715cecd44b | |||
| dd756fce00 | |||
| 56a003704d | |||
| 50421e0b70 | |||
| 9f0d00f793 | |||
| a56fd8ff18 | |||
| f86fc7b0e1 | |||
| e6197776ca | |||
| 0415ae261b | |||
| d5313c7f98 | |||
| 360231e01f | |||
| 4d86d6f96b | |||
| dd03daae84 | |||
| 5d285fd60e | |||
| 7d4206bcd8 | |||
| a816636d9a | |||
| c6a5522b35 | |||
| 8b888f0ab4 | |||
| ef41a3aea5 | |||
| ba2206931f | |||
| ef4b7b28d8 | |||
| 4a5f12d341 | |||
| ced96f5f70 | |||
| 4180d87b36 | |||
| 2b7f802584 | |||
| 3e9a348019 | |||
| 9725402623 | |||
| 9827b04057 | |||
| b3052485f5 | |||
| d3dc09d377 | |||
| 58905c14a8 | |||
| aadbbbf2ea | |||
| 5256a9b267 | |||
| 0ded7b33f2 | |||
| cdc3158f30 | |||
| 06de179c9e | |||
| f32dc628ef | |||
| 62e371c928 | |||
| 84bcc481af | |||
| 085ddd4ea6 | |||
| b3e859678e | |||
| 7f586fbf13 | |||
| 9dab3dd263 | |||
| 3ee30f05f0 | |||
| 69c8c51000 | |||
| 28742f54bb | |||
| f62751423d | |||
| b0b699679e | |||
| 3c55284d86 | |||
| b6ae508cf0 | |||
| c13ee31ece | |||
| c87a1ba56e | |||
| 9f07cc7720 | |||
| 7bdfe7cef3 | |||
| 667126f92c | |||
| 0409d33d5e | |||
| 14e8285c0f | |||
| c7d63f9df1 | |||
| e2d9ad07d1 | |||
| 9287b6ac4c | |||
| 450da5e0db | |||
| 0397092414 | |||
| ddc515b490 | |||
| a6edde7853 | |||
| 80282f7bcc | |||
| 664df5cb44 | |||
| 8396a55ed2 | |||
| 5ee3f597bd | |||
| 9c8bd9f85e | |||
| 4321e0a33c | |||
| 6f75229209 | |||
| d6bd561e58 | |||
| c957d7585c | |||
| db0e92fd68 | |||
| 992446cf70 | |||
| dcfa52b05a | |||
| 2a06c41dca | |||
| 24214c5d6b | |||
| c839eff88d | |||
| 663505fdc9 | |||
| 641a820ea5 | |||
| bb3f888f88 | |||
| 75bdf6f251 | |||
| 0cacc15e7d | |||
| e4c2ac0aae | |||
| 7acf4c5941 | |||
| 8b22361213 | |||
| a1dee46436 | |||
| 49bf8c9e30 | |||
| 407686ca5b | |||
| 89b7b45ba0 | |||
| b00e7a2826 | |||
| 383d6e7700 | |||
| edce98e4c6 | |||
| a2c3873c8d | |||
| 7990353d08 | |||
| a7b138b2b2 | |||
| 951768e070 | |||
| 69f29fe83b | |||
| 88e28b2388 | |||
| 538bc6f97c | |||
| b1940125f4 | |||
| e1f8e293c2 | |||
| 0a49f27ed2 | |||
| 5dc7badc97 | |||
| d185d39985 | |||
| d9c98d39b5 | |||
| 6949f2b2ff | |||
| 2141440ec4 | |||
| 464c212638 | |||
| dbe74b2091 | |||
| ba55a5a61c | |||
| 452a94f4a2 | |||
| 310be97fe4 | |||
| 2fc45777e4 | |||
| da283fc1f6 | |||
| fee4e4635c | |||
| ebcd50cdee | |||
| cd922dd286 | |||
| 97598d7330 | |||
| 0db59a56d0 | |||
| bee3f5957e | |||
| 65d4b43c9c | |||
| 41f510d333 | |||
| 64d5af036c | |||
| b4c827bddf | |||
| caf3dfa9ee | |||
| c5c10ab208 | |||
| c2251e1ad6 | |||
| bd6d51dab3 | |||
| 1cf9bfcca3 | |||
| 992ec7bfe8 | |||
| cc39bfd06c | |||
| 15d0ad6f49 | |||
| a2e2379073 | |||
| d2431ed8ff | |||
| 80818dee55 | |||
| f2d0916a16 | |||
| 2fa84e0ce1 | |||
| c9f5cfd4aa | |||
| d6c1f692be | |||
| 12e6fb8330 | |||
| ad857d4500 | |||
| 43d8d24c1c | |||
| a34ee5a753 | |||
| ca39f723e1 |
134
app/build.gradle
134
app/build.gradle
@ -6,6 +6,8 @@ apply plugin: 'kotlin-kapt'
|
||||
// apkChannelPackage
|
||||
apply plugin: 'channel'
|
||||
|
||||
import groovy.xml.XmlUtil
|
||||
|
||||
//apply from: 'tinker-support.gradle'
|
||||
|
||||
android {
|
||||
@ -18,6 +20,10 @@ android {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
viewBinding {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
@ -125,15 +131,27 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "nonsense"
|
||||
flavorDimensions("env")
|
||||
|
||||
sourceSets {
|
||||
publish {
|
||||
java.srcDirs = ['src/main/java']
|
||||
}
|
||||
internal {
|
||||
java.srcDirs = ['src/main/java']
|
||||
}
|
||||
tea {
|
||||
java.srcDirs = ['src/main/java', 'src/tea/java']
|
||||
}
|
||||
gdt {
|
||||
java.srcDirs = ['src/main/java', 'src/gdt/java']
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多渠道打包,渠道请参考"channel.txt"文件,所有渠道值均通过java code设置
|
||||
*/
|
||||
productFlavors {
|
||||
// publish release host
|
||||
publish {
|
||||
dimension "nonsense"
|
||||
dimension "env"
|
||||
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
|
||||
|
||||
buildConfigField "String", "SENSITIVE_API_HOST", "\"${SENSITIVE_API_HOST}\""
|
||||
@ -144,7 +162,7 @@ android {
|
||||
}
|
||||
// internal test dev host
|
||||
internal {
|
||||
dimension "nonsense"
|
||||
dimension "env"
|
||||
versionNameSuffix "-debug"
|
||||
|
||||
buildConfigField "String", "API_HOST", "\"${DEV_API_HOST}\""
|
||||
@ -155,6 +173,30 @@ android {
|
||||
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${DEV_UMENG_MESSAGE_SECRET}\""
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${DEV_BUGLY_APPID}\""
|
||||
}
|
||||
|
||||
tea {
|
||||
dimension "env"
|
||||
|
||||
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
|
||||
|
||||
buildConfigField "String", "SENSITIVE_API_HOST", "\"${SENSITIVE_API_HOST}\""
|
||||
|
||||
buildConfigField "String", "UMENG_APPKEY", "\"${UMENG_APPKEY}\""
|
||||
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${UMENG_MESSAGE_SECRET}\""
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${BUGLY_APPID}\""
|
||||
}
|
||||
|
||||
gdt {
|
||||
dimension "env"
|
||||
|
||||
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
|
||||
|
||||
buildConfigField "String", "SENSITIVE_API_HOST", "\"${SENSITIVE_API_HOST}\""
|
||||
|
||||
buildConfigField "String", "UMENG_APPKEY", "\"${UMENG_APPKEY}\""
|
||||
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${UMENG_MESSAGE_SECRET}\""
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${BUGLY_APPID}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,6 +226,7 @@ repositories {
|
||||
dependencies {
|
||||
|
||||
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
|
||||
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
@ -289,7 +332,7 @@ dependencies {
|
||||
|
||||
debugImplementation "com.github.nichbar.chucker:library:$chucker"
|
||||
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
|
||||
// implementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
|
||||
teaImplementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
|
||||
// implementation "com.bytedance.ies.ugc.aweme:opensdk-china-external:$bytedanceAweme"
|
||||
// implementation "com.bytedance.ies.ugc.aweme:opensdk-common:$bytedanceAweme"
|
||||
|
||||
@ -299,6 +342,8 @@ dependencies {
|
||||
|
||||
implementation "net.lingala.zip4j:zip4j:${zip4j}"
|
||||
|
||||
implementation "io.sentry:sentry-android:$sentry"
|
||||
|
||||
implementation("com.github.piasy:BigImageViewer:$bigImageViewer", {
|
||||
exclude group: 'com.squareup.okhttp3'
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
@ -371,3 +416,78 @@ if (propFile.exists()) {
|
||||
// task.name.startsWith('merge') && task.name.endsWith('Resources')
|
||||
// }.each { t -> t.dependsOn generateMetaJson }
|
||||
//}
|
||||
|
||||
|
||||
project.afterEvaluate {
|
||||
def variants = null
|
||||
try {
|
||||
variants = android.applicationVariants
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace()
|
||||
try {
|
||||
variants = android.libraryVariants
|
||||
} catch (Throwable tt) {
|
||||
tt.printStackTrace()
|
||||
}
|
||||
}
|
||||
if (variants != null) {
|
||||
variants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def task = output.processManifestProvider.get()
|
||||
if (task == null) {
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 Manifest 的 Activity 的 configChanges 添加自己手动处理 configurationChanges 配置 [https://developer.android.com/guide/topics/resources/runtime-changes]
|
||||
* AGP 4.1.0 从 ProcessManifest task 里拿 manifest 的 API 变更调整可以参考这里 [https://github.com/Tencent/tinker/pull/1476/commits/d71645729b13d545ca4ba6826f93fbf558751434]
|
||||
* (搞半天还是不会抽离方法,有空再把 gradle 改成用 kotlin 实现吧)
|
||||
*/
|
||||
task.doLast {
|
||||
def manifestFile = new File(multiApkManifestOutputDirectory.get().asFile, "AndroidManifest.xml")
|
||||
if (manifestFile == null || !manifestFile.exists()) {
|
||||
return
|
||||
}
|
||||
def parser = new XmlSlurper(false, true)
|
||||
def manifest = parser.parse(manifestFile)
|
||||
def app = manifest.'application'[0]
|
||||
app.'activity'.each { act ->
|
||||
String value = act.attributes()['android:configChanges']
|
||||
if (value == null || value.isEmpty()) {
|
||||
value = "keyboardHidden|orientation|screenSize|screenLayout|density|fontScale|locale"
|
||||
act.attributes()['androidconfigChanges'] = value
|
||||
} else {
|
||||
String[] valueSplit = value.split("\\|")
|
||||
if (!valueSplit.contains("keyboardHidden")) {
|
||||
value += "|keyboardHidden"
|
||||
}
|
||||
if (!valueSplit.contains("orientation")) {
|
||||
value += "|orientation"
|
||||
}
|
||||
if (!valueSplit.contains("screenSize")) {
|
||||
value += "|screenSize"
|
||||
}
|
||||
if (!valueSplit.contains("screenLayout")) {
|
||||
value += "|screenLayout"
|
||||
}
|
||||
if (!valueSplit.contains("density")) {
|
||||
value += "|density"
|
||||
}
|
||||
if (!valueSplit.contains("fontScale")) {
|
||||
value += "|fontScale"
|
||||
}
|
||||
if (!valueSplit.contains("locale")) {
|
||||
value += "|locale"
|
||||
}
|
||||
act.attributes()['android:configChanges'] = value
|
||||
}
|
||||
}
|
||||
|
||||
def tmpManifest = XmlUtil.serialize(manifest).replaceAll("androidconfigChanges", "android:configChanges")
|
||||
manifest = parser.parseText(tmpManifest)
|
||||
manifestFile.setText(XmlUtil.serialize(manifest), "utf-8")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,6 +241,13 @@
|
||||
-dontwarn com.shuyu.gsyvideoplayer.utils.**
|
||||
-keep class tv.danmaku.ijk.** { *; }
|
||||
-dontwarn tv.danmaku.ijk.**
|
||||
-keep public class * extends android.view.View{
|
||||
*** get*();
|
||||
void set*(***);
|
||||
public <init>(android.content.Context);
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
#穿山甲
|
||||
-keep class com.bytedance.sdk.openadsdk.** { *; }
|
||||
@ -258,4 +265,7 @@
|
||||
|
||||
-keep class com.alibaba.sdk.android.**{*;}
|
||||
-keep class com.ut.**{*;}
|
||||
-keep class com.ta.**{*;}
|
||||
-keep class com.ta.**{*;}
|
||||
|
||||
-keep class com.gh.gamecenter.GdtHelper { *; }
|
||||
-keep class com.gh.gamecenter.TeaHelper { *; }
|
||||
75
app/src/gdt/java/com/gh/gamecenter/GdtHelper.kt
Normal file
75
app/src/gdt/java/com/gh/gamecenter/GdtHelper.kt
Normal file
@ -0,0 +1,75 @@
|
||||
package com.gh.gamecenter
|
||||
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import com.gh.common.util.ToastUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import com.qq.gdt.action.GDTAction
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
|
||||
*
|
||||
* 更换帐号 [https://gitlab.ghzs.com/pm/yunying/issues/893]
|
||||
*/
|
||||
object GdtHelper {
|
||||
|
||||
const val NETWORK_TYPE = "NETWORK_TYPE"
|
||||
const val PAGE_TYPE = "PAGE_TYPE"
|
||||
const val CONTENT_TYPE = "CONTENT_TYPE"
|
||||
const val CONTENT_ID = "CONTENT_ID"
|
||||
const val KEYWORD = "KEYWORD"
|
||||
const val GAME_ID = "GAME_ID"
|
||||
const val SCORE = "SCORE"
|
||||
const val PLATFORM = "PLATFORM"
|
||||
|
||||
@JvmStatic
|
||||
fun init(application: Application, channel: String) {
|
||||
if (shouldUseGdtHelper()) {
|
||||
if (channel == "GH_728") {
|
||||
GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
|
||||
} else if (channel == "GH_729") {
|
||||
GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
|
||||
} else {
|
||||
GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
}
|
||||
}
|
||||
Utils.log("init GdtHelper")
|
||||
}
|
||||
|
||||
// fun logAction(type: String) {
|
||||
// if (shouldUseGdtHelper()) {
|
||||
// GDTAction.logAction(type)
|
||||
// Utils.log("GDT", type)
|
||||
// }
|
||||
// }
|
||||
@JvmStatic
|
||||
fun logAction(type: String, vararg kv: String?) {
|
||||
try {
|
||||
val actionParam = JSONObject()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
actionParam.put(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
|
||||
GDTAction.logAction(type, actionParam)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 确认开启的渠道条件
|
||||
private fun shouldUseGdtHelper(): Boolean {
|
||||
return true
|
||||
//
|
||||
// val channel = HaloApp.getInstance().channel
|
||||
// return !(TextUtils.isEmpty(channel) || channel.contains("GDT".toLowerCase(Locale.CHINA)))
|
||||
}
|
||||
|
||||
}
|
||||
BIN
app/src/gdt/libs/GDTActionSDK.min.1.6.10.aar
Normal file
BIN
app/src/gdt/libs/GDTActionSDK.min.1.6.10.aar
Normal file
Binary file not shown.
@ -9,8 +9,6 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<!-- 允许应用程序读取扩展存储器 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<!-- 允许挂载和反挂载文件系统可移动存储 -->
|
||||
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
|
||||
<!-- 允许应用程序访问Wi-Fi网络状态信息 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<!-- 允许应用程序获取网络信息状态 -->
|
||||
@ -25,8 +23,6 @@
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<!-- 允许应用程序打开系统窗口,显示其他应用程序 -->
|
||||
<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" />
|
||||
|
||||
@ -35,7 +31,7 @@
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<!-- bugly with tinker -->
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<!-- <uses-permission android:name="android.permission.READ_LOGS" />-->
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<!--可选,穿山甲提供“获取地理位置权限”和“不给予地理位置权限,开发者传入地理位置参数”两种方式上报用户位置,两种方式均可不选,添加位置权限或参数将帮助投放定位广告-->
|
||||
@ -79,6 +75,10 @@
|
||||
tools:replace="android:allowBackup"
|
||||
tools:targetApi="n">
|
||||
|
||||
<meta-data
|
||||
android:name="io.sentry.auto-init"
|
||||
android:value="false" />
|
||||
|
||||
<!--android:launchMode = "singleTask"-->
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.SplashScreenActivity"
|
||||
@ -462,7 +462,7 @@
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.video.upload.view.UploadVideoActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden"/>
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
|
||||
@ -577,7 +577,7 @@
|
||||
<activity
|
||||
android:name=".personalhome.background.BackgroundClipActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar"/>
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.excellentcomments.ExcellentCommentsActivity"
|
||||
@ -591,12 +591,24 @@
|
||||
android:name=".simulatorgame.SimulatorManagementActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.PushProxyActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@android:style/Theme.Translucent" />
|
||||
android:name=".catalog.CatalogActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".catalog.NewCatalogListActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".forum.search.ForumOrUserSearchActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- <!– 使用小米/华为推送弹窗功能提高推送成功率–>-->
|
||||
<!-- <activity-->
|
||||
<!-- android:name="com.gh.gamecenter.PushProxyActivity"-->
|
||||
<!-- android:exported="true"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
<!-- android:theme="@android:style/Theme.Translucent" />-->
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.SkipActivity"
|
||||
@ -608,6 +620,14 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<data android:scheme="market" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@ -618,11 +638,11 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
<!-- android:taskAffinity="${applicationId}"-->
|
||||
<!-- android:exported="true" />-->
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
<!-- android:taskAffinity="${applicationId}"-->
|
||||
<!-- android:exported="true" />-->
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
@ -657,45 +677,45 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="com.gh.gamecenter.UMENG" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="com.gh.gamecenter.UMENG" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<!-- <!–魅族push应用定义消息receiver声明 –>-->
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <!– 接收push消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.MESSAGE" />-->
|
||||
<!-- <!– 接收register消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 接收unregister消息–>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 兼容低版本Flyme3推送服务配置 –>-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.REGISTRATION" />-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.RECEIVE" />-->
|
||||
<!-- <!–魅族push应用定义消息receiver声明 –>-->
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <!– 接收push消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.MESSAGE" />-->
|
||||
<!-- <!– 接收register消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 接收unregister消息–>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 兼容低版本Flyme3推送服务配置 –>-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.REGISTRATION" />-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.RECEIVE" />-->
|
||||
|
||||
<!-- <category android:name="${applicationId}" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
<!-- <category android:name="${applicationId}" />-->
|
||||
<!-- </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"-->
|
||||
<!-- android:value="@string/huawei_push_appid" />-->
|
||||
<!-- <meta-data-->
|
||||
<!-- android:name="com.huawei.hms.client.appid"-->
|
||||
<!-- android:value="@string/huawei_push_appid" />-->
|
||||
|
||||
<!-- <service-->
|
||||
<!-- android:name="com.gh.base.GHUmengNotificationService"-->
|
||||
<!-- android:permission="android.permission.BIND_JOB_SERVICE" />-->
|
||||
<!-- <service-->
|
||||
<!-- android:name="com.gh.base.GHUmengNotificationService"-->
|
||||
<!-- android:permission="android.permission.BIND_JOB_SERVICE" />-->
|
||||
|
||||
<!--<service android:name = "com.gh.gamecenter.statistics.AppStaticService" />-->
|
||||
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
emoji_kf_1.png,:smile:
|
||||
emoji_kf_2.png,:smiley:
|
||||
emoji_kf_3.png,:laughing:
|
||||
emoji_kf_4.png,:blush:
|
||||
emoji_kf_5.png,:heart_eyes:
|
||||
emoji_kf_6.png,:smirk:
|
||||
emoji_kf_7.png,:flushed:
|
||||
emoji_kf_8.png,:kissing_heart:
|
||||
emoji_kf_9.png,:grin:
|
||||
emoji_kf_10.png,:wink:
|
||||
emoji_kf_11.png,:stuck_out_tongue_winking_eye:
|
||||
emoji_kf_12.png,:stuck_out_tongue_closed eyes:
|
||||
emoji_kf_13.png,:worried:
|
||||
emoji_kf_14.png,:sleeping:
|
||||
emoji_kf_15.png,:expressionless:
|
||||
emoji_kf_16.png,:sweat_smile:
|
||||
emoji_kf_17.png,:joy:
|
||||
emoji_kf_18.png,:cold_sweat:
|
||||
emoji_kf_19.png,:sob:
|
||||
emoji_kf_20.png,:angry:
|
||||
emoji_kf_21.png,:mask:
|
||||
emoji_kf_22.png,:scream:
|
||||
emoji_kf_23.png,:sunglasses:
|
||||
emoji_kf_24.png,:heart:
|
||||
emoji_kf_25.png,:broken_heart:
|
||||
emoji_kf_26.png,:star:
|
||||
emoji_kf_27.png,:anger:
|
||||
emoji_kf_28.png,:exclamation:
|
||||
emoji_kf_29.png,:question:
|
||||
emoji_kf_30.png,:zzz:
|
||||
emoji_kf_31.png,:thumbsup:
|
||||
emoji_kf_32.png,:thumbsdown:
|
||||
emoji_kf_33.png,:ok_hand:
|
||||
emoji_kf_34.png,:punch:
|
||||
emoji_kf_35.png,:yeah:
|
||||
emoji_kf_36.png,:clap:
|
||||
emoji_kf_37.png,:muscle:
|
||||
emoji_kf_38.png,:pray:
|
||||
emoji_kf_39.png,:skull:
|
||||
emoji_kf_40.png,:trollface:
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
@ -1,5 +0,0 @@
|
||||
# This is a simple Microlog configuration file
|
||||
microlog.level=DEBUG
|
||||
microlog.appender=LogCatAppender;FileAppender
|
||||
microlog.formatter=PatternFormatter
|
||||
microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,161 +1,493 @@
|
||||
<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>
|
||||
<!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>
|
||||
<style>
|
||||
* {
|
||||
-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>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
</body></html>
|
||||
.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>
|
||||
|
||||
@ -26,6 +26,8 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import io.sentry.core.Sentry;
|
||||
|
||||
public class AppUncaughtHandler implements UncaughtExceptionHandler {
|
||||
|
||||
private Context mContext;
|
||||
@ -45,7 +47,9 @@ public class AppUncaughtHandler implements UncaughtExceptionHandler {
|
||||
Looper.loop();
|
||||
}
|
||||
});
|
||||
|
||||
saveLocalLog(mContext, ex);
|
||||
Sentry.captureException(ex);
|
||||
restart(mContext);
|
||||
}
|
||||
|
||||
|
||||
@ -32,13 +32,17 @@ import com.gh.common.util.ExtensionsKt;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.RunningUtils;
|
||||
import com.gh.common.util.SPUtils;
|
||||
import com.gh.common.util.ShareUtils;
|
||||
import com.gh.common.util.StringUtils;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.LoginActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.SplashScreenActivity;
|
||||
import com.gh.gamecenter.eventbus.EBShowDialog;
|
||||
import com.lightgame.BaseAppCompatActivity;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.tauth.Tencent;
|
||||
@ -122,6 +126,23 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("ACTIVITY_ENTRANCE -> " + mEntrance);
|
||||
}
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
String xapkUnzipActivity = SPUtils.getString(Constants.SP_XAPK_UNZIP_ACTIVITY);
|
||||
String xapkUrl = SPUtils.getString(Constants.SP_XAPK_URL);
|
||||
Utils.log("页面重建了--" + xapkUnzipActivity + "--" + xapkUrl);
|
||||
if (this.getClass().getName().equals(SplashScreenActivity.class.getName())) {
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "");
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, "");
|
||||
return;
|
||||
}
|
||||
if (this.getClass().getName().equals(xapkUnzipActivity) && !TextUtils.isEmpty(xapkUrl)) {
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance(this).getDownloadEntityByUrl(xapkUrl);
|
||||
PackageInstaller.install(this, downloadEntity, false);
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "");
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
|
||||
@ -81,8 +81,13 @@ public class WaitingDialogFragment extends BaseDialogFragment {
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
dismissAllowingStateLoss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissAllowingStateLoss() {
|
||||
mBackListener = null;
|
||||
super.dismiss();
|
||||
super.dismissAllowingStateLoss();
|
||||
}
|
||||
|
||||
public static class WaitingDialogData {
|
||||
|
||||
@ -252,6 +252,11 @@ class DefaultJsApi(var context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun openInNewWebview(url: Any) {
|
||||
runOnUiThread { DirectUtils.directToWebView(context, url.toString(), "内部网页") }
|
||||
}
|
||||
|
||||
@Keep
|
||||
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
|
||||
|
||||
|
||||
@ -129,6 +129,11 @@ public class Constants {
|
||||
|
||||
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";
|
||||
//包名检测是否点击不再提示
|
||||
public static final String SP_PACKAGE_CHECK = "package_check";
|
||||
|
||||
public static final String SP_XAPK_UNZIP_ACTIVITY = "xapk_unzip_activity";
|
||||
public static final String SP_XAPK_URL = "xapk_url";
|
||||
|
||||
//手机号码匹配规则
|
||||
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
||||
|
||||
@ -14,10 +14,17 @@ 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;
|
||||
import com.gh.common.dialog.CertificationDialog;
|
||||
import com.gh.common.dialog.PackageCheckDialogFragment;
|
||||
import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
@ -38,7 +45,6 @@ import com.gh.common.util.NewsUtils;
|
||||
import com.gh.common.util.NumberUtils;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.PermissionHelper;
|
||||
import com.gh.common.util.PlatformUtils;
|
||||
import com.gh.common.util.ReservationHelper;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
@ -74,12 +80,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
/**
|
||||
* Created by khy on 12/02/18.
|
||||
*/
|
||||
@ -256,6 +256,14 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lazy 的 paddingTop
|
||||
*/
|
||||
@BindingAdapter("lazyPaddingLeft")
|
||||
public static void lazyPaddingLeft(View view, int paddingLeftInDp) {
|
||||
view.setPadding(DisplayUtils.dip2px(paddingLeftInDp), view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom());
|
||||
}
|
||||
|
||||
/**
|
||||
* lazy 的 paddingTop
|
||||
*/
|
||||
@ -448,12 +456,14 @@ public class BindingAdapters {
|
||||
return;
|
||||
}
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity.getPackageDialog(), () -> {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -509,13 +519,11 @@ public class BindingAdapters {
|
||||
break;
|
||||
case RESERVABLE:
|
||||
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
|
||||
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(progressBar.getContext(), () -> {
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(gameEntity, () -> {
|
||||
LogUtils.logReservation(gameEntity, traceEvent);
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
dialogFragment.show(((AppCompatActivity) progressBar.getContext()).getSupportFragmentManager(), "reserve");
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(gameEntity, () -> {
|
||||
LogUtils.logReservation(gameEntity, traceEvent);
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
dialogFragment.show(((AppCompatActivity) progressBar.getContext()).getSupportFragmentManager(), "reserve");
|
||||
});
|
||||
break;
|
||||
case RESERVED:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -118,7 +118,9 @@ class CertificationDialog(context: Context, private val authDialogEntity: AuthDi
|
||||
|
||||
//跳转登录页面
|
||||
private fun gotoLoginPage() {
|
||||
CheckLoginUtils.checkLogin(AppManager.getInstance().currentActivity() as AppCompatActivity,
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
CheckLoginUtils.checkLogin(currentActivity as AppCompatActivity,
|
||||
null, true, "实名认证弹窗") {
|
||||
if (UserManager.getInstance().isAuth) {
|
||||
listener.onConfirm()
|
||||
@ -129,7 +131,9 @@ class CertificationDialog(context: Context, private val authDialogEntity: AuthDi
|
||||
|
||||
//跳转实名认证页面
|
||||
private fun gotoAuthPage() {
|
||||
AvoidOnResultManager.getInstance(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity)
|
||||
.startForResult(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD), object : Callback {
|
||||
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
|
||||
@ -48,7 +48,7 @@ class GameOffServiceDialogFragment
|
||||
siteTv.setOnClickListener {
|
||||
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
|
||||
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
container.addView(siteTv)
|
||||
|
||||
@ -13,16 +13,19 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.util.PermissionHelper
|
||||
import com.gh.common.util.PermissionHelper.INSTALL_PERMISS_CODE
|
||||
import com.gh.common.util.goneIf
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.PermissionHelper.INSTALL_PERMISSION_CODE
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.gamecenter.R
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import kotlin.random.Random
|
||||
|
||||
class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
|
||||
|
||||
lateinit var mView: View
|
||||
var isXapk = false
|
||||
var url: String = ""
|
||||
var mCallBack: (() -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
@ -35,16 +38,26 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
|
||||
val closeTv = mView.findViewById<TextView>(R.id.closeTv)
|
||||
val closeIv = mView.findViewById<ImageView>(R.id.closeIv)
|
||||
val activateTv = mView.findViewById<TextView>(R.id.activateTv)
|
||||
val contentTv = mView.findViewById<TextView>(R.id.contentTv)
|
||||
val switchLottie = mView.findViewById<LottieAnimationView>(R.id.switchLottie)
|
||||
contentTv.text = if (isXapk) "未授权下解压XAPK可能导致解压失败" else "以保证游戏的安装和更新"
|
||||
|
||||
switchLottie.setAnimation("lottie/install_permission_switch.json")
|
||||
switchLottie.playAnimation()
|
||||
|
||||
val randomNumber = Random.nextInt(2)
|
||||
val randomNumber = if (isXapk) 1 else Random.nextInt(2)
|
||||
closeTv.goneIf(randomNumber == 0)
|
||||
closeIv.goneIf(randomNumber != 0)
|
||||
if (isXapk) {
|
||||
closeTv.text = "暂不,尝试解压"
|
||||
closeIv.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
closeTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), "文案样式_点击以后再说")
|
||||
if (isXapk) {
|
||||
mCallBack?.invoke()
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
closeIv.setOnClickListener {
|
||||
@ -54,12 +67,18 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
|
||||
activateTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), if (randomNumber == 0) "文案样式_点击立即开启" else "图标样式_点击立即开启")
|
||||
PermissionHelper.toInstallPermissionSetting(requireActivity())
|
||||
if (isXapk) {
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, requireActivity().javaClass.name)
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISS_CODE) {
|
||||
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) {
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, "")
|
||||
mCallBack?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
@ -71,30 +90,43 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(activity: AppCompatActivity, callBack: (() -> Unit)?) {
|
||||
fun show(activity: AppCompatActivity, downloadEntity: DownloadEntity, callBack: (() -> Unit)?) {
|
||||
val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == downloadEntity.path.getExtension()
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
if (!Config.isPermissionPopupSwitchOpen()) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
val haveInstallPermission = activity.packageManager.canRequestPackageInstalls();
|
||||
val haveInstallPermission = activity.packageManager.canRequestPackageInstalls()
|
||||
if (haveInstallPermission) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
|
||||
}
|
||||
if (isXapk) {
|
||||
val xapkUnzipVersions = Config.getSettings()?.permissionPopupAppliedVersions?.xapkUnzip
|
||||
if (xapkUnzipVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
val installVersions = Config.getSettings()?.permissionPopupAppliedVersions?.install
|
||||
if (installVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
}
|
||||
var installPermissionDialogFragment = activity.supportFragmentManager.findFragmentByTag(InstallPermissionDialogFragment::class.java.simpleName) as? InstallPermissionDialogFragment
|
||||
if (installPermissionDialogFragment != null) {
|
||||
installPermissionDialogFragment.mCallBack = callBack
|
||||
installPermissionDialogFragment.isXapk = isXapk
|
||||
installPermissionDialogFragment.url = downloadEntity.url
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(installPermissionDialogFragment)
|
||||
transaction.commit()
|
||||
} else {
|
||||
installPermissionDialogFragment = InstallPermissionDialogFragment().apply {
|
||||
mCallBack = callBack
|
||||
this.mCallBack = callBack
|
||||
this.isXapk = isXapk
|
||||
this.url = downloadEntity.url
|
||||
}
|
||||
installPermissionDialogFragment.show(activity.supportFragmentManager, InstallPermissionDialogFragment::class.java.simpleName)
|
||||
}
|
||||
|
||||
@ -0,0 +1,305 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.view.CustomLinkMovementMethod
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.FragmentPackageCheckBinding
|
||||
import com.gh.gamecenter.databinding.PackageCheckItemBinding
|
||||
import com.gh.gamecenter.entity.DetectionObjectEntity
|
||||
import com.gh.gamecenter.entity.PackageDialogEntity
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
import com.lightgame.dialog.BaseDialogFragment
|
||||
import io.reactivex.disposables.Disposable
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
/**
|
||||
* 包名检测弹窗
|
||||
*/
|
||||
class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private lateinit var binding: FragmentPackageCheckBinding
|
||||
private var mTotalWidth = 0f
|
||||
private val mDuration = 3000
|
||||
private var mDisposable: Disposable? = null
|
||||
private var mAdapter: PackageCheckAdapter? = null
|
||||
var packageDialogEntity: PackageDialogEntity? = null
|
||||
var callBack: DialogUtils.ConfirmListener? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = FragmentPackageCheckBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
packageDialogEntity?.let {
|
||||
changeParams(it.detectionObjects.size)
|
||||
|
||||
binding.packageRv.layoutManager = LinearLayoutManager(requireContext())
|
||||
mAdapter = PackageCheckAdapter(requireContext(), it.detectionObjects)
|
||||
binding.packageRv.adapter = mAdapter
|
||||
|
||||
binding.titleTv.text = it.title
|
||||
binding.contentTv.text = it.content
|
||||
|
||||
val spanBuilder = SpanBuilder(it.linkHintText).build()
|
||||
it.links.forEachIndexed { index, link ->
|
||||
val linkSpan = SpanBuilder(link.title ?: "").click(0, (link.title
|
||||
?: "").length, R.color.theme_font, true) {
|
||||
DirectUtils.directToLinkPage(requireContext(), link, "包名检测弹窗", "")
|
||||
}.build()
|
||||
spanBuilder.append(linkSpan)
|
||||
if (index != it.links.size - 1) {
|
||||
spanBuilder.append("、")
|
||||
}
|
||||
}
|
||||
binding.linkHintTv.text = spanBuilder
|
||||
binding.linkHintTv.movementMethod = CustomLinkMovementMethod.getInstance()
|
||||
|
||||
when (it.level) {
|
||||
"HINT_SKIP" -> {
|
||||
binding.cancelTv.text = "取消"
|
||||
binding.noRemindAgainCb.visibility = View.GONE
|
||||
}
|
||||
"ALWAYS_HINT" -> {
|
||||
binding.cancelTv.text = "我知道了"
|
||||
binding.noRemindAgainCb.visibility = View.GONE
|
||||
}
|
||||
else -> {
|
||||
binding.cancelTv.text = "我知道了"
|
||||
binding.noRemindAgainCb.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
initListener(it)
|
||||
}
|
||||
checkPackage()
|
||||
}
|
||||
|
||||
private fun changeParams(size: Int) {
|
||||
val params = binding.packageRv.layoutParams as LinearLayout.LayoutParams
|
||||
params.height = if (size > 3) (28f.dip2px() * 3.5).toInt() else 28f.dip2px() * size
|
||||
binding.packageRv.layoutParams = params
|
||||
}
|
||||
|
||||
private fun initListener(entity: PackageDialogEntity) {
|
||||
binding.downloadBtn.setOnClickListener {
|
||||
if (binding.noRemindAgainCb.isChecked) {
|
||||
SPUtils.setBoolean(Constants.SP_PACKAGE_CHECK, true)
|
||||
}
|
||||
val isAllPackageInstalled = isAllPackageInstalled(entity)
|
||||
if (isAllPackageInstalled) {
|
||||
callBack?.onConfirm()
|
||||
dismissAllowingStateLoss()
|
||||
} else {
|
||||
val packageLink = entity.links.find { it.buttonLink }
|
||||
if (packageLink != null) {
|
||||
DirectUtils.directToLinkPage(requireContext(), packageLink, "包名检测弹窗", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.cancelTv.setOnClickListener {
|
||||
if (entity.level != "HINT_SKIP") {
|
||||
callBack?.onConfirm()
|
||||
}
|
||||
if (binding.noRemindAgainCb.isChecked) {
|
||||
SPUtils.setBoolean(Constants.SP_PACKAGE_CHECK, true)
|
||||
}
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkPackage() {
|
||||
var index = 0
|
||||
mTotalWidth = (DisplayUtils.getScreenWidth() - 108f.dip2px()).toFloat()
|
||||
mDisposable = rxTimer(1) {
|
||||
val width = (mTotalWidth / mDuration) * it
|
||||
val params = binding.progressView.layoutParams as RelativeLayout.LayoutParams
|
||||
params.width = width.toInt()
|
||||
binding.progressView.layoutParams = params
|
||||
|
||||
packageDialogEntity?.detectionObjects?.let { objects ->
|
||||
if (objects.isNotEmpty()) {
|
||||
val averageTime = if (objects.size == 1) {
|
||||
mDuration
|
||||
} else {
|
||||
mDuration / objects.size
|
||||
}
|
||||
if (it != 0L && it % averageTime == 0L && index < objects.size) {
|
||||
mAdapter?.notifyPackages()
|
||||
binding.packageRv.smoothScrollToPosition(index)
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (it >= mDuration) {
|
||||
mDisposable?.dispose()
|
||||
binding.downloadBtn.isEnabled = true
|
||||
binding.progressText.text = "检测完成"
|
||||
binding.progressView.background = ContextCompat.getDrawable(requireContext(), R.drawable.package_check_complete_bg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val width = requireContext().resources.displayMetrics.widthPixels - 60F.dip2px()
|
||||
val height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
dialog?.window?.setLayout(width, height)
|
||||
dialog?.setCanceledOnTouchOutside(true)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
packageDialogEntity?.let {
|
||||
if (isAllPackageInstalled(it)) {
|
||||
callBack?.onConfirm()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
EventBus.getDefault().unregister(this)
|
||||
if (mDisposable?.isDisposed == false) {
|
||||
mDisposable?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
//安装、卸载事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if ("安装" == busFour.type || "卸载" == busFour.type) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
class PackageCheckAdapter(val context: Context, val entities: ArrayList<DetectionObjectEntity>) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
|
||||
private var index = -1
|
||||
|
||||
fun notifyPackages() {
|
||||
index++
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return PackageCheckViewHolder(PackageCheckItemBinding.bind(LayoutInflater.from(context).inflate(R.layout.package_check_item, parent, false)))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = entities.size
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is PackageCheckViewHolder) {
|
||||
val entity = entities[position]
|
||||
holder.binding.entity = entity
|
||||
if (position <= index) {
|
||||
var isAllInstalled = false
|
||||
entity.packages.forEach { packageName ->
|
||||
val isInstalled = PackageUtils.getInstalledPackages(context, 0).find { it.packageName == packageName } != null
|
||||
if (isInstalled) {
|
||||
isAllInstalled = true
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
if (isAllInstalled) {
|
||||
holder.binding.statusTv.text = "已安装"
|
||||
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font))
|
||||
} else {
|
||||
holder.binding.statusTv.text = "未安装"
|
||||
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.text_FF4147))
|
||||
}
|
||||
holder.binding.statusTv.visibility = View.VISIBLE
|
||||
} else {
|
||||
holder.binding.statusTv.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PackageCheckViewHolder(val binding: PackageCheckItemBinding) : BaseRecyclerViewHolder<DetectionObjectEntity>(binding.root)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(activity: AppCompatActivity, packageDialogEntity: PackageDialogEntity?, callBack: DialogUtils.ConfirmListener) {
|
||||
if (packageDialogEntity == null) {
|
||||
callBack.onConfirm()
|
||||
return
|
||||
}
|
||||
if (isAllPackageInstalled(packageDialogEntity)) {
|
||||
callBack.onConfirm()
|
||||
return
|
||||
}
|
||||
val isChoose = SPUtils.getBoolean(Constants.SP_PACKAGE_CHECK, false)
|
||||
if (packageDialogEntity.level == "OPTIONAL_HINT" && isChoose) {
|
||||
callBack.onConfirm()
|
||||
return
|
||||
}
|
||||
|
||||
var dialogFragment = activity.supportFragmentManager.findFragmentByTag(PackageCheckDialogFragment::class.java.simpleName) as? PackageCheckDialogFragment
|
||||
if (dialogFragment == null) {
|
||||
dialogFragment = PackageCheckDialogFragment()
|
||||
dialogFragment.packageDialogEntity = packageDialogEntity
|
||||
dialogFragment.callBack = callBack
|
||||
|
||||
dialogFragment.show(activity.supportFragmentManager, PackageCheckDialogFragment::class.java.simpleName)
|
||||
} else {
|
||||
dialogFragment.packageDialogEntity = packageDialogEntity
|
||||
dialogFragment.callBack = callBack
|
||||
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(dialogFragment)
|
||||
transaction.commit()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun isAllPackageInstalled(packageDialogEntity: PackageDialogEntity): Boolean {
|
||||
var isAllInstalled = true
|
||||
|
||||
val isPackagesInstall: (ArrayList<String>) -> Boolean = { packages ->
|
||||
var isPackagesInstalled = false
|
||||
packages.forEach {packageName->
|
||||
val isInstalled = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0).find { it.packageName == packageName } != null
|
||||
if (isInstalled) {
|
||||
isPackagesInstalled = true
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
isPackagesInstalled
|
||||
}
|
||||
|
||||
packageDialogEntity.detectionObjects.forEach loop@{ obj ->
|
||||
if (!isPackagesInstall(obj.packages)) {
|
||||
isAllInstalled = false
|
||||
return isAllInstalled
|
||||
}
|
||||
}
|
||||
return isAllInstalled
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,23 +2,27 @@ package com.gh.common.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.TextPaint
|
||||
import android.text.method.ScrollingMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.view.*
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.gh.base.fragment.BaseDialogFragment
|
||||
import com.gh.common.util.DirectUtils.directToExternalBrowser
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.common.view.CustomLinkMovementMethod
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
class PrivacyDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private val mLocalPrivacyHtml = "file:///android_asset/privacy_policies.html"
|
||||
private val mLocalRegulationHtml = "file:///android_asset/user_regulation.html"
|
||||
// private val mLocalPrivacyHtml = "file:///android_asset/privacy_policies.html"
|
||||
// private val mLocalRegulationHtml = "file:///android_asset/user_regulation.html"
|
||||
|
||||
var containerView: View? = null
|
||||
var mCallBack: ((isSuccess: Boolean) -> Unit)? = null
|
||||
@ -30,83 +34,80 @@ class PrivacyDialogFragment : BaseDialogFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
|
||||
val mWebViewRegulation = containerView?.findViewById<WebView>(R.id.webView2)
|
||||
// val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
|
||||
// val mWebViewRegulation = containerView?.findViewById<WebView>(R.id.webView2)
|
||||
//
|
||||
// mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
|
||||
// mWebViewRegulation?.isHorizontalScrollBarEnabled = false
|
||||
|
||||
mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
|
||||
mWebViewRegulation?.isHorizontalScrollBarEnabled = false
|
||||
val contentTv = containerView?.findViewById<TextView>(R.id.contentTv)
|
||||
val descTv = containerView?.findViewById<TextView>(R.id.descTv)
|
||||
contentTv?.movementMethod = ScrollingMovementMethod()
|
||||
|
||||
val mTitlePrivacyTv = containerView?.findViewById<TextView>(R.id.privacyTitleTv)
|
||||
val mTitleRegulationTv = containerView?.findViewById<TextView>(R.id.userRegulationTitleTv)
|
||||
|
||||
val settingsArrayList = arrayListOf(mWebViewPrivacy?.settings, mWebViewRegulation?.settings)
|
||||
|
||||
for (settings in settingsArrayList) {
|
||||
settings?.javaScriptEnabled = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
settings?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
|
||||
}
|
||||
// 避免提示网页有害信息不能访问
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
settings?.safeBrowsingEnabled = false
|
||||
val skipText = SpannableStringBuilder("查看完整版的隐私政策和用户协议")
|
||||
skipText.setSpan(object : ClickableSpan() {
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
super.updateDrawState(ds)
|
||||
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
|
||||
ds.isUnderlineText = false
|
||||
}
|
||||
|
||||
// 适配大于屏幕宽度的页面
|
||||
settings?.useWideViewPort = true
|
||||
settings?.loadWithOverviewMode = true
|
||||
settings?.domStorageEnabled = true
|
||||
|
||||
// 自适应屏幕
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
settings?.layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||
override fun onClick(widget: View) {
|
||||
directToExternalBrowser(context!!, context!!.getString(R.string.privacy_policy_url))
|
||||
}
|
||||
}
|
||||
}, skipText.length - 9, skipText.length - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
|
||||
// if (NetworkUtils.isNetworkConnected(requireContext())) {
|
||||
// mWebViewPrivacy?.loadUrl(requireContext().getString(R.string.privacy_policy_url))
|
||||
// mWebViewRegulation?.loadUrl(requireContext().getString(R.string.user_regulation_url))
|
||||
// } else {
|
||||
mWebViewPrivacy?.loadUrl(mLocalPrivacyHtml)
|
||||
mWebViewRegulation?.loadUrl(mLocalRegulationHtml)
|
||||
// }
|
||||
skipText.setSpan(object : ClickableSpan() {
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
super.updateDrawState(ds)
|
||||
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
|
||||
ds.isUnderlineText = false
|
||||
}
|
||||
|
||||
// val client = object : WebViewClient() {
|
||||
// override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
|
||||
// super.onReceivedError(view, request, error)
|
||||
// if (view == mWebViewPrivacy) {
|
||||
// view?.loadUrl(mLocalPrivacyHtml)
|
||||
// } else {
|
||||
// view?.loadUrl(mLocalRegulationHtml)
|
||||
// }
|
||||
override fun onClick(widget: View) {
|
||||
directToExternalBrowser(requireContext(), requireContext().getString(R.string.disclaimer_url))
|
||||
}
|
||||
}, skipText.length - 4, skipText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
descTv?.movementMethod = CustomLinkMovementMethod()
|
||||
descTv?.text = skipText
|
||||
|
||||
// val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
|
||||
//
|
||||
// mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
|
||||
//
|
||||
// val settingsArrayList = arrayListOf(mWebViewPrivacy?.settings, mWebViewRegulation?.settings)
|
||||
//
|
||||
// for (settings in settingsArrayList) {
|
||||
// settings?.javaScriptEnabled = true
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// settings?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
|
||||
// }
|
||||
// // 避免提示网页有害信息不能访问
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// settings?.safeBrowsingEnabled = false
|
||||
// }
|
||||
//
|
||||
// // 适配大于屏幕宽度的页面
|
||||
// settings?.useWideViewPort = true
|
||||
// settings?.loadWithOverviewMode = true
|
||||
// settings?.domStorageEnabled = true
|
||||
//
|
||||
// // 自适应屏幕
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// settings?.layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||
// }
|
||||
// }
|
||||
|
||||
// mWebViewPrivacy?.webViewClient = client
|
||||
// mWebViewRegulation?.webViewClient = client
|
||||
|
||||
mTitlePrivacyTv?.setOnClickListener {
|
||||
mTitlePrivacyTv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
|
||||
mTitleRegulationTv?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_F5F5F5))
|
||||
|
||||
mWebViewPrivacy?.visibility = View.VISIBLE
|
||||
mWebViewRegulation?.visibility = View.GONE
|
||||
}
|
||||
|
||||
mTitleRegulationTv?.setOnClickListener {
|
||||
mTitlePrivacyTv?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_F5F5F5))
|
||||
mTitleRegulationTv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
|
||||
|
||||
mWebViewPrivacy?.visibility = View.GONE
|
||||
mWebViewRegulation?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
containerView?.findViewById<View>(R.id.refuseTv)?.setOnClickListener {
|
||||
mCallBack?.invoke(false)
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
containerView?.findViewById<View>(R.id.agreeTv)?.setOnClickListener {
|
||||
mCallBack?.invoke(true)
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ object MetaUtil {
|
||||
|
||||
private var m: Meta? = null
|
||||
private var imei: String? = null
|
||||
private var base64EncodedImei: String? = null
|
||||
private var androidId: String? = null
|
||||
|
||||
fun refreshMeta() {
|
||||
@ -104,6 +105,20 @@ object MetaUtil {
|
||||
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getBase64EncodedIMEI(): String {
|
||||
if (TextUtils.isEmpty(base64EncodedImei) && imei != null) {
|
||||
try {
|
||||
base64EncodedImei = android.util.Base64.encodeToString(getIMEI().trim().toByteArray(), android.util.Base64.NO_WRAP)
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
return base64EncodedImei ?: ""
|
||||
}
|
||||
|
||||
fun getModel(): String? {
|
||||
return Build.MODEL
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import com.gh.common.runOnIoThread
|
||||
import com.gh.common.util.clearHtmlFormatCompletely
|
||||
import com.gh.common.util.removeInsertedContent
|
||||
import com.gh.common.util.removeVideoContent
|
||||
import com.gh.common.util.tryCatchInRelease
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
|
||||
import com.gh.gamecenter.qa.entity.AnswerEntity
|
||||
@ -14,27 +15,28 @@ object HistoryHelper {
|
||||
|
||||
fun insertAnswerEntity(answerDetailEntity: AnswerDetailEntity) {
|
||||
val answerEntity = convertAnswerDetailToAnswer(answerDetailEntity)
|
||||
runOnIoThread { HistoryDatabase.instance.answerDao().addAnswer(answerEntity) }
|
||||
// 偶尔有设备会出现磁盘满了写不进数据库的问题 database or disk is full 异常,毕竟只是插入个本地历史,这里直接捕抓
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.answerDao().addAnswer(answerEntity) } }
|
||||
}
|
||||
|
||||
fun insertArticleEntity(articleDetailEntity: ArticleDetailEntity) {
|
||||
val articleEntity = convertArticleDetailToArticle(articleDetailEntity)
|
||||
runOnIoThread { HistoryDatabase.instance.articleDao().addArticle(articleEntity) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.articleDao().addArticle(articleEntity) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun insertGameEntity(gameEntity: GameEntity) {
|
||||
val historyGameEntity = convertGameEntityToHistoryGameEntity(gameEntity)
|
||||
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun insertGameEntity(updateEntity: GameUpdateEntity) {
|
||||
val historyGameEntity = convertGameUpdateEntityToHistoryGameEntity(updateEntity)
|
||||
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) } }
|
||||
}
|
||||
|
||||
private fun convertGameUpdateEntityToHistoryGameEntity(updateEntity: GameUpdateEntity): HistoryGameEntity{
|
||||
private fun convertGameUpdateEntityToHistoryGameEntity(updateEntity: GameUpdateEntity): HistoryGameEntity {
|
||||
val historyGame = HistoryGameEntity()
|
||||
|
||||
historyGame.orderTag = System.currentTimeMillis()
|
||||
|
||||
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.database.ContentObserver
|
||||
import android.media.AudioManager
|
||||
import android.os.Handler
|
||||
import com.gh.common.util.tryCatchInRelease
|
||||
|
||||
class VolumeObserver(var context: Context, handler: Handler, var callback: MuteCallback? = null)
|
||||
: ContentObserver(handler) {
|
||||
@ -11,14 +12,20 @@ class VolumeObserver(var context: Context, handler: Handler, var callback: MuteC
|
||||
|
||||
init {
|
||||
val audio = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
previousVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
// 部分设备的 audioManager getStreamVolume 内部会触发空指针 :(
|
||||
tryCatchInRelease { previousVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC) }
|
||||
}
|
||||
|
||||
override fun onChange(selfChange: Boolean) {
|
||||
super.onChange(selfChange)
|
||||
|
||||
val audio = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
val currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
var currentVolume = 0
|
||||
|
||||
tryCatchInRelease {
|
||||
// 部分设备(Meizu 7.1.2 M6 Note)的 audioManager getStreamVolume 内部会触发空指针 :(
|
||||
currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
}
|
||||
|
||||
val delta = previousVolume - currentVolume
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.common.simulator
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.ProgressBar
|
||||
@ -116,8 +117,8 @@ class SimulatorDownloadManager private constructor() {
|
||||
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
|
||||
logShowEvent = true
|
||||
)
|
||||
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, {
|
||||
if (shouldShowUpdate && isInstalled){
|
||||
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, Gravity.LEFT, {
|
||||
if (shouldShowUpdate && isInstalled) {
|
||||
cancelCallback?.invoke()
|
||||
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ object SimulatorGameManager {
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGames(names: List<String>) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
val downloadEntityList = DownloadManager.getInstance(HaloApp.getInstance().application).allDownloadEntity
|
||||
names.forEach { name ->
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
@ -48,7 +48,7 @@ object SimulatorGameManager {
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGame(name: String) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
val downloadEntityList = DownloadManager.getInstance(HaloApp.getInstance().application).allDownloadEntity
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
val file = File(downloadEntity.path)
|
||||
|
||||
@ -33,6 +33,7 @@ object CommentHelper {
|
||||
showConversation: Boolean,
|
||||
articleId: String,
|
||||
communityId: String,
|
||||
isShowTop: Boolean = false,
|
||||
ignoreModerator: Boolean = false,
|
||||
listener: OnCommentOptionClickListener?) {
|
||||
showCommentOptions(view = view,
|
||||
@ -40,6 +41,7 @@ object CommentHelper {
|
||||
showConversation = showConversation,
|
||||
articleId = articleId,
|
||||
communityId = communityId,
|
||||
isShowTop = isShowTop,
|
||||
ignoreModerator = ignoreModerator,
|
||||
listener = listener)
|
||||
}
|
||||
@ -79,11 +81,16 @@ object CommentHelper {
|
||||
communityId: String? = null,
|
||||
answerId: String? = null,
|
||||
videoId: String? = null,
|
||||
isShowTop: Boolean = false,
|
||||
ignoreModerator: Boolean = false,
|
||||
isVideoAuthor: Boolean = false,
|
||||
listener: OnCommentOptionClickListener? = null) {
|
||||
val context = view.context
|
||||
val dialogOptions = ArrayList<String>()
|
||||
if (isShowTop && articleId != null && commentEntity.me?.isArticleOrAnswerAuthor == true) {
|
||||
dialogOptions.add(if (commentEntity.isTop) "取消置顶" else "置顶")
|
||||
}
|
||||
|
||||
dialogOptions.add("复制")
|
||||
if (commentEntity.user.id != UserManager.getInstance().userId) {
|
||||
dialogOptions.add("投诉")
|
||||
|
||||
@ -2,7 +2,6 @@ package com.gh.common.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
@ -12,6 +11,9 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.gamecenter.CommentDetailActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
|
||||
@ -39,8 +41,6 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.ResponseBody;
|
||||
@ -529,10 +529,7 @@ public class CommentUtils {
|
||||
|
||||
//复制文字
|
||||
public static void copyText(String copyContent, Context context) {
|
||||
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(copyContent);
|
||||
|
||||
ToastUtils.INSTANCE.showToast("复制成功");
|
||||
ExtensionsKt.copyTextAndToast(copyContent, "复制成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,11 +3,13 @@ package com.gh.common.util;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gid.GidCallback;
|
||||
import com.gh.gid.GidHelper;
|
||||
import com.halo.assistant.HaloApp;
|
||||
@ -16,7 +18,10 @@ import com.lightgame.utils.Utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import io.sentry.android.core.SentryAndroid;
|
||||
import io.sentry.core.Sentry;
|
||||
import io.sentry.core.protocol.User;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/6/15.
|
||||
@ -35,6 +40,40 @@ public class DataUtils {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
return;
|
||||
}
|
||||
|
||||
SentryAndroid.init(context, options -> {
|
||||
// Sentry 疯狂报 ANR (很大一部分还是莫名奇妙的 ANR)严重影响到其它闪退日志的收集
|
||||
// 这里将它局限到只有官网渠道的包才统计 ANR
|
||||
if ("GH_206".equals(channel)) {
|
||||
options.setAnrEnabled(true);
|
||||
options.setAnrTimeoutIntervalMillis(6000);
|
||||
} else {
|
||||
options.setAnrEnabled(false);
|
||||
}
|
||||
|
||||
options.setDebug(BuildConfig.DEBUG);
|
||||
options.setEnableSessionTracking(true);
|
||||
options.setEnvironment(BuildConfig.FLAVOR);
|
||||
options.setDsn("https://6b1caf0d17c1408e8680f3f73ff80bd0@sentry.ghzs.com/22");
|
||||
|
||||
options.setBeforeSend((event, hint) -> {
|
||||
if (BuildConfig.DEBUG) {
|
||||
return null;
|
||||
} else {
|
||||
return event;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Sentry.configureScope(scope -> {
|
||||
if (BuildConfig.BUILD_TIME != 0L) {
|
||||
scope.setTag("alias", "内测版" + BuildConfig.VERSION_NAME + "_" + BuildConfig.BUILD_TIME);
|
||||
} else {
|
||||
scope.setTag("alias", "正式版" + BuildConfig.VERSION_NAME);
|
||||
scope.setTag("channel", channel);
|
||||
}
|
||||
});
|
||||
|
||||
//TalkingData
|
||||
// try {
|
||||
// TCAgent.LOG_ON = false;
|
||||
@ -139,8 +178,8 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2) {
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty(var1, var2);
|
||||
// Properties prop = new Properties();
|
||||
// prop.setProperty(var1, var2);
|
||||
// StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
@ -161,64 +200,64 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2, Map<String, Object> var3) {
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty("label", var2);
|
||||
for (String key : var3.keySet()) {
|
||||
prop.setProperty(key, var3.get(key) + "");
|
||||
}
|
||||
// Properties prop = new Properties();
|
||||
// prop.setProperty("label", var2);
|
||||
// for (String key : var3.keySet()) {
|
||||
// prop.setProperty(key, var3.get(key) + "");
|
||||
// }
|
||||
// StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
public static void trackTimeEvent(Context context, String eventId, int costTime, String... kv) {
|
||||
|
||||
Properties prop = new Properties();
|
||||
for (int i = 0; i < kv.length; i++) {
|
||||
if (i % 2 != 0 || i != 0) {
|
||||
String key = kv[i - 1];
|
||||
String value = kv[i];
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.size() == 0) return;
|
||||
|
||||
//
|
||||
// Properties prop = new Properties();
|
||||
// for (int i = 0; i < kv.length; i++) {
|
||||
// if (i % 2 != 0 || i != 0) {
|
||||
// String key = kv[i - 1];
|
||||
// String value = kv[i];
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (prop.size() == 0) return;
|
||||
//
|
||||
// StatService.trackCustomKVTimeIntervalEvent(context, costTime, eventId, prop);
|
||||
}
|
||||
|
||||
// 游戏下载
|
||||
public static void onGameDownloadEvent(Context context, String gameName, String platform, String entrance, String status, String method) {
|
||||
// Map<String, Object> kv = new HashMap<>();
|
||||
//
|
||||
// platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
|
||||
//
|
||||
// kv.put("版本", platform);
|
||||
// kv.put("用户机型", Build.MODEL);
|
||||
// kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
|
||||
// kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
// kv.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
// kv.put("位置", entrance);
|
||||
// kv.put("类型", method);
|
||||
// kv.put("厂商", Build.MANUFACTURER);
|
||||
// kv.put("Android版本", Build.VERSION.RELEASE);
|
||||
// onEvent(context, "游戏下载", gameName, kv);
|
||||
//
|
||||
// Map<String, Object> kv2 = new HashMap<>();
|
||||
// kv2.put("状态", status);
|
||||
// kv2.put("位置", entrance);
|
||||
//
|
||||
// if (status.equals("开始")) {
|
||||
// kv2.put("版本", entrance + "-开始");
|
||||
// kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
|
||||
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
|
||||
// } else {
|
||||
// kv2.put("版本", platform);
|
||||
// kv2.put("游戏分平台", gameName + "-" + platform);
|
||||
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
// }
|
||||
//
|
||||
// onEvent(context, "游戏下载位置", gameName, kv2);
|
||||
Map<String, Object> kv = new HashMap<>();
|
||||
|
||||
platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
|
||||
|
||||
kv.put("版本", platform);
|
||||
kv.put("用户机型", Build.MODEL);
|
||||
kv.put("设备IMEI", MetaUtil.getIMEI());
|
||||
kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
kv.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
kv.put("位置", entrance);
|
||||
kv.put("类型", method);
|
||||
kv.put("厂商", Build.MANUFACTURER);
|
||||
kv.put("Android版本", Build.VERSION.RELEASE);
|
||||
onEvent(context, "游戏下载", gameName, kv);
|
||||
|
||||
Map<String, Object> kv2 = new HashMap<>();
|
||||
kv2.put("状态", status);
|
||||
kv2.put("位置", entrance);
|
||||
|
||||
if (status.equals("开始")) {
|
||||
kv2.put("版本", entrance + "-开始");
|
||||
kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
|
||||
kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
|
||||
} else {
|
||||
kv2.put("版本", platform);
|
||||
kv2.put("游戏分平台", gameName + "-" + platform);
|
||||
kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
}
|
||||
|
||||
onEvent(context, "游戏下载位置", gameName, kv2);
|
||||
}
|
||||
|
||||
// 游戏更新
|
||||
|
||||
@ -350,7 +350,7 @@ public class DialogUtils {
|
||||
* @param cmListener 确认按钮监听
|
||||
*/
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, TrackableEntity trackableEntity, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
, String negative, String positive, TrackableEntity trackableEntity, int gravity, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
context = checkDialogContext(context);
|
||||
final Dialog dialog;
|
||||
if (trackableEntity != null) {
|
||||
@ -373,6 +373,8 @@ public class DialogUtils {
|
||||
TextView cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
TextView confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
View middleLine = contentView.findViewById(R.id.middle_line);
|
||||
titleTv.setGravity(gravity);
|
||||
contentTv.setGravity(gravity);
|
||||
|
||||
titleTv.setText(title);
|
||||
contentTv.setText(message);
|
||||
@ -411,7 +413,7 @@ public class DialogUtils {
|
||||
|
||||
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);
|
||||
return showNewAlertDialog(context, title, message, negative, positive, null, Gravity.LEFT, clListener, cmListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -986,13 +988,13 @@ public class DialogUtils {
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.horizontalMargin = 0;
|
||||
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
|
||||
int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
|
||||
int maxHeight = DisplayUtils.dip2px(446);
|
||||
if (height > maxHeight) {
|
||||
params.height = maxHeight;
|
||||
} else {
|
||||
params.height = height;
|
||||
}
|
||||
// int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
|
||||
// int maxHeight = DisplayUtils.dip2px(446);
|
||||
// if (height > maxHeight) {
|
||||
// params.height = maxHeight;
|
||||
// } else {
|
||||
// params.height = height;
|
||||
// }
|
||||
window.setAttributes(params);
|
||||
}
|
||||
|
||||
@ -1025,8 +1027,6 @@ public class DialogUtils {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_storage);
|
||||
} else if (position == 1) {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_phone_state);
|
||||
} else {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_sdk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import com.gh.common.exposure.ExposureType
|
||||
import com.gh.common.util.EntranceUtils.*
|
||||
import com.gh.gamecenter.*
|
||||
import com.gh.gamecenter.amway.AmwayActivity
|
||||
import com.gh.gamecenter.catalog.CatalogActivity
|
||||
import com.gh.gamecenter.category.CategoryDirectoryActivity
|
||||
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
|
||||
import com.gh.gamecenter.entity.*
|
||||
@ -57,7 +58,6 @@ import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
import com.gh.gamecenter.video.game.GameVideoActivity
|
||||
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_ClipboardManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@ -133,7 +133,9 @@ object DirectUtils {
|
||||
"server",
|
||||
"top_game_comment",
|
||||
"wechat_bind",
|
||||
"video")
|
||||
"video",
|
||||
"catalog"
|
||||
)
|
||||
|
||||
fun directToLinkPage(context: Context,
|
||||
linkEntity: LinkEntity,
|
||||
@ -200,6 +202,8 @@ object DirectUtils {
|
||||
|
||||
"category", "分类" -> directCategoryDirectory(context, linkEntity.link!!, linkEntity.text!!)
|
||||
|
||||
"catalog" -> directCatalog(context, linkEntity.link!!, linkEntity.text!!, entrance, path)
|
||||
|
||||
"block", "版块" -> {
|
||||
if (linkEntity.link.isNullOrEmpty()) return
|
||||
directToBlock(context,
|
||||
@ -575,7 +579,7 @@ object DirectUtils {
|
||||
@JvmStatic
|
||||
fun directToExternalBrowser(context: Context, url: String) {
|
||||
if (url.isEmpty()) return
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Uri.decode(url)))
|
||||
if (context !is AppCompatActivity) {
|
||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
@ -606,8 +610,7 @@ object DirectUtils {
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
// 没有安装QQ 复制账号
|
||||
Util_System_ClipboardManager.setText(context, qq)
|
||||
Utils.toast(context, "已复制 QQ $qq")
|
||||
qq?.copyTextAndToast("已复制 QQ $qq")
|
||||
}
|
||||
}
|
||||
|
||||
@ -889,6 +892,20 @@ object DirectUtils {
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转新分类
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directCatalog(context: Context, catalogId: String, catalogTitle: String, entrance: String? = null, path: String? = "") {
|
||||
if (catalogId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, CatalogActivity::class.java.name)
|
||||
bundle.putString(KEY_CATALOG_ID, catalogId)
|
||||
bundle.putString(KEY_CATALOG_TITLE, catalogTitle)
|
||||
bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到问题标签详情
|
||||
*/
|
||||
|
||||
@ -8,9 +8,16 @@ import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.collection.ArrayMap;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.CertificationDialog;
|
||||
import com.gh.common.dialog.DeviceRemindDialog;
|
||||
import com.gh.common.dialog.PackageCheckDialogFragment;
|
||||
import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
@ -39,12 +46,6 @@ import com.lightgame.utils.Utils;
|
||||
import java.io.File;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.collection.ArrayMap;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* todo 下载判断不能以按钮文案为判断条件,否则按钮文案修改时又要修改判断逻辑
|
||||
*/
|
||||
@ -419,7 +420,7 @@ public class DownloadItemUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clickCallback 供那些需要知道点击回调的地方使用
|
||||
* @param clickCallback 供那些需要知道点击回调的地方使用,触发具体响应才会回调
|
||||
*/
|
||||
public static void setOnClickListener(final Context context,
|
||||
final TextView downloadBtn,
|
||||
@ -431,103 +432,13 @@ public class DownloadItemUtils {
|
||||
final ExposureEvent traceEvent,
|
||||
@Nullable final EmptyCallback clickCallback) {
|
||||
|
||||
if (gameEntity.isReservable()) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
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 -> {
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
setOnClickListener(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent, clickCallback, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clickCallback 供那些需要知道点击回调的地方使用,只要触发了点击事件就响应回调(未登录状态下点击预约也要响应回调)
|
||||
* @param allStateClickCallback 供那些需要知道点击回调的地方使用,只要触发点击动作就会回调
|
||||
*/
|
||||
public static void setOnClickListenerWithInvokeCallbackForAllState(final Context context,
|
||||
public static void setOnClickListener(final Context context,
|
||||
final TextView downloadBtn,
|
||||
final GameEntity gameEntity,
|
||||
final int position,
|
||||
@ -535,29 +446,36 @@ public class DownloadItemUtils {
|
||||
final String entrance,
|
||||
final String location,
|
||||
final ExposureEvent traceEvent,
|
||||
@Nullable final EmptyCallback clickCallback) {
|
||||
@Nullable final EmptyCallback clickCallback,
|
||||
@Nullable final EmptyCallback allStateClickCallback) {
|
||||
|
||||
if (gameEntity.isReservable()) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
if (allStateClickCallback != null) {
|
||||
allStateClickCallback.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");
|
||||
});
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
|
||||
gameEntity,
|
||||
() -> {
|
||||
LogUtils.logReservation(gameEntity, traceEvent);
|
||||
adapter.notifyItemChanged(position);
|
||||
}
|
||||
);
|
||||
dialogFragment.show(((AppCompatActivity) context).getSupportFragmentManager(), "reserve");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (allStateClickCallback != null) {
|
||||
allStateClickCallback.onCallback();
|
||||
}
|
||||
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
@ -581,9 +499,10 @@ public class DownloadItemUtils {
|
||||
|
||||
if (gameEntity.getApk().size() == 0 && gameEntity.getH5Link() != null) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
if (allStateClickCallback != null) {
|
||||
allStateClickCallback.onCallback();
|
||||
}
|
||||
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
|
||||
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
@ -599,6 +518,10 @@ public class DownloadItemUtils {
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
EmptyCallback clickRunnable = () -> {
|
||||
if (allStateClickCallback != null) {
|
||||
allStateClickCallback.onCallback();
|
||||
}
|
||||
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
@ -614,6 +537,10 @@ public class DownloadItemUtils {
|
||||
});
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (allStateClickCallback != null) {
|
||||
allStateClickCallback.onCallback();
|
||||
}
|
||||
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
@ -656,24 +583,27 @@ public class DownloadItemUtils {
|
||||
|
||||
if (str.equals(context.getString(R.string.download))) {
|
||||
// 先弹下载弹窗(如果需要的话)
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
PackageCheckDialogFragment.show((AppCompatActivity) context, gameEntity.getPackageDialog(), () -> {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.getId(), gameEntity.getName(), entrance);
|
||||
} else if (str.equals(context.getString(R.string.attempt))) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
PackageCheckDialogFragment.show((AppCompatActivity) context, gameEntity.getPackageDialog(), () -> {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -700,7 +630,7 @@ public class DownloadItemUtils {
|
||||
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);
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
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.exposure.meta.MetaUtil
|
||||
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
|
||||
import com.gh.download.DownloadManager
|
||||
@ -77,9 +76,10 @@ object DownloadObserver {
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
|
||||
// "游戏", downloadEntity.name,
|
||||
// "平台", downloadEntity.platform)
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
DialogUtils.showAlertDialog(AppManager.getInstance().currentActivity(), "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
|
||||
SuggestionActivity.startSuggestionActivity(AppManager.getInstance().currentActivity(),
|
||||
DialogUtils.showAlertDialog(currentActivity, "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
|
||||
SuggestionActivity.startSuggestionActivity(currentActivity,
|
||||
SuggestType.gameQuestion, "notfound",
|
||||
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
|
||||
SimpleGameEntity(gameId, downloadEntity.name, ""))
|
||||
@ -115,7 +115,9 @@ object DownloadObserver {
|
||||
// 会有 ActivityNotFoundException 异常,catch 掉不管了
|
||||
tryWithDefaultCatch {
|
||||
if (Constants.SILENT_UPDATE != downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)) {
|
||||
PackageInstaller.install(mApplication, downloadEntity)
|
||||
// TODO 在 Android 11 上没有授权安装未知应用的权限前第一次调用这个方法系统会杀掉我们的进程...
|
||||
// 没能找到类似的解释,最接近的是这个 https://issuetracker.google.com/issues/154157387,但也只是点授权杀进程而已
|
||||
PackageInstaller.install(mApplication, downloadEntity);
|
||||
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
|
||||
}
|
||||
}
|
||||
@ -140,7 +142,9 @@ object DownloadObserver {
|
||||
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,
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(currentActivity, gameEntity.simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
|
||||
?: "", null)
|
||||
}
|
||||
@ -175,15 +179,15 @@ object DownloadObserver {
|
||||
}
|
||||
|
||||
// 下载过程分析统计
|
||||
val pm = mApplication.packageManager
|
||||
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
|
||||
if (packageInfo == null) {
|
||||
// val pm = mApplication.packageManager
|
||||
// val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, 0)
|
||||
// if (packageInfo == null) {
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
|
||||
// "游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
//
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
|
||||
// "游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.done) {
|
||||
|
||||
@ -215,6 +215,12 @@ public class EntranceUtils {
|
||||
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 final String KEY_MARKET_DETAILS = "market_details";
|
||||
public static final String KEY_CATALOG_ID = "catalogId";
|
||||
public static final String KEY_PRIMARY_CATALOG_ID = "primaryCatalogId";
|
||||
public static final String KEY_PRIMARY_CATALOG_NAME = "primaryCatalogName";
|
||||
public static final String KEY_CATALOG_TITLE = "catalog_title";
|
||||
public static final String KEY_CATALOG_INIT_TITLE = "catalog_init_title";
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.animation.Animator
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
@ -43,8 +44,11 @@ import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.ObservableTransformer
|
||||
import io.reactivex.SingleTransformer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import java.net.URI
|
||||
@ -124,6 +128,20 @@ fun ViewPager.addOnScrollStateChanged(onStateChanged: ((state: Int) -> Unit)? =
|
||||
addOnPageChangeListener(listener)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragment related
|
||||
*/
|
||||
inline fun <reified T : Fragment> Fragment.fragmentFromActivity() =
|
||||
parentFragmentManager.findFragmentByTag(T::class.java.simpleName) as? T
|
||||
?: parentFragmentManager.fragmentFactory.instantiate(requireContext().classLoader, T::class.java.canonicalName) as T
|
||||
|
||||
|
||||
inline fun <reified T : Fragment> Fragment.fragmentFromParentFragment() =
|
||||
childFragmentManager.findFragmentByTag(T::class.java.simpleName) as? T
|
||||
?: childFragmentManager.fragmentFactory.instantiate(requireContext().classLoader, T::class.java.canonicalName) as T
|
||||
|
||||
|
||||
/**
|
||||
* RecyclerView Extensions
|
||||
*/
|
||||
@ -255,23 +273,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()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -329,6 +347,15 @@ fun throwExceptionInDebug(message: String = "", predicate: Boolean = true) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在自动打包的包里弹 toast
|
||||
*/
|
||||
fun toastInInternalRelease(content: String) {
|
||||
if (BuildConfig.BUILD_TIME != 0L) {
|
||||
Utils.toast(HaloApp.getInstance(), content)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动抛出异常
|
||||
*/
|
||||
@ -388,11 +415,25 @@ fun String.getFirstElementDividedByDivider(divider: String): String {
|
||||
return this
|
||||
}
|
||||
|
||||
fun String.copyText() {
|
||||
this.copyTextAndToast("")
|
||||
}
|
||||
|
||||
fun String.copyTextAndToast(toastText: String = "复制成功") {
|
||||
val application = HaloApp.getInstance().application
|
||||
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
cmb.text = this
|
||||
ToastUtils.showToast(toastText)
|
||||
try {
|
||||
val application = HaloApp.getInstance().application
|
||||
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(null, this)
|
||||
cmb.primaryClip = clip
|
||||
|
||||
if (!TextUtils.isEmpty(toastText)) {
|
||||
ToastUtils.showToast(toastText)
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
// 在一些情况下会报以下这样的错误,可能是以浮动窗口显示然后没有焦点?(https://developer.android.com/about/versions/10/privacy/changes#clipboard-data)
|
||||
// java.lang.Throwable: java.lang.SecurityException: com.xunmeng.pinduoduo from uid 10317 not allowed to perform READ_CLIPBOARD
|
||||
ToastUtils.showToast("复制失败,请重试")
|
||||
}
|
||||
}
|
||||
|
||||
fun Map<String, String>.createRequestBody(): RequestBody {
|
||||
@ -436,6 +477,7 @@ fun Float.sp2px(): Int {
|
||||
return (this * scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PopupWindow 自动适配方向
|
||||
* 弹出与锚点右对齐
|
||||
@ -559,6 +601,19 @@ fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayList related
|
||||
*/
|
||||
fun <T> ArrayList<T>.safelyGetInRelease(index: Int): T? {
|
||||
return if (index >= size) {
|
||||
throwExceptionInDebug("这里触发了数组越界,请检查")
|
||||
toastInInternalRelease("这个操作可能触发闪退,请确定复现方式并联系开发处理")
|
||||
null
|
||||
} else {
|
||||
this[index]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截 TextView 中的 Url Span,用应用内页面的形式打开链接
|
||||
* @param shrankText 未展开时的文字
|
||||
@ -849,4 +904,18 @@ fun SeekBar.doOnSeekBarChangeListener(progressChange: ((progress: Int) -> Unit)?
|
||||
onStopTrackingTouch?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun <T> observableToMain(): ObservableTransformer<T, T> {
|
||||
return ObservableTransformer { upstream ->
|
||||
upstream.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> singleToMain(): SingleTransformer<T, T> {
|
||||
return SingleTransformer { upstream ->
|
||||
upstream.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
}
|
||||
@ -78,6 +78,9 @@ public class GameUtils {
|
||||
int pluginCount = 0; // 可插件化数量
|
||||
int updateCount = 0; // 可更新数量
|
||||
int installCount = 0; // 已安装数量
|
||||
|
||||
boolean isRelatedEmulatorInstalled = false; // 若该游戏是模拟器游戏时其对应的模拟器是否已经安装
|
||||
|
||||
DownloadEntity downloadEntity;
|
||||
Object gh_id;
|
||||
apkFor:
|
||||
@ -123,20 +126,26 @@ public class GameUtils {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (isInstalled) {
|
||||
installCount++;
|
||||
isRelatedEmulatorInstalled = true;
|
||||
} else {
|
||||
doneCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (installCount != 0) {
|
||||
|
||||
if (isRelatedEmulatorInstalled && doneCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
}
|
||||
|
||||
if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} 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 (installCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen() && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.attempt);
|
||||
} else {
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.app.Application
|
||||
|
||||
/**
|
||||
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
|
||||
*
|
||||
* 更换帐号 [https://gitlab.ghzs.com/pm/yunying/issues/893]
|
||||
*/
|
||||
object GdtHelper {
|
||||
|
||||
const val NETWORK_TYPE = "NETWORK_TYPE"
|
||||
const val PAGE_TYPE = "PAGE_TYPE"
|
||||
const val CONTENT_TYPE = "CONTENT_TYPE"
|
||||
const val CONTENT_ID = "CONTENT_ID"
|
||||
const val KEYWORD = "KEYWORD"
|
||||
const val GAME_ID = "GAME_ID"
|
||||
const val SCORE = "SCORE"
|
||||
const val PLATFORM = "PLATFORM"
|
||||
|
||||
fun init(application: Application, channel: String) {
|
||||
// if (channel == "GH_728") {
|
||||
// GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
|
||||
// } else if (channel == "GH_729") {
|
||||
// GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
|
||||
// } else {
|
||||
// GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
// }
|
||||
}
|
||||
|
||||
fun logAction(type: String) {
|
||||
// GDTAction.logAction(type)
|
||||
// Utils.log("GDT", type)
|
||||
}
|
||||
|
||||
fun logAction(type: String, vararg kv: String?) {
|
||||
// try {
|
||||
// val actionParam = JSONObject()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// actionParam.put(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
|
||||
// GDTAction.logAction(type, actionParam)
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ object HomePluggableHelper {
|
||||
if (apkList.isNotEmpty()) {
|
||||
val apk = apkList.first()
|
||||
val tag = if (isNever) "never" else apk.version ?: ""
|
||||
mHomePluggableFilterDao.addData(HomePluggableFilterEntity(pkgName = apk.packageName, tag = tag, active = isNever))
|
||||
tryCatchInRelease { mHomePluggableFilterDao.addData(HomePluggableFilterEntity(pkgName = apk.packageName, tag = tag, active = isNever)) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ object HomePluggableHelper {
|
||||
for (entity in filterList) {
|
||||
entity.active = true
|
||||
}
|
||||
mHomePluggableFilterDao.addData(filterList)
|
||||
tryCatchInRelease { mHomePluggableFilterDao.addData(filterList) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,4 +67,15 @@ public class HtmlUtils {
|
||||
|
||||
return htmlStr.trim(); //返回文本字符串
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤掉标签,保留标签内容
|
||||
*/
|
||||
public static String filterHtmlLabel(String htmlStr) {
|
||||
String regEx_html = "<[^>]+>([\\s\\S]*?)<\\/[^>]+>"; //定义HTML标签的正则表达式
|
||||
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
||||
Matcher m_html = p_html.matcher(htmlStr);
|
||||
htmlStr = m_html.replaceAll("$1"); //过滤html标签
|
||||
return htmlStr.trim(); //返回文本字符串
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,68 +279,74 @@ object ImageUtils {
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun display(view: SimpleDraweeView?, url: String?) {
|
||||
display(view, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 规则 width>0 Wifi/4G:x2 traffic:x1
|
||||
* 第一种方案:通过LayoutParams获取 可以快速(无延迟)获取宽高,但是无法获取wrap_content和match_parent的View
|
||||
* 第二种方案(备用方案):有延迟,View的宽高需要在Measure过程后才能确定,能够在这里获取到正确的宽高
|
||||
* @param isAutoPlayGif 是否禁止播放动图
|
||||
*/
|
||||
@JvmStatic
|
||||
fun display(view: SimpleDraweeView?, url: String?) {
|
||||
url?.let {
|
||||
val width = view?.layoutParams?.width
|
||||
val height = view?.layoutParams?.height
|
||||
fun display(view: SimpleDraweeView?, url: String?, isAutoPlayGif: Boolean = true) {
|
||||
if (url == null) return
|
||||
|
||||
var lowResUrl = ""
|
||||
var highResUrl = ""
|
||||
val width = view?.layoutParams?.width
|
||||
val height = view?.layoutParams?.height
|
||||
|
||||
// 找同一图片地址已加载过的图片作为低质量预览图
|
||||
// TODO 根据实际请求大小(w_width)来避免小图用大图作为低质量图片
|
||||
for (cachedImageUrl in mImageUrlCacheSet) {
|
||||
if (cachedImageUrl.contains(url)) {
|
||||
lowResUrl = cachedImageUrl
|
||||
break
|
||||
}
|
||||
var lowResUrl = ""
|
||||
var highResUrl = ""
|
||||
|
||||
// 找同一图片地址已加载过的图片作为低质量预览图
|
||||
// TODO 根据实际请求大小(w_width)来避免小图用大图作为低质量图片
|
||||
for (cachedImageUrl in mImageUrlCacheSet) {
|
||||
if (url.isNotEmpty() && cachedImageUrl.contains(url)) {
|
||||
lowResUrl = cachedImageUrl
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
val loadImageClosure: (autoPlay: Boolean, highResUrl: String, lowResUrl: String) -> Unit = { autoPlay, hUrl, lUrl ->
|
||||
view?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(ImageRequest.fromUri(hUrl))
|
||||
.apply {
|
||||
if (lUrl.isNotEmpty()
|
||||
&& lUrl != hUrl
|
||||
&& hUrl != view?.getTag(R.string.highResImageTag)) {
|
||||
lowResImageRequest = ImageRequest.fromUri(lUrl)
|
||||
}
|
||||
autoPlayAnimations = autoPlay
|
||||
val loadImageClosure: (autoPlay: Boolean, highResUrl: String, lowResUrl: String) -> Unit = { autoPlay, hUrl, lUrl ->
|
||||
view?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(ImageRequest.fromUri(hUrl))
|
||||
.apply {
|
||||
if (lUrl.isNotEmpty()
|
||||
&& lUrl != hUrl
|
||||
&& hUrl != view?.getTag(R.string.highResImageTag)) {
|
||||
lowResImageRequest = ImageRequest.fromUri(lUrl)
|
||||
}
|
||||
.build()
|
||||
autoPlayAnimations = autoPlay
|
||||
}
|
||||
.build()
|
||||
|
||||
view?.setTag(R.string.highResImageTag, highResUrl)
|
||||
view?.setTag(R.string.highResImageTag, highResUrl)
|
||||
}
|
||||
|
||||
val shouldLoadAsGif = url.endsWith(".gif") && isAutoPlayGif && view?.getTag(R.id.tag_show_gif) != false
|
||||
|
||||
if (shouldLoadAsGif && view?.tag == url) return
|
||||
|
||||
if (width != null && width > 0) {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, width, height ?: 0)
|
||||
} else {
|
||||
getTransformLimitUrl(url, width, view.context) ?: ""
|
||||
}
|
||||
|
||||
val shouldLoadAsGif = it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false
|
||||
|
||||
if (shouldLoadAsGif && view?.tag == url) return
|
||||
|
||||
if (width != null && width > 0) {
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
} else {
|
||||
view?.post {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, width, height ?: 0)
|
||||
resizeGif(url, view.width, height ?: 0)
|
||||
} else {
|
||||
getTransformLimitUrl(url, width, view.context) ?: ""
|
||||
getTransformLimitUrl(url, view.width, view.context) ?: ""
|
||||
}
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
} else {
|
||||
view?.post {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, view.width, height ?: 0)
|
||||
} else {
|
||||
getTransformLimitUrl(url, view.width, view.context) ?: ""
|
||||
}
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
}
|
||||
}
|
||||
view?.tag = url
|
||||
}
|
||||
view?.tag = url
|
||||
}
|
||||
|
||||
// Wifi/4G:x2 traffic:x1
|
||||
|
||||
@ -48,7 +48,7 @@ public class InstallUtils {
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.what == INSTALL_WHAT && packageManager != null) {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
|
||||
List<PackageInfo> packageInfos = PackageUtils.getInstalledPackages(context, 0);
|
||||
for (PackageInfo packageInfo : packageInfos) {
|
||||
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
list.add(packageInfo.packageName);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.graphics.Color;
|
||||
@ -11,6 +10,8 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.LibaoDetailAdapter;
|
||||
@ -36,7 +37,6 @@ import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
@ -237,85 +237,160 @@ public class LibaoUtils {
|
||||
|
||||
// 领取限制
|
||||
CheckLoginUtils.checkLogin(context, "礼包详情-[" + btnStatus + "]", () -> {
|
||||
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(context, () -> {
|
||||
if ("领取".equals(btnStatus) || "淘号".equals(btnStatus)) {
|
||||
if (isInstallRequired && !isAppInstalled(context, libaoEntity.getPackageName())) {
|
||||
String platform;
|
||||
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
|
||||
platform = "";
|
||||
} else {
|
||||
platform = PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform());
|
||||
}
|
||||
if ("领取".equals(btnStatus) || "淘号".equals(btnStatus)) {
|
||||
if (isInstallRequired && !isAppInstalled(context, libaoEntity.getPackageName())) {
|
||||
String platform;
|
||||
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
|
||||
platform = "";
|
||||
} else {
|
||||
platform = PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform());
|
||||
}
|
||||
|
||||
boolean isExistPlatform = false;
|
||||
ArrayList<ApkEntity> apk = adapter.getGameEntity().getApk();
|
||||
for (ApkEntity apkEntity : apk) {
|
||||
if (TextUtils.isEmpty(libaoEntity.getPlatform())) break;
|
||||
if (libaoEntity.getPlatform().equals(apkEntity.getPlatform())) {
|
||||
isExistPlatform = true;
|
||||
break;
|
||||
}
|
||||
boolean isExistPlatform = false;
|
||||
ArrayList<ApkEntity> apk = adapter.getGameEntity().getApk();
|
||||
for (ApkEntity apkEntity : apk) {
|
||||
if (TextUtils.isEmpty(libaoEntity.getPlatform())) break;
|
||||
if (libaoEntity.getPlatform().equals(apkEntity.getPlatform())) {
|
||||
isExistPlatform = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String dialogContent = context.getString(R.string.ling_rules_dialog, libaoEntity.getGame().getName(), platform);
|
||||
boolean finalIsExistPlatform = isExistPlatform;
|
||||
DialogUtils.showWarningDialog(context, "条件不符",
|
||||
Html.fromHtml(dialogContent), isExistPlatform ? "关闭" : null,
|
||||
isExistPlatform ? "立即安装" : "关闭",
|
||||
() -> {
|
||||
if (finalIsExistPlatform) {
|
||||
adapter.openDownload(libaoEntity.getPlatform());
|
||||
}
|
||||
}, null);
|
||||
String dialogContent = context.getString(R.string.ling_rules_dialog, libaoEntity.getGame().getName(), platform);
|
||||
boolean finalIsExistPlatform = isExistPlatform;
|
||||
DialogUtils.showWarningDialog(context, "条件不符",
|
||||
Html.fromHtml(dialogContent), isExistPlatform ? "关闭" : null,
|
||||
isExistPlatform ? "立即安装" : "关闭",
|
||||
() -> {
|
||||
if (finalIsExistPlatform) {
|
||||
adapter.openDownload(libaoEntity.getPlatform());
|
||||
}
|
||||
}, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (btnStatus) {
|
||||
case "未开始":
|
||||
Utils.toast(context, "还没到开始领取时间");
|
||||
break;
|
||||
case "查看":
|
||||
if (!TextUtils.isEmpty(libaoEntity.getDes())) {
|
||||
DialogUtils.showAlertDialog(v.getContext(), "使用说明",
|
||||
Html.fromHtml(libaoEntity.getDes()), "关闭", null, null, null);
|
||||
}
|
||||
break;
|
||||
case "再领一个":
|
||||
case "领取":
|
||||
if ("repeatLing".equals(status)) {
|
||||
DialogUtils.showWarningDialog(context, "礼包刷新提醒"
|
||||
, "礼包每天0点刷新,换新区或者换新角色需要继续领取礼包的童鞋,请于明天0点之后回来即可[再领一个]"
|
||||
, null, "知道了", null, null);
|
||||
} else {
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance);
|
||||
}
|
||||
break;
|
||||
case "再淘一个":
|
||||
case "淘号":
|
||||
if ("repeatTao".equals(status)) {
|
||||
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "淘号中...");
|
||||
postLibaoTao(context, libaoEntity.getId(), new PostLibaoListener() {
|
||||
@Override
|
||||
public void postSucceed(Object response) {
|
||||
|
||||
switch (btnStatus) {
|
||||
case "未开始":
|
||||
Utils.toast(context, "还没到开始领取时间");
|
||||
break;
|
||||
case "查看":
|
||||
if (!TextUtils.isEmpty(libaoEntity.getDes())) {
|
||||
DialogUtils.showAlertDialog(v.getContext(), "使用说明",
|
||||
Html.fromHtml(libaoEntity.getDes()), "关闭", null, null, null);
|
||||
}
|
||||
break;
|
||||
case "再领一个":
|
||||
case "领取":
|
||||
if ("repeatLing".equals(status)) {
|
||||
DialogUtils.showWarningDialog(context, "礼包刷新提醒"
|
||||
, "礼包每天0点刷新,换新区或者换新角色需要继续领取礼包的童鞋,请于明天0点之后回来即可[再领一个]"
|
||||
, null, "知道了", null, null);
|
||||
} else {
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance);
|
||||
}
|
||||
break;
|
||||
case "再淘一个":
|
||||
case "淘号":
|
||||
if ("repeatTao".equals(status)) {
|
||||
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
|
||||
return;
|
||||
}
|
||||
final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "淘号中...");
|
||||
postLibaoTao(context, libaoEntity.getId(), new PostLibaoListener() {
|
||||
@Override
|
||||
public void postSucceed(Object response) {
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
JSONObject responseBody = (JSONObject) response;
|
||||
String libaoCode = null;
|
||||
try {
|
||||
libaoCode = responseBody.getString("code");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
JSONObject responseBody = (JSONObject) response;
|
||||
String libaoCode = null;
|
||||
if (TextUtils.isEmpty(libaoCode)) {
|
||||
try {
|
||||
libaoCode = responseBody.getString("code");
|
||||
String detail = responseBody.getString("detail");
|
||||
switch (detail) {
|
||||
case "maintaining":
|
||||
Utils.toast(context, "网络状态异常,请稍后再试");
|
||||
break;
|
||||
case "fail to compete":
|
||||
Utils.toast(context, "淘号失败,稍后重试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "淘号异常");
|
||||
break;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(libaoCode)) {
|
||||
Utils.toast(context, "淘号成功");
|
||||
|
||||
libaoEntity.setStatus("taoed");
|
||||
|
||||
EventBus.getDefault().post(new EBReuse("libaoChanged"));
|
||||
|
||||
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "tao", Utils.getTime(context)));
|
||||
|
||||
final String finalLibaoCode = libaoCode;
|
||||
|
||||
DialogUtils.showWarningDialog(context, "淘号成功"
|
||||
, Html.fromHtml(context.getString(R.string.taoed_dialog, libaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, () -> {
|
||||
copyLink(finalLibaoCode, context);
|
||||
if (isInstallRequired) {
|
||||
libaoBtn.postDelayed(() -> {
|
||||
Spanned msg = Html.fromHtml(
|
||||
context.getString(R.string.taoed_copy_dialog
|
||||
, finalLibaoCode));
|
||||
lunningAppDialog(context
|
||||
, msg, libaoEntity);
|
||||
}, 300);
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable error) {
|
||||
Utils.log("---" + error.toString());
|
||||
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
if (error instanceof HttpException) {
|
||||
HttpException exception = (HttpException) error;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = responseBody.getString("detail");
|
||||
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
|
||||
String detail = errorJson.getString("detail");
|
||||
// Utils.toast(context, "返回::" + detail);
|
||||
switch (detail) {
|
||||
case "coming":
|
||||
Utils.toast(context, "礼包领取时间未开始");
|
||||
break;
|
||||
case "finish":
|
||||
Utils.toast(context, "礼包领取时间已结束");
|
||||
break;
|
||||
case "fetched":
|
||||
Utils.toast(context, "你今天已领过这个礼包了, 不能再淘号");
|
||||
|
||||
libaoBtn.setText("已淘号");
|
||||
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
|
||||
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
|
||||
libaoEntity.setStatus("taoed");
|
||||
break;
|
||||
case "try tao":
|
||||
case "used up":
|
||||
DialogUtils.showHintDialog(context, "礼包已领光"
|
||||
, "手速不够快,礼包已经被抢光了,十分抱歉", "知道了");
|
||||
break;
|
||||
case "maintaining":
|
||||
Utils.toast(context, "网络状态异常,请稍后再试");
|
||||
break;
|
||||
@ -323,101 +398,24 @@ public class LibaoUtils {
|
||||
Utils.toast(context, "淘号失败,稍后重试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "淘号异常");
|
||||
Utils.toast(context, "操作失败");
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Utils.toast(context, "礼包处理异常" + ex.toString());
|
||||
}
|
||||
return;
|
||||
} else if (exception.code() == 401) {
|
||||
return;
|
||||
}
|
||||
|
||||
Utils.toast(context, "淘号成功");
|
||||
|
||||
libaoEntity.setStatus("taoed");
|
||||
|
||||
EventBus.getDefault().post(new EBReuse("libaoChanged"));
|
||||
|
||||
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "tao", Utils.getTime(context)));
|
||||
|
||||
final String finalLibaoCode = libaoCode;
|
||||
|
||||
DialogUtils.showWarningDialog(context, "淘号成功"
|
||||
, Html.fromHtml(context.getString(R.string.taoed_dialog, libaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, () -> {
|
||||
copyLink(finalLibaoCode, context);
|
||||
if (isInstallRequired) {
|
||||
libaoBtn.postDelayed(() -> {
|
||||
Spanned msg = Html.fromHtml(
|
||||
context.getString(R.string.taoed_copy_dialog
|
||||
, finalLibaoCode));
|
||||
lunningAppDialog(context
|
||||
, msg, libaoEntity);
|
||||
}, 300);
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable error) {
|
||||
Utils.log("---" + error.toString());
|
||||
|
||||
if (loadingDialog != null) loadingDialog.dismiss();
|
||||
|
||||
if (error instanceof HttpException) {
|
||||
HttpException exception = (HttpException) error;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
JSONObject errorJson = new JSONObject(exception.response().errorBody().string());
|
||||
String detail = errorJson.getString("detail");
|
||||
// Utils.toast(context, "返回::" + detail);
|
||||
switch (detail) {
|
||||
case "coming":
|
||||
Utils.toast(context, "礼包领取时间未开始");
|
||||
break;
|
||||
case "finish":
|
||||
Utils.toast(context, "礼包领取时间已结束");
|
||||
break;
|
||||
case "fetched":
|
||||
Utils.toast(context, "你今天已领过这个礼包了, 不能再淘号");
|
||||
|
||||
libaoBtn.setText("已淘号");
|
||||
libaoBtn.setBackgroundResource(R.drawable.libao_taoed_style);
|
||||
libaoBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.libao_taoed_selector));
|
||||
libaoEntity.setStatus("taoed");
|
||||
break;
|
||||
case "try tao":
|
||||
case "used up":
|
||||
DialogUtils.showHintDialog(context, "礼包已领光"
|
||||
, "手速不够快,礼包已经被抢光了,十分抱歉", "知道了");
|
||||
break;
|
||||
case "maintaining":
|
||||
Utils.toast(context, "网络状态异常,请稍后再试");
|
||||
break;
|
||||
case "fail to compete":
|
||||
Utils.toast(context, "淘号失败,稍后重试");
|
||||
break;
|
||||
default:
|
||||
Utils.toast(context, "操作失败");
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Utils.toast(context, "礼包处理异常" + ex.toString());
|
||||
}
|
||||
return;
|
||||
} else if (exception.code() == 401) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "发生异常");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
Utils.toast(context, "发生异常");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -458,7 +456,7 @@ public class LibaoUtils {
|
||||
adapter.notifyDataSetChanged();
|
||||
final String finalLibaoCode = libaoCode;
|
||||
NotificationHelper.showNotificationHintDialog(NotificationUgc.GIFT, isShow -> {
|
||||
if (!isShow){
|
||||
if (!isShow) {
|
||||
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, finalLibaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, () -> {
|
||||
@ -547,8 +545,7 @@ public class LibaoUtils {
|
||||
}
|
||||
|
||||
public static boolean isAppInstalled(Context context, String packageName) {
|
||||
final android.content.pm.PackageManager packageManager = context.getPackageManager();
|
||||
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
|
||||
List<PackageInfo> pinfo = PackageUtils.getInstalledPackages(context, 0);
|
||||
if (pinfo != null) {
|
||||
for (int i = 0; i < pinfo.size(); i++) {
|
||||
String pn = pinfo.get(i).packageName;
|
||||
@ -576,10 +573,7 @@ public class LibaoUtils {
|
||||
|
||||
//复制文字
|
||||
public static void copyLink(String copyContent, Context context) {
|
||||
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(copyContent);
|
||||
|
||||
Utils.toast(context, copyContent + " 复制成功");
|
||||
ExtensionsKt.copyTextAndToast(copyContent, copyContent + " 复制成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
@ -637,4 +638,49 @@ public class LogUtils {
|
||||
}
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
|
||||
public static void logNewCatalogAppearanceEvent(String entrance, String key) {
|
||||
logCatalogEvent("access_to_classification", entrance, key, -1, -1, -1, -1);
|
||||
}
|
||||
|
||||
public static void logSubCatalogClickEvent(String entrance, String key, int seq1) {
|
||||
logCatalogEvent("click_first_classification", entrance, key, seq1, -1, -1, -1);
|
||||
}
|
||||
|
||||
public static void logSubCatalogContentClickEvent(String entrance, String key, int seq1, int seq2) {
|
||||
logCatalogEvent("click_secondary_classification", entrance, key, seq1, seq2, -1, -1);
|
||||
}
|
||||
|
||||
public static void logSpecialCatalogContentClickEvent(String entrance, String key, int seq1, int seqContent) {
|
||||
logCatalogEvent("click_content", entrance, key, seq1, -1, seqContent, -1);
|
||||
}
|
||||
|
||||
public static void logSpecialCatalogSpecificContentClickEvent(String entrance, String key, int seq1, int seqContent, int seqContentList) {
|
||||
logCatalogEvent("click_content_list", entrance, key, seq1, -1, seqContent, seqContentList);
|
||||
}
|
||||
|
||||
private static void logCatalogEvent(String event, String entrance, String key, int seq1, int seq2, int seqContent, int seqContentList) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
object.put("event", event);
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
|
||||
payload.put("entrance", entrance); //入口分类, 分为 首页或版块,
|
||||
payload.put("key", key); //搜索类型, 有四种取值 默认搜索/历史搜索/自动搜索/主动搜索
|
||||
payload.put("seq_1st", seq1); //从0开始,默认-1表示没有
|
||||
payload.put("seq_2nd", seq2); //从0开始,默认-1表示没有
|
||||
payload.put("seq_content", seqContent); //精选页上 图片、专题-全部按钮、专题合集-全部按钮 的排序;从0开始,默认-1表示没有
|
||||
payload.put("seq_content_list", seqContentList);
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ object MtaHelper {
|
||||
// if (kv.size == 1) {
|
||||
// prop.setProperty(kv[0], kv[0])
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}]")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
@ -23,7 +23,7 @@ object MtaHelper {
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}]")
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ object MtaHelper {
|
||||
// }
|
||||
//
|
||||
// if (prop.size == 0) return
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
|
||||
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
|
||||
// StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ object MtaHelper {
|
||||
// prop.setProperty("GID", HaloApp.getInstance().gid)
|
||||
// }
|
||||
//
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// Utils.log("MTA", "$eventId + [${kv.joinToString(" , ")}]")
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
}
|
||||
|
||||
|
||||
@ -154,8 +154,8 @@ object NotificationHelper {
|
||||
callBack?.invoke(false)
|
||||
} else {
|
||||
callBack?.invoke(true)
|
||||
// if (activity.supportFragmentManager.isStateSaved) return
|
||||
// NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
|
||||
if (activity.supportFragmentManager.isStateSaved) return
|
||||
NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ object PackageHelper {
|
||||
private fun getAllPackageName(context: Context): HashSet<String> {
|
||||
val set = HashSet<String>()
|
||||
return try {
|
||||
val packageInfos = context.applicationContext.packageManager.getInstalledPackages(0)
|
||||
val packageInfos = PackageUtils.getInstalledPackages(context, 0)
|
||||
for (packageInfo in packageInfos) {
|
||||
if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
|
||||
if (context.packageName != packageInfo.packageName) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@ -38,13 +39,17 @@ object PackageInstaller {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) {
|
||||
InstallPermissionDialogFragment.show(AppManager.getInstance().currentActivity() as AppCompatActivity) {
|
||||
val pkgPath = downloadEntity.path
|
||||
val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()
|
||||
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
InstallPermissionDialogFragment.show(currentActivity as AppCompatActivity, downloadEntity) {
|
||||
// 取消状态栏下载完成的通知,若存在
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
val pkgPath = downloadEntity.path
|
||||
if (XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()) {
|
||||
if (isXapk) {
|
||||
XapkInstaller.install(context, downloadEntity, showUnzipToast)
|
||||
} else {
|
||||
install(context, downloadEntity.path)
|
||||
@ -113,6 +118,9 @@ object PackageInstaller {
|
||||
val uninstallIntent = Intent()
|
||||
uninstallIntent.action = Intent.ACTION_DELETE
|
||||
uninstallIntent.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
if (context !is Activity) {
|
||||
uninstallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
val packageName = PackageUtils.getPackageNameByPath(context, path)
|
||||
uninstallIntent.data = Uri.parse("package:$packageName")
|
||||
InstallUtils.getInstance(context).addUninstall(packageName)
|
||||
|
||||
@ -30,8 +30,11 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
@ -180,11 +183,13 @@ public class PackageUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO 找一个更好的办法来比较签名并且不触发 ANR
|
||||
public static boolean compareSignatureBetweenInstalledAppWithApk(Context context, String packageName, String apkFilePath) {
|
||||
try {
|
||||
// 据 Sentry 统计,刚上架一个周末的包里对这个方法有 700+ 次调用,然后其中一部分会造成 ANR
|
||||
Signature sig = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];
|
||||
|
||||
// Fuck HUAWEI, 华为系统调用 getPackageArchiveInfo 获取魔羯 apk 的签名时会耗时超过5秒造成 ANR,没有找到解决方法
|
||||
// 调用 getPackageArchiveInfo 获取较大的 apk 的签名时会耗时超过5秒造成 ANR,没有找到解决方法
|
||||
// 如果可以的话尽量避免调用 getPackageArchiveInfo 方法
|
||||
Signature releaseSig = context.getPackageManager().getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNATURES).signatures[0];
|
||||
return sig.hashCode() == releaseSig.hashCode();
|
||||
@ -286,7 +291,7 @@ public class PackageUtils {
|
||||
*/
|
||||
public static String getPackageNameByPath(Context context, String path) {
|
||||
PackageManager packageManager = context.getApplicationContext().getPackageManager();
|
||||
PackageInfo info = packageManager.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
|
||||
PackageInfo info = packageManager.getPackageArchiveInfo(path, 0);
|
||||
if (info != null) {
|
||||
ApplicationInfo appInfo = info.applicationInfo;
|
||||
return appInfo.packageName;
|
||||
@ -370,7 +375,7 @@ public class PackageUtils {
|
||||
*/
|
||||
public static ArrayList<String> getAllPackageName(Context context) {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
List<PackageInfo> packageInfos = context.getApplicationContext().getPackageManager().getInstalledPackages(0);
|
||||
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
|
||||
for (PackageInfo packageInfo : packageInfos) {
|
||||
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
if (!context.getPackageName().equals(packageInfo.packageName)) {
|
||||
@ -385,7 +390,7 @@ public class PackageUtils {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
|
||||
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
|
||||
for (PackageInfo packageInfo : packageInfos) {
|
||||
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
@ -557,4 +562,42 @@ public class PackageUtils {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
|
||||
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-to-get-a-list-of-applications-installed/30062632#30062632
|
||||
*/
|
||||
public static List<PackageInfo> getInstalledPackages(Context context, int flags) {
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
return pm.getInstalledPackages(flags);
|
||||
} catch (Exception ignored) {
|
||||
//we don't care why it didn't succeed. We'll do it using an alternative way instead
|
||||
}
|
||||
// use fallback:
|
||||
Process process;
|
||||
List<PackageInfo> result = new ArrayList<>();
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec("pm list packages");
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
final String packageName = line.substring(line.indexOf(':') + 1);
|
||||
final PackageInfo packageInfo = pm.getPackageInfo(packageName, flags);
|
||||
result.add(packageInfo);
|
||||
}
|
||||
process.waitFor();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bufferedReader != null)
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import com.tbruyelle.rxpermissions2.RxPermissions
|
||||
|
||||
object PermissionHelper {
|
||||
|
||||
const val INSTALL_PERMISS_CODE = 100
|
||||
const val INSTALL_PERMISSION_CODE = 100
|
||||
|
||||
@JvmStatic
|
||||
fun requestReadPhoneStateAndStoragePermissionFromStartUp(context: Context) {
|
||||
@ -232,7 +232,7 @@ object PermissionHelper {
|
||||
} else {
|
||||
val packageURI = Uri.fromParts("package", activity.packageName, null)
|
||||
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
|
||||
activity.startActivityForResult(intent, INSTALL_PERMISS_CODE)
|
||||
activity.startActivityForResult(intent, INSTALL_PERMISSION_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
47
app/src/main/java/com/gh/common/util/SentryHelper.kt
Normal file
47
app/src/main/java/com/gh/common/util/SentryHelper.kt
Normal file
@ -0,0 +1,47 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.text.TextUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import io.sentry.core.Sentry
|
||||
import io.sentry.core.SentryEvent
|
||||
import io.sentry.core.SentryLevel
|
||||
import io.sentry.core.protocol.Message
|
||||
|
||||
object SentryHelper {
|
||||
|
||||
/**
|
||||
* 注意 tag-key 不支持中文
|
||||
*/
|
||||
fun onEvent(eventId: String, vararg kv: String?) {
|
||||
val sentryEvent = SentryEvent()
|
||||
val message = Message()
|
||||
message.message = eventId
|
||||
sentryEvent.message = message
|
||||
sentryEvent.level = SentryLevel.LOG
|
||||
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
sentryEvent.setTag(key, value)
|
||||
debugOnly {
|
||||
throwExceptionInDebug("tag-key 不支持中文", isContainChinese(key))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Utils.log("Sentry", "$eventId + [${kv.joinToString(" , ")}]")
|
||||
Sentry.captureEvent(sentryEvent)
|
||||
}
|
||||
|
||||
// 判断一个字符串是否含有中文
|
||||
private fun isContainChinese(str: String?): Boolean {
|
||||
if (str == null) return false
|
||||
for (c in str.toCharArray()) {
|
||||
if (c.toInt() in 0x4E00..0x9FA5) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,9 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
@ -24,6 +22,9 @@ 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;
|
||||
@ -50,9 +51,6 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
|
||||
|
||||
/**
|
||||
@ -159,8 +157,7 @@ public class ShareUtils {
|
||||
|
||||
//检查是否安装手机QQ
|
||||
public static boolean isQQClientAvailable(Context context) {
|
||||
final PackageManager packageManager = context.getPackageManager();
|
||||
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
|
||||
List<PackageInfo> pinfo = PackageUtils.getInstalledPackages(context, 0);
|
||||
if (pinfo != null) {
|
||||
for (int i = 0; i < pinfo.size(); i++) {
|
||||
String pn = pinfo.get(i).packageName;
|
||||
@ -634,13 +631,11 @@ public class ShareUtils {
|
||||
private void copyLink(String copyContent) {
|
||||
shareType = "copy_link";
|
||||
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
|
||||
ClipboardManager cmb = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(copyContent);
|
||||
if (mShareEntrance != ShareEntrance.shareGh) {
|
||||
Utils.toast(mContext, "复制成功");
|
||||
ExtensionsKt.copyTextAndToast(copyContent, "复制成功");
|
||||
safelyDismiss();
|
||||
} else {
|
||||
Utils.toast(mContext, "复制成功,请到微信/QQ粘贴分享");
|
||||
ExtensionsKt.copyTextAndToast(copyContent, "复制成功,请到微信/QQ粘贴分享");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import androidx.core.content.ContextCompat
|
||||
import com.gh.common.view.CenterImageSpan
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
class SpanBuilder(content: String) {
|
||||
class SpanBuilder(content: CharSequence) {
|
||||
private var spannableString: SpannableStringBuilder = SpannableStringBuilder(content)
|
||||
|
||||
fun color(context: Context, start: Int, end: Int, colorRes: Int): SpanBuilder {
|
||||
@ -70,12 +70,12 @@ class SpanBuilder(content: String) {
|
||||
return this
|
||||
}
|
||||
|
||||
fun click(start: Int, end: Int, colorRes: Int, onClick: () -> Unit): SpanBuilder {
|
||||
fun click(start: Int, end: Int, colorRes: Int, isUnderlineText: Boolean = false, onClick: () -> Unit): SpanBuilder {
|
||||
val clickSpan = object : ClickableSpan() {
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
super.updateDrawState(ds)
|
||||
ds.color = ContextCompat.getColor(HaloApp.getInstance().application, colorRes)
|
||||
ds.isUnderlineText = false
|
||||
ds.isUnderlineText = isUnderlineText
|
||||
}
|
||||
|
||||
override fun onClick(widget: View) {
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* 今日头条的激活统计 SDK https://gitlab.ghzs.com/pm/halo-app-issues/issues/567
|
||||
*
|
||||
* 更新 SDK https://gitlab.ghzs.com/pm/halo-app-issues/issues/743
|
||||
*/
|
||||
object TeaHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun init(context: Context, channel: String) {
|
||||
// val config = InitConfig("163824", channel)
|
||||
// config.setUriConfig(UriConfig.DEFAULT)
|
||||
// config.appName = "guanghuan1"
|
||||
// config.setEnablePlay(true)
|
||||
// AppLog.setEnableLog(false)
|
||||
// AppLog.init(context, config)
|
||||
//
|
||||
// AppLog.setOaidObserver {
|
||||
// HaloApp.getInstance().oaid = it.id
|
||||
// Utils.log("oaid is $it.id")
|
||||
// MetaUtil.refreshMeta()
|
||||
// }
|
||||
//
|
||||
// // gameReportHelper ?!
|
||||
// GameReportHelper.onEventRegister("wechat", true)
|
||||
// GameReportHelper.onEventPurchase("gift", "flower", "008", 1, "wechat", "¥", true, 1)
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ package com.gh.common.view
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.*
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -14,7 +13,6 @@ import com.gh.common.util.ImageUtils
|
||||
import com.gh.common.util.rxTimer
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.SettingsEntity
|
||||
import com.squareup.picasso.Picasso
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlin.math.abs
|
||||
|
||||
|
||||
301
app/src/main/java/com/gh/common/view/CatalogFilterView.kt
Normal file
301
app/src/main/java/com/gh/common/view/CatalogFilterView.kt
Normal file
@ -0,0 +1,301 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.common.util.toColor
|
||||
import com.gh.common.util.visibleIf
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.gh.gamecenter.entity.SubjectSettingEntity
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
|
||||
class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var mTypeTv: TextView
|
||||
private var mCatalogTv: TextView
|
||||
private var mSizeTv: TextView
|
||||
private var mTypeContainer: View
|
||||
private var mCatalogContainer: View
|
||||
private var mSizeContainer: View
|
||||
|
||||
private var mTypeFilterArray = ArrayList<SortType>()
|
||||
private var mCatalogFilterArray = ArrayList<CatalogEntity.SubCatalogEntity>()
|
||||
private var sizeFilterArray: ArrayList<SubjectSettingEntity.Size>? = null
|
||||
|
||||
private var mOnCatalogFilterSetupListener: OnCatalogFilterSetupListener? = null
|
||||
|
||||
init {
|
||||
View.inflate(context, R.layout.layout_catalog_filter, this)
|
||||
|
||||
mTypeTv = findViewById(R.id.type_tv)
|
||||
mCatalogTv = findViewById(R.id.catalog_tv)
|
||||
mSizeTv = findViewById(R.id.size_tv)
|
||||
mTypeContainer = findViewById(R.id.container_type)
|
||||
mCatalogContainer = findViewById(R.id.container_catalog)
|
||||
mSizeContainer = findViewById(R.id.container_size)
|
||||
|
||||
mTypeContainer.setOnClickListener {
|
||||
showSelectTypePopupWindow(this, mTypeTv, mTypeTv.text.toString())
|
||||
}
|
||||
|
||||
mCatalogContainer.setOnClickListener {
|
||||
showSelectCatalogPopupWindow(this, mCatalogTv, mCatalogTv.text.toString())
|
||||
}
|
||||
|
||||
mSizeContainer.setOnClickListener {
|
||||
showSelectSizePopupWindow(this, mSizeTv, mSizeTv.text.toString())
|
||||
}
|
||||
}
|
||||
|
||||
fun setTypeList(switch: CatalogEntity.CatalogSwitch) {
|
||||
switch.run {
|
||||
if ("on" == hotSort) mTypeFilterArray.add(SortType.RECOMMENDED)
|
||||
if ("on" == newSort) mTypeFilterArray.add(SortType.NEWEST)
|
||||
if ("on" == starSort) mTypeFilterArray.add(SortType.RATING)
|
||||
}
|
||||
if (mTypeFilterArray.isNotEmpty()) mTypeTv.text = mTypeFilterArray[0].value
|
||||
}
|
||||
|
||||
fun setCatalogList(subCatalogList: List<CatalogEntity.SubCatalogEntity>, initCatalogName: String) {
|
||||
mCatalogFilterArray = ArrayList(subCatalogList)
|
||||
mCatalogTv.text = initCatalogName
|
||||
}
|
||||
|
||||
fun setOnConfigSetupListener(onCatalogFilterSetupListener: OnCatalogFilterSetupListener) {
|
||||
mOnCatalogFilterSetupListener = onCatalogFilterSetupListener
|
||||
}
|
||||
|
||||
private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
|
||||
if (highlightIt) {
|
||||
targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
|
||||
targetTextView.setTextColor(Color.WHITE)
|
||||
} else {
|
||||
targetTextView.background = null
|
||||
targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSelectTypePopupWindow(containerView: View, typeTv: TextView, typeText: String) {
|
||||
val drawableUp = ContextCompat.getDrawable(typeTv.context, R.drawable.ic_filter_arrow_up)
|
||||
val drawableDown = ContextCompat.getDrawable(typeTv.context, R.drawable.ic_filter_arrow_down)
|
||||
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
|
||||
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
|
||||
|
||||
typeTv.setTextColor(R.color.theme_font.toColor())
|
||||
typeTv.setCompoundDrawables(null, null, drawableUp, null)
|
||||
|
||||
val inflater = LayoutInflater.from(typeTv.context)
|
||||
val layout = inflater.inflate(R.layout.layout_filter_size, null)
|
||||
val popupWindow = PopupWindow(
|
||||
layout,
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT)
|
||||
|
||||
val flexboxLayout = layout.findViewById<FlexboxLayout>(R.id.flexbox)
|
||||
val backgroundView = layout.findViewById<View>(R.id.background)
|
||||
|
||||
backgroundView.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
}
|
||||
|
||||
for (type in mTypeFilterArray) {
|
||||
val item = inflater.inflate(R.layout.item_filter_size, flexboxLayout, false)
|
||||
|
||||
// 单列 3 个,强行设置宽度为屏幕的 1/3
|
||||
val width = typeTv.context.resources.displayMetrics.widthPixels / 3
|
||||
val height = item.layoutParams.height
|
||||
|
||||
item.layoutParams = ViewGroup.LayoutParams(width, height)
|
||||
flexboxLayout.addView(item)
|
||||
|
||||
val tv = item.findViewById<TextView>(R.id.size_tv)
|
||||
tv.text = type.value
|
||||
|
||||
toggleHighlightedTextView(tv, typeText == type.value)
|
||||
|
||||
tv.tag = type.value
|
||||
|
||||
item.setOnClickListener {
|
||||
toggleHighlightedTextView(tv, true)
|
||||
popupWindow.dismiss()
|
||||
typeTv.text = type.value
|
||||
|
||||
mOnCatalogFilterSetupListener?.onSetupSortType(type)
|
||||
}
|
||||
}
|
||||
|
||||
popupWindow.setOnDismissListener {
|
||||
typeTv.setTextColor(R.color.text_757575.toColor())
|
||||
typeTv.setCompoundDrawables(null, null, drawableDown, null)
|
||||
}
|
||||
|
||||
popupWindow.isTouchable = true
|
||||
popupWindow.isFocusable = true
|
||||
popupWindow.animationStyle = 0
|
||||
popupWindow.showAsDropDown(containerView, 0, 0)
|
||||
}
|
||||
|
||||
private fun showSelectCatalogPopupWindow(containerView: View, catalogTv: TextView, catalogText: String) {
|
||||
val drawableUp = ContextCompat.getDrawable(catalogTv.context, R.drawable.ic_filter_arrow_up)
|
||||
val drawableDown = ContextCompat.getDrawable(catalogTv.context, R.drawable.ic_filter_arrow_down)
|
||||
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
|
||||
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
|
||||
|
||||
catalogTv.setTextColor(R.color.theme_font.toColor())
|
||||
catalogTv.setCompoundDrawables(null, null, drawableUp, null)
|
||||
|
||||
val inflater = LayoutInflater.from(catalogTv.context)
|
||||
val layout = inflater.inflate(R.layout.layout_filter_size, null)
|
||||
val popupWindow = PopupWindow(
|
||||
layout,
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT)
|
||||
|
||||
val flexboxLayout = layout.findViewById<FlexboxLayout>(R.id.flexbox)
|
||||
val backgroundView = layout.findViewById<View>(R.id.background)
|
||||
|
||||
backgroundView.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
}
|
||||
|
||||
for (entity in mCatalogFilterArray) {
|
||||
val item = inflater.inflate(R.layout.item_filter_size, flexboxLayout, false)
|
||||
|
||||
// 单列 3 个,强行设置宽度为屏幕的 1/3
|
||||
val width = catalogTv.context.resources.displayMetrics.widthPixels / 3
|
||||
val height = item.layoutParams.height
|
||||
|
||||
item.layoutParams = ViewGroup.LayoutParams(width, height)
|
||||
flexboxLayout.addView(item)
|
||||
|
||||
val tv = item.findViewById<TextView>(R.id.size_tv)
|
||||
val iv = item.findViewById<ImageView>(R.id.recommend_iv)
|
||||
tv.text = entity.name
|
||||
iv.visibleIf(entity.recommended)
|
||||
|
||||
toggleHighlightedTextView(tv, catalogText == entity.name)
|
||||
|
||||
tv.tag = entity.name
|
||||
|
||||
item.setOnClickListener {
|
||||
toggleHighlightedTextView(tv, true)
|
||||
popupWindow.dismiss()
|
||||
catalogTv.text = entity.name
|
||||
|
||||
mOnCatalogFilterSetupListener?.onSetupSortCatalog(entity)
|
||||
}
|
||||
}
|
||||
|
||||
popupWindow.setOnDismissListener {
|
||||
catalogTv.setTextColor(R.color.text_757575.toColor())
|
||||
catalogTv.setCompoundDrawables(null, null, drawableDown, null)
|
||||
}
|
||||
|
||||
popupWindow.isTouchable = true
|
||||
popupWindow.isFocusable = true
|
||||
popupWindow.animationStyle = 0
|
||||
popupWindow.showAsDropDown(containerView, 0, 0)
|
||||
}
|
||||
|
||||
private fun showSelectSizePopupWindow(containerView: View, sizeTv: TextView, sizeText: String) {
|
||||
val drawableUp = ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_up)
|
||||
val drawableDown = ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_down)
|
||||
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
|
||||
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
|
||||
|
||||
sizeTv.setTextColor(R.color.theme_font.toColor())
|
||||
sizeTv.setCompoundDrawables(null, null, drawableUp, null)
|
||||
|
||||
val inflater = LayoutInflater.from(sizeTv.context)
|
||||
val layout = inflater.inflate(R.layout.layout_filter_size, null)
|
||||
val popupWindow = PopupWindow(
|
||||
layout,
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT)
|
||||
|
||||
val flexboxLayout = layout.findViewById<FlexboxLayout>(R.id.flexbox)
|
||||
val backgroundView = layout.findViewById<View>(R.id.background)
|
||||
|
||||
sizeFilterArray = if (sizeFilterArray == null) {
|
||||
getDefaultSizeFilterArray()
|
||||
} else {
|
||||
sizeFilterArray?.apply {
|
||||
if (firstOrNull()?.text != "全部大小") {
|
||||
add(0, SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
backgroundView.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
}
|
||||
|
||||
for (size in sizeFilterArray!!) {
|
||||
val item = inflater.inflate(R.layout.item_filter_size, flexboxLayout, false)
|
||||
|
||||
// 单列 3 个,强行设置宽度为屏幕的 1/3
|
||||
val width = sizeTv.context.resources.displayMetrics.widthPixels / 3
|
||||
val height = item.layoutParams.height
|
||||
|
||||
item.layoutParams = ViewGroup.LayoutParams(width, height)
|
||||
flexboxLayout.addView(item)
|
||||
|
||||
val tv = item.findViewById<TextView>(R.id.size_tv)
|
||||
tv.text = size.text
|
||||
|
||||
toggleHighlightedTextView(tv, sizeText == size.text)
|
||||
|
||||
tv.tag = size.text
|
||||
|
||||
item.setOnClickListener {
|
||||
toggleHighlightedTextView(tv, true)
|
||||
popupWindow.dismiss()
|
||||
sizeTv.text = size.text
|
||||
|
||||
mOnCatalogFilterSetupListener?.onSetupSortSize(size)
|
||||
}
|
||||
}
|
||||
|
||||
popupWindow.setOnDismissListener {
|
||||
sizeTv.setTextColor(R.color.text_757575.toColor())
|
||||
sizeTv.setCompoundDrawables(null, null, drawableDown, null)
|
||||
}
|
||||
|
||||
popupWindow.isTouchable = true
|
||||
popupWindow.isFocusable = true
|
||||
popupWindow.animationStyle = 0
|
||||
popupWindow.showAsDropDown(containerView, 0, 0)
|
||||
}
|
||||
|
||||
private fun getDefaultSizeFilterArray(): ArrayList<SubjectSettingEntity.Size> {
|
||||
return arrayListOf<SubjectSettingEntity.Size>().apply {
|
||||
add(SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"))
|
||||
add(SubjectSettingEntity.Size(min = -1, max = 100, text = "100M以下"))
|
||||
add(SubjectSettingEntity.Size(min = 100, max = 300, text = "100-300M"))
|
||||
add(SubjectSettingEntity.Size(min = 300, max = 500, text = "300-500M"))
|
||||
add(SubjectSettingEntity.Size(min = 500, max = 1000, text = "500M-1G"))
|
||||
add(SubjectSettingEntity.Size(min = 1000, max = -1, text = "1G以上"))
|
||||
}
|
||||
}
|
||||
|
||||
interface OnCatalogFilterSetupListener {
|
||||
fun onSetupSortSize(sortSize: SubjectSettingEntity.Size)
|
||||
fun onSetupSortType(sortType: SortType)
|
||||
fun onSetupSortCatalog(sortCatalog: CatalogEntity.SubCatalogEntity)
|
||||
}
|
||||
|
||||
enum class SortType(val value: String) {
|
||||
RECOMMENDED("热门推荐"),
|
||||
NEWEST("最新上线"),
|
||||
RATING("最高评分")
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.common.util.toColor
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.SubjectSettingEntity
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
@ -69,16 +69,13 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
mOnConfigFilterSetupListener = onConfigFilterSetupListener
|
||||
}
|
||||
|
||||
fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
|
||||
private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
|
||||
if (highlightIt) {
|
||||
targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.text_blue_background)
|
||||
targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
|
||||
targetTextView.setTextColor(Color.WHITE)
|
||||
} else {
|
||||
val colorDrawable = GradientDrawable()
|
||||
colorDrawable.setColor(Color.WHITE)
|
||||
colorDrawable.cornerRadius = DisplayUtils.dip2px(1.5f).toFloat()
|
||||
targetTextView.background = colorDrawable
|
||||
targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_3a3a3a))
|
||||
targetTextView.background = null
|
||||
targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +85,8 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
|
||||
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
|
||||
|
||||
sizeTv.setTextColor(R.color.theme_font.toColor())
|
||||
sizeTv.setCompoundDrawables(null, null, drawableUp, null)
|
||||
sizeTv.text = "收起"
|
||||
|
||||
val inflater = LayoutInflater.from(sizeTv.context)
|
||||
val layout = inflater.inflate(R.layout.layout_filter_size, null)
|
||||
@ -146,25 +143,24 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
}
|
||||
|
||||
popupWindow.setOnDismissListener {
|
||||
sizeTv.setTextColor(R.color.text_757575.toColor())
|
||||
sizeTv.setCompoundDrawables(null, null, drawableDown, null)
|
||||
if (sizeTv.text == "收起") {
|
||||
sizeTv.text = sizeText
|
||||
}
|
||||
}
|
||||
|
||||
popupWindow.isTouchable = true
|
||||
popupWindow.isFocusable = true
|
||||
popupWindow.animationStyle = 0
|
||||
popupWindow.showAsDropDown(containerView, 0, 0)
|
||||
}
|
||||
|
||||
private fun getDefaultSizeFilterArray(): ArrayList<SubjectSettingEntity.Size> {
|
||||
return arrayListOf<SubjectSettingEntity.Size>().apply {
|
||||
add(SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"))
|
||||
add(SubjectSettingEntity.Size(min = -1, max = 20, text = "20M以下"))
|
||||
add(SubjectSettingEntity.Size(min = 20, max = 50, text = "20-50M"))
|
||||
add(SubjectSettingEntity.Size(min = 50, max = 100, text = "50-100M"))
|
||||
add(SubjectSettingEntity.Size(min = 100, max = 500, text = "100-500M"))
|
||||
add(SubjectSettingEntity.Size(min = 500, max = -1, text = "500M以上"))
|
||||
add(SubjectSettingEntity.Size(min = -1, max = 100, text = "100M以下"))
|
||||
add(SubjectSettingEntity.Size(min = 100, max = 300, text = "100-300M"))
|
||||
add(SubjectSettingEntity.Size(min = 300, max = 500, text = "300-500M"))
|
||||
add(SubjectSettingEntity.Size(min = 500, max = 1000, text = "500M-1G"))
|
||||
add(SubjectSettingEntity.Size(min = 1000, max = -1, text = "1G以上"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import android.text.TextUtils
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.facebook.drawee.generic.RoundingParams
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.gh.common.util.DisplayUtils
|
||||
@ -18,6 +19,7 @@ class GameIconView : ConstraintLayout {
|
||||
|
||||
private var mCornerRadius = 10
|
||||
private var mBorderColor = 0
|
||||
private var mGameIconOverlayColor = 0
|
||||
private var mBorderWidth = 1
|
||||
private var mFadeDuration = -1
|
||||
|
||||
@ -36,11 +38,15 @@ class GameIconView : ConstraintLayout {
|
||||
val ta = context.obtainStyledAttributes(attrs, R.styleable.GameIconView)
|
||||
mCornerRadius = ta.getDimensionPixelSize(R.styleable.GameIconView_gameIconCornerRadius, DisplayUtils.dip2px(10F))
|
||||
mBorderColor = ta.getColor(R.styleable.GameIconView_gameIconBorderColor, 0)
|
||||
mGameIconOverlayColor = ta.getColor(R.styleable.GameIconView_gameIconOverlayColor, 0)
|
||||
mBorderWidth = ta.getDimensionPixelSize(R.styleable.GameIconView_gameIconBorderWidth, 1)
|
||||
mFadeDuration = ta.getInt(R.styleable.GameIconView_gameIconFadeDuration, -1)
|
||||
ta.recycle()
|
||||
|
||||
val roundingParams = RoundingParams.fromCornersRadius(mCornerRadius.toFloat())
|
||||
if (mGameIconOverlayColor != 0) {
|
||||
roundingParams.overlayColor = mGameIconOverlayColor
|
||||
}
|
||||
|
||||
if (mBorderColor != 0) {
|
||||
roundingParams.setBorder(mBorderColor, mBorderWidth.toFloat())
|
||||
|
||||
@ -32,7 +32,7 @@ class ReserveDialog : BaseDialogFragment() {
|
||||
binding.more.setOnClickListener {
|
||||
val intent = MyGameActivity.getIntentWithConfig(requireContext(), 2)
|
||||
startActivity(intent)
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
binding.recyclerView.layoutManager = if (mReserveList.size > 4) {
|
||||
GridLayoutManager(context, 4)
|
||||
@ -54,7 +54,7 @@ class ReserveDialog : BaseDialogFragment() {
|
||||
holder.binding.game = entity
|
||||
holder.itemView.setOnClickListener {
|
||||
GameDetailActivity.startGameDetailActivity(mContext, entity.id, "(预约弹窗)")
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.text.Selection
|
||||
import android.text.Spannable
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.text.style.URLSpan
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewParent
|
||||
import android.widget.TextView
|
||||
import com.gh.common.DefaultUrlHandler
|
||||
|
||||
/**
|
||||
* 拦截处理以 "ghzhushou://" 起始的 URLSpan
|
||||
*/
|
||||
class UrlInterceptedLinkMovementMethod : LinkMovementMethod() {
|
||||
|
||||
override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
|
||||
val action = event.action
|
||||
var isTouchEventConsumed = false
|
||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
|
||||
var x = event.x.toInt()
|
||||
var y = event.y.toInt()
|
||||
x -= widget.totalPaddingLeft
|
||||
y -= widget.totalPaddingTop
|
||||
x += widget.scrollX
|
||||
y += widget.scrollY
|
||||
val layout = widget.layout
|
||||
val line = layout.getLineForVertical(y)
|
||||
val off = layout.getOffsetForHorizontal(line, x.toFloat())
|
||||
val links = buffer.getSpans(off, off, ClickableSpan::class.java)
|
||||
if (links.size != 0) {
|
||||
val link = links[0]
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
if (link is URLSpan && link.url.contains("ghzhushou")) {
|
||||
DefaultUrlHandler.interceptUrl(widget.context, link.url, "")
|
||||
} else {
|
||||
link.onClick(widget)
|
||||
}
|
||||
} else if (action == MotionEvent.ACTION_DOWN) {
|
||||
// do nothing
|
||||
}
|
||||
isTouchEventConsumed = true
|
||||
} else {
|
||||
Selection.removeSelection(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
//解决点击事件冲突问题
|
||||
if (!isTouchEventConsumed && event.action == MotionEvent.ACTION_UP) {
|
||||
val parent: ViewParent? = iterateViewParentForClicking(widget.parent) //处理widget的父控件点击事件
|
||||
if (parent is ViewGroup) {
|
||||
return parent.performClick()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun iterateViewParentForClicking(parent: ViewParent): ViewParent? {
|
||||
return if (parent is ViewGroup) {
|
||||
if (parent.hasOnClickListeners()) {
|
||||
parent
|
||||
} else {
|
||||
iterateViewParentForClicking(parent.getParent())
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
}
|
||||
@ -86,7 +86,7 @@ class WelcomeDialog : BaseDialogFragment() {
|
||||
|
||||
mDismissByClickImage = true
|
||||
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
binding.ivOpeningCover.loadingCallback = object : WrapContentDraweeView.LoadingCallback {
|
||||
@ -102,15 +102,24 @@ class WelcomeDialog : BaseDialogFragment() {
|
||||
}
|
||||
|
||||
binding.ivCloseBackup.setOnClickListener {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
binding.ivClose.setOnClickListener {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
binding.welcome = mWelcomeEntity
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun dismissAllowingStateLoss() {
|
||||
try {
|
||||
mDismissByClickImage = false
|
||||
super.dismissAllowingStateLoss()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
try {
|
||||
mDismissByClickImage = false
|
||||
|
||||
@ -414,7 +414,7 @@ public class DWebView extends WebView {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
super.loadUrl("javascript:" + script);
|
||||
} catch (Exception ignored){
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1023,4 +1023,19 @@ public class DWebView extends WebView {
|
||||
mainHandler.post(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverScrollMode(int mode) {
|
||||
try {
|
||||
super.setOverScrollMode(mode);
|
||||
} catch (Throwable e) {
|
||||
String trace = Log.getStackTraceString(e);
|
||||
if (trace.contains("android.content.pm.PackageManager$NameNotFoundException")
|
||||
|| trace.contains("java.lang.RuntimeException: Cannot load WebView")
|
||||
|| trace.contains("android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed")) {
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataChanger
|
||||
import com.lightgame.download.DownloadEntity
|
||||
@ -124,14 +121,9 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
DownloadManager.getInstance(mContext).updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
|
||||
MtaHelper.onEvent("解压失败"
|
||||
, "安卓版本", Build.VERSION.RELEASE
|
||||
, "IMEI", MetaUtil.getIMEI()
|
||||
, "光环版本", BuildConfig.VERSION_NAME
|
||||
, "厂商", Build.MANUFACTURER
|
||||
, "机型", Build.MODEL
|
||||
, "游戏", downloadEntity.name
|
||||
, "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
SentryHelper.onEvent("XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage)
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onFailure->$exception")
|
||||
@ -142,7 +134,14 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
val pkgPath = checkNotNull(downloadEntity.meta[XAPK_PACKAGE_PATH_TAG])
|
||||
val pkgPath = downloadEntity.meta[XAPK_PACKAGE_PATH_TAG]
|
||||
|
||||
if (pkgPath == null) {
|
||||
Utils.toast(mContext, "下载出错,请重新下载!")
|
||||
|
||||
return@execute
|
||||
}
|
||||
|
||||
PackageInstaller.install(mContext, pkgPath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
|
||||
@ -4,10 +4,8 @@ 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.common.util.*
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataChanger
|
||||
@ -58,8 +56,8 @@ object DownloadDataHelper {
|
||||
return "下载完成"
|
||||
}
|
||||
val pm = HaloApp.getInstance().application.applicationContext.packageManager
|
||||
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
|
||||
if (packageInfo == null) {
|
||||
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, 0)
|
||||
if (packageInfo == null && XapkInstaller.PACKAGE_EXTENSION_NAME == downloadEntity.path.getExtension()) {
|
||||
"解析包错误"
|
||||
} else {
|
||||
"下载完成"
|
||||
|
||||
@ -150,6 +150,8 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
// 只有下载模块需要这坨东西,因此移动到这里初始化
|
||||
ConnectionUtils.initHttpsUrlConnection(context);
|
||||
|
||||
updateMetaMap();
|
||||
|
||||
// DownloadNotification.showDownloadingNotification(mContext);
|
||||
|
||||
lastTimeMap = new ArrayMap<>();
|
||||
@ -292,8 +294,6 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
downloadEntity.setUpdate(true);
|
||||
}
|
||||
|
||||
updateMetaMap();
|
||||
|
||||
downloadEntity.setPlugin(!TextUtils.isEmpty(apkEntity.getGhVersion()));
|
||||
|
||||
ExposureUtils.DownloadType downloadType = ExposureUtils.getDownloadType(apkEntity, gameEntity.getId());
|
||||
@ -340,6 +340,8 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* @param downloadEntity
|
||||
*/
|
||||
public void add(DownloadEntity downloadEntity) {
|
||||
updateMetaMap();
|
||||
|
||||
if (downloadEntity != null) {
|
||||
String url = downloadEntity.getUrl();
|
||||
checkDownloadEntryRecordValidate(url);
|
||||
@ -397,6 +399,8 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* @param downloadEntity
|
||||
*/
|
||||
public void subscribe(DownloadEntity downloadEntity) {
|
||||
updateMetaMap();
|
||||
|
||||
if (downloadEntity != null) {
|
||||
String url = downloadEntity.getUrl();
|
||||
checkDownloadEntryRecordValidate(url);
|
||||
@ -539,7 +543,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
|
||||
public List<DownloadEntity> getAllSimulatorDownloadEntity() {
|
||||
List<DownloadEntity> downloadEntityList = mDownloadDao.getAll();
|
||||
List<DownloadEntity> downloadEntityList = getAllDownloadEntity();
|
||||
ArrayList<DownloadEntity> filteredDownloadEntityList = new ArrayList<>();
|
||||
for (DownloadEntity downloadEntity : downloadEntityList) {
|
||||
if (ExtensionsKt.isSimulatorGame(downloadEntity) && downloadEntity.getStatus() == DownloadStatus.done) {
|
||||
@ -556,7 +560,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
CommonDebug.logMethodName(this);
|
||||
}
|
||||
List<DownloadEntity> all = mDownloadDao.getAll();
|
||||
List<DownloadEntity> all = getAllDownloadEntity();
|
||||
return filterSilentDownloadTask(all);
|
||||
}
|
||||
|
||||
@ -992,7 +996,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
map.put(HttpDnsManager.GID, HaloApp.getInstance().getGid());
|
||||
map.put(HttpDnsManager.OAID, HaloApp.getInstance().getOAID());
|
||||
map.put(HttpDnsManager.USER_ID, UserManager.getInstance().getUserId());
|
||||
map.put(HttpDnsManager.IMEI, MetaUtil.INSTANCE.getIMEI());
|
||||
map.put(HttpDnsManager.IMEI, MetaUtil.getBase64EncodedIMEI());
|
||||
|
||||
HttpDnsManager.metaMap = map;
|
||||
}
|
||||
|
||||
203
app/src/main/java/com/gh/download/PackageObserver.kt
Normal file
203
app/src/main/java/com/gh/download/PackageObserver.kt
Normal file
@ -0,0 +1,203 @@
|
||||
package com.gh.download
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.preference.PreferenceManager
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.loghub.LoghubUtils
|
||||
import com.gh.common.runOnIoThread
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.entity.GameDigestEntity
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
import com.gh.gamecenter.packagehelper.PackageViewModel
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.halo.assistant.fragment.SettingsFragment
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
object PackageObserver {
|
||||
|
||||
private val mPackageViewModel: PackageViewModel
|
||||
by lazy { PackageViewModel(HaloApp.getInstance().application, PackageRepository) }
|
||||
|
||||
@JvmStatic
|
||||
fun onPackageChanged(busFour: EBPackage) {
|
||||
val application = HaloApp.getInstance().application
|
||||
val packageName = busFour.packageName
|
||||
val versionName = busFour.versionName
|
||||
var gameId = ""
|
||||
var mDownloadEntity: DownloadEntity? = null
|
||||
val sp = PreferenceManager.getDefaultSharedPreferences(application)
|
||||
|
||||
for (downloadEntity in DownloadManager.getInstance(application).allDownloadEntity) {
|
||||
if (packageName == downloadEntity.packageName) {
|
||||
mDownloadEntity = downloadEntity
|
||||
gameId = mDownloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER)
|
||||
if (TextUtils.isEmpty(busFour.versionName)) {
|
||||
// 没有版本号的事件直接选用第一个找到的 downloadEntity
|
||||
break
|
||||
} else {
|
||||
// 有版本号的事件直接尽量找到版本一致的 downloadEntity
|
||||
if (versionName == downloadEntity.versionName) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ("安装" == busFour.type) {
|
||||
mPackageViewModel.addInstalledGame(packageName)
|
||||
|
||||
// TODO 这个取消通知栏看起来没什么用,没在其它地方看到它,暂且保留一个版本
|
||||
// 删除下载完成 弹窗
|
||||
val nManager = application.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
nManager.cancel(packageName.hashCode())
|
||||
|
||||
if (mDownloadEntity != null) {
|
||||
if (mDownloadEntity.isPluggable) {
|
||||
val kv6: MutableMap<String, Any> = HashMap()
|
||||
kv6["安装或卸载"] = "安装完成"
|
||||
DataUtils.onEvent(application, "插件化", mDownloadEntity.name, kv6)
|
||||
|
||||
// DataUtils.onMtaEvent(this,
|
||||
// "插件化_新",
|
||||
// "位置", mDownloadEntity.getEntrance(),
|
||||
// "游戏", mDownloadEntity.getName() + "-" + mDownloadEntity.getPlatform(),
|
||||
// "操作", "安装完成",
|
||||
// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
}
|
||||
|
||||
// 没有光环 ID 的都记录一下游戏 ID,供'我的游戏'区分同包名不同插件用
|
||||
val gh_id = PackageUtils.getMetaData(application, mDownloadEntity.packageName, "gh_id")
|
||||
if (gh_id == null) {
|
||||
ThirdPartyPackageHelper.saveGameId(mDownloadEntity.packageName, mDownloadEntity.gameId)
|
||||
}
|
||||
DownloadManager.getInstance(application).cancel(
|
||||
mDownloadEntity.url, false, true) // 默认不删除安装包 mSp.getBoolean("autodelete", true)
|
||||
}
|
||||
if (sp.getBoolean(SettingsFragment.CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注
|
||||
// 安装后关注游戏
|
||||
val finalDownloadEntity = mDownloadEntity
|
||||
RetrofitManager.getInstance(application).sensitiveApi
|
||||
.getGameDigestByPackageName(UrlFilterUtils.getFilterQuery("package", packageName))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<GameDigestEntity?>?>() {
|
||||
override fun onResponse(response: List<GameDigestEntity?>?) {
|
||||
for (gameDigestEntity in response!!) {
|
||||
if (!TextUtils.isEmpty(gameDigestEntity?.id)) { // 关注游戏
|
||||
if (finalDownloadEntity != null && gameDigestEntity?.id == finalDownloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER)) {
|
||||
ConcernUtils.postConcernGameId(application, gameDigestEntity?.id ?: "", null, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
runOnIoThread { postNewlyInstalledApp(gameId, packageName) }
|
||||
}
|
||||
|
||||
if ("卸载" == busFour.type) {
|
||||
mPackageViewModel.addUninstalledGame(packageName)
|
||||
if (mDownloadEntity != null && mDownloadEntity.isPluggable) {
|
||||
val kv6: MutableMap<String, Any> = HashMap()
|
||||
kv6["安装或卸载"] = "卸载完成"
|
||||
DataUtils.onEvent(application, "插件化", mDownloadEntity.name, kv6)
|
||||
|
||||
// DataUtils.onMtaEvent(this,
|
||||
// "插件化_新",
|
||||
// "位置", mDownloadEntity.getEntrance(),
|
||||
// "游戏", mDownloadEntity.getName() + "-" + mDownloadEntity.getPlatform(),
|
||||
// "操作", "卸载完成",
|
||||
// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
PackageInstaller.install(application, mDownloadEntity)
|
||||
}
|
||||
|
||||
// 更新已安装游戏
|
||||
deleteInstalledPackage(packageName)
|
||||
}
|
||||
DataCollectionUtils.uploadInorunstall(application, busFour.type, busFour.packageName)
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun postNewlyInstalledApp(gameId: String, packageName: String) {
|
||||
|
||||
// 发送应用变更前都检查一下是否需要把所有应用都上传
|
||||
PackageRepository.checkAndUploadAppList()
|
||||
|
||||
// 更新已安装游戏
|
||||
val packageObject = PackageUtils.getAppBasicInfoByPackageName(packageName)
|
||||
val dataObject = JSONObject()
|
||||
val wrapperObject = JSONObject()
|
||||
try {
|
||||
dataObject.put("type", "POST")
|
||||
dataObject.put("device_id", HaloApp.getInstance().gid)
|
||||
dataObject.put("app", packageObject)
|
||||
dataObject.put("time", Utils.getTime(HaloApp.getInstance().application))
|
||||
wrapperObject.put("content", dataObject.toString())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
LoghubUtils.log(wrapperObject, "halo-api-device-installed", true)
|
||||
val requestBody = RequestBody.create(MediaType.parse("application/json"),
|
||||
packageObject.toString())
|
||||
// 更新已安装游戏
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.postNewlyInstalledApp(HaloApp.getInstance().gid, requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(EmptyResponse())
|
||||
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn) {
|
||||
val jsonObject = JSONObject()
|
||||
try {
|
||||
jsonObject.put("game_id", gameId)
|
||||
jsonObject.put("package", packageName)
|
||||
val rBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.postPlayedGame(UserManager.getInstance().userId, rBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(EmptyResponse())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun deleteInstalledPackage(packageName: String) {
|
||||
|
||||
// 发送应用变更前都检查一下是否需要把所有应用都上传
|
||||
PackageRepository.checkAndUploadAppList()
|
||||
|
||||
// 删除已安装游戏
|
||||
val dataObject = JSONObject()
|
||||
val wrapperObject = JSONObject()
|
||||
try {
|
||||
dataObject.put("type", "DELETE")
|
||||
dataObject.put("device_id", HaloApp.getInstance().gid)
|
||||
dataObject.put("package", packageName)
|
||||
dataObject.put("time", Utils.getTime(HaloApp.getInstance().application))
|
||||
wrapperObject.put("content", dataObject.toString())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
LoghubUtils.log(wrapperObject, "halo-api-device-installed", true)
|
||||
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
|
||||
}
|
||||
})
|
||||
mViewModel.dismissLiveData.observe(this, Observer {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
})
|
||||
|
||||
mElapsedHelper = TimeElapsedHelper()
|
||||
@ -173,7 +173,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
|
||||
postBrowseMta()
|
||||
mViewModel.collectionLiveData.postValue(null)
|
||||
} else {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
mGestureDetector = GestureDetector(requireContext(), SingleTapConfirm())
|
||||
@ -332,7 +332,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
|
||||
MotionEvent.ACTION_UP,
|
||||
MotionEvent.ACTION_OUTSIDE -> {
|
||||
if (mBinding.root.y >= mBinding.root.height / 2) {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
} else {
|
||||
resetDialogPosition(300)
|
||||
}
|
||||
|
||||
@ -2,11 +2,13 @@ package com.gh.download.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.dialog.CertificationDialog
|
||||
import com.gh.common.dialog.DeviceRemindDialog
|
||||
import com.gh.common.dialog.PackageCheckDialogFragment
|
||||
import com.gh.common.exposure.ExposureEvent
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
@ -24,6 +26,7 @@ import com.lightgame.download.DownloadStatus
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.sentry.core.protocol.App
|
||||
|
||||
class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
@ -278,19 +281,21 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
if (msg.isNullOrEmpty()) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apkEntity, object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, DialogUtils.ConfirmListener {
|
||||
DialogUtils.checkDownload(context, apkEntity.size) { isSubscribe ->
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
downloadMethod,
|
||||
entrance,
|
||||
location,
|
||||
isSubscribe, traceEvent)
|
||||
PackageCheckDialogFragment.show(context as AppCompatActivity, gameEntity.packageDialog, DialogUtils.ConfirmListener {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, DialogUtils.ConfirmListener {
|
||||
DialogUtils.checkDownload(context, apkEntity.size) { isSubscribe ->
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
downloadMethod,
|
||||
entrance,
|
||||
location,
|
||||
isSubscribe, traceEvent)
|
||||
|
||||
DeviceRemindDialog.showDeviceRemindDialog(context, gameEntity)
|
||||
}
|
||||
DeviceRemindDialog.showDeviceRemindDialog(context, gameEntity)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@ -28,7 +28,7 @@ class DownloadLinkDialog : BaseDialogFragment() {
|
||||
mLinkEntity.content, "text/html", "utf-8", null)
|
||||
|
||||
binding.confirm.setOnClickListener {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ 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.
|
||||
|
||||
@ -19,6 +19,7 @@ import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RestrictTo;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.gh.base.AppUncaughtHandler;
|
||||
@ -71,6 +72,7 @@ import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.eventbus.EBSkip;
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment;
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment;
|
||||
import com.gh.gamecenter.manager.DataCollectionManager;
|
||||
import com.gh.gamecenter.manager.UpdateManager;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
@ -78,12 +80,14 @@ import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository;
|
||||
import com.gh.gamecenter.packagehelper.PackageViewModel;
|
||||
import com.gh.gamecenter.qa.CommunityFragment;
|
||||
import com.gh.gamecenter.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
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.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.halo.assistant.fragment.SettingsFragment;
|
||||
@ -96,6 +100,7 @@ import com.lightgame.utils.Utils;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@ -125,9 +130,11 @@ 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;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_DATA;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_MARKET_DETAILS;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_NEXT_TO;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_TO;
|
||||
import static com.gh.common.util.EntranceUtils.KEY_TYPE;
|
||||
import static com.gh.common.util.ExtensionsKt.singleToMain;
|
||||
import static com.gh.gamecenter.fragment.MainWrapperFragment.INDEX_PERSONAL;
|
||||
import static com.gh.gamecenter.personal.PersonalFragment.LOGIN_TAG;
|
||||
import static com.gh.gamecenter.personal.PersonalFragment.LOGOUT_TAG;
|
||||
@ -164,10 +171,6 @@ 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);
|
||||
@ -403,6 +406,9 @@ public class MainActivity extends BaseActivity {
|
||||
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
|
||||
}
|
||||
break;
|
||||
case KEY_MARKET_DETAILS:
|
||||
redirectGameDetail(bundle.getString(KEY_DATA));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -416,6 +422,28 @@ public class MainActivity extends BaseActivity {
|
||||
}, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用跳转
|
||||
* @param packageName
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
private void redirectGameDetail(String packageName) {
|
||||
RetrofitManager.getInstance(this).getApi().redirectGameDetail(packageName)
|
||||
.compose(singleToMain())
|
||||
.subscribe(new BiResponse<JsonObject>() {
|
||||
@Override
|
||||
public void onSuccess(JsonObject data) {
|
||||
String gameId = data.get("game_id").getAsString();
|
||||
DirectUtils.directToGameDetail(MainActivity.this, gameId, GameDetailFragment.INDEX_DESC, "应用跳转");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Exception exception) {
|
||||
super.onFailure(exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkNotificationPermission() {
|
||||
// 仅登录后再启动光环时请求一次权限
|
||||
if (UserManager.getInstance().isLoggedIn()) {
|
||||
@ -717,184 +745,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(EBPackage busFour) {
|
||||
final String packageName = busFour.getPackageName();
|
||||
final String versionName = busFour.getVersionName();
|
||||
String gameId = "";
|
||||
|
||||
DownloadEntity mDownloadEntity = null;
|
||||
for (DownloadEntity downloadEntity : DownloadManager.getInstance(getApplicationContext()).getAllDownloadEntity()) {
|
||||
if (packageName.equals(downloadEntity.getPackageName())) {
|
||||
mDownloadEntity = downloadEntity;
|
||||
gameId = mDownloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER);
|
||||
if (TextUtils.isEmpty(busFour.getVersionName())) {
|
||||
// 没有版本号的事件直接选用第一个找到的 downloadEntity
|
||||
break;
|
||||
} else {
|
||||
// 有版本号的事件直接尽量找到版本一致的 downloadEntity
|
||||
if (versionName.equals(downloadEntity.getVersionName())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("安装".equals(busFour.getType())) {
|
||||
mPackageViewModel.addInstalledGame(packageName);
|
||||
|
||||
// 删除下载完成 弹窗
|
||||
NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nManager.cancel(packageName.hashCode());
|
||||
|
||||
if (mDownloadEntity != null) {
|
||||
if (mDownloadEntity.isPluggable()) {
|
||||
Map<String, Object> kv6 = new HashMap<>();
|
||||
kv6.put("安装或卸载", "安装完成");
|
||||
DataUtils.onEvent(this, "插件化", mDownloadEntity.getName(), kv6);
|
||||
|
||||
// DataUtils.onMtaEvent(this,
|
||||
// "插件化_新",
|
||||
// "位置", mDownloadEntity.getEntrance(),
|
||||
// "游戏", mDownloadEntity.getName() + "-" + mDownloadEntity.getPlatform(),
|
||||
// "操作", "安装完成",
|
||||
// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
}
|
||||
|
||||
// 没有光环 ID 的都记录一下游戏 ID,供'我的游戏'区分同包名不同插件用
|
||||
Object gh_id = PackageUtils.getMetaData(this, mDownloadEntity.getPackageName(), "gh_id");
|
||||
if (gh_id == null) {
|
||||
ThirdPartyPackageHelper.saveGameId(mDownloadEntity.getPackageName(), mDownloadEntity.getGameId());
|
||||
}
|
||||
DownloadManager.getInstance(getApplicationContext()).cancel(
|
||||
mDownloadEntity.getUrl(), false, true); // 默认不删除安装包 mSp.getBoolean("autodelete", true)
|
||||
}
|
||||
|
||||
|
||||
if (mSp.getBoolean(SettingsFragment.CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注
|
||||
// 安装后关注游戏
|
||||
DownloadEntity finalDownloadEntity = mDownloadEntity;
|
||||
RetrofitManager.getInstance(this).getSensitiveApi().getGameDigestByPackageName(UrlFilterUtils.getFilterQuery("package", packageName))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<List<GameDigestEntity>>() {
|
||||
@Override
|
||||
public void onResponse(List<GameDigestEntity> response) {
|
||||
for (GameDigestEntity gameDigestEntity : response) {
|
||||
if (!TextUtils.isEmpty(gameDigestEntity.getId())) { // 关注游戏
|
||||
if (finalDownloadEntity != null && gameDigestEntity.getId().equals(finalDownloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER))) {
|
||||
ConcernUtils.INSTANCE.postConcernGameId(MainActivity.this, gameDigestEntity.getId(), null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
postNewlyInstalledApp(gameId, packageName);
|
||||
}
|
||||
if ("卸载".equals(busFour.getType())) {
|
||||
mPackageViewModel.addUninstalledGame(packageName);
|
||||
|
||||
if (mDownloadEntity != null && mDownloadEntity.isPluggable()) {
|
||||
Map<String, Object> kv6 = new HashMap<>();
|
||||
kv6.put("安装或卸载", "卸载完成");
|
||||
DataUtils.onEvent(this, "插件化", mDownloadEntity.getName(), kv6);
|
||||
|
||||
// DataUtils.onMtaEvent(this,
|
||||
// "插件化_新",
|
||||
// "位置", mDownloadEntity.getEntrance(),
|
||||
// "游戏", mDownloadEntity.getName() + "-" + mDownloadEntity.getPlatform(),
|
||||
// "操作", "卸载完成",
|
||||
// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
|
||||
PackageInstaller.install(this, mDownloadEntity);
|
||||
}
|
||||
|
||||
// 更新已安装游戏
|
||||
deleteInstalledPackage(packageName);
|
||||
}
|
||||
|
||||
DataCollectionUtils.uploadInorunstall(this, busFour.getType(), busFour.getPackageName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@SuppressLint("CheckResult")
|
||||
private void postNewlyInstalledApp(String gameId, String packageName) {
|
||||
|
||||
// 发送应用变更前都检查一下是否需要把所有应用都上传
|
||||
PackageRepository.checkAndUploadAppList();
|
||||
|
||||
// 更新已安装游戏
|
||||
JSONObject packageObject = PackageUtils.getAppBasicInfoByPackageName(packageName);
|
||||
JSONObject dataObject = new JSONObject();
|
||||
JSONObject wrapperObject = new JSONObject();
|
||||
try {
|
||||
dataObject.put("type", "POST");
|
||||
dataObject.put("device_id", HaloApp.getInstance().getGid());
|
||||
dataObject.put("app", packageObject);
|
||||
dataObject.put("time", Utils.getTime(getApplicationContext()));
|
||||
wrapperObject.put("content", dataObject.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
LoghubUtils.log(wrapperObject, "halo-api-device-installed", true);
|
||||
|
||||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"),
|
||||
packageObject.toString());
|
||||
// 更新已安装游戏
|
||||
RetrofitManager.getInstance(MainActivity.this).getApi()
|
||||
.postNewlyInstalledApp(HaloApp.getInstance().getGid(), requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(new EmptyResponse<>());
|
||||
|
||||
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn()) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("game_id", gameId);
|
||||
jsonObject.put("package", packageName);
|
||||
RequestBody rBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString());
|
||||
|
||||
RetrofitManager.getInstance(MainActivity.this).getApi()
|
||||
.postPlayedGame(UserManager.getInstance().getUserId(), rBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(new EmptyResponse<>());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void deleteInstalledPackage(String packageName) {
|
||||
|
||||
// 发送应用变更前都检查一下是否需要把所有应用都上传
|
||||
PackageRepository.checkAndUploadAppList();
|
||||
|
||||
// 删除已安装游戏
|
||||
JSONObject dataObject = new JSONObject();
|
||||
JSONObject wrapperObject = new JSONObject();
|
||||
try {
|
||||
dataObject.put("type", "DELETE");
|
||||
dataObject.put("device_id", HaloApp.getInstance().getGid());
|
||||
dataObject.put("package", packageName);
|
||||
dataObject.put("time", Utils.getTime(getApplicationContext()));
|
||||
wrapperObject.put("content", dataObject.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
LoghubUtils.log(wrapperObject, "halo-api-device-installed", true);
|
||||
|
||||
// 删除已安装游戏
|
||||
RetrofitManager.getInstance(MainActivity.this).getApi()
|
||||
.deleteInstalledApp(HaloApp.getInstance().getGid(), packageName)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(new EmptyResponse<>());
|
||||
}
|
||||
|
||||
// 接收登录和登出更新事件统计的 Meta
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(EBReuse reuse) {
|
||||
|
||||
@ -7,6 +7,7 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.EditText
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import com.gh.base.BaseActivity
|
||||
@ -21,12 +22,15 @@ import com.lightgame.utils.Util_System_Keyboard
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import kotlinx.android.synthetic.main.toolbar_search.*
|
||||
import kotterknife.bindView
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
open class SearchActivity : BaseActivity() {
|
||||
|
||||
private val searchEt by bindView<EditText>(R.id.searchEt)
|
||||
|
||||
private var mDao: SearchHistoryDao? = null
|
||||
|
||||
protected var mSearchKey: String? = null
|
||||
@ -53,6 +57,7 @@ open class SearchActivity : BaseActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
val hint = intent.getStringExtra(EntranceUtils.KEY_HINT)
|
||||
val searchImmediately = intent.getBooleanExtra(KEY_SEARCH_IMMEDIATELY, false)
|
||||
var ignoreTextChanges = savedInstanceState != null
|
||||
|
||||
mDao = SearchHistoryDao(this)
|
||||
mPublishSubject = PublishSubject.create()
|
||||
@ -62,21 +67,27 @@ open class SearchActivity : BaseActivity() {
|
||||
.distinctUntilChanged()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
if (searchEt.text.isNotEmpty()) {
|
||||
if (searchEt.text.isNotEmpty()
|
||||
&& searchEt.text != searchEt.hint
|
||||
&& !ignoreTextChanges) {
|
||||
search(SearchType.AUTO, it)
|
||||
}
|
||||
|
||||
ignoreTextChanges = false
|
||||
}
|
||||
|
||||
initSearchBar()
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mDisplayType = DisplayType.fromInt(savedInstanceState.getInt(KEY_DISPLAY_TYPE, 0))
|
||||
mSearchKey = savedInstanceState.getString(EntranceUtils.KEY_SEARCHKEY, null)
|
||||
mSearchType = SearchType.fromString(savedInstanceState.getString(KEY_SEARCH_TYPE, null))
|
||||
if (mDisplayType != DisplayType.DEFAULT && !TextUtils.isEmpty(mSearchKey)) {
|
||||
search(mSearchType, mSearchKey)
|
||||
}
|
||||
} else if (!TextUtils.isEmpty(hint)) {
|
||||
// 子 Fragment 自己恢复状态
|
||||
// if (savedInstanceState != null) {
|
||||
// mDisplayType = DisplayType.fromInt(savedInstanceState.getInt(KEY_DISPLAY_TYPE, 0))
|
||||
// mSearchKey = savedInstanceState.getString(EntranceUtils.KEY_SEARCHKEY, null)
|
||||
// mSearchType = SearchType.fromString(savedInstanceState.getString(KEY_SEARCH_TYPE, null))
|
||||
// if (mDisplayType != DisplayType.DEFAULT && !TextUtils.isEmpty(mSearchKey)) {
|
||||
// search(mSearchType, mSearchKey)
|
||||
// }
|
||||
// } else
|
||||
if (!TextUtils.isEmpty(hint)) {
|
||||
searchEt.hint = hint
|
||||
if (searchImmediately) {
|
||||
mDisplayType = GAME_DETAIL
|
||||
@ -87,7 +98,8 @@ open class SearchActivity : BaseActivity() {
|
||||
searchEt.hint = "搜索游戏..."
|
||||
}
|
||||
|
||||
if (mDisplayType == DisplayType.DEFAULT) {
|
||||
if (savedInstanceState == null
|
||||
&& mDisplayType == DisplayType.DEFAULT) {
|
||||
updateDisplayType(DisplayType.DEFAULT)
|
||||
}
|
||||
}
|
||||
@ -233,7 +245,7 @@ open class SearchActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_SEARCH_TYPE = "search_type"
|
||||
const val KEY_SEARCH_TYPE = "search_type"
|
||||
private const val KEY_DISPLAY_TYPE = "display_type"
|
||||
private const val KEY_SEARCH_IMMEDIATELY = "search_immediately"
|
||||
|
||||
@ -274,11 +286,13 @@ enum class SearchType(var value: String) {
|
||||
* [DEFAULT] 默认搜索页
|
||||
* [GAME_DIGEST] 游戏为部分文字样式的列表
|
||||
* [GAME_DETAIL] 游戏全为标准样式的列表
|
||||
* [FORUM_OR_USER] 论坛内容和用户
|
||||
*/
|
||||
enum class DisplayType(var value: Int) {
|
||||
DEFAULT(0),
|
||||
GAME_DIGEST(1),
|
||||
GAME_DETAIL(2);
|
||||
GAME_DETAIL(2),
|
||||
FORUM_OR_USER(3);
|
||||
|
||||
companion object {
|
||||
fun fromInt(typeInt: Int) = values().find { typeInt == it.value } ?: DEFAULT
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@ -10,15 +9,16 @@ import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.gh.base.ToolBarActivity;
|
||||
import com.gh.common.util.ExtensionsKt;
|
||||
import com.gh.common.util.MessageShareUtils;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.QRCodeUtils;
|
||||
import com.gh.common.util.ShareUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.tauth.Tencent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
@ -73,9 +73,6 @@ public class ShareGhActivity extends ToolBarActivity {
|
||||
@OnClick(R.id.gh_address_tv)
|
||||
public void copyAddress() {
|
||||
MtaHelper.onEvent("我的光环_新", "分享光环", "复制官网");
|
||||
ClipboardManager cmb = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(getString(R.string.gh_website_url_100));
|
||||
|
||||
Utils.toast(this, "网址复制成功,请到微信/QQ粘贴分享");
|
||||
ExtensionsKt.copyTextAndToast(getString(R.string.gh_website_url_100), "网址复制成功,请到微信/QQ粘贴分享");
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,310 +80,325 @@ public class SkipActivity extends BaseActivity {
|
||||
Uri uri = getIntent().getData();
|
||||
Bundle bundle;
|
||||
if (uri != null) {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
Utils.log("SkipActivity:: Uri=>" + uri.toString());
|
||||
}
|
||||
String host = uri.getHost();
|
||||
String path = uri.getPath();
|
||||
if ("ghzhushou".equals(uri.getScheme())) {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
Utils.log("SkipActivity:: Uri=>" + uri.toString());
|
||||
}
|
||||
String host = uri.getHost();
|
||||
String path = uri.getPath();
|
||||
|
||||
String to = uri.getQueryParameter("to");
|
||||
String type = uri.getQueryParameter("type");
|
||||
String name = uri.getQueryParameter("name");
|
||||
String referer = uri.getQueryParameter("referer");
|
||||
String id = uri.getQueryParameter("id");
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
String to = uri.getQueryParameter("to");
|
||||
String type = uri.getQueryParameter("type");
|
||||
String name = uri.getQueryParameter("name");
|
||||
String referer = uri.getQueryParameter("referer");
|
||||
String id = uri.getQueryParameter("id");
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
if (host != null) {
|
||||
Intent intent;
|
||||
switch (host) {
|
||||
case HOST_ARTICLE:
|
||||
DirectUtils.directToArticle(this, path, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_GAME:
|
||||
DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null);
|
||||
break;
|
||||
case HOST_COLUMN:
|
||||
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_SUGGESTION:
|
||||
String platform = uri.getQueryParameter(KEY_PLATFORM);
|
||||
String platformName = PlatformUtils.getInstance(this).getPlatformName(platform);
|
||||
String gameId = uri.getQueryParameter(EntranceUtils.KEY_GAMEID);
|
||||
String packageMd5 = uri.getQueryParameter(EntranceUtils.KEY_PACKAGE_MD5);
|
||||
String content = (TextUtils.isEmpty(gameId) || TextUtils.isEmpty(packageMd5)) ?
|
||||
String.format("%s-%s-V%s,",
|
||||
uri.getQueryParameter(KEY_GAME_NAME),
|
||||
TextUtils.isEmpty(platformName) ? platform : platformName,
|
||||
uri.getQueryParameter(KEY_VERSION)) :
|
||||
String.format("%s-%s-V%s\n游戏ID:%s\n游戏包MD5:%s\n",
|
||||
uri.getQueryParameter(KEY_GAME_NAME),
|
||||
TextUtils.isEmpty(platformName) ? platform : platformName,
|
||||
uri.getQueryParameter(KEY_VERSION), gameId, packageMd5);
|
||||
String qaId = uri.getQueryParameter("qa_id");
|
||||
String qaTitle = uri.getQueryParameter(EntranceUtils.KEY_QA_TITLE);
|
||||
if (!TextUtils.isEmpty(qaId)) {
|
||||
DirectUtils.directToQa(this, qaTitle, qaId);
|
||||
} else {
|
||||
DirectUtils.directToFeedback(this, content, ENTRANCE_BROWSER);
|
||||
}
|
||||
break;
|
||||
case HOST_DOWNLOAD:
|
||||
DirectUtils.directToDownloadManagerAndStartUpdate(this, path, uri.getQueryParameter(KEY_PACKAGENAME), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_ANSWER:
|
||||
DirectUtils.directToAnswerDetail(this, path, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_QUESTION:
|
||||
DirectUtils.directToQuestionDetail(this, path, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_TOOLBOX:
|
||||
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_COMMUNITY:
|
||||
UserManager.getInstance().setCommunityData(new CommunityEntity(path, name));
|
||||
// 把切换放到 MainActivity 处理
|
||||
if (RunningUtils.isRunning(this)
|
||||
&& MainActivity.class.getName().equals(RunningUtils.getBaseActivity(this))) {
|
||||
intent = new Intent(this, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.putExtra(MainActivity.SWITCH_TO_COMMUNITY, true);
|
||||
} else {
|
||||
bundle = new Bundle();
|
||||
bundle.putBoolean(MainActivity.SWITCH_TO_COMMUNITY, true);
|
||||
intent = SplashScreenActivity.getSplashScreenIntent(this, bundle);
|
||||
}
|
||||
startActivity(intent);
|
||||
break;
|
||||
// 社区文章格式一
|
||||
case "community.article":
|
||||
DirectUtils.directToCommunityArticle(this, uri.getQueryParameter("articleId"), uri.getQueryParameter("communityId"), ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
// 社区文章格式二
|
||||
case "communities":
|
||||
String communityId = "";
|
||||
String typeId = "";
|
||||
String[] split = path.split("/");
|
||||
for (String text : split) {
|
||||
if (TextUtils.isEmpty(communityId)) {
|
||||
communityId = text;
|
||||
continue;
|
||||
}
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
type = text;
|
||||
continue;
|
||||
}
|
||||
if (TextUtils.isEmpty(typeId)) {
|
||||
typeId = text;
|
||||
}
|
||||
}
|
||||
if ("articles".equals(type)) {
|
||||
DirectUtils.directToCommunityArticle(this, typeId, communityId, ENTRANCE_BROWSER, "浏览器");
|
||||
if (host != null) {
|
||||
Intent intent;
|
||||
switch (host) {
|
||||
case HOST_ARTICLE:
|
||||
DirectUtils.directToArticle(this, path, ENTRANCE_BROWSER);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HOST_VIDEO:
|
||||
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.HOTTEST_GAME_VIDEO.getValue(),
|
||||
false, id, ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer);
|
||||
break;
|
||||
case HOST_UPLOAD_VIDEO://跳转上传视频
|
||||
String titleParameter = uri.getQueryParameter("title");
|
||||
String title = TextUtils.isEmpty(titleParameter) ? "" : "#" + titleParameter + "#";
|
||||
String categoryId = uri.getQueryParameter("category_id");
|
||||
String link = uri.getQueryParameter("link");
|
||||
gameId = uri.getQueryParameter("gameId");
|
||||
String gameName = uri.getQueryParameter("gameName");
|
||||
String tagActivityId = uri.getQueryParameter("tagActivityId");
|
||||
String tagActivityName = uri.getQueryParameter("tagActivityName");
|
||||
VideoLinkEntity linkEntity = new VideoLinkEntity(title, categoryId, link, tagActivityId, tagActivityName);
|
||||
|
||||
SimpleGameEntity simpleGameEntity = new SimpleGameEntity(gameId != null ? gameId : "", gameName != null ? gameName : "", "");
|
||||
Bundle nextToBundle = VideoManagerActivity.getVideoManagerBundle(linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "");
|
||||
CheckLoginUtils.checkLogin(this, nextToBundle, true, EntranceUtils.ENTRANCE_BROWSER, () ->
|
||||
DirectUtils.directToVideoManager(SkipActivity.this, linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "浏览器"));
|
||||
break;
|
||||
case HOST_VIDEO_SINGLE:
|
||||
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.getValue(),
|
||||
false, "", ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer);
|
||||
break;
|
||||
case HOST_VIDEO_MORE:
|
||||
gameId = uri.getQueryParameter("gameId");
|
||||
String act = uri.getQueryParameter("act");
|
||||
String fieldId = uri.getQueryParameter("fieldId");
|
||||
String sectionName = uri.getQueryParameter("sectionName");
|
||||
String paginationType = uri.getQueryParameter("paginationType");//活动分页方式 page filter
|
||||
String location;
|
||||
if (!TextUtils.isEmpty(act)) {
|
||||
location = VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.getValue();
|
||||
} else if (!TextUtils.isEmpty(fieldId)) {
|
||||
location = VideoDetailContainerViewModel.Location.GAME_ZONE.getValue();
|
||||
} else {
|
||||
location = path;
|
||||
}
|
||||
DirectUtils.directToVideoDetail(this, path, location,
|
||||
false, TextUtils.isEmpty(gameId) ? "" : gameId, ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer,
|
||||
TextUtils.isEmpty(type) ? "" : type, TextUtils.isEmpty(act) ? "" : act, TextUtils.isEmpty(paginationType) ? "page" : paginationType, TextUtils.isEmpty(fieldId) ? "" : fieldId,
|
||||
TextUtils.isEmpty(sectionName) ? "" : sectionName);
|
||||
break;
|
||||
case HOST_VIDEO_STREAMING_HOME:
|
||||
// 把切换放到 MainActivity 处理
|
||||
if (RunningUtils.isRunning(this)
|
||||
&& MainActivity.class.getName().equals(RunningUtils.getBaseActivity(this))) {
|
||||
intent = new Intent(this, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true);
|
||||
} else {
|
||||
bundle = new Bundle();
|
||||
bundle.putBoolean(MainActivity.SWITCH_TO_VIDEO, true);
|
||||
intent = SplashScreenActivity.getSplashScreenIntent(this, bundle);
|
||||
}
|
||||
startActivity(intent);
|
||||
break;
|
||||
case HOST_VIDEO_STREAMING_DESC:
|
||||
DirectUtils.directToGameDetailVideoStreaming(this, path, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_VIDEO_COLLECTION:
|
||||
DirectUtils.directToGameVideo(this, path, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_QQ:
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_QQ);
|
||||
bundle.putString(KEY_DATA, path);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_QQ_GROUP:
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_QQ_GROUP);
|
||||
bundle.putString(KEY_DATA, path);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_QQ_QUN:
|
||||
String key = uri.getQueryParameter("key");
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_QQ_GROUP);
|
||||
bundle.putString(KEY_DATA, key);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_WEB:
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_WEB);
|
||||
bundle.putString(KEY_DATA, to);
|
||||
bundle.putString(KEY_TYPE, type);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_LIBAO:
|
||||
DirectUtils.directToGiftDetail(this, path, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_USERHOME:
|
||||
String position = uri.getQueryParameter("position");
|
||||
DirectUtils.directToHomeActivity(this, path, TextUtils.isEmpty(position) ? -1 : Integer.parseInt(position), ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COMMUNITY_COLUMN:
|
||||
CommunityEntity community = new CommunityEntity();
|
||||
community.setId(uri.getQueryParameter("community_id"));
|
||||
community.setName(uri.getQueryParameter("community_name"));
|
||||
String columnId = uri.getQueryParameter("column_id");
|
||||
DirectUtils.directToCommunityColumn(this, community, columnId, ENTRANCE_BROWSER, "");
|
||||
break;
|
||||
|
||||
case HOST_CATEGORY:
|
||||
title = uri.getQueryParameter("title");
|
||||
DirectUtils.directCategoryDirectory(this, path, title, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COLUMN_COLLECTION:
|
||||
DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COMMUNITY_QUESTION_LABEL_DETAIL:
|
||||
community = new CommunityEntity();
|
||||
community.setId(uri.getQueryParameter("community_id"));
|
||||
community.setName(uri.getQueryParameter("community_name"));
|
||||
String tag = uri.getQueryParameter("tag");
|
||||
DirectUtils.directAskColumnLabelDetail(this, tag, community, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COMMUNITY_COLUMN_DETAIL:
|
||||
community = new CommunityEntity();
|
||||
community.setId(uri.getQueryParameter("community_id"));
|
||||
community.setName(uri.getQueryParameter("community_name"));
|
||||
columnId = uri.getQueryParameter("column_id");
|
||||
DirectUtils.directAskColumnDetail(this, columnId, community, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case EntranceUtils.HOST_BLOCK:
|
||||
name = uri.getQueryParameter("name");
|
||||
SubjectRecommendEntity entity = new SubjectRecommendEntity();
|
||||
entity.setLink(path);
|
||||
entity.setName(name);
|
||||
entity.setText(name);
|
||||
DirectUtils.directToBlock(this, entity, mEntrance);
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_SERVER_BLOCK:
|
||||
DirectUtils.directToGameServers(this, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_AMWAY_BLOCK:
|
||||
DirectUtils.directToAmway(this, null, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_HELP:
|
||||
name = uri.getQueryParameter("name");
|
||||
DirectUtils.directToQa(this, name, path);
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_HELP_COLLECTION:
|
||||
name = uri.getQueryParameter("name");
|
||||
DirectUtils.directToQaCollection(this, name, path);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_UPLOAD:
|
||||
DirectUtils.directGameUpload(this, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_ZONE:
|
||||
String zoneUrl = uri.getQueryParameter("url");
|
||||
DirectUtils.directGameZone(this, path, zoneUrl, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_LINK:
|
||||
try {
|
||||
String dataString = uri.getQueryParameter("data");
|
||||
if (!TextUtils.isEmpty(dataString)) {
|
||||
byte[] linkData = Base64.decode(dataString, Base64.DEFAULT);
|
||||
String linkDataString = new String(linkData, "UTF-8");
|
||||
LinkEntity le = GsonUtils.INSTANCE.getGson().fromJson(linkDataString, LinkEntity.class);
|
||||
DirectUtils.directToLinkPage(this, le, ENTRANCE_BROWSER, "");
|
||||
case HOST_GAME:
|
||||
DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null);
|
||||
break;
|
||||
case HOST_COLUMN:
|
||||
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_SUGGESTION:
|
||||
String platform = uri.getQueryParameter(KEY_PLATFORM);
|
||||
String platformName = PlatformUtils.getInstance(this).getPlatformName(platform);
|
||||
String gameId = uri.getQueryParameter(EntranceUtils.KEY_GAMEID);
|
||||
String packageMd5 = uri.getQueryParameter(EntranceUtils.KEY_PACKAGE_MD5);
|
||||
String content = (TextUtils.isEmpty(gameId) || TextUtils.isEmpty(packageMd5)) ?
|
||||
String.format("%s-%s-V%s,",
|
||||
uri.getQueryParameter(KEY_GAME_NAME),
|
||||
TextUtils.isEmpty(platformName) ? platform : platformName,
|
||||
uri.getQueryParameter(KEY_VERSION)) :
|
||||
String.format("%s-%s-V%s\n游戏ID:%s\n游戏包MD5:%s\n",
|
||||
uri.getQueryParameter(KEY_GAME_NAME),
|
||||
TextUtils.isEmpty(platformName) ? platform : platformName,
|
||||
uri.getQueryParameter(KEY_VERSION), gameId, packageMd5);
|
||||
String qaId = uri.getQueryParameter("qa_id");
|
||||
String qaTitle = uri.getQueryParameter(EntranceUtils.KEY_QA_TITLE);
|
||||
if (!TextUtils.isEmpty(qaId)) {
|
||||
DirectUtils.directToQa(this, qaTitle, qaId);
|
||||
} else {
|
||||
DirectUtils.directToFeedback(this, content, ENTRANCE_BROWSER);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
toast(e.getMessage());
|
||||
}
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_NEWS:
|
||||
DirectUtils.directToGameNews(
|
||||
this,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_ID),
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
EntranceUtils.ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_CALENDAR:
|
||||
DirectUtils.directToGameServerCalendar(this, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID));
|
||||
break;
|
||||
case EntranceUtils.HOST_HISTORY_APK:
|
||||
DirectUtils.directToHistoryApk(this, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID));
|
||||
break;
|
||||
case EntranceUtils.HOST_FORUM_DETAIL:
|
||||
DirectUtils.directForumDetail(this, id, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_RATING_DETAIL:
|
||||
DirectUtils.directToGameRatingDetail(this, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID), uri.getQueryParameter(EntranceUtils.KEY_COMMENT_ID), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_FORUM:
|
||||
DirectUtils.directToForum(this);
|
||||
break;
|
||||
case EntranceUtils.HOST_HELP_AND_FEEDBACK:
|
||||
position = uri.getQueryParameter("position");
|
||||
DirectUtils.directToHelpAndFeedback(this, TextUtils.isEmpty(position) ? 0 : Integer.parseInt(position));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case HOST_DOWNLOAD:
|
||||
DirectUtils.directToDownloadManagerAndStartUpdate(this, path, uri.getQueryParameter(KEY_PACKAGENAME), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_ANSWER:
|
||||
DirectUtils.directToAnswerDetail(this, path, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_QUESTION:
|
||||
DirectUtils.directToQuestionDetail(this, path, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_TOOLBOX:
|
||||
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_COMMUNITY:
|
||||
UserManager.getInstance().setCommunityData(new CommunityEntity(path, name));
|
||||
// 把切换放到 MainActivity 处理
|
||||
if (RunningUtils.isRunning(this)
|
||||
&& MainActivity.class.getName().equals(RunningUtils.getBaseActivity(this))) {
|
||||
intent = new Intent(this, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.putExtra(MainActivity.SWITCH_TO_COMMUNITY, true);
|
||||
} else {
|
||||
bundle = new Bundle();
|
||||
bundle.putBoolean(MainActivity.SWITCH_TO_COMMUNITY, true);
|
||||
intent = SplashScreenActivity.getSplashScreenIntent(this, bundle);
|
||||
}
|
||||
startActivity(intent);
|
||||
break;
|
||||
// 社区文章格式一
|
||||
case "community.article":
|
||||
DirectUtils.directToCommunityArticle(this, uri.getQueryParameter("articleId"), uri.getQueryParameter("communityId"), ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
// 社区文章格式二
|
||||
case "communities":
|
||||
String communityId = "";
|
||||
String typeId = "";
|
||||
String[] split = path.split("/");
|
||||
for (String text : split) {
|
||||
if (TextUtils.isEmpty(communityId)) {
|
||||
communityId = text;
|
||||
continue;
|
||||
}
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
type = text;
|
||||
continue;
|
||||
}
|
||||
if (TextUtils.isEmpty(typeId)) {
|
||||
typeId = text;
|
||||
}
|
||||
}
|
||||
if ("articles".equals(type)) {
|
||||
DirectUtils.directToCommunityArticle(this, typeId, communityId, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HOST_VIDEO:
|
||||
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.HOTTEST_GAME_VIDEO.getValue(),
|
||||
false, id, ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer);
|
||||
break;
|
||||
case HOST_UPLOAD_VIDEO://跳转上传视频
|
||||
String titleParameter = uri.getQueryParameter("title");
|
||||
String title = TextUtils.isEmpty(titleParameter) ? "" : "#" + titleParameter + "#";
|
||||
String categoryId = uri.getQueryParameter("category_id");
|
||||
String link = uri.getQueryParameter("link");
|
||||
gameId = uri.getQueryParameter("gameId");
|
||||
String gameName = uri.getQueryParameter("gameName");
|
||||
String tagActivityId = uri.getQueryParameter("tagActivityId");
|
||||
String tagActivityName = uri.getQueryParameter("tagActivityName");
|
||||
VideoLinkEntity linkEntity = new VideoLinkEntity(title, categoryId, link, tagActivityId, tagActivityName);
|
||||
|
||||
SimpleGameEntity simpleGameEntity = new SimpleGameEntity(gameId != null ? gameId : "", gameName != null ? gameName : "", "");
|
||||
Bundle nextToBundle = VideoManagerActivity.getVideoManagerBundle(linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "");
|
||||
CheckLoginUtils.checkLogin(this, nextToBundle, true, EntranceUtils.ENTRANCE_BROWSER, () ->
|
||||
DirectUtils.directToVideoManager(SkipActivity.this, linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "浏览器"));
|
||||
break;
|
||||
case HOST_VIDEO_SINGLE:
|
||||
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.getValue(),
|
||||
false, "", ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer);
|
||||
break;
|
||||
case HOST_VIDEO_MORE:
|
||||
gameId = uri.getQueryParameter("gameId");
|
||||
String act = uri.getQueryParameter("act");
|
||||
String fieldId = uri.getQueryParameter("fieldId");
|
||||
String sectionName = uri.getQueryParameter("sectionName");
|
||||
String paginationType = uri.getQueryParameter("paginationType");//活动分页方式 page filter
|
||||
String location;
|
||||
if (!TextUtils.isEmpty(act)) {
|
||||
location = VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.getValue();
|
||||
} else if (!TextUtils.isEmpty(fieldId)) {
|
||||
location = VideoDetailContainerViewModel.Location.GAME_ZONE.getValue();
|
||||
} else {
|
||||
location = path;
|
||||
}
|
||||
DirectUtils.directToVideoDetail(this, path, location,
|
||||
false, TextUtils.isEmpty(gameId) ? "" : gameId, ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer,
|
||||
TextUtils.isEmpty(type) ? "" : type, TextUtils.isEmpty(act) ? "" : act, TextUtils.isEmpty(paginationType) ? "page" : paginationType, TextUtils.isEmpty(fieldId) ? "" : fieldId,
|
||||
TextUtils.isEmpty(sectionName) ? "" : sectionName);
|
||||
break;
|
||||
case HOST_VIDEO_STREAMING_HOME:
|
||||
// 把切换放到 MainActivity 处理
|
||||
if (RunningUtils.isRunning(this)
|
||||
&& MainActivity.class.getName().equals(RunningUtils.getBaseActivity(this))) {
|
||||
intent = new Intent(this, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true);
|
||||
} else {
|
||||
bundle = new Bundle();
|
||||
bundle.putBoolean(MainActivity.SWITCH_TO_VIDEO, true);
|
||||
intent = SplashScreenActivity.getSplashScreenIntent(this, bundle);
|
||||
}
|
||||
startActivity(intent);
|
||||
break;
|
||||
case HOST_VIDEO_STREAMING_DESC:
|
||||
DirectUtils.directToGameDetailVideoStreaming(this, path, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_VIDEO_COLLECTION:
|
||||
DirectUtils.directToGameVideo(this, path, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_QQ:
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_QQ);
|
||||
bundle.putString(KEY_DATA, path);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_QQ_GROUP:
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_QQ_GROUP);
|
||||
bundle.putString(KEY_DATA, path);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_QQ_QUN:
|
||||
String key = uri.getQueryParameter("key");
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_QQ_GROUP);
|
||||
bundle.putString(KEY_DATA, key);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_WEB:
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, HOST_WEB);
|
||||
bundle.putString(KEY_DATA, to);
|
||||
bundle.putString(KEY_TYPE, type);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
break;
|
||||
case HOST_LIBAO:
|
||||
DirectUtils.directToGiftDetail(this, path, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case HOST_USERHOME:
|
||||
String position = uri.getQueryParameter("position");
|
||||
DirectUtils.directToHomeActivity(this, path, TextUtils.isEmpty(position) ? -1 : Integer.parseInt(position), ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COMMUNITY_COLUMN:
|
||||
CommunityEntity community = new CommunityEntity();
|
||||
community.setId(uri.getQueryParameter("community_id"));
|
||||
community.setName(uri.getQueryParameter("community_name"));
|
||||
String columnId = uri.getQueryParameter("column_id");
|
||||
DirectUtils.directToCommunityColumn(this, community, columnId, ENTRANCE_BROWSER, "");
|
||||
break;
|
||||
|
||||
case HOST_CATEGORY:
|
||||
title = uri.getQueryParameter("title");
|
||||
DirectUtils.directCategoryDirectory(this, path, title, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COLUMN_COLLECTION:
|
||||
DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COMMUNITY_QUESTION_LABEL_DETAIL:
|
||||
community = new CommunityEntity();
|
||||
community.setId(uri.getQueryParameter("community_id"));
|
||||
community.setName(uri.getQueryParameter("community_name"));
|
||||
String tag = uri.getQueryParameter("tag");
|
||||
DirectUtils.directAskColumnLabelDetail(this, tag, community, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case HOST_COMMUNITY_COLUMN_DETAIL:
|
||||
community = new CommunityEntity();
|
||||
community.setId(uri.getQueryParameter("community_id"));
|
||||
community.setName(uri.getQueryParameter("community_name"));
|
||||
columnId = uri.getQueryParameter("column_id");
|
||||
DirectUtils.directAskColumnDetail(this, columnId, community, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case EntranceUtils.HOST_BLOCK:
|
||||
name = uri.getQueryParameter("name");
|
||||
SubjectRecommendEntity entity = new SubjectRecommendEntity();
|
||||
entity.setLink(path);
|
||||
entity.setName(name);
|
||||
entity.setText(name);
|
||||
DirectUtils.directToBlock(this, entity, mEntrance);
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_SERVER_BLOCK:
|
||||
DirectUtils.directToGameServers(this, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_AMWAY_BLOCK:
|
||||
DirectUtils.directToAmway(this, null, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_HELP:
|
||||
name = uri.getQueryParameter("name");
|
||||
DirectUtils.directToQa(this, name, path);
|
||||
break;
|
||||
|
||||
case EntranceUtils.HOST_HELP_COLLECTION:
|
||||
name = uri.getQueryParameter("name");
|
||||
DirectUtils.directToQaCollection(this, name, path);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_UPLOAD:
|
||||
DirectUtils.directGameUpload(this, ENTRANCE_BROWSER, "浏览器");
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_ZONE:
|
||||
String zoneUrl = uri.getQueryParameter("url");
|
||||
DirectUtils.directGameZone(this, path, zoneUrl, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_LINK:
|
||||
try {
|
||||
String dataString = uri.getQueryParameter("data");
|
||||
if (!TextUtils.isEmpty(dataString)) {
|
||||
byte[] linkData = Base64.decode(dataString, Base64.DEFAULT);
|
||||
String linkDataString = new String(linkData, "UTF-8");
|
||||
LinkEntity le = GsonUtils.INSTANCE.getGson().fromJson(linkDataString, LinkEntity.class);
|
||||
DirectUtils.directToLinkPage(this, le, ENTRANCE_BROWSER, "");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
toast(e.getMessage());
|
||||
}
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_NEWS:
|
||||
DirectUtils.directToGameNews(
|
||||
this,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_ID),
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
EntranceUtils.ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_CALENDAR:
|
||||
DirectUtils.directToGameServerCalendar(this, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID));
|
||||
break;
|
||||
case EntranceUtils.HOST_HISTORY_APK:
|
||||
DirectUtils.directToHistoryApk(this, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID));
|
||||
break;
|
||||
case EntranceUtils.HOST_FORUM_DETAIL:
|
||||
DirectUtils.directForumDetail(this, id, ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_GAME_RATING_DETAIL:
|
||||
DirectUtils.directToGameRatingDetail(this, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID), uri.getQueryParameter(EntranceUtils.KEY_COMMENT_ID), ENTRANCE_BROWSER);
|
||||
break;
|
||||
case EntranceUtils.HOST_FORUM:
|
||||
DirectUtils.directToForum(this);
|
||||
break;
|
||||
case EntranceUtils.HOST_HELP_AND_FEEDBACK:
|
||||
position = uri.getQueryParameter("position");
|
||||
DirectUtils.directToHelpAndFeedback(this, TextUtils.isEmpty(position) ? 0 : Integer.parseInt(position));
|
||||
break;
|
||||
default:
|
||||
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ("market".equals(uri.getScheme())) {
|
||||
String host = uri.getHost();
|
||||
String id = uri.getQueryParameter("id");
|
||||
if (host != null) {
|
||||
if ("details".equals(host)) {
|
||||
bundle = new Bundle();
|
||||
bundle.putString(KEY_TO, EntranceUtils.KEY_MARKET_DETAILS);
|
||||
bundle.putString(KEY_DATA, id);
|
||||
EntranceUtils.jumpActivity(this, bundle);
|
||||
} else {
|
||||
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -15,6 +16,12 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.g00fy2.versioncompare.Version;
|
||||
import com.gh.base.BaseActivity;
|
||||
import com.gh.common.AppExecutor;
|
||||
@ -23,6 +30,7 @@ import com.gh.common.constant.Constants;
|
||||
import com.gh.common.dialog.PrivacyDialogFragment;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DeviceTokenUtils;
|
||||
import com.gh.common.util.DeviceUtils;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
import com.gh.common.util.EmptyCallback;
|
||||
import com.gh.common.util.GameSubstituteRepositoryHelper;
|
||||
@ -32,7 +40,6 @@ import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.PlatformUtils;
|
||||
import com.gh.common.util.SPUtils;
|
||||
import com.gh.common.util.TagUtils;
|
||||
import com.gh.common.util.TeaHelper;
|
||||
import com.gh.common.util.UsageStatsHelper;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.entity.AuthDialogEntity;
|
||||
@ -50,17 +57,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.ResponseBody;
|
||||
@ -74,7 +78,8 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
|
||||
private SharedPreferences mSharedPreferences;
|
||||
|
||||
private boolean isNewFirstLaunch;
|
||||
private boolean mIsNewForThisVersion;
|
||||
private boolean mStartMainActivityDirectly = false; // 是否不需要用户点击立即体验就直接跳转首页
|
||||
|
||||
private static final int REQUEST_PERMISSION_TAG = 30001;
|
||||
private String[] mPermissions = {
|
||||
@ -94,7 +99,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
isNewFirstLaunch = mSharedPreferences.getBoolean("isNewFirstLaunchV" + PackageUtils.getVersionName(), true);
|
||||
mIsNewForThisVersion = mSharedPreferences.getBoolean("isNewFirstLaunchV" + PackageUtils.getVersionName(), true);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@ -105,13 +110,14 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
// 判断是不是这个版本的新用户
|
||||
if (isNewFirstLaunch) {
|
||||
if (mIsNewForThisVersion) {
|
||||
mContentView.setPadding(0, 0, 0, 0);
|
||||
ViewPager guideLayout = findViewById(R.id.splash_intro_vp_guide);
|
||||
guideLayout.setAdapter(new GuidePagerAdapter());
|
||||
|
||||
// 判断是不是光环的新用户
|
||||
if (SPUtils.getBoolean(Constants.SP_BRAND_NEW_USER, true)) {
|
||||
mStartMainActivityDirectly = true;
|
||||
SPUtils.setLong(Constants.SP_INITIAL_USAGE_TIME, System.currentTimeMillis());
|
||||
HaloApp.getInstance().isBrandNewInstall = true;
|
||||
showPrivacyDialog(guideLayout);
|
||||
@ -124,6 +130,9 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
} else {
|
||||
launchMainActivity();
|
||||
}
|
||||
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "");
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, "");
|
||||
}
|
||||
|
||||
private void showPrivacyDialog(ViewPager guideLayout) {
|
||||
@ -131,13 +140,12 @@ 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();
|
||||
launchMainActivity();
|
||||
requestPermission();
|
||||
});
|
||||
} else {
|
||||
DialogUtils.showPrivacyPolicyDisallowDialog(this, PrivacyPolicyEntity.createDefaultData(),()->{
|
||||
DialogUtils.showPrivacyPolicyDisallowDialog(this, PrivacyPolicyEntity.createDefaultData(), () -> {
|
||||
showPrivacyDialog(guideLayout);
|
||||
});
|
||||
}
|
||||
@ -231,7 +239,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
public void onSuccess(PrivacyPolicyEntity data) {
|
||||
DialogUtils.showPrivacyPolicyDialog(
|
||||
SplashScreenActivity.this,
|
||||
PrivacyPolicyEntity.createDefaultData(), callback);
|
||||
data, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,7 +254,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
if (isNewFirstLaunch) {
|
||||
if (mIsNewForThisVersion) {
|
||||
return R.layout.activity_splash_intro;
|
||||
} else {
|
||||
return 0;
|
||||
@ -256,7 +264,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
|
||||
if (isNewFirstLaunch && EasyPermissions.hasPermissions(this, mPermissions)) {
|
||||
if (mIsNewForThisVersion && EasyPermissions.hasPermissions(this, mPermissions)) {
|
||||
launchMainActivity();
|
||||
} else {
|
||||
return true;
|
||||
@ -283,9 +291,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
|
||||
prefetchData();
|
||||
|
||||
// 在可能获取了相关权限后才初始化SDK/发送激活数据
|
||||
TeaHelper.init(getApplication(), HaloApp.getInstance().getChannel());
|
||||
// GdtHelper.INSTANCE.logAction(ActionType.START_APP, GdtHelper.NETWORK_TYPE, DeviceUtils.getNetwork(this));
|
||||
uploadTeaAndGdtData();
|
||||
|
||||
Bundle bundle = getIntent().getExtras();
|
||||
Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
|
||||
@ -294,6 +300,33 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
finish();
|
||||
}
|
||||
|
||||
private void uploadTeaAndGdtData() {
|
||||
// 在可能获取了相关权限后才初始化SDK/发送激活数据
|
||||
// TeaHelper.init(getApplication(), HaloApp.getInstance().getChannel());
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.gh.gamecenter.TeaHelper");
|
||||
Method method = clazz.getMethod("init", Context.class, String.class);
|
||||
method.invoke(null, getApplication(), HaloApp.getInstance().getChannel());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// GdtHelper.INSTANCE.logAction(ActionType.START_APP, GdtHelper.NETWORK_TYPE, DeviceUtils.getNetwork(this));
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.gh.gamecenter.GdtHelper");
|
||||
Field field = clazz.getDeclaredField("NETWORK_TYPE");
|
||||
String type = (String) field.get(null);
|
||||
Method method = clazz.getMethod("logAction", String.class, String[].class);
|
||||
|
||||
Class<?> actionTypeClazz = Class.forName("com.qq.gdt.action.ActionType");
|
||||
Field typeField = actionTypeClazz.getDeclaredField("START_APP");
|
||||
String actionType = (String) typeField.get(null);
|
||||
|
||||
method.invoke(null, actionType, new String[]{type, DeviceUtils.getNetwork(this)});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void getUniqueId() {
|
||||
DataUtils.getGid();
|
||||
}
|
||||
@ -337,6 +370,9 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
MtaHelper.onEvent("授权情况", "启动授权", "都授权");
|
||||
// 检查是否有旧版本光环,有就删掉
|
||||
AppExecutor.getIoExecutor().execute(this::deleteOutdatedUpdatePackage);
|
||||
if (mStartMainActivityDirectly) {
|
||||
launchMainActivity();
|
||||
}
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, mPermissions, REQUEST_PERMISSION_TAG);
|
||||
}
|
||||
@ -351,12 +387,22 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
}, () -> logGrantedPermission(perms));
|
||||
}, () -> {
|
||||
logGrantedPermission(perms);
|
||||
if (mStartMainActivityDirectly) {
|
||||
launchMainActivity();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
DialogUtils.showPermissionDialog(this, "权限申请",
|
||||
"在设置-应用-光环助手-权限中开启存储和手机信息权限,以保证能正常使用相关功能", "重试", "放弃",
|
||||
this::checkAndRequestPermission,
|
||||
() -> logGrantedPermission(perms));
|
||||
() -> {
|
||||
logGrantedPermission(perms);
|
||||
if (mStartMainActivityDirectly) {
|
||||
launchMainActivity();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,25 +422,25 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
// 检查下载文件夹下是否有旧版本的光环助手的包,有则删除
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private void deleteOutdatedUpdatePackage() {
|
||||
File folder = new File(FileUtils.getDownloadDir(this) + File.separator);
|
||||
if (folder.isDirectory()) {
|
||||
for (File file : folder.listFiles()) {
|
||||
if (!file.isDirectory() && file.getName().startsWith("光环助手V")) {
|
||||
String name = file.getName();
|
||||
int index = name.indexOf("_");
|
||||
if (index != -1) {
|
||||
try {
|
||||
try {
|
||||
File folder = new File(FileUtils.getDownloadDir(this) + File.separator);
|
||||
if (folder.isDirectory()) {
|
||||
for (File file : folder.listFiles()) {
|
||||
if (!file.isDirectory() && file.getName().startsWith("光环助手V")) {
|
||||
String name = file.getName();
|
||||
int index = name.indexOf("_");
|
||||
if (index != -1) {
|
||||
String versionString = name.substring(name.indexOf("V") + 1, index);
|
||||
Version currentVersion = new Version(PackageUtils.getVersionName());
|
||||
if (currentVersion.isHigherThan(versionString) || currentVersion.isEqual(versionString)) {
|
||||
file.delete();
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat;
|
||||
import com.gh.common.util.BitmapUtils;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
|
||||
import com.gh.gamecenter.entity.InstallGameEntity;
|
||||
@ -106,7 +107,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
|
||||
for (String apk_path : mApkPath) {
|
||||
InstallGameEntity apkEntity = new InstallGameEntity();
|
||||
PackageManager pm = mContext.getApplicationContext().getPackageManager();
|
||||
PackageInfo packageInfo = pm.getPackageArchiveInfo(apk_path, PackageManager.GET_ACTIVITIES);
|
||||
PackageInfo packageInfo = pm.getPackageArchiveInfo(apk_path, 0);
|
||||
if (packageInfo == null) continue;
|
||||
|
||||
ApplicationInfo appInfo = packageInfo.applicationInfo;
|
||||
@ -132,7 +133,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
|
||||
/**安装处理类型*/
|
||||
/** 得到包名 */
|
||||
String packageName = packageInfo.packageName;
|
||||
int type = doType(pm, packageName);
|
||||
int type = doType(packageName);
|
||||
apkEntity.setInstallStatus(type);
|
||||
|
||||
mApkList.add(apkEntity);
|
||||
@ -176,8 +177,8 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
|
||||
}
|
||||
}
|
||||
|
||||
private int doType(PackageManager pm, String packageName) {
|
||||
List<PackageInfo> pakageinfos = pm.getInstalledPackages(0);
|
||||
private int doType(String packageName) {
|
||||
List<PackageInfo> pakageinfos = PackageUtils.getInstalledPackages(mContext, 0);
|
||||
for (PackageInfo pi : pakageinfos) {
|
||||
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
String pi_packageName = pi.packageName;
|
||||
|
||||
@ -5,9 +5,14 @@ import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.gh.common.dialog.CertificationDialog;
|
||||
import com.gh.common.dialog.DeviceRemindDialog;
|
||||
import com.gh.common.dialog.GameOffServiceDialogFragment;
|
||||
import com.gh.common.dialog.PackageCheckDialogFragment;
|
||||
import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
@ -39,16 +44,13 @@ import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.AppManager;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/06/17.
|
||||
* 详情页面下载ViewHolder
|
||||
@ -165,16 +167,18 @@ public class DetailViewHolder {
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> {
|
||||
if (mGameEntity.getApk().size() == 1) {
|
||||
ApkEntity apk = mGameEntity.getApk().get(0);
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk,
|
||||
() -> {
|
||||
CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.checkDownload(mViewHolder.context, apk.getSize(), this::download);
|
||||
});
|
||||
PackageCheckDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity.getPackageDialog(), () -> {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.checkDownload(mViewHolder.context, apk.getSize(), this::download);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> {
|
||||
@ -248,15 +252,13 @@ public class DetailViewHolder {
|
||||
break;
|
||||
case RESERVABLE:
|
||||
CheckLoginUtils.checkLogin(mViewHolder.context, mEntrance, () -> {
|
||||
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(mViewHolder.context, () -> {
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
|
||||
mGameEntity,
|
||||
() -> {
|
||||
LogUtils.logReservation(mGameEntity, mTraceEvent);
|
||||
DetailDownloadUtils.detailInitDownload(mViewHolder, false);
|
||||
});
|
||||
dialogFragment.show(((AppCompatActivity) mViewHolder.context).getSupportFragmentManager(), "reserve");
|
||||
});
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
|
||||
mGameEntity,
|
||||
() -> {
|
||||
LogUtils.logReservation(mGameEntity, mTraceEvent);
|
||||
DetailDownloadUtils.detailInitDownload(mViewHolder, false);
|
||||
});
|
||||
dialogFragment.show(((AppCompatActivity) mViewHolder.context).getSupportFragmentManager(), "reserve");
|
||||
});
|
||||
break;
|
||||
case RESERVED:
|
||||
|
||||
@ -63,7 +63,7 @@ class AmwaySearchActivity : SearchActivity() {
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
when (type) {
|
||||
DisplayType.DEFAULT -> {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(AmwaySearchDefaultFragment::class.java.simpleName)
|
||||
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.simpleName)
|
||||
?: AmwaySearchDefaultFragment()
|
||||
transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.simpleName)
|
||||
}
|
||||
|
||||
@ -44,14 +44,10 @@ class AmwaySearchViewHolder(var binding: AmwaySearchItemBinding, val mViewModel:
|
||||
it.context.showRegulationTestDialogIfNeeded {
|
||||
val installPackageName = mViewModel.canUserCommentThisGame(gameEntity)
|
||||
if (gameEntity.directComment || !installPackageName.isNullOrEmpty()) {
|
||||
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(activity, object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
MtaHelper.onEvent("发表评论", "进入", "选中游戏_${gameEntity.name}")
|
||||
val intent = RatingEditActivity.getIntent(binding.root.context, gameEntity, 0.0F, installPackageName, true)
|
||||
activity.startActivity(intent)
|
||||
activity.finish()
|
||||
}
|
||||
})
|
||||
MtaHelper.onEvent("发表评论", "进入", "选中游戏_${gameEntity.name}")
|
||||
val intent = RatingEditActivity.getIntent(binding.root.context, gameEntity, 0.0F, installPackageName, true)
|
||||
activity.startActivity(intent)
|
||||
activity.finish()
|
||||
} else {
|
||||
Utils.toast(activity, "安装游戏后才能评论哦")
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ public abstract class ListAdapter<DataType> extends BaseRecyclerAdapter {
|
||||
public static final int FOOTER_ITEM_COUNT = 1;
|
||||
public static final int TOP_ITEM_COUNT = 1;
|
||||
|
||||
// TODO mEntityList 适配多线程读写
|
||||
protected List<DataType> mEntityList = new ArrayList<>();
|
||||
|
||||
protected boolean mIsOver;
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.gamecenter.NormalActivity
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
class CatalogActivity : NormalActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setToolbarMenu(R.menu.menu_download)
|
||||
}
|
||||
|
||||
override fun showDownloadMenu(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun provideNormalIntent(): Intent {
|
||||
return getTargetIntent(this, CatalogActivity::class.java, CatalogFragment::class.java)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context, catalogId: String, catalogTitle: String, entrance: String): Intent {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceUtils.KEY_CATALOG_ID, catalogId)
|
||||
bundle.putString(EntranceUtils.KEY_CATALOG_TITLE, catalogTitle)
|
||||
bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance)
|
||||
return getTargetIntent(context, CatalogActivity::class.java, CatalogFragment::class.java, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.util.toColor
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.CatalogItemBinding
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class CatalogAdapter(context: Context,
|
||||
private val mFragment: CatalogFragment,
|
||||
private val mViewModel: CatalogViewModel,
|
||||
private val mList: List<CatalogEntity.SubCatalogEntity>)
|
||||
: BaseRecyclerAdapter<CatalogAdapter.CatalogItemViewHolder>(context) {
|
||||
|
||||
override fun getItemCount() = mList.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
CatalogItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_item,parent, false))
|
||||
|
||||
override fun onBindViewHolder(holder: CatalogItemViewHolder, position: Int) {
|
||||
holder.binding.run {
|
||||
val catalogEntity = mList[position]
|
||||
entity = catalogEntity
|
||||
executePendingBindings()
|
||||
if (catalogEntity.name == mViewModel.selectedCatalogName) {
|
||||
selectedTag.visibility = View.VISIBLE
|
||||
catalogName.setTextColor(R.color.theme_font.toColor())
|
||||
root.setBackgroundColor(R.color.white.toColor())
|
||||
} else {
|
||||
selectedTag.visibility = View.GONE
|
||||
catalogName.setTextColor(R.color.text_333333.toColor())
|
||||
root.setBackgroundColor(R.color.text_F5F5F5.toColor())
|
||||
}
|
||||
root.setOnClickListener {
|
||||
if (catalogEntity.name != mViewModel.selectedCatalogName) {
|
||||
mViewModel.selectedCatalogName = catalogEntity.name
|
||||
mViewModel.logSubCatalogClick(position)
|
||||
mFragment.changeCatalog(position)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CatalogItemViewHolder(val binding: CatalogItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
}
|
||||
116
app/src/main/java/com/gh/gamecenter/catalog/CatalogFragment.kt
Normal file
116
app/src/main/java/com/gh/gamecenter/catalog/CatalogFragment.kt
Normal file
@ -0,0 +1,116 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.Observer
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.viewModelProviderFromParent
|
||||
import com.gh.common.view.FixLinearLayoutManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.FragmentCatalogBinding
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.gh.gamecenter.normal.NormalFragment
|
||||
|
||||
class CatalogFragment : NormalFragment() {
|
||||
|
||||
private lateinit var mBinding: FragmentCatalogBinding
|
||||
private lateinit var mViewModel: CatalogViewModel
|
||||
private lateinit var mEntity: CatalogEntity
|
||||
private lateinit var mSpecialCatalogFragment: SpecialCatalogFragment
|
||||
private lateinit var mSubCatalogFragment: SubCatalogFragment
|
||||
|
||||
private var mCatalogId: String = ""
|
||||
private var mCatalogTitle: String = ""
|
||||
|
||||
override fun getLayoutId() = 0
|
||||
|
||||
override fun getInflatedLayout() = FragmentCatalogBinding.inflate(layoutInflater).apply { mBinding = this }.root
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
mCatalogId = arguments?.getString(EntranceUtils.KEY_CATALOG_ID) ?: ""
|
||||
mCatalogTitle = arguments?.getString(EntranceUtils.KEY_CATALOG_TITLE) ?: ""
|
||||
mViewModel = viewModelProviderFromParent(CatalogViewModel.Factory(mCatalogId, mCatalogTitle))
|
||||
|
||||
mViewModel.validEntranceName = if (mEntrance.contains("首页")) "首页" else "板块"
|
||||
mViewModel.logAppearance()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setNavigationTitle(mCatalogTitle)
|
||||
mViewModel.catalogs.observe(viewLifecycleOwner, Observer {
|
||||
mBinding.run {
|
||||
reuseLoading.root.visibility = View.GONE
|
||||
if (it != null) {
|
||||
reuseNoConnection.root.visibility = View.GONE
|
||||
if (it.subCatalog.isNotEmpty()) {
|
||||
containerCatalog.visibility = View.VISIBLE
|
||||
reuseNoneData.root.visibility = View.GONE
|
||||
mEntity = it
|
||||
if (mEntity.hasSpecial) {
|
||||
val specialEntity = CatalogEntity.SubCatalogEntity(name = "精选")
|
||||
(mEntity.subCatalog as ArrayList).add(0, specialEntity)
|
||||
}
|
||||
initView()
|
||||
} else {
|
||||
containerCatalog.visibility = View.GONE
|
||||
reuseNoneData.root.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
containerCatalog.visibility = View.GONE
|
||||
reuseNoneData.root.visibility = View.GONE
|
||||
reuseNoConnection.root.visibility = View.VISIBLE
|
||||
reuseNoConnection.root.setOnClickListener {
|
||||
reuseLoading.root.visibility = View.VISIBLE
|
||||
mViewModel.getCatalogs()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
mEntity.run {
|
||||
if (subCatalog.isNotEmpty()) {
|
||||
mViewModel.selectedCatalogName = subCatalog[0].name
|
||||
mBinding.rvCatalog.layoutManager = FixLinearLayoutManager(requireContext())
|
||||
mBinding.rvCatalog.adapter = CatalogAdapter(requireContext(), this@CatalogFragment, mViewModel, subCatalog)
|
||||
|
||||
if (hasSpecial) {
|
||||
mSpecialCatalogFragment = childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.simpleName) as? SpecialCatalogFragment ?: SpecialCatalogFragment()
|
||||
mSpecialCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id)
|
||||
childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSpecialCatalogFragment, SpecialCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
|
||||
} else {
|
||||
mSubCatalogFragment = childFragmentManager.findFragmentByTag(SubCatalogFragment::class.java.simpleName) as? SubCatalogFragment ?: SubCatalogFragment()
|
||||
mSubCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id, EntranceUtils.KEY_PRIMARY_CATALOG_ID to subCatalog[0].id)
|
||||
childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSubCatalogFragment, SubCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun changeCatalog(position: Int) {
|
||||
mEntity.run {
|
||||
if (hasSpecial) {
|
||||
if (mViewModel.selectedCatalogPosition == 0) {
|
||||
mSubCatalogFragment = childFragmentManager.findFragmentByTag(SubCatalogFragment::class.java.simpleName) as? SubCatalogFragment ?: SubCatalogFragment()
|
||||
mSubCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id, EntranceUtils.KEY_PRIMARY_CATALOG_ID to subCatalog[position].id)
|
||||
childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSubCatalogFragment, SubCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
|
||||
} else {
|
||||
if (position == 0) {
|
||||
mSpecialCatalogFragment = childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.simpleName) as? SpecialCatalogFragment ?: SpecialCatalogFragment()
|
||||
mSpecialCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id)
|
||||
childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSpecialCatalogFragment, SpecialCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
|
||||
} else {
|
||||
mSubCatalogFragment.changeSubCatalog(subCatalog[position].id)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mSubCatalogFragment.changeSubCatalog(subCatalog[position].id)
|
||||
}
|
||||
mViewModel.selectedCatalogPosition = position
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.common.exposure.ExposureSource
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class CatalogViewModel(application: Application, private val catalogId: String, val catalogTitle: String)
|
||||
: AndroidViewModel(application) {
|
||||
|
||||
private val api = RetrofitManager.getInstance(getApplication()).api
|
||||
var catalogs = MutableLiveData<CatalogEntity>()
|
||||
|
||||
var selectedCatalogName: String = ""
|
||||
var selectedCatalogPosition: Int = 0
|
||||
|
||||
var validEntranceName: String = ""
|
||||
|
||||
val basicExposureSource by lazy { ExposureSource("分类", catalogTitle) }
|
||||
|
||||
init {
|
||||
getCatalogs()
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getCatalogs() {
|
||||
api.getCatalogs(catalogId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<CatalogEntity>() {
|
||||
override fun onSuccess(data: CatalogEntity) {
|
||||
catalogs.postValue(data)
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
catalogs.postValue(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun logAppearance() {
|
||||
LogUtils.logNewCatalogAppearanceEvent(validEntranceName, catalogTitle)
|
||||
}
|
||||
|
||||
fun logSubCatalogClick(position: Int) {
|
||||
LogUtils.logSubCatalogClickEvent(validEntranceName, "${catalogTitle}_${selectedCatalogName}", position)
|
||||
}
|
||||
|
||||
fun logSubCatalogContentClick(itemName: String, listPosition: Int) {
|
||||
LogUtils.logSubCatalogContentClickEvent(validEntranceName, "${catalogTitle}_${selectedCatalogName}_${itemName}", selectedCatalogPosition, listPosition)
|
||||
}
|
||||
|
||||
fun logSpecialCatalogContentClick(contentType: String, contentName: String, listPosition: Int) {
|
||||
LogUtils.logSpecialCatalogContentClickEvent(validEntranceName, "${catalogTitle}_${contentType}_${contentName}", selectedCatalogPosition, listPosition)
|
||||
}
|
||||
|
||||
fun logSpecialCatalogSpecificContentClick(contentType: String, contentName: String, targetName: String, listPosition: Int, specificListPosition: Int) {
|
||||
LogUtils.logSpecialCatalogSpecificContentClickEvent(validEntranceName, "${catalogTitle}_${contentType}_${contentName}_${targetName}", selectedCatalogPosition, listPosition, specificListPosition)
|
||||
}
|
||||
|
||||
class Factory(private val catalogId: String, private val catalogTitle: String) : ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return CatalogViewModel(HaloApp.getInstance().application, catalogId, catalogTitle) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.gamecenter.NormalActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
|
||||
class NewCatalogListActivity : NormalActivity() {
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context,
|
||||
primaryCatalogName: String, // 一级分类名
|
||||
catalogTitle: String,
|
||||
catalog: CatalogEntity,
|
||||
initTitle: String): Intent {
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable(EntranceUtils.KEY_DATA, catalog)
|
||||
bundle.putString(EntranceUtils.KEY_PRIMARY_CATALOG_NAME, primaryCatalogName)
|
||||
bundle.putString(EntranceUtils.KEY_NAME, catalog.name)
|
||||
bundle.putString(EntranceUtils.KEY_CATALOG_TITLE, catalogTitle)
|
||||
bundle.putString(EntranceUtils.KEY_CATALOG_INIT_TITLE, initTitle)
|
||||
return getTargetIntent(context, NewCatalogListActivity::class.java, NewCatalogListFragment::class.java, bundle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setToolbarMenu(R.menu.menu_download)
|
||||
}
|
||||
|
||||
override fun showDownloadMenu(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.util.SparseArray
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.constant.ItemViewType
|
||||
import com.gh.common.exposure.ExposureEvent
|
||||
import com.gh.common.exposure.ExposureSource
|
||||
import com.gh.common.exposure.ExposureType
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.common.util.GameViewUtils
|
||||
import com.gh.common.util.StringUtils
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.baselist.ListAdapter
|
||||
import com.gh.gamecenter.baselist.LoadType
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.game.GameItemViewHolder
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import java.util.*
|
||||
|
||||
class NewCatalogListAdapter(context: Context,
|
||||
private val mBaseExposureSource: ExposureSource,
|
||||
private val mViewModel: NewCatalogListViewModel,
|
||||
private val mEntrance: String?) : ListAdapter<GameEntity>(context), IExposable {
|
||||
|
||||
private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
|
||||
|
||||
val positionAndPackageMap = HashMap<String, Int>()
|
||||
|
||||
override fun setListData(updateData: MutableList<GameEntity>?) {
|
||||
// 记录游戏位置
|
||||
if (updateData != null) {
|
||||
for (i in 0 until updateData.size) {
|
||||
val gameEntity = updateData[i]
|
||||
var packages = gameEntity.id
|
||||
for (apkEntity in gameEntity.getApk()) {
|
||||
packages += apkEntity.packageName
|
||||
}
|
||||
positionAndPackageMap[packages + i] = i
|
||||
}
|
||||
}
|
||||
super.setListData(updateData)
|
||||
}
|
||||
|
||||
fun clearPositionAndPackageMap() {
|
||||
positionAndPackageMap.clear()
|
||||
}
|
||||
|
||||
override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
|
||||
return oldItem?.id == newItem?.id
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
if (position == itemCount - 1) {
|
||||
return ItemViewType.ITEM_FOOTER
|
||||
}
|
||||
return ItemViewType.GAME_NORMAL
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return when (viewType) {
|
||||
ItemViewType.GAME_NORMAL -> {
|
||||
GameItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.game_item, parent, false))
|
||||
}
|
||||
else -> {
|
||||
FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is GameItemViewHolder) {
|
||||
val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
|
||||
holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
|
||||
|
||||
val gameEntity = mEntityList[position]
|
||||
|
||||
holder.binding.game = gameEntity
|
||||
holder.initServerType(gameEntity)
|
||||
holder.binding.hideSize = true
|
||||
holder.binding.executePendingBindings()
|
||||
|
||||
GameViewUtils.setLabelList(mContext, holder.binding.labelList, gameEntity.tagStyle)
|
||||
|
||||
gameEntity.sequence = position + 1
|
||||
|
||||
val sortType = mViewModel.sortType.value
|
||||
val sortSize = mViewModel.sortSize.text
|
||||
val toolbarTitle = mViewModel.title
|
||||
val selectedCatalogName = mViewModel.selectedCatalog.name
|
||||
|
||||
val exposureSources = ArrayList<ExposureSource>()
|
||||
exposureSources.add(mBaseExposureSource)
|
||||
exposureSources.add(ExposureSource(toolbarTitle))
|
||||
exposureSources.add(ExposureSource("二级分类详情", "$selectedCatalogName+$sortType+$sortSize"))
|
||||
gameEntity.sequence = position + 1
|
||||
|
||||
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
|
||||
mExposureEventSparseArray.put(position, event)
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
GameDetailActivity.startGameDetailActivity(
|
||||
mContext,
|
||||
gameEntity,
|
||||
StringUtils.buildString(mEntrance, "+(", toolbarTitle, ":列表[", selectedCatalogName, "=", sortType, "=", (position + 1).toString(), "])"),
|
||||
event)
|
||||
}
|
||||
DownloadItemUtils.setOnClickListener(mContext,
|
||||
holder.binding.downloadBtn,
|
||||
gameEntity,
|
||||
position,
|
||||
this,
|
||||
StringUtils.buildString(StringUtils.buildString(mEntrance, "+(", toolbarTitle, ":列表[", selectedCatalogName, "=", sortType, "=", (position + 1).toString(), "])")),
|
||||
StringUtils.buildString(selectedCatalogName, ":", gameEntity.name),
|
||||
event)
|
||||
|
||||
DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), true, "star&brief")
|
||||
} else if (holder is FooterViewHolder) {
|
||||
holder.initItemPadding()
|
||||
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
|
||||
holder.itemView.setOnClickListener {
|
||||
if (mIsNetworkError) {
|
||||
mViewModel.load(LoadType.RETRY)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyItemByDownload(download: DownloadEntity) {
|
||||
for (key in positionAndPackageMap.keys) {
|
||||
if (key.contains(download.packageName) && key.contains(download.gameId)) {
|
||||
val position = positionAndPackageMap[key]
|
||||
if (position != null && mEntityList != null && position < mEntityList.size) {
|
||||
mEntityList[position].getEntryMap()[download.platform] = download
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
|
||||
for (key in positionAndPackageMap.keys) {
|
||||
if (key.contains(status.packageName) && key.contains(status.gameId)) {
|
||||
val position = positionAndPackageMap[key]
|
||||
if (position != null && mEntityList != null && position < mEntityList.size) {
|
||||
mEntityList[position].getEntryMap().remove(status.platform)
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEventByPosition(pos: Int): ExposureEvent? {
|
||||
return mExposureEventSparseArray.get(pos)
|
||||
}
|
||||
|
||||
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,182 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.ethanhua.skeleton.Skeleton
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.common.exposure.ExposureSource
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.observeNonNull
|
||||
import com.gh.common.util.viewModelProvider
|
||||
import com.gh.common.view.CatalogFilterView
|
||||
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.baselist.ListFragment
|
||||
import com.gh.gamecenter.databinding.FragmentCatalogListBinding
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class NewCatalogListFragment : ListFragment<GameEntity, NewCatalogListViewModel>() {
|
||||
|
||||
private var mPrimaryCatalogName: String = "" // 一级分类名
|
||||
private var mPrimeCatalog: CatalogEntity? = null
|
||||
private var mSubCatalogList = arrayListOf<CatalogEntity.SubCatalogEntity>()
|
||||
private var mInitCatalogName = ""
|
||||
private var mAdapter: NewCatalogListAdapter? = null
|
||||
private val mDataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
mAdapter?.notifyItemByDownload(downloadEntity)
|
||||
|
||||
if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
|
||||
showUnzipFailureDialog(downloadEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var mBinding: FragmentCatalogListBinding
|
||||
private lateinit var mExposureListener: ExposureListener
|
||||
private lateinit var mViewModel: NewCatalogListViewModel
|
||||
|
||||
override fun getLayoutId() = 0
|
||||
|
||||
override fun getInflatedLayout() = FragmentCatalogListBinding.inflate(layoutInflater).apply { mBinding = this }.root
|
||||
|
||||
override fun provideListViewModel() = viewModelProvider<NewCatalogListViewModel>()
|
||||
|
||||
override fun provideListAdapter() = mAdapter
|
||||
?: NewCatalogListAdapter(
|
||||
requireContext(),
|
||||
ExposureSource(mPrimaryCatalogName),
|
||||
mViewModel,
|
||||
mEntrance).apply { mAdapter = this }
|
||||
|
||||
override fun getItemDecoration() = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
mViewModel = provideListViewModel()
|
||||
|
||||
mViewModel.title = arguments?.getString(EntranceUtils.KEY_NAME) ?: ""
|
||||
mViewModel.categoryTitle = arguments?.getString(EntranceUtils.KEY_CATALOG_TITLE) ?: ""
|
||||
mEntrance = arguments?.getString(EntranceUtils.KEY_ENTRANCE) ?: Constants.ENTRANCE_UNKNOWN
|
||||
mPrimeCatalog = arguments?.getParcelable(EntranceUtils.KEY_DATA)
|
||||
mSubCatalogList = mPrimeCatalog?.subCatalog as ArrayList<CatalogEntity.SubCatalogEntity>
|
||||
|
||||
mInitCatalogName = arguments?.getString(EntranceUtils.KEY_CATALOG_INIT_TITLE) ?: ""
|
||||
mPrimaryCatalogName = arguments?.getString(EntranceUtils.KEY_PRIMARY_CATALOG_NAME) ?: ""
|
||||
|
||||
mViewModel.selectedCatalog = mSubCatalogList.find { entity -> entity.name == mInitCatalogName }
|
||||
?: CatalogEntity.SubCatalogEntity()
|
||||
initSortType()
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
setNavigationTitle(mViewModel.title)
|
||||
|
||||
initFilterView()
|
||||
|
||||
mViewModel.refresh.observeNonNull(this) { onRefresh() }
|
||||
|
||||
mExposureListener = ExposureListener(this, mAdapter!!)
|
||||
mListRv.addOnScrollListener(mExposureListener)
|
||||
|
||||
mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false).load(R.layout.fragment_subject_skeleton).show()
|
||||
}
|
||||
|
||||
private fun initSortType() {
|
||||
mPrimeCatalog?.switch?.run {
|
||||
if (hotSort == "on") {
|
||||
mViewModel.sortType = CatalogFilterView.SortType.RECOMMENDED
|
||||
return@run
|
||||
}
|
||||
if (newSort == "on") {
|
||||
mViewModel.sortType = CatalogFilterView.SortType.NEWEST
|
||||
return@run
|
||||
}
|
||||
if (starSort == "on") {
|
||||
mViewModel.sortType = CatalogFilterView.SortType.RATING
|
||||
return@run
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initFilterView() {
|
||||
mBinding.filterContainer.run {
|
||||
visibility = View.VISIBLE
|
||||
setTypeList(mPrimeCatalog?.switch ?: CatalogEntity.CatalogSwitch())
|
||||
setCatalogList(mSubCatalogList, mInitCatalogName)
|
||||
setOnConfigSetupListener(object : CatalogFilterView.OnCatalogFilterSetupListener {
|
||||
override fun onSetupSortSize(sortSize: SubjectSettingEntity.Size) {
|
||||
mViewModel.updateSortConfig(sortSize = sortSize)
|
||||
}
|
||||
|
||||
override fun onSetupSortType(sortType: CatalogFilterView.SortType) {
|
||||
mViewModel.updateSortConfig(sortType = sortType)
|
||||
}
|
||||
|
||||
override fun onSetupSortCatalog(sortCatalog: CatalogEntity.SubCatalogEntity) {
|
||||
mViewModel.updateSortConfig(sortCatalog = sortCatalog)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
|
||||
super.onResume()
|
||||
DownloadManager.getInstance(context).addObserver(mDataWatcher)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
DownloadManager.getInstance(context).removeObserver(mDataWatcher)
|
||||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
mAdapter?.clearPositionAndPackageMap()
|
||||
|
||||
super.onRefresh()
|
||||
}
|
||||
|
||||
// 下载被删除事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(status: EBDownloadStatus) {
|
||||
if ("delete" == status.status) {
|
||||
mAdapter?.notifyItemAndRemoveDownload(status)
|
||||
}
|
||||
}
|
||||
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if ("安装" == busFour.type || "卸载" == busFour.type) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
|
||||
val data = mAdapter?.positionAndPackageMap ?: return
|
||||
for (gameAndPosition in data) {
|
||||
if (gameAndPosition.key.contains(downloadEntity.packageName)) {
|
||||
val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
|
||||
if (targetView != null) {
|
||||
DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.common.view.CatalogFilterView
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SubjectSettingEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
class NewCatalogListViewModel(application: Application) : ListViewModel<GameEntity, GameEntity>(application) {
|
||||
|
||||
var title = "" // 显示在 Toolbar 的标题
|
||||
var categoryTitle = "" // 跳转进来的分类的标题
|
||||
|
||||
val refresh = MutableLiveData<Boolean>()
|
||||
|
||||
var selectedCatalog = CatalogEntity.SubCatalogEntity()
|
||||
var sortType = CatalogFilterView.SortType.RECOMMENDED
|
||||
var sortSize = SubjectSettingEntity.Size()
|
||||
private val sensitiveApi = RetrofitManager.getInstance(getApplication()).sensitiveApi
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<List<GameEntity>>? = null
|
||||
|
||||
override fun provideDataSingle(page: Int): Single<List<GameEntity>> {
|
||||
return if (selectedCatalog.link.type == "column") { // column(专题)/tag(标签)
|
||||
sensitiveApi.getColumn(selectedCatalog.link.link, getSortType(), getSortSize(), page) // 专题
|
||||
} else {
|
||||
sensitiveApi.getGamesWithSpecificTag(getSortSize(), getSortType(), page) // 标签
|
||||
}
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
|
||||
}
|
||||
|
||||
fun updateSortConfig(sortSize: SubjectSettingEntity.Size? = null,
|
||||
sortType: CatalogFilterView.SortType? = null,
|
||||
sortCatalog: CatalogEntity.SubCatalogEntity? = null) {
|
||||
when {
|
||||
sortSize != null && sortSize != this.sortSize -> {
|
||||
this.sortSize = sortSize
|
||||
refresh.postValue(true)
|
||||
}
|
||||
|
||||
sortType != null && sortType != this.sortType -> {
|
||||
this.sortType = sortType
|
||||
refresh.postValue(true)
|
||||
}
|
||||
|
||||
sortCatalog != null && sortCatalog != selectedCatalog -> {
|
||||
selectedCatalog = sortCatalog
|
||||
refresh.postValue(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSortSize(): String? {
|
||||
return if (selectedCatalog.link.type == "column") {
|
||||
UrlFilterUtils.getFilterQuery(
|
||||
"min_size", sortSize.min.toString(),
|
||||
"max_size", sortSize.max.toString())
|
||||
} else {
|
||||
UrlFilterUtils.getFilterQuery(
|
||||
"tag_id", selectedCatalog.link.link,
|
||||
"min_size", sortSize.min.toString(),
|
||||
"max_size", sortSize.max.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSortType(): String? {
|
||||
return when (sortType) {
|
||||
CatalogFilterView.SortType.RECOMMENDED -> if (selectedCatalog.link.type == "column") "position:1" else "download:-1"
|
||||
CatalogFilterView.SortType.NEWEST -> "publish:-1"
|
||||
CatalogFilterView.SortType.RATING -> "star:-1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,245 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.util.SparseArray
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.constant.ItemViewType
|
||||
import com.gh.common.exposure.ExposureEvent
|
||||
import com.gh.common.exposure.ExposureSource
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.baselist.ListAdapter
|
||||
import com.gh.gamecenter.databinding.CatalogHeaderItemBinding
|
||||
import com.gh.gamecenter.databinding.CatalogImageItemBinding
|
||||
import com.gh.gamecenter.databinding.CatalogSubjectCollectionItemBinding
|
||||
import com.gh.gamecenter.databinding.CatalogSubjectItemBinding
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.subject.SubjectActivity.Companion.startSubjectActivity
|
||||
|
||||
class SpecialCatalogAdapter(context: Context, private val mCatalogViewModel: CatalogViewModel)
|
||||
: ListAdapter<SpecialCatalogItemData>(context), IExposable {
|
||||
|
||||
private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
|
||||
|
||||
override fun getItemCount() = if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT
|
||||
|
||||
override fun areItemsTheSame(oldItem: SpecialCatalogItemData?, newItem: SpecialCatalogItemData?): Boolean {
|
||||
return when {
|
||||
oldItem?.header != null && newItem?.header != null -> {
|
||||
oldItem.header.id == newItem.header.id
|
||||
}
|
||||
|
||||
oldItem?.bigImage != null && newItem?.bigImage != null -> {
|
||||
oldItem.bigImage.id == newItem.bigImage.id
|
||||
}
|
||||
|
||||
oldItem?.subject != null && newItem?.subject != null -> {
|
||||
oldItem.subject.id == newItem.subject.id
|
||||
}
|
||||
|
||||
oldItem?.subjectCollection != null && newItem?.subjectCollection != null -> {
|
||||
oldItem.subjectCollection.id == newItem.subjectCollection.id
|
||||
}
|
||||
|
||||
else -> super.areItemsTheSame(oldItem, newItem)
|
||||
}
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: SpecialCatalogItemData?, newItem: SpecialCatalogItemData?): Boolean {
|
||||
return when {
|
||||
oldItem?.header != null && newItem?.header != null -> {
|
||||
oldItem.header.id == newItem.header.id
|
||||
}
|
||||
|
||||
oldItem?.bigImage != null && newItem?.bigImage != null -> {
|
||||
oldItem.bigImage.id == newItem.bigImage.id
|
||||
}
|
||||
|
||||
oldItem?.subject != null && newItem?.subject != null -> {
|
||||
oldItem.subject.id == newItem.subject.id
|
||||
}
|
||||
|
||||
oldItem?.subjectCollection != null && newItem?.subjectCollection != null -> {
|
||||
oldItem.subjectCollection.id == newItem.subjectCollection.id
|
||||
}
|
||||
|
||||
else -> super.areItemsTheSame(oldItem, newItem)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val view: View
|
||||
return when (viewType) {
|
||||
ItemViewType.ITEM_FOOTER -> {
|
||||
view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
|
||||
FooterViewHolder(view)
|
||||
}
|
||||
|
||||
TYPE_HEADER -> CatalogHeaderItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_header_item, parent, false))
|
||||
|
||||
TYPE_BIG_IMAGE -> CatalogImageItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_image_item, parent, false))
|
||||
|
||||
TYPE_SUBJECT -> CatalogSubjectItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_item, parent, false))
|
||||
|
||||
TYPE_SUBJECT_COLLECTION -> CatalogSubjectCollectionItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_collection_item, parent, false))
|
||||
|
||||
else -> throw NullPointerException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is CatalogImageItemHolder -> {
|
||||
val imageEntity = mEntityList[position].bigImage!!
|
||||
holder.binding.run {
|
||||
image.layoutParams = image.layoutParams.apply {
|
||||
val imageWidth = mContext.resources.displayMetrics.widthPixels - (80F + 16F + 16F).dip2px()
|
||||
height = imageWidth * 9 / 16
|
||||
}
|
||||
|
||||
entity = imageEntity.image
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
if (imageEntity.link.type == "game") {
|
||||
exposureEvent = ExposureEvent.createEvent(
|
||||
GameEntity(id = imageEntity.link.link),
|
||||
listOf(mCatalogViewModel.basicExposureSource, ExposureSource("精选页图片", "")))
|
||||
mExposureEventSparseArray.append(position, exposureEvent)
|
||||
}
|
||||
root.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(mContext, imageEntity.link, "新分类-精选分类", "图片", exposureEvent)
|
||||
mCatalogViewModel.logSpecialCatalogContentClick("图片", imageEntity.image.title, mEntityList[position].position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is CatalogHeaderItemHolder -> {
|
||||
val entity = mEntityList[position].header!!
|
||||
val specialLink = entity.link
|
||||
holder.binding.run {
|
||||
link = specialLink
|
||||
headMore.setOnClickListener {
|
||||
if (entity.type == "专题合集") {
|
||||
DirectUtils.directToColumnCollection(mContext, specialLink.link
|
||||
?: "", -1, "(游戏-专题:" + specialLink.text + "-全部)")
|
||||
} else {
|
||||
startSubjectActivity(mContext, specialLink.link, specialLink.text, false, "(游戏-专题:" + specialLink.text + "-全部)")
|
||||
}
|
||||
mCatalogViewModel.logSpecialCatalogContentClick(entity.type, specialLink.text
|
||||
?: "", mEntityList[position].position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is CatalogSubjectItemHolder -> {
|
||||
val subject = mEntityList[position].subject!!
|
||||
|
||||
val exposureList = arrayListOf<ExposureEvent>()
|
||||
for (game in subject.link.data) {
|
||||
val exposureEvent = ExposureEvent.createEvent(game,
|
||||
listOf(mCatalogViewModel.basicExposureSource, ExposureSource("精选页专题", subject.link.text ?: "")))
|
||||
exposureList.add(exposureEvent)
|
||||
game.exposureEvent = exposureEvent
|
||||
game.subjectName = subject.link.text
|
||||
}
|
||||
mEntityList[position].exposureEventList = exposureList
|
||||
|
||||
holder.bindSubject(subject.link.data, mEntityList[position].position)
|
||||
}
|
||||
|
||||
is CatalogSubjectCollectionItemHolder -> {
|
||||
val subjectCollection = mEntityList[position].subjectCollection!!
|
||||
|
||||
for (subject in subjectCollection.link.data) {
|
||||
subject.subjectName = subjectCollection.link.text
|
||||
}
|
||||
|
||||
holder.bindSubjectCollection(subjectCollection.link.data, mEntityList[position].position)
|
||||
}
|
||||
|
||||
is FooterViewHolder -> {
|
||||
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (position == itemCount - 1) {
|
||||
ItemViewType.ITEM_FOOTER
|
||||
} else {
|
||||
val item = mEntityList[position]
|
||||
when {
|
||||
item.header != null -> TYPE_HEADER
|
||||
item.bigImage != null -> TYPE_BIG_IMAGE
|
||||
item.subject != null -> TYPE_SUBJECT
|
||||
item.subjectCollection != null -> TYPE_SUBJECT_COLLECTION
|
||||
else -> TYPE_SUBJECT_COLLECTION
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEventByPosition(pos: Int): ExposureEvent? = mExposureEventSparseArray.get(pos)
|
||||
|
||||
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? = mEntityList[pos].exposureEventList
|
||||
|
||||
class CatalogImageItemHolder(val binding: CatalogImageItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
|
||||
class CatalogHeaderItemHolder(val binding: CatalogHeaderItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
|
||||
inner class CatalogSubjectItemHolder(val binding: CatalogSubjectItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
fun bindSubject(gameList: List<GameEntity>, position: Int) {
|
||||
binding.gameList.run {
|
||||
var subjectAdapter = adapter
|
||||
if (subjectAdapter is SpecialCatalogSubjectAdapter) {
|
||||
subjectAdapter.checkResetData(gameList)
|
||||
subjectAdapter.updatePosition(position)
|
||||
return
|
||||
}
|
||||
subjectAdapter = SpecialCatalogSubjectAdapter(context, mCatalogViewModel, gameList).apply {
|
||||
updatePosition(position)
|
||||
}
|
||||
layoutManager = GridLayoutManager(context, 3)
|
||||
adapter = subjectAdapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class CatalogSubjectCollectionItemHolder(val binding: CatalogSubjectCollectionItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
fun bindSubjectCollection(subjectCollection: List<GameEntity>, position: Int) {
|
||||
binding.subjectCollectionList.run {
|
||||
var collectionAdapter = adapter
|
||||
if (collectionAdapter is SpecialCatalogSubjectCollectionAdapter) {
|
||||
collectionAdapter.checkResetData(subjectCollection)
|
||||
collectionAdapter.updatePosition(position)
|
||||
return
|
||||
}
|
||||
collectionAdapter = SpecialCatalogSubjectCollectionAdapter(context, mCatalogViewModel, subjectCollection).apply {
|
||||
updatePosition(position)
|
||||
}
|
||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
adapter = collectionAdapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TYPE_HEADER = 900
|
||||
|
||||
private const val TYPE_BIG_IMAGE = 901
|
||||
|
||||
private const val TYPE_SUBJECT = 902
|
||||
|
||||
private const val TYPE_SUBJECT_COLLECTION = 903
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.viewModelProvider
|
||||
import com.gh.common.util.viewModelProviderFromParent
|
||||
import com.gh.gamecenter.baselist.ListFragment
|
||||
|
||||
class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatalogViewModel>() {
|
||||
|
||||
private var mCatalogId = ""
|
||||
|
||||
private var mAdapter: SpecialCatalogAdapter? = null
|
||||
|
||||
private lateinit var mCatalogViewModel: CatalogViewModel
|
||||
|
||||
private lateinit var mExposureListener: ExposureListener
|
||||
|
||||
override fun provideListViewModel() = viewModelProvider<SpecialCatalogViewModel>(SpecialCatalogViewModel.Factory(mCatalogId))
|
||||
|
||||
override fun provideListAdapter() = mAdapter ?: SpecialCatalogAdapter(requireContext(), mCatalogViewModel).apply {
|
||||
mAdapter = this
|
||||
mExposureListener = ExposureListener(this@SpecialCatalogFragment, this)
|
||||
}
|
||||
|
||||
override fun getItemDecoration() = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
mCatalogId = arguments?.getString(EntranceUtils.KEY_CATALOG_ID) ?: ""
|
||||
// 按理来说在这里获取不需要再传值给构造函数,但保守起见还是传了
|
||||
mCatalogViewModel = viewModelProviderFromParent(CatalogViewModel.Factory(mCatalogId, ""))
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mListRv.setBackgroundColor(Color.WHITE)
|
||||
mListRv.addOnScrollListener(mExposureListener)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import com.gh.common.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.entity.SpecialCatalogEntity
|
||||
|
||||
data class SpecialCatalogItemData(
|
||||
val header: SpecialCatalogEntity? = null,
|
||||
val bigImage: SpecialCatalogEntity? = null,
|
||||
val subject: SpecialCatalogEntity? = null,
|
||||
val subjectCollection: SpecialCatalogEntity? = null,
|
||||
|
||||
var position: Int = 0,
|
||||
var exposureEventList: ArrayList<ExposureEvent>? = null
|
||||
)
|
||||
@ -0,0 +1,82 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.CatalogSubjectGameItemBinding
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class SpecialCatalogSubjectAdapter(context: Context,
|
||||
private val mCatalogViewModel: CatalogViewModel,
|
||||
private var mList: List<GameEntity>)
|
||||
: BaseRecyclerAdapter<SpecialCatalogSubjectAdapter.CatalogSubjectGameItemViewHolder>(context) {
|
||||
|
||||
private val mEntrance = "精选分类"
|
||||
private var countAndKey: Pair<Int, String>? = null
|
||||
private var mPosition: Int = -1
|
||||
|
||||
init {
|
||||
var dataIds = ""
|
||||
mList.forEach {
|
||||
dataIds += it.id
|
||||
}
|
||||
if (dataIds.isNotEmpty()) countAndKey = Pair(mList.size, dataIds)
|
||||
}
|
||||
|
||||
override fun getItemCount() = mList.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
|
||||
= CatalogSubjectGameItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_game_item, parent, false))
|
||||
|
||||
override fun onBindViewHolder(holder: CatalogSubjectGameItemViewHolder, position: Int) {
|
||||
holder.binding.run {
|
||||
root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||
topMargin = if (position > 2) 24F.dip2px() else 16F.dip2px()
|
||||
}
|
||||
|
||||
val entity = mList[position]
|
||||
game = entity
|
||||
executePendingBindings()
|
||||
|
||||
if (!gameName.isSelected) {
|
||||
gameName.postDelayed({ gameName.isSelected = true }, 500)
|
||||
}
|
||||
|
||||
root.setOnClickListener {
|
||||
GameDetailActivity.startGameDetailActivity(mContext, entity.id, "(${mEntrance})", entity.exposureEvent)
|
||||
mCatalogViewModel.logSpecialCatalogSpecificContentClick(
|
||||
"专题",
|
||||
game?.subjectName ?: "",
|
||||
game?.name ?: "",
|
||||
mPosition,
|
||||
position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkResetData(update: List<GameEntity>) {
|
||||
var dataIds = ""
|
||||
mList.forEach { dataIds += it.id }
|
||||
|
||||
mList = update
|
||||
if (countAndKey?.first == update.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
|
||||
notifyItemRangeChanged(0, itemCount)
|
||||
} else if (countAndKey?.first != update.size) { // 数量发生改变
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
// 重新刷新数据标识
|
||||
countAndKey = Pair(update.size, dataIds)
|
||||
}
|
||||
|
||||
fun updatePosition(position: Int) {
|
||||
mPosition = position
|
||||
}
|
||||
|
||||
class CatalogSubjectGameItemViewHolder(val binding: CatalogSubjectGameItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.ImageUtils
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.CatalogSubjectCollectionListItemBinding
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.LinkEntity
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class SpecialCatalogSubjectCollectionAdapter(context: Context,
|
||||
private val mCatalogViewModel: CatalogViewModel,
|
||||
private var mList: List<GameEntity>)
|
||||
: BaseRecyclerAdapter<SpecialCatalogSubjectCollectionAdapter.CatalogSubjectCollectionListItemViewHolder>(context) {
|
||||
|
||||
private var countAndKey: Pair<Int, String>? = null
|
||||
private var mPosition: Int = -1
|
||||
|
||||
init {
|
||||
var dataIds = ""
|
||||
mList.forEach {
|
||||
dataIds += it.id
|
||||
}
|
||||
if (dataIds.isNotEmpty()) countAndKey = Pair(mList.size, dataIds)
|
||||
}
|
||||
|
||||
override fun getItemCount() = mList.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
|
||||
= CatalogSubjectCollectionListItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_collection_list_item, parent, false))
|
||||
|
||||
|
||||
override fun onBindViewHolder(holder: CatalogSubjectCollectionListItemViewHolder, position: Int) {
|
||||
holder.binding.run {
|
||||
root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||
leftMargin = if (position == 0) 16F.dip2px() else 0
|
||||
}
|
||||
val entity = mList[position]
|
||||
ImageUtils.display(subjectCollectionImage, entity.image)
|
||||
root.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(mContext, LinkEntity(link = entity.link, type = entity.type), "精选分类", "专题合集")
|
||||
mCatalogViewModel.logSpecialCatalogSpecificContentClick(
|
||||
"专题合集",
|
||||
entity.subjectName ?: "",
|
||||
entity.name ?: "",
|
||||
mPosition,
|
||||
position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkResetData(update: List<GameEntity>) {
|
||||
var dataIds = ""
|
||||
mList.forEach { dataIds += it.id }
|
||||
|
||||
mList = update
|
||||
if (countAndKey?.first == update.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
|
||||
notifyItemRangeChanged(0, itemCount)
|
||||
} else if (countAndKey?.first != update.size) { // 数量发生改变
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
// 重新刷新数据标识
|
||||
countAndKey = Pair(update.size, dataIds)
|
||||
}
|
||||
|
||||
fun updatePosition(position: Int) {
|
||||
mPosition = position
|
||||
}
|
||||
|
||||
class CatalogSubjectCollectionListItemViewHolder(val binding: CatalogSubjectCollectionListItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
import com.gh.gamecenter.entity.SpecialCatalogEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
class SpecialCatalogViewModel(application: Application, private val catalogId: String) : ListViewModel<SpecialCatalogEntity, SpecialCatalogItemData>(application) {
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<List<SpecialCatalogEntity>>? = null
|
||||
|
||||
override fun provideDataSingle(page: Int): Single<List<SpecialCatalogEntity>> {
|
||||
return RetrofitManager.getInstance(getApplication())
|
||||
.api
|
||||
.getSpecialCatalogs(catalogId, page)
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) { list ->
|
||||
val itemDataList = arrayListOf<SpecialCatalogItemData>()
|
||||
list.forEachIndexed { index, it ->
|
||||
when (it.type) {
|
||||
"图片" -> itemDataList.add(SpecialCatalogItemData(bigImage = it).apply { position = index })
|
||||
|
||||
"专题" -> {
|
||||
itemDataList.add(SpecialCatalogItemData(header = it).apply { position = index })
|
||||
itemDataList.add(SpecialCatalogItemData(subject = it).apply { position = index })
|
||||
}
|
||||
|
||||
"专题合集" -> {
|
||||
itemDataList.add(SpecialCatalogItemData(header = it).apply { position = index })
|
||||
itemDataList.add(SpecialCatalogItemData(subjectCollection = it).apply { position = index })
|
||||
}
|
||||
}
|
||||
}
|
||||
mResultLiveData.postValue(itemDataList)
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(private val catalogId: String) : ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return SpecialCatalogViewModel(HaloApp.getInstance().application, catalogId) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.gh.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.SubCatalogItemBinding
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class SubCatalogAdapter(context: Context,
|
||||
private val mCatalogViewModel: CatalogViewModel,
|
||||
private val mPrimaryCatalog: CatalogEntity,
|
||||
private var mList: List<CatalogEntity.SubCatalogEntity>)
|
||||
: BaseRecyclerAdapter<SubCatalogAdapter.SubCatalogItemViewHolder>(context) {
|
||||
|
||||
private val mTypes = listOf("专题", "标签")
|
||||
|
||||
override fun getItemCount() = mList.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
SubCatalogItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.sub_catalog_item, parent, false))
|
||||
|
||||
override fun onBindViewHolder(holder: SubCatalogItemViewHolder, position: Int) {
|
||||
holder.binding.run {
|
||||
val catalogEntity = mList[position]
|
||||
entity = catalogEntity
|
||||
executePendingBindings()
|
||||
root.setOnClickListener {
|
||||
mCatalogViewModel.logSubCatalogContentClick(catalogEntity.name, position)
|
||||
if (mTypes.contains(catalogEntity.type)) {
|
||||
root.context.startActivity(NewCatalogListActivity.getIntent(mContext, mCatalogViewModel.catalogTitle, catalogEntity.name, mPrimaryCatalog, catalogEntity.name))
|
||||
} else {
|
||||
DialogUtils.showLowVersionDialog(mContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SubCatalogItemViewHolder(val binding: SubCatalogItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.viewModelProvider
|
||||
import com.gh.common.util.viewModelProviderFromParent
|
||||
import com.gh.gamecenter.databinding.FragmentSubCatalogBinding
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.gh.gamecenter.normal.NormalFragment
|
||||
|
||||
class SubCatalogFragment : NormalFragment() {
|
||||
|
||||
private lateinit var mBinding: FragmentSubCatalogBinding
|
||||
private lateinit var mViewModel: SubCatalogViewModel
|
||||
private lateinit var mCatalogViewModel: CatalogViewModel
|
||||
private lateinit var mEntity: CatalogEntity
|
||||
private var mCatalogId: String = ""
|
||||
private var mPrimaryCatalogId: String = ""
|
||||
|
||||
override fun getLayoutId() = 0
|
||||
|
||||
override fun getInflatedLayout() = FragmentSubCatalogBinding.inflate(layoutInflater).apply { mBinding = this }.root
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
mCatalogId = arguments?.getString(EntranceUtils.KEY_CATALOG_ID) ?: ""
|
||||
mPrimaryCatalogId = arguments?.getString(EntranceUtils.KEY_PRIMARY_CATALOG_ID) ?: ""
|
||||
mViewModel = viewModelProvider(SubCatalogViewModel.Factory(mCatalogId))
|
||||
mCatalogViewModel = viewModelProviderFromParent(CatalogViewModel.Factory(mCatalogId, ""))
|
||||
mViewModel.getSubCatalogs(mPrimaryCatalogId)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mViewModel.catalogs.observe(viewLifecycleOwner, Observer {
|
||||
mBinding.run {
|
||||
reuseLoading.root.visibility = View.GONE
|
||||
if (it != null) {
|
||||
reuseNoConnection.root.visibility = View.GONE
|
||||
if (it.subCatalog.isNotEmpty()) {
|
||||
rvSubCatalog.visibility = View.VISIBLE
|
||||
reuseNoneData.root.visibility = View.GONE
|
||||
mEntity = it
|
||||
initView()
|
||||
} else {
|
||||
rvSubCatalog.visibility = View.GONE
|
||||
reuseNoneData.root.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
rvSubCatalog.visibility = View.GONE
|
||||
reuseNoneData.root.visibility = View.GONE
|
||||
reuseNoConnection.root.visibility = View.VISIBLE
|
||||
reuseNoConnection.root.setOnClickListener {
|
||||
reuseLoading.root.visibility = View.VISIBLE
|
||||
mViewModel.getSubCatalogs(mPrimaryCatalogId)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
mEntity.run {
|
||||
mBinding.rvSubCatalog.layoutManager = GridLayoutManager(requireContext(), 3)
|
||||
mBinding.rvSubCatalog.adapter = SubCatalogAdapter(requireContext(), mCatalogViewModel, mEntity, subCatalog)
|
||||
}
|
||||
}
|
||||
|
||||
fun changeSubCatalog(primaryCatalogId: String) {
|
||||
mBinding.run {
|
||||
mPrimaryCatalogId = primaryCatalogId
|
||||
rvSubCatalog.visibility = View.GONE
|
||||
reuseNoneData.root.visibility = View.GONE
|
||||
reuseNoConnection.root.visibility = View.GONE
|
||||
reuseLoading.root.visibility = View.VISIBLE
|
||||
mViewModel.getSubCatalogs(mPrimaryCatalogId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.gh.gamecenter.catalog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.gamecenter.entity.CatalogEntity
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class SubCatalogViewModel(application: Application, private val catalogId: String): AndroidViewModel(application) {
|
||||
|
||||
private val api = RetrofitManager.getInstance(getApplication()).api
|
||||
var catalogs = MutableLiveData<CatalogEntity>()
|
||||
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getSubCatalogs(primaryCatalogId: String) {
|
||||
api.getSubCatalogs(catalogId, primaryCatalogId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<CatalogEntity>() {
|
||||
override fun onSuccess(data: CatalogEntity) {
|
||||
catalogs.postValue(data)
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
catalogs.postValue(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
class Factory(private val catalogId: String) : ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return SubCatalogViewModel(HaloApp.getInstance().application, catalogId) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.NormalActivity
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
|
||||
@ -27,21 +27,16 @@ class NewCategoryHorizontalAdapter(context: Context,
|
||||
|
||||
override fun onBindViewHolder(holder: TagsViewHolder, position: Int) {
|
||||
val categoryEntity = mCategoryList[position]
|
||||
val gradientDrawable = GradientDrawable()
|
||||
gradientDrawable.shape = GradientDrawable.RECTANGLE
|
||||
|
||||
if (mViewModel.selectedCategory.name == categoryEntity.name) {
|
||||
gradientDrawable.setColor(ContextCompat.getColor(mContext, R.color.theme))
|
||||
gradientDrawable.cornerRadius = DisplayUtils.dip2px(999f).toFloat()
|
||||
holder.tagTv.background = ContextCompat.getDrawable(mContext, R.drawable.bg_tag_text)
|
||||
holder.tagTv.setTextColor(Color.WHITE)
|
||||
} else {
|
||||
gradientDrawable.setColor(Color.WHITE)
|
||||
gradientDrawable.cornerRadius = DisplayUtils.dip2px(999f).toFloat()
|
||||
holder.tagTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_3a3a3a))
|
||||
holder.tagTv.background = null
|
||||
holder.tagTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_757575))
|
||||
}
|
||||
|
||||
holder.tagTv.text = categoryEntity.name
|
||||
holder.tagTv.background = gradientDrawable
|
||||
holder.tagTv.setOnClickListener {
|
||||
mViewModel.changeSelectedCategory(categoryEntity)
|
||||
notifyDataSetChanged()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user