Compare commits

...

70 Commits

Author SHA1 Message Date
5bd882b489 chore: 版本更新至 5.42.5 2025-07-09 10:34:02 +08:00
1c1d1ff9b9 Merge branch 'hotfix/v5.42.4-1194/GHZSCY-8199' into 'release'
fix: 鸿蒙版本识别错误 https://jira.shanqu.cc/browse/GHZSCY-8199

See merge request halo/android/assistant-android!2228
2025-07-09 09:34:06 +08:00
a4e806d536 fix: 鸿蒙版本识别错误 https://jira.shanqu.cc/browse/GHZSCY-8199 2025-07-08 17:36:11 +08:00
122a0b929f Merge branch 'hotfix/v5.42.4-1194/GHZS-8203' into 'release'
fix: 已安装游戏替换问题 https://jira.shanqu.cc/browse/GHZSCY-8203

See merge request halo/android/assistant-android!2227
2025-07-08 17:28:11 +08:00
2a069fb5e7 fix: 已安装游戏替换问题 https://jira.shanqu.cc/browse/GHZSCY-8203 2025-07-08 17:14:49 +08:00
115b6638a8 Merge branch 'hotfix/v5.42.4-1194/huawei-deadsystemexception' into 'release'
fix: 华为系 android 10 设备停用静默获取已安装应用列表功能

See merge request halo/android/assistant-android!2226
2025-07-08 15:42:42 +08:00
ecbdcdced7 fix: 华为系 android 10 设备停用静默获取已安装应用列表功能 2025-07-08 14:54:08 +08:00
01db3b07d4 Merge branch 'fix/GHZSCY-8198' into 'release'
fix:【光环助手】鸿蒙系统安装弹窗「前往设置」按钮点击无反应 https://jira.shanqu.cc/browse/GHZSCY-8198

See merge request halo/android/assistant-android!2225
2025-07-08 09:45:19 +08:00
081658873f fix:【光环助手】鸿蒙系统安装弹窗「前往设置」按钮点击无反应 https://jira.shanqu.cc/browse/GHZSCY-8198 2025-07-08 09:45:19 +08:00
8d7157095d Merge branch 'feat/GHZSCY-8150' into 'release'
feat: GameDetailPageTabSelect埋点事件优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-8150

See merge request halo/android/assistant-android!2224
2025-07-07 15:29:25 +08:00
1eb84ca71a feat: GameDetailPageTabSelect埋点事件优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-8150 2025-07-07 15:27:56 +08:00
9f4149358a Merge branch 'hotfix/v5.42.4-1194/simulator_crash' into 'release'
fix: 修复 mumu 模拟器上 loadDataWithBaseUrl 方法的空指针闪退问题

See merge request halo/android/assistant-android!2223
2025-07-07 14:33:46 +08:00
5451f244bc Merge branch 'hotfix/v5.42.4-1194/subject_tab_crash' into 'release'
fix: 修复进入专题合集页面后快速返回出现的闪退问题...

See merge request halo/android/assistant-android!2222
2025-07-07 11:31:14 +08:00
aca80aceea fix: 修复进入专题合集页面后快速返回出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/456018/?project=22 2025-07-07 11:29:16 +08:00
964b391eec fix: 修复 mumu 模拟器上 loadDataWithBaseUrl 方法的空指针闪退问题 2025-07-07 10:37:08 +08:00
7584da3734 Merge branch 'hotfix/v5.42.4-1194/exposure_crash' into 'release'
fix: 修复曝光获取当前页面名称时偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/456204

See merge request halo/android/assistant-android!2221
2025-06-30 15:01:27 +08:00
62060a5bf0 fix: 修复曝光获取当前页面名称时偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/456204 2025-06-30 14:59:46 +08:00
f49caa11c8 Merge branch 'hotfix/v5.42.4-1194/tab_wrapper_crash' into 'release'
fix: 修复二级多tab导航页显示引导时出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/447802

See merge request halo/android/assistant-android!2219
2025-06-30 14:58:41 +08:00
61c2f48a50 fix: 修复二级多tab导航页显示引导时出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/447802 2025-06-30 14:43:40 +08:00
b9e0585dc9 chore: 版本更新至 5.42.4 2025-06-16 17:31:54 +08:00
9f191832fd Merge branch 'hotfix/v5.42.3-1193/GHZSCY-8143' into 'release'
fix: 修复 dsp 广告曝光上报问题 https://jira.shanqu.cc/browse/GHZSCY-8143

See merge request halo/android/assistant-android!2215
2025-06-16 14:48:43 +08:00
d8ee461a0a fix: 修复 dsp 广告曝光上报问题 2025-06-16 13:58:49 +08:00
99094896b1 Merge branch 'fix/libao_crash' into 'release'
fix: 修复礼包列表偶发闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/455408

See merge request halo/android/assistant-android!2214
2025-06-09 11:10:34 +08:00
23203b0c5d fix: 修复礼包列表偶发闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/455408 2025-06-09 10:46:01 +08:00
4e054aa834 chore: 版本更新至 5.42.3 2025-06-03 11:07:01 +08:00
e36cc54083 Merge branch 'fix/202506/454319' into 'release'
fix:https://sentry.shanqu.cc/organizations/lightgame/issues/454319/?project=22

See merge request halo/android/assistant-android!2213
2025-06-03 11:01:58 +08:00
bc5935d4b4 Merge branch 'hotfix/v5.42.2-1192/filter_crash' into 'release'
fix: 修复游戏屏蔽功能偶发的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/453949

See merge request halo/android/assistant-android!2212
2025-06-03 10:56:07 +08:00
8fc3bb720d fix:https://sentry.shanqu.cc/organizations/lightgame/issues/454319/?project=22 2025-06-03 10:45:27 +08:00
e8b68f889d fix: 修复游戏屏蔽功能偶发的闪退问题 2025-06-03 10:42:36 +08:00
649af64e62 Merge branch 'fix/GHZSCY-8061' into 'release'
fix:【光环助手】自定义专题合集-自定义设置点击问题 https://jira.shanqu.cc/browse/GHZSCY-8061

See merge request halo/android/assistant-android!2211
2025-05-30 13:39:50 +08:00
46516fb9c0 fix:【光环助手】自定义专题合集-自定义设置点击问题 https://jira.shanqu.cc/browse/GHZSCY-8061 2025-05-30 13:39:50 +08:00
eecfdced32 chore: 版本更新至 5.42.2 2025-05-30 11:37:13 +08:00
74d9aaf664 Merge branch 'hotfix/v5.42.1-1191/exposure_crash' into 'release'
fix: 修复曝光收集时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/454091

See merge request halo/android/assistant-android!2210
2025-05-30 11:35:17 +08:00
28bbb128dd fix: 修复曝光收集时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/454091 2025-05-30 09:43:19 +08:00
7640812518 chore: 版本更新至 5.42.1 2025-05-29 11:03:59 +08:00
0a30e82e17 Merge branch 'hotfix/v5.42.0-1190/exposure_crash' into 'release'
fix: 修复曝光收集时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/453915

See merge request halo/android/assistant-android!2208
2025-05-29 11:01:45 +08:00
559951ad82 fix: 修复曝光收集时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/453915 2025-05-29 10:43:08 +08:00
4a4cba5445 Merge branch 'feat/GHZSCY-8049-merge' into 'release'
feat: 游戏详情UI优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-8049

See merge request halo/android/assistant-android!2209
2025-05-29 10:22:59 +08:00
b6d6568ac9 feat: 游戏详情UI优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-8049 2025-05-29 10:21:47 +08:00
ade32ef92d Merge branch 'feat/GHZSCY-7987' into 'dev'
合并【光环助手】畅玩游戏管理游戏显示问题

See merge request halo/android/assistant-android!2206
2025-05-27 11:19:57 +08:00
58702b46aa Revert "ci: 测试 https://jira.shanqu.cc/browse/GHZSCY-7987"
This reverts commit 75ca0a8379.
2025-05-27 11:15:55 +08:00
e6d6fc5309 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectCPMRemoteDataSource.kt
#	dependencies.gradle
2025-05-27 09:29:44 +08:00
1460348582 Merge branch 'feat/GHZSCY-7972' into 'dev'
feat: 【畅玩助手】文件夹权限申请 https://jira.shanqu.cc/browse/GHZSCY-7972

See merge request halo/android/assistant-android!2205
2025-05-26 11:31:40 +08:00
c49b3c5efe feat: 【畅玩助手】文件夹权限申请 https://jira.shanqu.cc/browse/GHZSCY-7972 2025-05-26 11:27:05 +08:00
4f7c468cde fix: 畅玩加载中没有显示正在下载的游戏 https://jira.shanqu.cc/browse/GHZSCY-7987 2025-05-23 17:53:59 +08:00
df93bdda2e Merge branch 'dev' into feat/GHZSCY-7987 2025-05-23 15:54:42 +08:00
086796915b Merge branch 'feat/GHZSCY-7955' into 'dev'
feat: CPM微信小游戏推荐优化 https://jira.shanqu.cc/browse/GHZSCY-7954

See merge request halo/android/assistant-android!2204
2025-05-22 16:40:44 +08:00
f99e5f403d feat: CPM微信小游戏推荐优化 https://jira.shanqu.cc/browse/GHZSCY-7954 2025-05-22 16:25:40 +08:00
9785f4fa13 Merge branch 'feat/GHZSCY-8006' into 'dev'
fix: 广告系统-新增广告游戏的过滤条件 https://jira.shanqu.cc/browse/GHZSCY-8006

See merge request halo/android/assistant-android!2203
2025-05-20 17:17:22 +08:00
6cdff338ed fix: 广告系统-新增广告游戏的过滤条件 https://jira.shanqu.cc/browse/GHZSCY-8006 2025-05-20 17:16:45 +08:00
761093a768 chore: 版本更新至 5.41.4 2025-05-20 11:05:49 +08:00
e5a0db4513 Merge branch 'hotfix/v5.41.3-1173/dsp_crash' into 'release'
fix: 修复 DetailViewHolder 触发的弹窗在模拟器上的闪退问题

See merge request halo/android/assistant-android!2202
2025-05-20 10:05:26 +08:00
a3df62bba8 fix: 修复 DetailViewHolder 触发的弹窗在模拟器上的闪退问题 2025-05-20 09:56:20 +08:00
ee773f7e31 Merge branch 'hotfix/v5.41.3-1173/huawei-crash' into 'release'
fix: 补充屏蔽华为 Android 10 设备上的热启动广告显示

See merge request halo/android/assistant-android!2201
2025-05-19 16:00:29 +08:00
227a5e677f fix: 补充屏蔽华为 Android 10 设备上的热启动广告显示 2025-05-19 15:56:04 +08:00
c41939cd79 Merge branch 'feat/GHZSCY-7999' into 'dev'
feat: 专题合集新增自定义设置-0516运营验收优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-7999

See merge request halo/android/assistant-android!2200
2025-05-19 14:10:04 +08:00
125ef60176 feat: 专题合集新增自定义设置-0516运营验收优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-7999 2025-05-19 14:10:04 +08:00
e2bf2773e4 Merge branch 'fix/GHZSCY-8001-pr' into 'dev'
fix:分类新增搜索功能-0516运营验收-客户端 https://jira.shanqu.cc/browse/GHZSCY-8001

See merge request halo/android/assistant-android!2199
2025-05-19 11:09:28 +08:00
e3596c758e fix:分类新增搜索功能-0516运营验收-客户端 https://jira.shanqu.cc/browse/GHZSCY-8001 2025-05-19 11:00:38 +08:00
75ca0a8379 ci: 测试 https://jira.shanqu.cc/browse/GHZSCY-7987 2025-05-19 10:49:17 +08:00
ef7d2860e5 feat: 修复页面onStart没有刷新数据 https://jira.shanqu.cc/browse/GHZSCY-7987 2025-05-19 10:48:04 +08:00
bfc8981253 chore: 版本更新至 5.41.3 2025-05-19 10:42:28 +08:00
12d6d338aa Merge branch 'hotfix/v5.41.2-1172/huawei-crash' into 'release'
fix: 屏蔽华为系 Android 10 设备的穿山甲广告,避免启动闪退

See merge request halo/android/assistant-android!2198
2025-05-19 10:39:51 +08:00
4da3c3aec1 fix: 屏蔽华为系 Android 10 设备的穿山甲广告,避免启动闪退 2025-05-19 10:37:59 +08:00
e608a51cce feat: 修复畅玩游戏管理页面编辑状态点击删除按钮,取消操作之后导致已下载的游戏变为暂停https://jira.shanqu.cc/browse/GHZSCY-7987 2025-05-16 18:19:53 +08:00
fd5a3104c4 Merge branch 'fix/game_detail_crash' into 'release'
fix: 修复游戏详情页滚动到顶部的偶发闪退...

See merge request halo/android/assistant-android!2188
2025-05-14 14:20:11 +08:00
486dd57a24 fix: 修复游戏详情页滚动到顶部的偶发闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/444460/?project=22&referrer=issue-stream&statsPeriod=14d 2025-05-14 14:07:36 +08:00
058b51f050 chore: 版本更新至 5.41.2 2025-05-14 13:57:16 +08:00
149a49fdd8 Merge branch 'cherry-pick-380939b8' into 'release'
Merge branch 'fix/GHZSCY-7971-pr' into 'dev'

See merge request halo/android/assistant-android!2187
2025-05-14 13:50:11 +08:00
4314797166 Merge branch 'fix/GHZSCY-7971-pr' into 'dev' 2025-05-14 13:50:11 +08:00
66 changed files with 457 additions and 208 deletions

View File

@ -5,6 +5,7 @@ import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.graphics.drawable.Animatable
import android.os.Build
import android.os.Message
import android.text.TextUtils
import android.view.View
@ -17,6 +18,7 @@ import com.therouter.TheRouter
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.g00fy2.versioncompare.Version
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.LogUtils
@ -43,6 +45,7 @@ import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
import java.util.Locale
/**
* 广告实现代理类
@ -120,7 +123,12 @@ object AdDelegateHelper {
if (isFromRetry && mAdConfigList.isNotEmpty()) {
return
}
val paramsMap = if (keyword.isNotEmpty()) mapOf("keyword" to keyword) else mapOf()
val paramsMap = if (keyword.isNotEmpty()) {
mapOf("keyword" to keyword, "android_sdk_version" to Build.VERSION.SDK_INT)
} else {
mapOf("android_sdk_version" to Build.VERSION.SDK_INT)
}
RetrofitManager.getInstance()
.newApi
.getAdConfig(paramsMap)
@ -179,11 +187,16 @@ object AdDelegateHelper {
"halo_launch" -> {
config.ownerAd?.startAd?.let { it.id = config.ownerAd.id }
// HarmonyOS 2.2.0 版本不展示第三方开屏广告 (因为会引起奇怪的闪退)
if (MetaUtil.getRom().name == "HarmonyOS"
&& MetaUtil.getRom().versionName == "2.2.0"
&& config.displayRule.adSource == "third_party_ads") {
// HarmonyOS 4.2.0 版本不展示第三方开屏广告 (因为会引起奇怪的闪退)
if (MetaUtil.getRom().romName == "HarmonyOS"
&& Version(MetaUtil.getRom().romVersion).isLowerThan(Version("4.2.0"))
&& config.displayRule.adSource == AD_TYPE_SDK
) {
return
}
// 华为系 Android 10 不展示第三方开屏广告 (因为会引起奇怪的闪退)
if (isBuggyHuaweiDevice() && config.displayRule.adSource == AD_TYPE_SDK) {
return
}
@ -215,6 +228,7 @@ object AdDelegateHelper {
private fun shouldShowStartUpAdWhenHotLaunch() = (mCsjAdImpl != null)
&& mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
&& mSplashAd?.hotStartThirdPartyAd != null
&& !isBuggyHuaweiDevice()
/**
* 是否需要显示下载管理广告
@ -783,4 +797,16 @@ object AdDelegateHelper {
mCsjAdImpl?.cancelSplashAd(context)
}
/**
* 是否为有问题的华为系 Android 10 设备
*/
private fun isBuggyHuaweiDevice(): Boolean {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
val manufacturer = Build.MANUFACTURER.lowercase(Locale.CHINA) ?: ""
return manufacturer == "huawei" || manufacturer == "honor"
} else {
return false
}
}
}

View File

@ -390,7 +390,7 @@ public class Config {
"manufacturer", Build.MANUFACTURER,
"model", Build.MODEL,
"android_sdk_version", String.valueOf(Build.VERSION.SDK_INT),
"rom", MetaUtil.INSTANCE.getRom().name() + " " + MetaUtil.INSTANCE.getRom().getVersionName()
"rom", MetaUtil.INSTANCE.getRom().getRomName() + " " + MetaUtil.INSTANCE.getRom().getRomVersion()
);
RetrofitManager.getInstance()

View File

@ -16,6 +16,7 @@ class DefaultExposureStateChangeListener : IExposureStateChangeListener {
val exposureStatus = if (inExposure) "曝光中" else "结束曝光"
val isCPMExposureEvent = exposureEvent.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM
val isDSPExposureEvent = exposureEvent.payload.miniGameType == Constants.DSP_GAME
Utils.log(
RecyclerViewExposureHelper.TAG,
@ -29,6 +30,12 @@ class DefaultExposureStateChangeListener : IExposureStateChangeListener {
"上报 CPM 曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}"
)
ExposureManager.logCPM(exposureEvent)
} else if (isDSPExposureEvent && inExposure) {
Utils.log(
RecyclerViewExposureHelper.TAG,
"上报 DSP 曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}"
)
ExposureManager.logDSP(exposureEvent)
}
if (!inExposure

View File

@ -111,6 +111,12 @@ object ExposureManager {
}
}
fun logDSP(event: ExposureEvent) {
AppExecutor.logExecutor.execute {
DspReportHelper.report(event.payload.showUrl)
}
}
/**
* @param forcedUpload Ignore all restrictions.
*/

View File

@ -73,7 +73,7 @@ object RegionSettingHelper {
if (list is ArrayList) return list
}
val listCopy: ArrayList<GameEntity> = if (list is ArrayList) list else ArrayList(list)
val listCopy: ArrayList<GameEntity> = ArrayList(list)
listCopy.removeAll { mFilterGameIdSet?.contains(it.id) ?: false }
return listCopy
}

View File

@ -108,21 +108,32 @@ object GameSubstituteRepositoryHelper {
var thisPositionNeedToBeReplaced = false
// 检查是否已安装该游戏里同包名的 APK
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
if (game.getApk().size == 1) {
val apk = game.getApk().firstOrNull()
// 若该游戏只有一个 APK且该 APK 的包名在本地已安装的包名列表中
if (PackageHelper.localPackageNameSet.contains(apk?.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
break
}
} else {
// 检查是否已安装该游戏里同包名的 APK
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
break
}
}
}
// 检查是否已安装该游戏 id
if (PackagesManager.getInstalledDataByGameId(game.id) != null) {
if (!thisPositionNeedToBeReplaced && PackagesManager.getInstalledDataByGameId(game.id) != null) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
break
continue
}
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
@ -152,11 +163,19 @@ object GameSubstituteRepositoryHelper {
if (mGameCollectionList.isNullOrEmpty()) return
// 临时的游戏 ID 列表(包含 gameList 的游戏),避免重复替换
val tempDisplayingGameIdSet = HashSet(displayingGameIdSet)
gameList.forEach {
tempDisplayingGameIdSet.add(it.id)
}
for (position in positionOfGameToBeReplacedList) {
val validGame = getValidGame(relatedCollectionId, displayingGameIdSet)
val validGame = getValidGame(relatedCollectionId, tempDisplayingGameIdSet)
validGame?.let {
gameList[position] = it
displayingGameIdSet.add(it.id)
tempDisplayingGameIdSet.add(it.id)
}
}
}

View File

@ -245,6 +245,7 @@ public class LogUtils {
object.put("jnfj", MetaUtil.getBase64EncodedIMEI());
object.put("G_ID", UserManager.getInstance().getDeviceId());
object.put("oaid", HaloApp.getInstance().getOAID());
object.put("rom", MetaUtil.getMeta().getRom());
} catch (JSONException e) {
e.printStackTrace();
}
@ -264,6 +265,7 @@ public class LogUtils {
object.put("channel", HaloApp.getInstance().getChannel());
object.put("dia", MetaUtil.getBase64EncodedAndroidId());
object.put("oaid", MetaUtil.INSTANCE.getMeta().getOaid());
object.put("rom", MetaUtil.getMeta().getRom());
object.put("time", Utils.getTime(context));
object.put("network", DeviceUtils.getNetwork(context));
object.put("user_id", UserManager.getInstance().getUserId());
@ -289,6 +291,7 @@ public class LogUtils {
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("oaid", meta.getOaid());
metaObject.put("rom", MetaUtil.getMeta().getRom());
metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
@ -495,6 +498,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
metaObject.put("oaid", HaloApp.getInstance().getOAID());
metaObject.put("rom", MetaUtil.getMeta().getRom());
} catch (JSONException e) {
e.printStackTrace();

View File

@ -33,6 +33,7 @@ import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.*
import java.util.HashMap
import java.util.Locale
import java.util.concurrent.Executors
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
@ -288,12 +289,22 @@ object PackageHelper {
* 用户是否已经使用另类方式获取已安装应用列表
*/
private fun isUseAlternativeWayToGetInstalledPackages(): Boolean {
if (isBuggyHuaweiDevice()) {
useAlternativeWayToGetInstalledPackages = false
return false
}
return useAlternativeWayToGetInstalledPackages
|| (SPUtils.getBoolean(SP_GET_INSTALLED_PACKAGES_BY_ALTERNATIVE_API)
.also { useAlternativeWayToGetInstalledPackages = it })
}
private fun updateUseAlternativeWayToGetInstalledPackages() {
if (isBuggyHuaweiDevice()) {
useAlternativeWayToGetInstalledPackages = false
return
}
// 启用另类获取已安装应用列表的 API
useAlternativeWayToGetInstalledPackages = true
SPUtils.setBoolean(SP_GET_INSTALLED_PACKAGES_BY_ALTERNATIVE_API, true)
@ -478,7 +489,12 @@ object PackageHelper {
/**
* 是否支持动态获取已安装应用列表权限
*/
fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
private fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
if (isBuggyHuaweiDevice()) {
// 华为系 Android 10 设备存在 bug调用过多可能会触发 DeadSystemException
return false
}
if (isUseAlternativeWayToGetInstalledPackages()) {
// 已经使用另类获取已安装应用列表形式,强制判定为不支持动态获取已安装应用列表权限
return false
@ -789,4 +805,13 @@ object PackageHelper {
return packageList
}
private fun isBuggyHuaweiDevice(): Boolean {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
val manufacturer = Build.MANUFACTURER.lowercase(Locale.CHINA) ?: ""
return manufacturer == "huawei" || manufacturer == "honor"
} else {
return false
}
}
}

View File

@ -37,7 +37,7 @@ public class PostCommentUtils {
device.put("model", Build.MODEL);
device.put("manufacturer", Build.MANUFACTURER);
device.put("android_version", android.os.Build.VERSION.RELEASE);
device.put("rom", MetaUtil.INSTANCE.getRom().name() + " " + MetaUtil.INSTANCE.getRom().getVersionName());
device.put("rom", MetaUtil.INSTANCE.getRom().getRomName() + " " + MetaUtil.INSTANCE.getRom().getRomVersion());
content.put("device", device);
} catch (Exception e) {
e.printStackTrace();

View File

@ -9,15 +9,14 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.gh.common.constant.Config
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.entity.NewApiSettingsEntity
import com.lightgame.utils.Utils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.enlargeTouchArea
import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.NewApiSettingsEntity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
/**
* 处理厂商纯净/安全模式的辅助类
@ -313,9 +312,11 @@ object PureModeHelper {
intent.setPackage("com.huawei.security.privacycenter")
intent.setAction("com.huawei.securitycenter.PURE_MODE_ACTIVITY")
intent.putExtra("intent_from_settings", true)
context.startActivity(intent)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
HaloApp.getInstance().startActivity(intent)
} catch (_: Exception) {
toSystemSettings(context)
}
}

View File

@ -20,6 +20,7 @@ import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.google.android.flexbox.FlexboxLayout
import splitties.views.leftPadding
class ConfigFilterView @JvmOverloads constructor(
context: Context,
@ -213,6 +214,10 @@ class ConfigFilterView @JvmOverloads constructor(
fun initSubjectFilterView(subjectSetting: SubjectSettingEntity) {
ratingTv.visibility = View.VISIBLE
if (subjectSetting.typeEntity.layout == "hide") {
container.leftPadding = 8F.dip2px()
}
if (subjectSetting.filterOptions.size > 1) {
// 重排序
subjectSetting.filterOptions.forEachIndexed { index, s ->

View File

@ -9,7 +9,11 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.exposure.meta.MetaUtil.getMeta
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.DeviceUtils
import com.gh.gamecenter.common.utils.asVGame
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.isSimulatorGame
import com.gh.ndownload.NDataChanger
import com.gh.ndownload.NDownloadBridge
import com.halo.assistant.HaloApp
@ -427,6 +431,7 @@ object DownloadDataHelper {
metaObject.put("channel", meta.channel)
metaObject.put("gid", meta.gid)
metaObject.put("oaid", meta.oaid)
metaObject.put("rom", meta.rom)
metaObject.put("manufacturer", meta.manufacturer)
metaObject.put("model", meta.model)
metaObject.put("network", DeviceUtils.getNetwork(context))

View File

@ -3,9 +3,6 @@ package com.gh.download
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.common.util.*
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.constant.Constants
@ -33,9 +30,7 @@ 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.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONException
import org.json.JSONObject

View File

@ -7,6 +7,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.common.DefaultUrlHandler
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.loadDataCompat
import com.gh.gamecenter.databinding.DownloadDialogInstructionItemBinding
class DownloadDialogInstructionItemViewHolder(val binding: DownloadDialogInstructionItemBinding) :
@ -14,11 +15,8 @@ class DownloadDialogInstructionItemViewHolder(val binding: DownloadDialogInstruc
fun bindItem(listData: List<DownloadDialogItemData>, position: Int, entrance: String) {
val instruction = listData[position].instruction
binding.webView.loadDataWithBaseURL(
null,
binding.webView.loadDataCompat(
"<body style='margin:0;padding:0;color:#666666;font-size:12px;line-height:18px;'>$instruction</body>",
"text/html",
"utf-8", null
)
binding.webView.settings
binding.webView.setBackgroundColor(Color.TRANSPARENT)

View File

@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentActivity
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.utils.loadDataCompat
import com.gh.gamecenter.databinding.DialogDownloadLinkBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.halo.assistant.HaloApp
@ -27,10 +28,7 @@ class DownloadLinkDialog : BaseDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding: DialogDownloadLinkBinding = DialogDownloadLinkBinding.inflate(layoutInflater, container, false)
binding.title.text = mLinkEntity?.title
binding.webView.loadDataWithBaseURL(
null,
mLinkEntity?.content ?: "", "text/html", "utf-8", null
)
binding.webView.loadDataCompat(mLinkEntity?.content ?: "")
binding.confirm.setOnClickListener {
dismissAllowingStateLoss()

View File

@ -135,7 +135,7 @@ class DetailViewHolder(
vUpdate = view.findViewById(R.id.v_update)
tvUpdate = view.findViewById(R.id.tv_update)
context = view.context
context = view.context.getActivity() ?: view.context
com.gh.gamecenter.common.R.color.text_aw_primary.toColor()
var gameDownloadMode = gameEntity.getGameDownloadButtonMode()

View File

@ -290,7 +290,6 @@ class CategoryV2Fragment : LazyFragment() {
mEntity?.run {
viewModel.run {
clearSelectedTag()
childFragmentManager.fragments.find { it.isAdded }
val targetFragment =
if (hasSpecial && position == 1) {
val fragment = childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.name)
@ -319,7 +318,6 @@ class CategoryV2Fragment : LazyFragment() {
)
fragment
}
childFragmentManager
.beginTransaction()
.replace(R.id.gamesContainer, targetFragment, targetFragment::class.java.name)

View File

@ -166,7 +166,7 @@ class CategoryV2ViewModel : ViewModel() {
if (position != oldPosition) {
_selectedSidebarsPosition.value = position
// 如果是点击搜索而被动切换到 “全部” tab则这里不需要更新筛选条件
if (triggerSearch && position != 1) {
if (triggerSearch && position != INVALID_POSITION) {
updateGameFiltered()
}
}

View File

@ -122,7 +122,9 @@ data class SubjectEntity(
@SerializedName("column_type")
private val _columnType: String? = null,
@SerializedName("size")
private val _size: Size? = null
private val _size: Size? = null,
@SerializedName("onlyFee")
private val _onlyFee: Boolean? = false,
) : Parcelable {
@IgnoredOnParcel
@ -161,6 +163,9 @@ data class SubjectEntity(
val size: Size
get() = _size ?: Size()
val onlyFee: Boolean
get() = _onlyFee ?: false
var isDspSubject: Boolean = false
companion object {
@ -173,9 +178,13 @@ data class SubjectEntity(
@Parcelize
data class Size(
@SerializedName("index")
private val _index: Int? = null
private val _index: Int? = null,
@SerializedName("limit")
private val _limit: Int? = null,
) : Parcelable {
val index: Int
get() = _index ?: 0
val limit: Int
get() = _limit ?: -1
}
}

View File

@ -886,7 +886,7 @@ class GameDetailViewModel(
params["source"] = HaloApp.getInstance().application.getString(R.string.app_name)
params["jnfj"] = MetaUtil.getBase64EncodedIMEI()
params["manufacturer"] = Build.MANUFACTURER
params["rom"] = MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
params["rom"] = MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
params["suggestion_type"] = "游戏求更新"
params["game_id"] = game?.id ?: ""

View File

@ -14,6 +14,7 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.doOnNextLayout
import androidx.core.view.isVisible
@ -96,6 +97,7 @@ import io.reactivex.disposables.Disposable
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import retrofit2.HttpException
import splitties.views.horizontalPadding
import java.util.*
class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
@ -286,7 +288,7 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
initSkeleton()
binding.reuseNoneData.reuseNoneDataTv.text = "页面不见了"
bodyBinding.tabIndicator.setIndicatorWidth(12)
bodyBinding.tabIndicator.setIndicatorWidth(16)
bodyBinding.viewPager.offscreenPageLimit = 4
binding.expandSpecialDownloadIv.enlargeTouchArea()
@ -357,8 +359,14 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
}
backBtn.setOnClickListener { requireActivity().finish() }
moreMenuItem = actionMenuView.menu.findItem(R.id.menu_more)
downloadMenuItem = actionMenuView.menu.findItem(R.id.menu_download)
downloadMenuItem = actionMenuView.menu.findItem(R.id.menu_download)?.apply {
actionView?.updateLayoutParams<LayoutParams> { width = 40F.dip2px() }
}
downloadMenuItem?.isVisible = Config.isShow()
actionMenuView.findViewById<ActionMenuItemView>(R.id.menu_more)?.run {
updateLayoutParams<LayoutParams> { width = 40F.dip2px() }
horizontalPadding = 8F.dip2px()
}
}
downloadMenuIcon = downloadMenuItem?.actionView?.findViewById(R.id.menu_download_iv)
@ -807,7 +815,10 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
downloadStatus = gameEntity?.downloadStatusChinese ?: "",
gameType = gameEntity?.categoryChinese ?: "",
position = position,
tabContent = tabEntity.name
tabContent = tabEntity.name,
linkType = tabEntity.link?.type ?: "",
linkId = tabEntity.link?.link ?: "",
linkText = tabEntity.link?.text ?: ""
)
val entrance = if (mEntrance.contains("论坛详情")) "论坛" else "游戏"
@ -910,7 +921,7 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
tab.customView = tabItemBinding.root
updateTabStyle(tab, i == bodyBinding.viewPager.currentItem)
tab.view.clipChildren = false
tab.view.setPadding(0, 0, 0, 0)
tab.view.setPadding(0, 0, if (i == tabEntityList.size - 1) 8F.dip2px() else 0, 0)
tab.view.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
handleTabTouchEvent(tabEntity?.name ?: "")
@ -937,7 +948,7 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
tab.customView?.findViewById<TextView>(R.id.tab_title)
?.setTypeface(if (isChecked) Typeface.DEFAULT_BOLD else Typeface.DEFAULT)
tab.customView?.findViewById<TextView>(R.id.tab_title)?.setTextColor(
if (isChecked) com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()) else com.gh.gamecenter.common.R.color.text_tertiary.toColor(
if (isChecked) com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()) else com.gh.gamecenter.common.R.color.text_secondary.toColor(
requireContext()
)
)

View File

@ -922,8 +922,10 @@ class GameDetailFragment : LazyFragment(), IScrollable {
}
override fun scrollToTop() {
binding.gamedetailAppbar.setExpanded(true)
binding.detailRv.scrollToPosition(0)
if (::binding.isInitialized) {
binding.gamedetailAppbar.setExpanded(true)
binding.detailRv.scrollToPosition(0)
}
}
// 登录事件/礼包状态变更事件

View File

@ -7,7 +7,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.LinearLayout
import androidx.core.view.children
import androidx.core.view.forEach
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
@ -117,7 +117,7 @@ class GameLibaoAdapter(
binding.horizontalScrollView.goneIf(libaoEntity.materials.isEmpty()) {
if (binding.imagesContainer.tag == libaoEntity.id) {
binding.imagesContainer.children.forEach { view ->
binding.imagesContainer.forEach { view ->
if (view is SimpleDraweeView) {
view.hierarchy.roundingParams = RoundingParams().apply {
setCornersRadius(4F.dip2px().toFloat())

View File

@ -541,7 +541,7 @@ class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver {
jsonObject.put("game_version", gameVersion)
jsonObject.put("source", if (mFromAmway) "anliwall" else "game_detail")
jsonObject.put("plugin_version", PackageUtils.getMetaData(this, mInstallPackageName, "gh_version"))
jsonObject.put("rom", MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName)
jsonObject.put("rom", MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion)
jsonObject.put("again", again)
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())

View File

@ -411,7 +411,7 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
if (gameList != null) {// 直接读取缓存数据
notifyWGameCPMABatchChanged(gameList, subjectId, page)
} else {
repository.loadChangeSubjectWGameCPM(page)
repository.loadChangeSubjectWGameCPM(page, subjectEntity.size.limit, subjectEntity.onlyFee)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<GameEntity>>() {

View File

@ -367,7 +367,7 @@ class CustomPageRepository private constructor(
pageInfo.componentPosition
)
)
wGameSubjectCPMListUseCase.getWechatMiniGameCPMList(subject.id)
wGameSubjectCPMListUseCase.getWechatMiniGameCPMList(subject.id, subject.size.limit, subject.onlyFee)
pageInfo.positionIncrement()
pageInfo.componentPositionIncrement()
}
@ -903,8 +903,8 @@ class CustomPageRepository private constructor(
.map(RegionSettingHelper.filterGame)
.map(ApkActiveUtils.filterMapperList)
fun loadChangeSubjectWGameCPM(page: Int): Observable<MutableList<GameEntity>> =
wGameSubjectCPMRemoteDataSource.getEditorRecommendCPMList(page, 10)// 微信小游戏CPM专题的“换一批”接口
fun loadChangeSubjectWGameCPM(page: Int, minimumSize: Int, onlyFee: Boolean): Observable<MutableList<GameEntity>> =
wGameSubjectCPMRemoteDataSource.getEditorRecommendCPMList(page = page, minimumSize = minimumSize, onlyFee = onlyFee)// 微信小游戏CPM专题的“换一批”接口
.toObservable()
.map(RegionSettingHelper.filterGame)
.map(ApkActiveUtils.filterMapperList)

View File

@ -9,15 +9,19 @@ import io.reactivex.Observable
import io.reactivex.Single
class QGameSubjectListRepository(
private val api: ApiService = RetrofitManager.getInstance().newApi
private val api: ApiService = RetrofitManager.getInstance().newApi,
) : ISubjectListRepository {
override fun getColumn(column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?): Single<MutableList<GameEntity>> {
override fun getColumn(
column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?,
minimumSize: Int,
onlyFee: Boolean,
): Single<MutableList<GameEntity>> {
return api.getQGameColumn(column_id, order, page, 20)
}

View File

@ -10,13 +10,17 @@ class WGameSubjectCPMListRepository(
private val dataSource: WGameSubjectCPMRemoteDataSource = WGameSubjectCPMRemoteDataSource()
) : ISubjectListRepository {
override fun getColumn(column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?): Single<MutableList<GameEntity>> {
return dataSource.getEditorRecommendCPMList(page)
override fun getColumn(
column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?,
minimumSize: Int,
onlyFee: Boolean
): Single<MutableList<GameEntity>> {
return dataSource.getEditorRecommendCPMList(page = page, minimumSize = minimumSize, onlyFee = onlyFee)
}
override fun getColumnSettings(column_id: String?): Observable<SubjectSettingEntity> {

View File

@ -27,13 +27,13 @@ class WGameSubjectCPMListUseCase(
val wechatMiniGameCPMListLiveData: LiveData<Pair<String, List<GameEntity>>> = _wechatMiniGameCPMListLiveData
@SuppressLint("CheckResult")
fun getWechatMiniGameCPMList(subjectId: String?) {
fun getWechatMiniGameCPMList(subjectId: String?, minimumSize: Int, onlyFee: Boolean) {
if (subjectId.isNullOrEmpty() || requestKeyList.contains(subjectId)) {
return
}
requestKeyList.add(subjectId)
repository.getColumn(null, 1, null, null, null, null)
repository.getColumn(null, 1, null, null, null, null, minimumSize, onlyFee)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<GameEntity>>() {

View File

@ -14,7 +14,12 @@ class WGameSubjectCPMRemoteDataSource(
private val api: WGameCPMApiService = RetrofitManager.getInstance().wGameCPMApi
) {
fun getEditorRecommendCPMList(page: Int, pageSize: Int = 10): Single<MutableList<GameEntity>> {
fun getEditorRecommendCPMList(
page: Int,
pageSize: Int = 10,
minimumSize: Int,
onlyFee: Boolean
): Single<MutableList<GameEntity>> {
val meta = MetaUtil.getMeta()
val request = mapOf(
"head" to mapOf(
@ -28,38 +33,44 @@ class WGameSubjectCPMRemoteDataSource(
"body" to mapOf(
"page" to page - 1,
"pageSize" to pageSize,
"onlyFee" to if (onlyFee) 1 else 0,
)
)
return api.getEditorRecommendList(request.toRequestBody())
.map {
if (it.ret == 0) {
it.appInfoList.map { info ->
GameEntity(
mName = info.appName,
mIcon = info.logo,
mBrief = info.briefIntro,
miniGameUid = info.appID,
miniGameAppId = info.userName,
miniGameCategory = Constants.WECHAT_MINI_GAME,
profit = Constants.WECHAT_MINI_GAME_PROFIT_CPM,
miniGameAppStatus = 2,
miniGameAppPath = info.wechatAppPath,
miniGameExtData = info.extData,
miniGameRecommendId = info.recommendID,
mTagStyle = arrayListOf(
TagStyleEntity(
name = info.categoryName,
color = TAG_COLOR,
background = TAG_BACKGROUND
),
TagStyleEntity(
name = info.subcategoryName,
color = TAG_COLOR,
background = TAG_BACKGROUND
// 数量不满足最小值时直接返回空
if (onlyFee && minimumSize > 0 && it.appInfoList.size < minimumSize) {
mutableListOf()
} else {
it.appInfoList.map { info ->
GameEntity(
mName = info.appName,
mIcon = info.logo,
mBrief = info.briefIntro,
miniGameUid = info.appID,
miniGameAppId = info.userName,
miniGameCategory = Constants.WECHAT_MINI_GAME,
profit = Constants.WECHAT_MINI_GAME_PROFIT_CPM,
miniGameAppStatus = 2,
miniGameAppPath = info.wechatAppPath,
miniGameExtData = info.extData,
miniGameRecommendId = info.recommendID,
mTagStyle = arrayListOf(
TagStyleEntity(
name = info.categoryName,
color = TAG_COLOR,
background = TAG_BACKGROUND
),
TagStyleEntity(
name = info.subcategoryName,
color = TAG_COLOR,
background = TAG_BACKGROUND
)
)
)
)
}.toMutableList()
}.toMutableList()
}
} else {
mutableListOf()
}

View File

@ -9,15 +9,19 @@ import io.reactivex.Observable
import io.reactivex.Single
class WGameSubjectListRepository(
private val api: ApiService = RetrofitManager.getInstance().newApi
private val api: ApiService = RetrofitManager.getInstance().newApi,
) : ISubjectListRepository {
override fun getColumn(column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?): Single<MutableList<GameEntity>> {
override fun getColumn(
column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?,
minimumSize: Int,
onlyFee: Boolean,
): Single<MutableList<GameEntity>> {
return api.getWGameColumn(column_id, order, page, 20)
}

View File

@ -9,15 +9,17 @@ import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.GameUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.InstalledPackagesAction
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.ObservableUtil
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.secondOrNull
import com.gh.gamecenter.common.utils.toArrayList
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.SPUtils
@ -41,10 +43,12 @@ import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import org.json.JSONObject
import java.util.*
import kotlin.collections.HashSet
/**
* 该类存储的是已安装的所有游戏(助手后台已收录的)和所有更新(包括插件化)数据
@ -624,7 +628,20 @@ object PackageRepository {
pkgSet.add(iterator.next())
}
postInstalledPackageList(pkgSet)
PackagesManager.initInstallPkgSet(pkgSet)
}
private fun postInstalledPackageList(pkgSet: HashSet<String>) {
val requestBody = InstalledPackagesAction(
action = "launch",
packages = pkgSet.toList()
).toRequestBody()
RetrofitManager.getInstance().newApi.postInstalledPackages(HaloApp.getInstance().gid, requestBody)
.subscribeOn(Schedulers.io())
.subscribe(EmptyResponse<ResponseBody>())
}
}

View File

@ -3521,4 +3521,11 @@ public interface ApiService {
@Headers({"Content-Type: application/json", "Accept: application/json"})
@POST("suggestions")
Single<ResponseBody> uploadAcceleratorErrorLog(@Body RequestBody toRequestBody);
/**
* 上传设备已安装的游戏
*/
@POST("/devices/{device_id}/installed_games")
Single<ResponseBody> postInstalledPackages(@Path("device_id") String deviceId, @Body RequestBody body);
}

View File

@ -13,7 +13,9 @@ interface ISubjectListRepository {
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?
columnCollectionId: String?,
minimumSize: Int,
onlyFee: Boolean
): Single<MutableList<GameEntity>>
fun getColumnSettings(column_id: String?): Observable<SubjectSettingEntity>

View File

@ -8,10 +8,19 @@ import io.reactivex.Observable
import io.reactivex.Single
class SubjectListRepository(
private val api: ApiService = RetrofitManager.getInstance().api
private val api: ApiService = RetrofitManager.getInstance().api,
) : ISubjectListRepository {
override fun getColumn(column_id: String?, page: Int, sort: String?, order: String?, ad: String?, columnCollectionId: String?): Single<MutableList<GameEntity>> {
override fun getColumn(
column_id: String?,
page: Int,
sort: String?,
order: String?,
ad: String?,
columnCollectionId: String?,
minimumSize: Int,
onlyFee: Boolean,
): Single<MutableList<GameEntity>> {
return api.getColumn(column_id, sort, order, ad, columnCollectionId, page)
}

View File

@ -49,7 +49,9 @@ open class SubjectListViewModel(
subjectData.sort,
subjectData.filter.ifEmpty { "type:全部" },
AdHelper.getIdfaString(),
columnCollectionId
columnCollectionId,
-1,
false
)
}

View File

@ -6,6 +6,7 @@ import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.view.Chips
import com.gh.gamecenter.databinding.ItemColumnCollectionCustomTabBinding
@ -30,8 +31,10 @@ class CustomTabFollowAdapter(private val viewModel: ColumnCollectionTabViewModel
endIcon.setImageResource(R.drawable.ic_basic_x_8_secondary)
endIcon.imageTintList = null
setOnClickListener {
if (!isForbidden) {
viewModel?.addMore(subjectData)
debounceActionWithInterval(500) {
if (!isForbidden) {
viewModel?.addMore(subjectData)
}
}
}
}

View File

@ -6,6 +6,7 @@ import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.view.Chips
import com.gh.gamecenter.databinding.ItemColumnCollectionCustomTabBinding
@ -26,7 +27,9 @@ class CustomTabMoreAdapter(private val viewModel: ColumnCollectionTabViewModel?)
startIcon.setImageResource(R.drawable.ic_auxiliary_plus_secondary_8)
startIcon.imageTintList = null
setOnClickListener {
viewModel?.addFollow(subjectData)
debounceActionWithInterval(500) {
viewModel?.addFollow(subjectData)
}
}
}
}

View File

@ -134,6 +134,7 @@ class SubjectTabFragment : ToolbarFragment() {
isSubject = subjectList.isEmpty()
tabStyle = when {
mIsFromMainWrapper && !isSubject -> TabStyle.COLUMN_COLLECTION_MAIN_WRAPPER
mIsFromTabWrapper && !isSubject -> TabStyle.COLUMN_COLLECTION_TAB_WRAPPER
isSubject -> TabStyle.SUBJECT_NORMAL
else -> TabStyle.COLUMN_COLLECTION_NORMAL
}
@ -370,18 +371,19 @@ class SubjectTabFragment : ToolbarFragment() {
}
private fun initTabLayout() {
if (isCustomEnabled && SPUtils.getBoolean(Constants.SP_SHOW_COLUMN_COLLECTION_CUSTOM_TAB_GUIDE, true)) {
binding.subjectTab.addOnTabSelectedListener(object : OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
showSettingGuideIfNeeded(this)
}
override fun onTabUnselected(tab: TabLayout.Tab?) {}
override fun onTabReselected(tab: TabLayout.Tab?) {
showSettingGuideIfNeeded(this)
}
})
}
if (tabStyle == TabStyle.COLUMN_COLLECTION_NORMAL) {
if (isCustomEnabled && SPUtils.getBoolean(Constants.SP_SHOW_COLUMN_COLLECTION_CUSTOM_TAB_GUIDE, true)) {
binding.subjectTab.addOnTabSelectedListener(object : OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
showSettingGuideIfNeeded(this)
}
override fun onTabUnselected(tab: TabLayout.Tab?) {}
override fun onTabReselected(tab: TabLayout.Tab?) {
showSettingGuideIfNeeded(this)
}
})
}
binding.subjectTabIndicator.run {
setIndicatorWidth(12)
updateLayoutParams<ConstraintLayout.LayoutParams> {
@ -420,10 +422,13 @@ class SubjectTabFragment : ToolbarFragment() {
}
}
} else {
when (i) {
0 -> tab.view.setPadding(16F.dip2px(), 0, 0, 0)
binding.subjectTab.tabCount - 1 -> tab.view.setPadding(8F.dip2px(), 0, 16F.dip2px(), 0)
else -> tab.view.setPadding(8F.dip2px(), 0, 0, 0)
val leftPadding = if (i == 0) 16F.dip2px() else 8F.dip2px()
val rightPadding = if (i == binding.subjectTab.tabCount - 1) 16F.dip2px() else 0
tab.view.setPadding(leftPadding, 0, rightPadding, 0)
tab.view.findViewById<View>(R.id.tab_title)?.let {
it.post {
tab.view.updateLayoutParams<ViewGroup.LayoutParams> { width = leftPadding + rightPadding + it.width }
}
}
}
}
@ -481,6 +486,7 @@ class SubjectTabFragment : ToolbarFragment() {
if (tabTitle is CheckedTextView) {
tabTitle.text = title
}
view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 32F.dip2px())
return view
}
}
@ -493,6 +499,7 @@ class SubjectTabFragment : ToolbarFragment() {
binding.subjectTab.setTabTextColors(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()), com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
}
TabStyle.COLUMN_COLLECTION_MAIN_WRAPPER -> updateTabStyle(binding.subjectViewpager.currentItem, 0F)
TabStyle.COLUMN_COLLECTION_TAB_WRAPPER,
TabStyle.SUBJECT_NORMAL -> {
for (i in 0 until binding.subjectTab.tabCount) {
val tab = binding.subjectTab.getTabAt(i) ?: continue
@ -805,6 +812,8 @@ class SubjectTabFragment : ToolbarFragment() {
}
override fun onBackPressed(): Boolean {
if (!isAdded) return super.onBackPressed()
if (binding.settingGuideContainer.isVisible) {
binding.settingGuideContainer.performClick()
return true
@ -828,9 +837,14 @@ class SubjectTabFragment : ToolbarFragment() {
COLUMN_COLLECTION_MAIN_WRAPPER,
/**
* 专题合集-常规样式
* 专题合集-二级页面样式
*/
COLUMN_COLLECTION_NORMAL,
/**
* 专题合集-关联多Tab导航栏样式
*/
COLUMN_COLLECTION_TAB_WRAPPER,
}
companion object {

View File

@ -118,6 +118,8 @@ class TabWrapperFragment: BaseTabWrapperFragment(), ISmartRefresh, ISmartRefresh
if (shouldShow && guide != null && guidePosition != -1) {
tabLayout?.post {
if (activity == null) return@post
val tabView = tabLayout?.getTabAt(guidePosition)?.view
if (tabView != null) {
if (!isDefaultCustomPageFragment() && priorityChain.isHandlerQueueEmpty()) {
@ -133,7 +135,7 @@ class TabWrapperFragment: BaseTabWrapperFragment(), ISmartRefresh, ISmartRefresh
} else {
multiTabGuideHandler.doPreProcess(
true,
requireActivity(),
activity,
mBaseHandler,
guide,
tabLayout,

View File

@ -25,6 +25,7 @@ import com.gh.gamecenter.history.IBatchDelete
import com.gh.gamecenter.history.ManageOption
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@ -109,7 +110,16 @@ class VDownloadManagerFragment :
ToastUtils.showToast(it.message ?: "")
}
.collectLatest {
onLoadRefresh()
when (mViewModel.type) {
VDownloadManagerViewModel.TYPE_DOWNLOADED -> {
refreshApks(it.map { it.packageName })
}
VDownloadManagerViewModel.TYPE_DOWNLOADING -> {
refreshApks(DownloadManager.getInstance().allVDownloadTaskSnapshots.filter { it.status != DownloadStatus.done }
.map { it.packageName })
}
}
}
}
}
@ -125,9 +135,9 @@ class VDownloadManagerFragment :
override fun isAutomaticLoad(): Boolean = false
override fun onLoadRefresh() {
private fun refreshApks(apks: List<String>) {
mReuseNoData?.visibility = View.GONE
mViewModel.refresh()
mViewModel.refresh(apks)
}
override fun onDarkModeChanged() {

View File

@ -29,19 +29,19 @@ class VDownloadManagerViewModel(application: Application) :
var type = ""
var isFromHomeRecent = false
var loadPublishSubject: PublishSubject<LoadType> = PublishSubject.create()
private var loadPublishSubject: PublishSubject<List<String>> = PublishSubject.create()
val disposable: Disposable = loadPublishSubject.debounce(300, TimeUnit.MILLISECONDS)
.distinctUntilChanged()
.distinctUntilChanged { p1, p2 -> p1.sorted() == p2.sorted() }
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
load(it)
load(LoadType.REFRESH)
}
val vGames = VHelper.vGameDao.getAllGames()
fun refresh() {
loadPublishSubject.onNext(LoadType.REFRESH)
fun refresh(apks: List<String>) {
loadPublishSubject.onNext(apks)
}
override fun mergeResultLiveData() {
@ -180,9 +180,13 @@ class VDownloadManagerViewModel(application: Application) :
fun pauseItems(idList: ArrayList<String>) {
for (id in idList) {
val apkEntity =
mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull()
DownloadManager.getInstance().pause(apkEntity?.url)
mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull()?.url?.let { url ->
DownloadManager.getInstance().getDownloadEntitySnapshot(url)
?.takeIf { it.status != DownloadStatus.done }
?.let {
DownloadManager.getInstance().pause(url)
}
}
}
}

View File

@ -97,12 +97,6 @@ class VDownloadManagerWrapperFragment : BaseLazyTabFragment() {
}
fun onNewIntent(intent: Intent?) {
childFragmentManager.fragments.forEach {
if (it.isAdded && it is VDownloadManagerFragment) {
it.onLoadRefresh()
}
}
intent?.getIntExtra(EntranceConsts.KEY_POSITION, 0)?.let {
mViewPager.post { mViewPager.currentItem = it }
}

View File

@ -243,7 +243,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() {
"source" to HaloApp.getInstance().application.getString(R.string.app_name)
"jnfj" to MetaUtil.getBase64EncodedIMEI()
"manufacturer" to Build.MANUFACTURER
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
"suggestion_type" to "游戏问题"
"game_id" to game.id

View File

@ -152,7 +152,7 @@ class AccelerationUseCase {
"from" to "",
"game_id" to game.id,
"manufacturer" to Build.MANUFACTURER,
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName,
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion,
"suggestion_type" to "加速器失败",
"message" to "加速失败, 游戏ID: ${game.id}, 游戏名: ${game.name ?: ""}",
"log" to it

View File

@ -693,7 +693,7 @@ class WebFragment : LazyFragment(), IScrollable {
webview.loadUrl(mWebUrl)
}
} else {
webview.loadDataWithBaseURL(null, mWebUrl, "text/html", "utf-8", null)
webview.loadDataCompat(mWebUrl)
}
}
if (mIsHorizontalDispatcherEnabled) {

View File

@ -14,7 +14,7 @@
android:layout_width="wrap_content"
android:layout_height="48dp"
android:gravity="center"
android:textColor="@color/text_tertiary"
android:textColor="@color/text_secondary"
android:textSize="@dimen/secondary_title_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -33,14 +33,15 @@
<FrameLayout
android:id="@+id/backContainer"
android:layout_width="48dp"
android:layout_width="40dp"
android:layout_height="48dp">
<ImageView
android:id="@+id/backBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_gravity="center_vertical"
android:layout_marginStart="12dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
@ -73,8 +74,8 @@
<com.gh.gamecenter.common.view.TabIndicatorView
android:id="@+id/tabIndicator"
android:layout_width="0dp"
android:layout_height="@dimen/default_tab_indicator_height"
android:layout_marginBottom="10dp"
android:layout_height="4dp"
android:layout_marginBottom="8dp"
app:indicatorColor="@color/primary_theme"
app:disableIndicatorScaling="true"
app:layout_constraintBottom_toBottomOf="parent"
@ -97,6 +98,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_marginHorizontal="8dp"
android:minWidth="44dp" />
</LinearLayout>

View File

@ -1,20 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<CheckedTextView
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/subject_tab_background_selector"
android:gravity="center"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="人气榜"
android:textAlignment="center"
android:textColor="@color/text_tabbar_style"
android:textSize="12sp" />
</LinearLayout>
android:layout_height="32dp"
android:background="@drawable/subject_tab_background_selector"
android:gravity="center"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="人气榜"
android:textAlignment="center"
android:textColor="@color/text_tabbar_style"
android:textSize="12sp" />

View File

@ -14,10 +14,4 @@
android:title="@string/menu_more"
app:showAsAction="always" />
<item
android:orderInCategory="-1"
android:title=""
app:actionLayout="@layout/layout_menu_inset"
app:showAsAction="always" />
</menu>

View File

@ -15,9 +15,14 @@ import com.tencent.vasdolly.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {
private var isInit = false
private val pendingEvent = arrayListOf<String>()
override fun init(application: Application, activity: Activity, activateRatio: Int) {
SMHelper.init(application, getChannelStr(application))
isInit = true
if (HaloApp.getInstance().isBrandNewInstall) {
logEvent("EVENT_ACTIVE")
SPUtils.setLong("TIME_OF_BRAND_NEW_INSTALL", System.currentTimeMillis() / 1000)
@ -31,6 +36,8 @@ class FlavorProviderImp : IFlavorProvider {
SPUtils.setBoolean("SHOULD_SEND_RETENTION_EVENT", false)
}
}
pendingEvent.forEach(SMHelper::onEvent)
pendingEvent.clear()
}
override fun getChannelStr(application: Application): String {
@ -43,7 +50,11 @@ class FlavorProviderImp : IFlavorProvider {
}
override fun logEvent(content: String) {
SMHelper.onEvent(content)
if (isInit) {
SMHelper.onEvent(content)
} else {
pendingEvent.add(content)
}
}
override fun logCoreEvent() {

View File

@ -7,8 +7,8 @@ ext {
targetSdkVersion = 30 // 升级targetSdkVersion到 34 时需要根据官方文档补全前台服务的权限类型。比如 NDownloadServiceKeepAliveService
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 1190
versionName = "5.42.0"
versionCode = 1195
versionName = "5.42.5"
applicationId = "com.gh.gamecenter"
applicationIdGat = "com.gh.gamecenter.intl"
@ -99,7 +99,7 @@ ext {
verifier = "1.0.6"
skeleton = "1.1.5"
mta = "6.8.0"
romChecker = "1.0.3"
romChecker = "2.0.0"
oss = "2.8.8"
desugarJdkLibs = "1.1.5"
toolargetool = "0.3.0"

View File

@ -39,7 +39,7 @@ class QaFeedbackViewModel(application: Application, private val contentId: Strin
map["source"] = HaloApp.getInstance().getString(R.string.app_name)
map["jnfj"] = getBase64EncodedIMEI()
map["manufacturer"] = Build.MANUFACTURER
map["rom"] = MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
map["rom"] = MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
val requestBody = map.toRequestBody()
RetrofitManager.getInstance().api

View File

@ -209,7 +209,7 @@ class SuggestViewModel(
"source" to getApplication<Application>().getString(R.string.app_name)
"jnfj" to getBase64EncodedIMEI()
"manufacturer" to Build.MANUFACTURER
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
"suggestion_type" to suggestType
"from" to contact
"contact_func" to contactType.value
@ -318,7 +318,7 @@ class SuggestViewModel(
"source" to getApplication<Application>().getString(R.string.app_name)
"jnfj" to getBase64EncodedIMEI()
"manufacturer" to Build.MANUFACTURER
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
"suggestion_type" to mSuggestType
"app_name" to appName
"owner_type" to copyrightIdentity

View File

@ -63,7 +63,7 @@ dependencies {
kapt "com.google.auto.service:auto-service:${autoServiceVersion}"
api "com.louiscad.splitties:splitties-views-dsl:${splitties}"
api "com.louiscad.splitties:splitties-views-dsl-constraintlayout:${splitties}"
api "com.github.nichbar:AndroidRomChecker:${romChecker}"
api "com.lg:romchecker:${romChecker}"
api "androidx.cardview:cardview:${cardView}"
api "com.google.android.material:material:${material}"
api "com.scwang.smartrefresh:SmartRefreshLayout:${smartRefreshLayout}"

View File

@ -0,0 +1,10 @@
package com.gh.gamecenter.common.entity
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
class InstalledPackagesAction(
val action: String,
val packages: List<String>,
): Parcelable

View File

@ -33,7 +33,6 @@ object MetaUtil {
private var rom: Rom? = null
fun refreshMeta() {
val appProvider = TheRouter.get(IAppProvider::class.java)
val buildConfigProvider = TheRouter.get(IBuildConfigProvider::class.java)
val userManagerProvider = TheRouter.get(IUserManagerProvider::class.java)
@ -55,7 +54,7 @@ object MetaUtil {
exposureVersion = buildConfigProvider?.getExposureVersion(),
session_id = Tracker.sessionId,
launch_id = Tracker.launchId,
rom = ""
rom = getRom().romName + " " + getRom().romVersion
)
}
@ -68,7 +67,13 @@ object MetaUtil {
}
fun getRom(): Rom {
if (rom == null) {
val appProvider = TheRouter.get(IAppProvider::class.java)
if (appProvider?.isUserAcceptPrivacyPolicy(HaloApp.getInstance()) == false) {
// 如果用户没有同意隐私政策,则返回一个默认的 Rom 对象
return Rom.create("unknown", "unknown", "unknown")
}
if (rom == null || rom?.romName == "unknown") {
rom = RomIdentifier.getRom()
}
return rom!!

View File

@ -167,20 +167,22 @@ object TrackerLogger {
}
private fun getMeta(): JSONObject {
val (_, _, model, manufacturer, _, _, android_version, network, _, gid, oaid, channel, appVersion, userId) = MetaUtil.getMeta()
val meta = MetaUtil.getMeta()
val metaObject = JSONObject()
try {
metaObject.put("dia", getBase64EncodedAndroidId())
metaObject.put("android_version", android_version)
metaObject.put("app_version", appVersion)
metaObject.put("channel", channel)
metaObject.put("gid", gid)
metaObject.put("oaid", oaid)
metaObject.put("android_version", meta.android_version)
metaObject.put("app_version", meta.appVersion)
metaObject.put("channel", meta.channel)
metaObject.put("gid", meta.gid)
metaObject.put("oaid", meta.oaid)
metaObject.put("rom", meta.rom)
metaObject.put("jnfj", getBase64EncodedIMEI())
metaObject.put("manufacturer", manufacturer)
metaObject.put("model", model)
metaObject.put("network", network)
metaObject.put("user_id", userId)
metaObject.put("manufacturer", meta.manufacturer)
metaObject.put("model", meta.model)
metaObject.put("network", meta.network)
metaObject.put("user_id", meta.userId)
} catch (e: JSONException) {
e.printStackTrace()
}

View File

@ -1494,6 +1494,26 @@ fun WebView.enableForceDark(isDarkModeOn: Boolean) {
}
}
fun WebView.loadDataCompat(data: String, mimeType: String = "text/html", encoding: String = "utf-8") {
try {
this.loadDataWithBaseURL(
null,
data,
mimeType,
encoding,
null
)
} catch (e: NullPointerException) {
this.loadDataWithBaseURL(
"localhost",
data,
"text/html",
"utf-8",
null
)
}
}
/**
* WebView是否启用强制深色模式
*/

View File

@ -52,7 +52,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
metaObject.put("oaid", appProvider.getOaid());
metaObject.put("rom", meta.getRom());
} catch (JSONException e) {
e.printStackTrace();
}
@ -71,6 +71,7 @@ public class LogUtils {
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("oaid", meta.getOaid());
metaObject.put("rom", meta.getRom());
metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
@ -79,7 +80,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("user_id", meta.getUserId());
metaObject.put("oaid", appProvider.getOaid());
metaObject.put("rom", meta.getRom());
} catch (JSONException e) {
e.printStackTrace();
}
@ -132,7 +133,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
metaObject.put("oaid", meta.getOaid());
metaObject.put("rom", meta.getRom());
object.put("event", "SHARE");
object.put("meta", metaObject);
object.put("timestamp", System.currentTimeMillis() / 1000);

View File

@ -517,7 +517,10 @@ object SensorsBridge {
downloadStatus: String,
gameType: String,
position: Int,
tabContent: String
tabContent: String,
linkType: String,
linkId: String,
linkText: String,
) {
val json = json {
KEY_GAME_ID to gameId
@ -532,6 +535,9 @@ object SensorsBridge {
KEY_GAME_TYPE to gameType
KEY_POSITION to position
KEY_TAB_CONTENT to tabContent
KEY_LINK_TYPE to linkType
KEY_LINK_ID to linkId
KEY_LINK_TEXT to linkText
}
trackEvent(EVENT_GAME_DETAIL_PAGE_TAB_SELECT, json)

View File

@ -65,6 +65,7 @@ object AppExecutor {
val cachedScheduler by lazy { Schedulers.from(ioExecutor) }
val computationScheduler by lazy { Schedulers.from(heavyWeightIoExecutor) }
val logScheduler by lazy { Schedulers.from(logExecutor) }
class MainThreadExecutor : Executor {
private val mainThreadHandler = Handler(Looper.getMainLooper())

View File

@ -49,7 +49,12 @@ data class ExposureEvent(
eTrace: List<ExposureEvent>? = null,
event: ExposureType = ExposureType.EXPOSURE
) {
val currentActivity = CurrentActivityHolder.getCurrentActivity()
val currentActivity = try {
CurrentActivityHolder.getCurrentActivity()
} catch (e: Exception) {
// 捕获异常,避免在获取当前 Activity 时出现问题
null
}
val currentActivitySimpleName = if (currentActivity != null) currentActivity::class.simpleName else "unknown"
val businessId = if (currentActivity is IBusiness) currentActivity.getBusinessId() else null

View File

@ -72,7 +72,7 @@ class RecyclerViewExposureHelper(
init {
val disposable = collectExposureSubject
.throttleLatest(SAMPLE_RATE, TimeUnit.MILLISECONDS)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
collectExposureData()
}, {

View File

@ -169,7 +169,7 @@ class Va : IVa {
LogConstants.KEY_MANUFACTURER to Build.MANUFACTURER,
LogConstants.KEY_MODEL to Build.MODEL,
LogConstants.KEY_NETWORK to (MetaUtil.getMeta().network ?: ""),
LogConstants.KEY_ROM to RomIdentifier.getRom().name + " " + RomIdentifier.getRom().versionName,
LogConstants.KEY_ROM to RomIdentifier.getRom().romName + " " + RomIdentifier.getRom().romVersion,
LogConstants.KEY_HOST_VERSION to hostVersion,
LogConstants.KEY_HOST_CHANNEL to hostChannel,
LogConstants.KEY_OAID to oaid,

2
vasdk

Submodule vasdk updated: 950989924d...16201868dd