Compare commits

..

5 Commits

43 changed files with 245 additions and 921 deletions

View File

@ -71,7 +71,7 @@ android_build:
exit_codes: 137
only:
- dev
- release
- feat/GHZSCY-5250
# 代码检查
sonarqube_analysis:
@ -152,4 +152,4 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail-jira-comment.py
only:
- dev
- release
- feat/GHZSCY-5250

View File

@ -401,7 +401,7 @@ dependencies {
implementation(project(':feature:pkg'))
implementation(project(':feature:oaid'))
implementation(project(':feature:floating-window'))
// implementation(project(':feature:csj_ad'))
implementation(project(':feature:csj_ad'))
// implementation(project(':feature:beizi_startup_ad'))
implementation(project(':feature:xapk-installer'))
implementation(project(':feature:qq_game')) {
@ -409,13 +409,12 @@ dependencies {
}
internalImplementation(project(':module_internal_test'))
// def pushProperty = findProperty('BUILD_PUSH_TYPE')
// // 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用极光推送
// def pushProject = (pushProperty == null || pushProperty == 'jg')
// ? project(':feature:jg_push') : project(':feature:acloud_push')
// implementation(pushProject) {
// exclude group: 'androidx.swiperefreshlayout'
// }
// 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用阿里云推送
def pushProject = findProperty('BUILD_PUSH_TYPE') == 'jg'
? project(':feature:jg_push') : project(':feature:acloud_push')
implementation(pushProject) {
exclude group: 'androidx.swiperefreshlayout'
}
}
File propFile = file('sign.properties')

View File

@ -191,11 +191,10 @@ object AdDelegateHelper {
}
/**
* 热启动是否需要显示开屏广告(目前只展示第三方广告)
* 热启动是否需要显示开屏广告
*/
private fun shouldShowStartUpAdWhenHotLaunch() = (mCsjAdImpl != null || mBeiziAdImpl != null)
&& mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
&& mSplashAd?.hotStartThirdPartyAd != null
private fun shouldShowStartUpAdWhenHotLaunch() =
mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK && mSplashAd?.hotStartThirdPartyAd != null
/**
* 是否需要显示下载管理广告

View File

@ -45,14 +45,6 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
isFromBackgroundToForeground = false
}
if (activityCount == 1) {
// 清除桌面角标
if (activity !is SplashScreenActivity && activity !is AuthorizationActivity) {
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
}
}
override fun onActivityResumed(activity: Activity) {
@ -92,6 +84,10 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
XapkInstaller.updateCurrentInstallStatus()
// 清除桌面角标
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
override fun onActivityPaused(activity: Activity) {

View File

@ -1,7 +1,6 @@
package com.gh.common.constant;
import android.annotation.SuppressLint;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
@ -29,7 +28,6 @@ import com.gh.gamecenter.entity.VSetting;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.utils.ContentBlockedHelper;
import com.gh.gamecenter.receiver.PackageChangeBroadcastReceiver;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
@ -333,31 +331,8 @@ public class Config {
if (mNewApiSettingsEntity.getGameShieldContents() != null) {
ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
}
// 更新安装列表是否开启的配置
// if (mNewApiSettingsEntity.getInstalledComplianceSwitch() != null) {
// PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(mNewApiSettingsEntity.getInstalledComplianceSwitch());
// } else {
// PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(false);
// }
// 更新包名监听是否开启
if (mNewApiSettingsEntity.isPackageObserveEnable()) {
observePackageChange(mNewApiSettingsEntity.getPackageObserveActions());
}
}
});
}
}
public static void observePackageChange(NewApiSettingsEntity.PackageObserveActions packageObserveActions) {
PackageChangeBroadcastReceiver receiver = new PackageChangeBroadcastReceiver(packageObserveActions);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(packageObserveActions.getAdd());
intentFilter.addAction(packageObserveActions.getRem());
intentFilter.addAction(packageObserveActions.getRep());
intentFilter.addDataScheme("package");
HaloApp.getInstance().registerReceiver(receiver, intentFilter);
}
}

View File

@ -9,12 +9,10 @@ import androidx.fragment.app.FragmentActivity
import com.gh.common.iinterface.ISuperiorChain
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.DialogEntity
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
@ -44,13 +42,12 @@ object GlobalPriorityChainHelper : ISuperiorChain {
return activity is FragmentActivity
&& !activity.isFinishing
&& activity !is SplashScreenActivity
&& activity !is SplashAdActivity
}
/**
* 预启动所有的优先级弹窗管理链
*/
fun preStart(withSpecialDelay: Boolean) {
fun preStart() {
val launchRedirectHandler = LaunchRedirectHandler(-101)
val updateDialogHandler = UpdateDialogHandler(-100)
val privacyPolicyDialogHandler = PrivacyPolicyDialogHandler(-99)
@ -67,13 +64,8 @@ object GlobalPriorityChainHelper : ISuperiorChain {
launchRedirectHandler.doPreProcess()
updateDialogHandler.doPreProcess()
// 首次启动延迟 300ms保证请求首次启动时已经获取到了 GID 、 OAID 等标记
val requestDelay = if (withSpecialDelay) 300L else 0L
AppExecutor.uiExecutor.executeWithDelay({
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
}, requestDelay)
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
}
/**
@ -131,17 +123,6 @@ object GlobalPriorityChainHelper : ISuperiorChain {
mainChain.resume()
}
/**
* 添加新的 handler 到优先级弹窗管理链 (插队!)
*/
fun queueNewHandler(handler: PriorityChainHandler) {
if (mainChain.isHandlerQueueEmpty()) {
observeLifecycle()
}
mainChain.addHandler(handler)
}
/**
* 请求首页启动弹窗相关的数据并执行相关 handler 的 preProcess
*/

View File

@ -1,28 +0,0 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.common.base.GlobalActivityManager
class RequestInstalledListPermissionHandler : PriorityChainHandler(-1000) {
init {
updateStatus(STATUS_VALID)
}
override fun onProcess(): Boolean {
val currentActivity = GlobalActivityManager.currentActivity ?: return false
if (currentActivity !is FragmentActivity) return false
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(
activity = currentActivity,
ignorePermanentlyDenied = true
) {
processNext()
}
return true
}
}

View File

@ -14,10 +14,12 @@ import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.base.activity.BaseActivity;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.login.entity.IdCardEntity;
@ -30,6 +32,8 @@ import com.halo.assistant.HaloApp;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import io.reactivex.schedulers.Schedulers;
import io.sentry.Sentry;
import io.sentry.android.core.SentryAndroid;
@ -104,51 +108,45 @@ public class DataUtils {
}
public static void getGid() {
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
String savedGid = SPUtils.getString(Constants.GID);
if (!TextUtils.isEmpty(savedGid)) {
HaloApp.getInstance().setGid(savedGid);
onGidReceived(savedGid);
} else {
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
@Override
public void onSuccess(String gid) {
Utils.log("Gid", gid);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
@Override
public void onSuccess(String gid) {
Utils.log("Gid", gid);
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
String savedGid = SPUtils.getString(Constants.GID);
if (!TextUtils.isEmpty(savedGid)) {
gid = savedGid;
} else {
SPUtils.setString(Constants.GID, gid);
onGidReceived(gid);
}
@Override
public void onFailure(String s) {
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
HaloApp.getInstance().setGid(gid);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
getDeviceCertification(gid);
// 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
MetaUtil.INSTANCE.refreshMeta();
ContentValues values = new ContentValues();
values.put(GhContentProvider.KEY_GID, gid);
values.put(GhContentProvider.KEY_ANDROID_ID, MetaUtil.getBase64EncodedAndroidId());
try {
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/device"), values);
} catch (Exception exception) {
SentryHelper.INSTANCE.onEvent("DEVICE_INSERT_ERROR", "exception_digest", exception.getLocalizedMessage());
exception.printStackTrace();
}
});
}
}
}
private static void onGidReceived(String gid) {
HaloApp.getInstance().setGid(gid);
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
getDeviceCertification(gid);
// 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
MetaUtil.INSTANCE.refreshMeta();
AppExecutor.getIoExecutor().execute(() -> {
ContentValues values = new ContentValues();
values.put(GhContentProvider.KEY_GID, gid);
values.put(GhContentProvider.KEY_ANDROID_ID, MetaUtil.getBase64EncodedAndroidId());
try {
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/device"), values);
} catch (Exception exception) {
SentryHelper.INSTANCE.onEvent("DEVICE_INSERT_ERROR", "exception_digest", exception.getLocalizedMessage());
exception.printStackTrace();
@Override
public void onFailure(String s) {
// 更新广告配置
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
}
});
}

View File

@ -1,136 +0,0 @@
package com.gh.common.util
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.gh.download.DownloadManager
import com.gh.download.PackageObserver
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
object PackageChangeHelper : DefaultLifecycleObserver {
private const val TAG = "PackageChangeHelper"
private const val INSTALL_PENDING = 1
private const val UNINSTALL_PENDING = 2
private const val UPDATE_PENDING = 3
// <包名pending 类型,应用版本> Triple
private var pendingPackagePair: Triple<String, Int, String>? = null
/**
* 添加一个等待中,待确定是否已成功安装的应用
*/
fun addInstallPendingPackage(packageName: String) {
val installData = PackagesManager.getInstalledData(packageName)
if (installData == null) {
Utils.log(TAG, "添加了: $packageName 包名等待安装成功")
pendingPackagePair = Triple(packageName, INSTALL_PENDING, "")
} else {
Utils.log(TAG, "添加了: $packageName 包名等待安装更新成功")
pendingPackagePair = Triple(packageName, UPDATE_PENDING, installData.version)
}
}
/**
* 添加一个等待中,待确定是否已成功卸载的应用
*/
fun addUninstallPendingPackage(packageName: String) {
Utils.log(TAG, "添加了: $packageName 包名等待卸载成功")
pendingPackagePair = Triple(packageName, UNINSTALL_PENDING, "")
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
if (pendingPackagePair != null) {
val packageName = pendingPackagePair?.first ?: return
val isInstallPending = pendingPackagePair?.second == INSTALL_PENDING
val isUninstallPending = pendingPackagePair?.second == UNINSTALL_PENDING
val isUpdatePending = pendingPackagePair?.second == UPDATE_PENDING
val pendingVersion = pendingPackagePair?.third ?: ""
val installedVersionName = PackageUtils.getVersionNameByPackageName(packageName)
val isInstalled = installedVersionName != null
if (isInstallPending && isInstalled) {
pendingPackagePair = null
PackageRepository.addInstalledGame(packageName)
performInstallSuccessAction(packageName)
} else if (isUninstallPending && !isInstalled) {
pendingPackagePair = null
performUninstallSuccessAction(packageName)
} else if (isUpdatePending
&& installedVersionName != pendingVersion) {
pendingPackagePair = null
performUninstallSuccessAction(packageName)
performInstallSuccessAction(packageName)
}
}
}
fun addInstall(packageName: String) {
performInstallSuccessAction(packageName)
}
/**
* 对应包名安装成功后的操作,继承至 PackageChangeBroadcastObserver
*/
private fun performInstallSuccessAction(packageName: String, withLog: Boolean = true) {
Utils.log(TAG, "安装了: $packageName 包名的程序")
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)
val gameId = if (downloadEntity != null && downloadEntity.gameId != null) downloadEntity.gameId else ""
val gameName = if (downloadEntity != null && downloadEntity.name != null) downloadEntity.name else ""
if (withLog) {
NewFlatLogUtils.logGameInstallComplete(gameId, gameName)
SensorsBridge.trackInstallGameFinish(gameId, gameName)
}
InstallUtils.getInstance().removeInstall(packageName)
PackageHelper.refreshLocalPackageList()
val versionName = PackageUtils.getVersionNameByPackageName(packageName)
val installEb = EBPackage(EBPackage.TYPE_INSTALLED, packageName, versionName)
PackageObserver.onPackageChanged(installEb)
EventBus.getDefault().post(installEb)
}
fun addUninstall(packageName: String) {
performUninstallSuccessAction(packageName)
}
/**
* 对应包名卸载成功后的操作,继承至 PackageChangeBroadcastObserver
*/
private fun performUninstallSuccessAction(packageName: String, withLog: Boolean = true) {
Utils.log(TAG, "卸载了: $packageName 包名的程序")
val install = PackagesManager.getInstalledData(packageName)
val gameId = if (install?.id != null) install.id else ""
val gameName = if (install?.name != null) install.name else ""
if (withLog) {
NewFlatLogUtils.logGameUninstallComplete(gameId!!, gameName!!)
SensorsBridge.trackUnloadGameFinish(gameId, gameName)
}
InstallUtils.getInstance().removeUninstall(packageName)
PackageHelper.refreshLocalPackageList()
val uninstallEb = EBPackage(EBPackage.TYPE_UNINSTALLED, packageName, "")
PackageObserver.onPackageChanged(uninstallEb)
EventBus.getDefault().post(uninstallEb)
}
}

View File

@ -1,6 +1,5 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
@ -8,28 +7,12 @@ import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.os.Build
import android.provider.Settings
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.constant.Config
import com.gh.common.prioritychain.GlobalPriorityChainHelper
import com.gh.common.prioritychain.RequestInstalledListPermissionHandler
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.common.utils.PermissionHelper.isGetInstalledListPermissionDisabled
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.WhitePackageListEntity
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
@ -46,15 +29,10 @@ object PackageHelper {
private const val UNSUPPORTED = 0
private const val SUPPORTED = 1
private const val ENABLED = 2
private const val DISABLED = 3
private var lastInstalledPackageListTime = 0L
private var cachedInstalledPackagesList: List<PackageInfo> = arrayListOf()
private var isGetInstalledPackagesApiAgreed = true // 用户是否已经同意使用已安装应用列表 API
private var isGetInstalledPackagesApiAgreedRequired = DISABLED // 需要用户手动授权才获取已安装应用列表的功能的开关
private var isGetInstalledPackagesPermissionSupported = UNKNOWN // 设备是否支持禁用获取已安装应用列表
private var installedPackageList: List<PackageInfo> = arrayListOf()
private var isGetInstalledPackagesApiAgreed = false
private var isGetInstalledListPermissionSupported = UNKNOWN // 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知0 代表不支持, 1 代表支持
// 评论黑名单包名列表,避免用户安装了 Xposed Installer 这样的工具,也能在包含该安装包的游戏详情页评论
private var _commentPackageNameBlackList = arrayListOf<String>()
@ -72,10 +50,6 @@ object PackageHelper {
private var _relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
val relatedPackageList: ArrayList<SettingsEntity.GameWithPackages> = _relatedPackageList
// 接口控制的已安装应用列表获取开关状态 (UI 显示)
private var _installedPackageApiSwitchStatusLiveData = MutableLiveData<Boolean>()
val installedPackageApiSwitchStatusLiveData: LiveData<Boolean> = _installedPackageApiSwitchStatusLiveData
// 本地已安装包的列表
var localPackageNameSet = hashSetOf<String>()
get() {
@ -87,22 +61,6 @@ object PackageHelper {
}
}
/**
* 获取已安装的白名单列表(为了在没有已安装应用列表获取能力的时候也能正常判断更新、插件化)
*/
@SuppressLint("CheckResult")
fun getInstalledWhiteList() {
RetrofitManager.getInstance().newApi.installWhitelist
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<WhitePackageListEntity>() {
override fun onSuccess(data: WhitePackageListEntity) {
data.data?.let {
addInstalledButMissingPackages(it)
}
}
})
}
@JvmStatic
fun refreshLocalPackageList() {
localPackageNameSet = getAllPackageName(HaloApp.getInstance().application)
@ -151,44 +109,6 @@ object PackageHelper {
lastInstalledPackageListTime = 0
}
/**
* 在超时后,若后台没有开启获取已安装应用列表的功能,默认以接口不控制的方式获取已安装应用列表
*/
fun fallbackInstalledPackageApiSwitchAfterTimeout(timeout: Long) {
CoroutineScope(SupervisorJob()).launch {
delay(timeout)
if (isGetInstalledPackagesApiAgreedRequired == UNKNOWN) {
Utils.log(TAG, "后台没有开启获取已安装应用列表的功能,超时后默认以接口不控制的方式获取已安装应用列表")
updateIsGetInstalledPackagesApiAgreedRequired(false)
}
}
}
/**
* 更新已安装应用列表获取开关状态
*/
fun updateIsGetInstalledPackagesApiAgreedRequired(isEnabled: Boolean) {
// 若状态不为 unknown 或者用户已经同意使用了,无需再更新
if (isGetInstalledPackagesApiAgreedRequired != UNKNOWN || isGetInstalledPackagesApiAgreed()) {
Utils.log(TAG, "installedPackageApiSwitchStatus 不为 UNKNOWN无需再更新")
return
}
if (isEnabled) {
getInstalledWhiteList()
_installedPackageApiSwitchStatusLiveData.postValue(true)
isGetInstalledPackagesApiAgreedRequired = ENABLED
} else {
isGetInstalledPackagesApiAgreedRequired = DISABLED
if (isSupportGetInstalledAppsPermission(HaloApp.getInstance())) {
GlobalPriorityChainHelper.queueNewHandler(RequestInstalledListPermissionHandler())
} else {
agreeOnGetInstalledPackagesApi()
}
}
}
/**
* 用户是否已经允许了调用获取已安装应用列表接口
* 优先用内存的值,没有再从 SP 中获取并更新
@ -198,18 +118,12 @@ object PackageHelper {
|| (SPUtils.getBoolean(SP_GET_INSTALLED_API_AGREED).also { isGetInstalledPackagesApiAgreed = it })
}
fun isGetInstalledPackagesApiAgreedRequired(): Boolean {
return isGetInstalledPackagesApiAgreedRequired == ENABLED
}
/**
* 同意使用已安装应用列表 API
*/
private fun agreeOnGetInstalledPackagesApi() {
fun agreeOnGetInstalledPackagesApi() {
isGetInstalledPackagesApiAgreed = true
SPUtils.setBoolean(SP_GET_INSTALLED_API_AGREED, true)
_installedPackageApiSwitchStatusLiveData.postValue(false)
}
/**
@ -218,16 +132,18 @@ object PackageHelper {
fun getInstalledPackages(context: Context?, flags: Int): List<PackageInfo> {
Utils.log(TAG, "即将获取已安装应用列表")
// Utils.log(TAG, "即将获取已安装应用列表" + Thread.currentThread().getStackTrace().contentToString().replace( ',', '\n' ))
// 用户未同意使用已安装应用列表 API返回空列表
if (!isGetInstalledPackagesApiAgreed()) {
Utils.log(TAG, "用户未同意使用已安装应用列表 API返回空列表")
return cachedInstalledPackagesList
return installedPackageList
}
// 简单 debounce 过于频繁的获取已安装应用列表调用
if (System.currentTimeMillis() - lastInstalledPackageListTime < 3000 && cachedInstalledPackagesList.isNotEmpty()) {
if (System.currentTimeMillis() - lastInstalledPackageListTime < 3000 && installedPackageList.isNotEmpty()) {
Utils.log(TAG, "使用了缓存的已安装应用列表")
return cachedInstalledPackagesList
return installedPackageList
}
var shouldGetNewInstalledPackagedList = false
@ -249,96 +165,10 @@ object PackageHelper {
if (shouldGetNewInstalledPackagedList) {
lastInstalledPackageListTime = System.currentTimeMillis()
cachedInstalledPackagesList = getInstalledPackagesInternal(context, flags)
installedPackageList = getInstalledPackagesInternal(context, flags)
}
return cachedInstalledPackagesList
}
/**
* 显示获取已安装应用列表的对话框并请求权限
*/
fun showGetInstallAppsListDialogAndRequestPermissionIfNeeded(
activity: FragmentActivity,
ignorePermanentlyDenied: Boolean = false,
resultClosure: (Boolean) -> Unit
) {
val globalOnPermissionGrantedClosure = {
agreeOnGetInstalledPackagesApi()
// 进行包名初始化相关的操作
PackageRepository.initData()
refreshLocalPackageList()
refreshList()
}
if (isSupportGetInstalledAppsPermission(activity)) {
// 若系统已经授予了获取应用列表的权限,直接进行授权成功回调
if (!isGetInstalledListPermissionDisabled(activity)) {
globalOnPermissionGrantedClosure.invoke()
resultClosure.invoke(true)
return
}
PermissionHelper.showGetInstalledAppsListPermissionDialog(
activity = activity,
requestPermission = true,
ignorePermanentlyDenied = ignorePermanentlyDenied
) { isGranted ->
if (isGranted) {
SensorsBridge.trackInstalledListPermissionsResult("成功")
globalOnPermissionGrantedClosure.invoke()
resultClosure.invoke(true)
trackInstalledListAfterDelay()
} else {
resultClosure.invoke(false)
SensorsBridge.trackInstalledListPermissionsResult("拒绝")
}
}
} else {
val hintDialog = PermissionHelper.showGetInstalledAppsListPermissionDialog(
activity = activity,
requestPermission = false,
) {
// do nothing
}
SensorsBridge.trackInstalledListPermissionsCustomDialogShow()
val noticeDialog = DialogHelper.showGuideDialog(
context = activity,
title = "权限申请",
content = "是否允许“光环助手”获取已安装的应用信息",
confirmText = "开启",
cancelText = "拒绝",
confirmClickCallback = {
SensorsBridge.trackInstalledListPermissionsCustomClick("开启")
globalOnPermissionGrantedClosure.invoke()
resultClosure.invoke(true)
trackInstalledListAfterDelay()
},
cancelClickCallback = {
resultClosure.invoke(false)
SensorsBridge.trackInstalledListPermissionsCustomClick("拒绝")
}
)
noticeDialog?.setOnDismissListener {
hintDialog?.dismiss()
}
}
}
/**
* 延迟5秒后上报已安装应用列表
*/
private fun trackInstalledListAfterDelay() {
CoroutineScope(SupervisorJob()).launch {
delay(5000)
SensorsBridge.trackNumberOfInstalledList(localPackageNameSet.size, localPackageNameSet)
}
return installedPackageList
}
/**
@ -346,8 +176,8 @@ object PackageHelper {
*/
fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
// 若存在缓存,直接返回缓存结果。
if (isGetInstalledPackagesPermissionSupported != UNKNOWN) {
return isGetInstalledPackagesPermissionSupported != UNSUPPORTED
if (isGetInstalledListPermissionSupported != UNKNOWN) {
return isGetInstalledListPermissionSupported != UNSUPPORTED
}
try {
@ -355,7 +185,7 @@ object PackageHelper {
val flag =
Settings.Secure.getInt(context.contentResolver, "oem_installed_apps_runtime_permission_enable", 0)
if (flag == 1) {
isGetInstalledPackagesPermissionSupported = SUPPORTED
isGetInstalledListPermissionSupported = SUPPORTED
return true
}
@ -364,81 +194,22 @@ object PackageHelper {
val permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (permissionInfo.protection == PermissionInfo.PROTECTION_DANGEROUS) {
isGetInstalledPackagesPermissionSupported = SUPPORTED
isGetInstalledListPermissionSupported = SUPPORTED
return true
} else {
isGetInstalledPackagesPermissionSupported = UNSUPPORTED
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
} else {
isGetInstalledPackagesPermissionSupported = UNSUPPORTED
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
} catch (e: PackageManager.NameNotFoundException) {
isGetInstalledPackagesPermissionSupported = UNSUPPORTED
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
}
/**
* 确保指定包名的应用在已安装了的情况下能正常收录
*/
fun addInstalledButMissingPackages(packageNameSet: HashSet<String>) {
Utils.log(TAG, "addInstalledButMissingPackages 检查已安装但未收录的应用")
val installedPackageNameSet: HashSet<String> = hashSetOf()
for (packageName in packageNameSet) {
if (!PackagesManager.isInstalled(packageName)
&& PackageUtils.getVersionNameByPackageName(packageName) != null
) {
installedPackageNameSet.add(packageName)
}
}
Utils.log(TAG, "addInstalledButMissingPackages 需要请求接口获取的包数量为 ${installedPackageNameSet.size}")
PackageRepository.addInstalledGames(
pkgNameList = ArrayList(installedPackageNameSet),
updateInstallStatus = true
)
}
fun refreshWrongInstallStatus(packageNameSet: MutableSet<String>) {
runOnIoThread {
Utils.log(TAG, "refreshWrongInstallStatus 检查安装状态异常的应用")
val installedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val uninstalledButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
for (packageName in packageNameSet) {
if (!PackagesManager.isInstalled(packageName)
&& PackageUtils.getVersionNameByPackageName(packageName) != null
) {
installedButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& PackageUtils.getVersionNameByPackageName(packageName) == null) {
uninstalledButKeepingWrongStatusPackageNameSet.add(packageName)
}
}
Utils.log(TAG, "refreshWrongInstallStatus 需要请求接口获取的包数量为 ${installedButKeepingWrongStatusPackageNameSet.size}")
Utils.log(TAG, "refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}")
if (installedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in installedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addInstall(packageName)
}
}
if (uninstalledButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in uninstalledButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUninstall(packageName)
}
}
}
}
/**
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632

View File

@ -108,9 +108,6 @@ object PackageInstaller {
return
}
val packageName = downloadEntity?.packageName ?: PackageUtils.getPackageNameByPath(context, pkgPath)
PackageChangeHelper.addInstallPendingPackage(packageName)
try {
// 判断是否需要使用浏览器来进行安装
if (BrowserInstallHelper.isUseBrowserToInstallEnabled()
@ -253,8 +250,6 @@ object PackageInstaller {
fun uninstallForPackageName(context: Context, pkn: String?) {
if (pkn.isNullOrEmpty()) return
PackageChangeHelper.addUninstallPendingPackage(pkn)
val uninstallIntent = Intent()
uninstallIntent.action = Intent.ACTION_DELETE
uninstallIntent.addCategory(Intent.CATEGORY_DEFAULT)

View File

@ -7,12 +7,14 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionInfo;
import android.content.pm.Signature;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.NonNull;
@ -27,6 +29,7 @@ import com.gh.common.xapk.XapkInstaller;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.PermissionHelper;
import com.gh.gamecenter.core.utils.MD5Utils;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.feature.entity.ApkEntity;
@ -45,10 +48,12 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
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;
@ -69,7 +74,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).applicationInfo.sourceDir;
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return null;
}
@ -307,7 +312,7 @@ public class PackageUtils {
return new String[]{null, null};
}
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return new String[]{null, null};
}
@ -587,7 +592,7 @@ public class PackageUtils {
.getPackageInfo(packageName, 0);
return packageInfo.firstInstallTime;
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return 0;
}
@ -614,7 +619,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager()
.getPackageInfo(BuildConfig.APPLICATION_ID, 0).lastUpdateTime;
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return 0;
@ -628,7 +633,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionName;
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return null;
}
@ -641,7 +646,7 @@ public class PackageUtils {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionCode;
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return 0;
}
@ -655,7 +660,7 @@ public class PackageUtils {
PackageManager packageManager = context.getApplicationContext().getPackageManager();
return packageManager.getApplicationIcon(packageName);
} catch (NameNotFoundException e) {
// do nothing
e.printStackTrace();
}
return null;
}

View File

@ -556,10 +556,7 @@ public class MainActivity extends BaseActivity {
} else {
TextView jumpBtn = findViewById(R.id.jumpBtn);
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - mCountdownCount));
Message newMsg = Message.obtain();
newMsg.what = COUNTDOWN_AD;
newMsg.obj = msg.obj;
mBaseHandler.sendMessageDelayed(newMsg, 1000);
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
}
}
}

View File

@ -197,15 +197,7 @@ class SplashScreenActivity : BaseActivity() {
// 尝试获取安装应用列表权限并启动首页(不在乎结果)
private fun requestGetInstallListPermissionAndLaunchMainActivity() {
if (PackageHelper.isSupportGetInstalledAppsPermission(this)
&& PermissionHelper.isGetInstalledListPermissionDisabled(this)
) {
PermissionHelper.requestGetInstalledAppsListPermission(this, true) {
launchMainActivity()
}
} else {
launchMainActivity()
}
launchMainActivity()
}
// 删除更新后的光环助手包

View File

@ -21,7 +21,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.HomePluggableHelper
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.DownloadManagerActivity
@ -277,12 +276,6 @@ class DownloadFragment : BaseFragment_TabLayout() {
if (mBinding.adGameItemContainer.isVisible) {
DownloadManager.getInstance().addObserver(mDataWatcher)
}
refreshInstallStatus()
}
private fun refreshInstallStatus() {
PackageHelper.refreshWrongInstallStatus(PackagesManager.getInstalledSet())
}
override fun onParentActivityFinish() {

View File

@ -10,8 +10,8 @@ import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.PackageHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.eventbus.EBReuse
@ -29,6 +29,7 @@ import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
@ -146,20 +147,15 @@ class NewInstalledGameFragment : ToolbarFragment() {
}
mBinding.run {
val isGetInstalledListDisagreed = PackageHelper.isGetInstalledPackagesApiAgreedRequired()
&& !PackageHelper.isGetInstalledPackagesApiAgreed()
val isGetInstalledListPermissionDisabled = PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())
if (isGetInstalledListDisagreed || isGetInstalledListPermissionDisabled) {
if (PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())) {
reuseNoneData.reuseNoneDataIv.visibility = View.GONE
reuseNoneData.reuseNoneDataTv.text = "开启应用列表权限"
reuseNoneData.reuseNoneDataDescTv.text = " 及时获悉游戏最新的更新消息"
reuseNoneData.reuseResetLoadTv.text = "去开启"
reuseNoneData.reuseResetLoadTv.setOnClickListener {
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(requireActivity()) { isGranted ->
if (isGranted) {
updateNoDataView()
}
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(requireActivity()) {
updateNoDataView()
PackageRepository.initData()
}
}
} else {

View File

@ -3,7 +3,6 @@ package com.gh.gamecenter.download
import android.view.View
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
@ -95,19 +94,18 @@ class UpdatableGameFragment : LazyFragment() {
noDataContainer.reuseResetLoadTv.layoutParams = layoutParam
noDataContainer.reuseResetLoadTv.visibility = View.VISIBLE
noDataContainer.reuseNoneDataDescTv.visibility = View.VISIBLE
val isGetInstalledListDisagreed = !PackageHelper.isGetInstalledPackagesApiAgreed()
val isGetInstalledListPermissionDisabled = PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())
if (isGetInstalledListDisagreed || isGetInstalledListPermissionDisabled) {
if (PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())) {
noDataContainer.reuseNoneDataIv.visibility = View.GONE
noDataContainer.reuseNoneDataTv.text = "开启应用列表权限"
noDataContainer.reuseNoneDataDescTv.text = "及时获悉游戏最新的更新消息"
noDataContainer.reuseResetLoadTv.text = "去开启"
noDataContainer.reuseResetLoadTv.setOnClickListener {
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(requireActivity()) { isGranted ->
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(
requireActivity()
) { isGranted ->
if (isGranted) {
updateNoDataView()
PackageRepository.initData()
}
}
}

View File

@ -11,12 +11,6 @@ class NewApiSettingsEntity(
var startup: StartupAdEntity? = null,//启动文案广告
@SerializedName("user_interested_game")
var userInterestedGame: Boolean = false, //偏好设置状态开关
@SerializedName("installed_compliance_switch")
var installedComplianceSwitch: Boolean? = false, //安装合规开关
@SerializedName("listen_switch")
var isPackageObserveEnable: Boolean = false, // 安装包监听开关
@SerializedName("listen_str")
var packageObserveActions: PackageObserveActions? = null, // 安装包监听的三个 action
var install: Install, // 安装相关的
@SerializedName("game_shield_contents")
var gameShieldContents: List<String>? = listOf(),//游戏屏蔽内容
@ -52,13 +46,4 @@ class NewApiSettingsEntity(
val type: String,
val link: LinkEntity
)
class PackageObserveActions(
@SerializedName("ADD")
val add: String,
@SerializedName("REM")
val rem: String,
@SerializedName("REP")
val rep: String
)
}

View File

@ -1,5 +0,0 @@
package com.gh.gamecenter.entity
class WhitePackageListEntity {
var data: HashSet<String>? = null
}

View File

@ -17,9 +17,11 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager.widget.ViewPager
import com.gh.common.browse.BrowseTimer
import com.gh.common.util.DirectUtils
import com.gh.common.browse.withLifecycle
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.TrackableDialog
import com.gh.gamecenter.common.base.adapter.FragmentAdapter
@ -72,6 +74,7 @@ class CommunityHomeFragment : LazyFragment() {
private var mBottomTabId = ""
private val browseTimer = BrowseTimer()
.withLifecycle(this)
.withResult {
SensorsBridge.trackCommunityBrowsingDuration(it / 1000.0)
}
@ -199,14 +202,13 @@ class CommunityHomeFragment : LazyFragment() {
mBottomTabId = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_ID, "") ?: ""
}
override fun onResume() {
super.onResume()
browseTimer.start()
}
override fun onPause() {
super.onPause()
browseTimer.stop()
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
browseTimer.start()
} else {
browseTimer.stop()
}
}
override fun onSaveInstanceState(outState: Bundle) {

View File

@ -798,8 +798,6 @@ class GameCollectionDetailFragment :
}
}, 2000)
}
mListViewModel.refreshPackageStatus()
}
override fun onPause() {

View File

@ -10,7 +10,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.ErrorHelper
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.Constants
@ -65,8 +64,6 @@ open class GameCollectionDetailViewModel(
var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
var isPostFirstOver = false
private var packageNameSet = hashSetOf<String>()
@SuppressLint("CheckResult")
fun getGameCollectionDetail() {
mApi.getGameCollectionDetail(gameCollectionId)
@ -131,17 +128,10 @@ open class GameCollectionDetailViewModel(
add(mResultLiveData.value!![i])
}
} else {
packageNameSet = hashSetOf()
games?.forEach {
it.isAdData = adIconActive
add(CommentItemData(game = it))
it.getApk().forEach { apk ->
packageNameSet.add(apk.packageName)
}
}
refreshPackageStatus()
}
}
@ -168,12 +158,6 @@ open class GameCollectionDetailViewModel(
override fun getHandleTopCommentCondition(index: Int) =
!isHandleTopComment && gameCollectionDetail != null && topCommentId.isNotBlank() && index == 0
fun refreshPackageStatus() {
if (packageNameSet.isNotEmpty()) {
PackageHelper.refreshWrongInstallStatus(packageNameSet)
}
}
fun followingCommand(userId: String, isFollow: Boolean) {
val observable = if (isFollow) {
RetrofitManager.getInstance().api.postFollowing(userId)

View File

@ -2399,8 +2399,6 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
DownloadManager.getInstance().addObserver(dataWatcher)
controlInstallHint()
mViewModel.refreshWrongInstallStatus()
}
override fun onFragmentPause() {

View File

@ -14,8 +14,8 @@ import com.gh.common.history.HistoryHelper
import com.gh.common.util.CheckLoginUtils
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.common.util.LibaoUtils
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.livedata.NonStickyMutableLiveData
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
@ -184,7 +184,6 @@ class GameDetailViewModel(
}
}
refreshWrongInstallStatus()
filterGameTags(data)
filterBlockedContent(data)
replaceWithMirrorInfoIfNeeded(data)
@ -257,14 +256,6 @@ class GameDetailViewModel(
}
}
fun refreshWrongInstallStatus() {
val packageNameSet = hashSetOf<String>()
game?.getApk()?.forEach {
packageNameSet.add(it.packageName)
}
PackageHelper.refreshWrongInstallStatus(packageNameSet)
}
private fun replaceWithMirrorInfoIfNeeded(data: NewGameDetailEntity) {
// 获取镜像相关数据,不存在时不替换
val mirrorData = getMirrorData(data) ?: return

View File

@ -168,8 +168,10 @@ class CustomHomeItemGameTestV2ViewHolder(
} else {
RIGHT_TEXT_MORE
}
if (tvRight.text.isBlank()) {
tvRight.text = rightText
}
tvRight.text = rightText
tvRight.setOnClickListener {
if (data.rightTop.text == ALL) {
NewFlatLogUtils.logGameTestV2MoreClick(rightText, "自定义页面")

View File

@ -7,7 +7,6 @@ import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.entity.GameUpdateEntity
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
/**
* todo 整理部分与[PackageUtils]冲突的方法
@ -19,11 +18,11 @@ object PackagesManager {
private val mInstalledList = ArrayList<GameInstall>()
// 实时更新(已安装到本地的包名列表,不包括畅玩游戏)
private val mInstalledPkgSet = Collections.synchronizedSet(HashSet<String>())
private val mInstalledPkgList = Collections.synchronizedList(ArrayList<String>())
fun initInstallPkgSet(set: Set<String>) {
mInstalledPkgSet.clear()
mInstalledPkgSet.addAll(set)
fun initInstallPkgList(list: List<String>) {
mInstalledPkgList.clear()
mInstalledPkgList.addAll(list)
}
/**
@ -87,11 +86,9 @@ object PackagesManager {
return false
}
return mInstalledPkgSet.contains(packageName)
return mInstalledPkgList.contains(packageName)
}
fun getInstalledSet(): MutableSet<String> = HashSet(mInstalledPkgSet)
/**
* 根据包名版本号判断是否已安装相应版本的应用
*

View File

@ -1,14 +1,12 @@
package com.gh.gamecenter.packagehelper
import android.annotation.SuppressLint
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
import com.gh.gamecenter.entity.PackageFilter
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
object PackageFilterManager {
@ -79,20 +77,11 @@ object PackageFilterManager {
if (appendOnly) {
mPendingPackageNameSet.addAll(packageList)
} else {
if (exception is retrofit2.HttpException && exception.code() == 403) {
// 403 代表 key 过期,需要重新获取
callbackClosure?.invoke(arrayListOf())
return
}
// 接口访问失败时从数据库读取上一次缓存的已安装收录列表进行更新
val packageEntityList =
AppDatabase.getInstance().packageFilterDao().getAllPackageName()
for (packageEntity in packageEntityList) {
// 依然为已安装状态才加入到有效包名列表中
if (PackageUtils.isInstalled(HaloApp.getInstance(), packageEntity.packageName)) {
mValidPackageNameSet.add(packageEntity.packageName)
}
mValidPackageNameSet.add(packageEntity.packageName)
}
callbackClosure?.invoke(ArrayList(mValidPackageNameSet))

View File

@ -20,9 +20,9 @@ import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.livedata.Event
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
@ -30,7 +30,6 @@ import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import org.json.JSONObject
import java.util.*
@ -55,7 +54,7 @@ object PackageRepository {
private const val LAST_UPLOAD_APPLIST_TIME = "last_upload_applist_time"
private const val PAGE_SIZE = 50
private val mInstalledPkgSet = Collections.synchronizedSet(HashSet<String>())
private val mInstalledPkgList = Collections.synchronizedList(ArrayList<String>())
@Volatile
private var mIsInitialisingData = false
@ -87,7 +86,7 @@ object PackageRepository {
if (gameInstalled.isNotEmpty()) gameInstalled.clear()
if (mInstalledGameList.isNotEmpty()) mInstalledGameList.clear()
if (gameUpdate.isNotEmpty()) gameUpdate.clear()
if (mInstalledPkgSet.isNotEmpty()) mInstalledPkgSet.clear()
if (mInstalledPkgList.isNotEmpty()) mInstalledPkgList.clear()
val list = PackageUtils.getAllPackageName(mApplication)
@ -96,7 +95,7 @@ object PackageRepository {
initFilterPackage(list) { filteredList ->
mIsInitialisingData = false
mInstalledPkgSet.addAll(filteredList)
mInstalledPkgList.addAll(filteredList)
notifyInstallPkgData()
loadInstalledGameDigestAndNotifyData(filteredList)
@ -204,14 +203,12 @@ object PackageRepository {
* @param filteredList 已安装的游戏包名集合 (仅已收录部分)
* @param onWorkerThreadOnly 是否在工作线程执行
* @param isVGame 包名列表是否为畅玩游戏
* @param updateInstallStatus 更新安装状态 (通过 EventBus 来进行)
*/
@SuppressLint("CheckResult")
private fun loadInstalledGameDigestAndNotifyData(
filteredList: ArrayList<String>,
onWorkerThreadOnly: Boolean = false,
isVGame: Boolean = false,
updateInstallStatus: Boolean = false
) {
var isNotifyUpdate = false
val maxPageCount = (filteredList.size / PAGE_SIZE) + 1
@ -246,7 +243,9 @@ object PackageRepository {
for (game in validGames) {
if (gh_id == null || gh_id == game.id) {
gameInstalled.add(GameInstall.transformGameInstall(game, pkgName, isVGame))
gameInstalled.add(
GameInstall.transformGameInstall(game, pkgName, isVGame)
)
mInstalledGameList.add(game)
val isCanPluggable = checkGamePlugin(game, pkgName)
val isCanUpdate = checkGameUpdate(game, isVGame)
@ -254,10 +253,6 @@ object PackageRepository {
if (!isNotifyUpdate && isCanUpdate || isCanPluggable) {
isNotifyUpdate = true
}
if (updateInstallStatus) {
EventBus.getDefault().post(EBPackage(EBPackage.TYPE_INSTALLED, pkgName, game.getApk().firstOrNull()?.version))
}
}
}
}
@ -405,18 +400,14 @@ object PackageRepository {
* 新增已安装的游戏
* @param pkgName 已安装的游戏包名
*/
fun addInstalledGame(pkgName: String, updateInstallStatus: Boolean = false) {
mInstalledPkgSet.add(pkgName)
fun addInstalledGame(pkgName: String) {
mInstalledPkgList.add(pkgName)
notifyInstallPkgData()
val list = arrayListOf(pkgName)
updateFilterPackage(list) {
loadInstalledGameDigestAndNotifyData(
filteredList = list,
onWorkerThreadOnly = true,
updateInstallStatus = updateInstallStatus
)
loadInstalledGameDigestAndNotifyData(list, true)
}
changeRecentVaPlayed()
}
@ -424,29 +415,18 @@ object PackageRepository {
/**
* 批量新增已安装的游戏数量
* @param pkgNameList 数组列表
* @param isVGame 是否为畅玩游戏
* @param updateInstallStatus 是否更新安装状态
*/
fun addInstalledGames(pkgNameList: ArrayList<String>,
isVGame: Boolean = false,
updateInstallStatus: Boolean = false,
) {
fun addInstalledGames(pkgNameList: ArrayList<String>, isVGame: Boolean = false) {
// 畅玩游戏不添加至本地的已安装包名列表中
if (!isVGame) {
mInstalledPkgSet.addAll(pkgNameList)
} else {
changeRecentVaPlayed()
mInstalledPkgList.addAll(pkgNameList)
}
notifyInstallPkgData()
updateFilterPackage(pkgNameList) {
loadInstalledGameDigestAndNotifyData(
filteredList = pkgNameList,
onWorkerThreadOnly = true,
isVGame = isVGame,
updateInstallStatus = updateInstallStatus
)
loadInstalledGameDigestAndNotifyData(pkgNameList, true, isVGame)
}
changeRecentVaPlayed()
}
/**
@ -455,8 +435,9 @@ object PackageRepository {
* @param isVGame 是否来自于畅玩游戏
*/
fun addUninstalledGame(pkgName: String, isVGame: Boolean) {
if (!isVGame && mInstalledPkgSet.isNotEmpty()) {
mInstalledPkgSet.remove(pkgName)
// TODO 检查为什么会有两个相同的包名添加到 mInstalledPkgList 里
if (!isVGame && mInstalledPkgList.isNotEmpty()) {
mInstalledPkgList.removeAll { it == pkgName }
}
// 尝试从临时的当前版本列表里移除已卸载的条目
tryCatchInRelease {
@ -512,7 +493,7 @@ object PackageRepository {
}
private fun notifyInstallPkgData() {
PackagesManager.initInstallPkgSet(mInstalledPkgSet)
PackagesManager.initInstallPkgList(mInstalledPkgList)
}
}

View File

@ -16,11 +16,11 @@ import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.feature.entity.GameInstall;
import com.gh.gamecenter.install.InstallService;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.ndownload.NDownloadService;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.utils.Utils;
@ -29,26 +29,21 @@ import org.greenrobot.eventbus.EventBus;
import java.util.Locale;
/**
* 监听安装包变更
*/
public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "PackageChangeBroadcastReceiver";
/**
* 监听应用安装和卸载的广播
*
* @author LGT 黄壮华
*/
public class InstallAndUninstallReceiver extends BroadcastReceiver {
private static final String webviewPackageName = "com.google.android.webview";
private final NewApiSettingsEntity.PackageObserveActions mActions;
public PackageChangeBroadcastReceiver(NewApiSettingsEntity.PackageObserveActions actions) {
mActions = actions;
}
@Override
public void onReceive(Context context, Intent intent) {
PackageHelper.INSTANCE.dumpInstalledListCache();
ExtensionsKt.doOnMainProcessOnly(() -> {
Utils.log(TAG, "onReceive->" + intent.getAction() + "==" + intent.getDataString());
Utils.log("InstallAndUninstallReceiver:: onReceive->" + intent.getAction() + "==" + intent.getDataString());
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU
&& Build.MANUFACTURER.toLowerCase(Locale.CHINA).contains("xiaomi")) {
@ -58,10 +53,10 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
}
// 接收安装广播
if (intent.getAction().equals(mActions.getAdd())) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
String packageName = intent.getDataString();
packageName = packageName.substring(packageName.indexOf(":") + 1);
Utils.log(TAG, "安装了:" + packageName + "包名的程序");
Utils.log("安装了:" + packageName + "包名的程序");
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName);
String gameId = downloadEntity != null && downloadEntity.getGameId() != null ? downloadEntity.getGameId() : "";
String gameName = downloadEntity != null && downloadEntity.getName() != null ? downloadEntity.getName() : "";
@ -89,10 +84,10 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
}
// 接收卸载广播
if (intent.getAction().equals(mActions.getRem())) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
String packageName = intent.getDataString();
packageName = packageName.substring(packageName.indexOf(":") + 1);
Utils.log(TAG, "卸载了:" + packageName + "包名的程序");
Utils.log("卸载了:" + packageName + "包名的程序");
GameInstall install = PackagesManager.getInstalledData(packageName);
String gameId = install != null && install.getId() != null ? install.getId() : "";
String gameName = install != null && install.getName() != null ? install.getName() : "";
@ -112,10 +107,10 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
}
// 接收替换广播
if (intent.getAction().equals(mActions.getRep())) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
String packageName = intent.getData().getSchemeSpecificPart();
packageName = packageName.substring(packageName.indexOf(":") + 1);
Utils.log(TAG, "替换了:" + packageName + "包名的程序");
Utils.log("替换了:" + packageName + "包名的程序");
String versionName = PackageUtils.getVersionNameByPackageName(packageName);
EBPackage updateEb = new EBPackage(EBPackage.TYPE_REPLACED, packageName, versionName);

View File

@ -93,7 +93,6 @@ import com.gh.gamecenter.entity.VideoDraftEntity;
import com.gh.gamecenter.entity.VideoEntity;
import com.gh.gamecenter.entity.VideoTagEntity;
import com.gh.gamecenter.entity.VoteEntity;
import com.gh.gamecenter.entity.WhitePackageListEntity;
import com.gh.gamecenter.feature.entity.AnswerEntity;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.ArticleDraftEntity;
@ -785,9 +784,6 @@ public interface ApiService {
@Query("systemVersion") int systemVersion,
@Query("ghVersion") String ghVersion);
@GET("/settings/game_installed/whitelist")
Single<WhitePackageListEntity> getInstallWhitelist();
/**
* 给一个回答新增评论
*/

View File

@ -148,8 +148,6 @@ class SearchGameIndexFragment : ListFragment<GameEntity, SearchGameResultViewMod
super.onResume()
DownloadManager.getInstance().addObserver(dataWatcher)
mListViewModel.refreshWrongInstallStatus()
}
override fun onPause() {

View File

@ -331,8 +331,6 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
override fun onResume() {
super.onResume()
DownloadManager.getInstance().addObserver(dataWatcher)
mListViewModel.refreshWrongInstallStatus()
}
override fun onPause() {

View File

@ -6,7 +6,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.ad.AdDelegateHelper
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.ListViewModel
@ -46,8 +45,6 @@ class SearchGameResultViewModel(
private var mAdPositionSet: HashSet<Int>? = null
private val mAdGameMap = ConcurrentHashMap<String, List<GameEntity>>()
private var mPackageNameSet = hashSetOf<String>()
fun updateSearchKeyWithType(searchKey: String, searchType: String) {
mSearchKey = searchKey
mSearchType = searchType
@ -70,18 +67,6 @@ class SearchGameResultViewModel(
SearchItemData(game = game, isFirst = index == 0)
}
)
mPackageNameSet = hashSetOf()
// 添加所有出现的游戏包名
list.forEach {
it.getApk().forEach { apk ->
mPackageNameSet.add(apk.packageName)
}
}
refreshWrongInstallStatus()
repository.getSearchSubject(mSearchKey, mPage)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -182,12 +167,6 @@ class SearchGameResultViewModel(
}
}
fun refreshWrongInstallStatus() {
if (mPackageNameSet.isNotEmpty()) {
PackageHelper.refreshWrongInstallStatus(mPackageNameSet)
}
}
private fun decorateListWithThirdPartyAdOnly(
decoratedItemDataList: ArrayList<SearchItemData>,
thirdPartyAdList: List<AdConfig>,

View File

@ -10,6 +10,7 @@ import androidx.annotation.ColorRes
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.text.color
import androidx.core.view.doOnNextLayout
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.R
@ -27,6 +28,7 @@ import com.gh.gamecenter.databinding.FragmentMainBinding
import com.gh.gamecenter.databinding.PieceBottomTabBinding
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.login.entity.UserInfoEntity
import com.gh.gamecenter.packagehelper.PackageRepository
import com.halo.assistant.HaloApp
import com.lightgame.listeners.OnBackPressedListener
import org.greenrobot.eventbus.EventBus
@ -65,6 +67,8 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
setCurrentItem(mViewModel!!.defaultBottomTabIndex)
}
}
PackageRepository.addInstalledGame("com.woobest.sgwg.aligames")
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -81,13 +85,8 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
updateRealNameErrorContainer()
}
PackageHelper.installedPackageApiSwitchStatusLiveData.observe(viewLifecycleOwner) {
if (it) {
showInstallApiHintView(mBinding)
SensorsBridge.trackInstalledListPermissionsDialogShow()
} else {
mBinding.installApiContainer.visibility = View.GONE
}
if (!PackageHelper.isGetInstalledPackagesApiAgreed()) {
showInstallApiHintView(mBinding)
}
}
@ -281,22 +280,53 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
binding.installApiContentTv.text = contentText
binding.installApiCloseIv.setOnClickListener {
binding.installApiContainer.visibility = View.GONE
SensorsBridge.trackInstalledListPermissionsClick("关闭")
}
binding.installApiBtn.setOnClickListener {
SensorsBridge.trackInstalledListPermissionsClick("去开启")
val grantedClosure = {
binding.installApiContainer.visibility = View.GONE
PackageHelper.agreeOnGetInstalledPackagesApi()
// 进行包名初始化相关的操作
val callbackClosure: (Boolean) -> Unit = { isGranted ->
if (isGranted) {
binding.installApiContainer.visibility = View.GONE
}
PackageRepository.initData()
PackageHelper.refreshLocalPackageList()
PackageHelper.refreshList()
}
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(
activity = requireActivity(),
ignorePermanentlyDenied = false,
resultClosure = callbackClosure
)
if (PackageHelper.isSupportGetInstalledAppsPermission(requireContext())) {
// 若系统已经授予了获取应用列表的权限,直接进行授权成功回调
if (!PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())) {
grantedClosure.invoke()
return@setOnClickListener
}
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(requireContext() as FragmentActivity) { isGranted ->
// TODO 处理回调,上报日志等
if (isGranted) {
grantedClosure.invoke()
} else {
// TODO 处理拒绝权限的情况
}
}
} else {
val hintDialog = PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(requireContext() as FragmentActivity) {
// do nothing
}
val noticeDialog = DialogHelper.showDialog(
context = requireContext(),
title = "权限申请",
content = "是否允许“光环助手”获取已安装的应用信息",
confirmText = "开启",
cancelText = "拒绝",
confirmClickCallback = {
grantedClosure.invoke()
}
)
noticeDialog?.setOnDismissListener {
hintDialog?.dismiss()
}
}
}
}

View File

@ -3,6 +3,7 @@ package com.halo.assistant;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.net.ConnectivityManager;
@ -38,12 +39,10 @@ import com.gh.common.util.DownloadNotificationHelper;
import com.gh.common.util.DownloadObserver;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
import com.gh.common.util.PackageChangeHelper;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.SignatureRepository;
import com.gh.common.videolog.VideoRecordUtils;
import com.gh.download.DownloadManager;
import com.gh.download.simple.DownloadMessageHandler;
import com.gh.download.simple.SimpleDownloadDatabase;
import com.gh.gamecenter.BuildConfig;
@ -73,6 +72,7 @@ import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.gamecenter.provider.FlavorProviderImp;
import com.gh.gamecenter.receiver.ActivitySkipReceiver;
import com.gh.gamecenter.receiver.DownloadReceiver;
import com.gh.gamecenter.receiver.InstallAndUninstallReceiver;
import com.gh.gamecenter.receiver.InstallReceiver;
import com.gh.gamecenter.receiver.NetworkStateReceiver;
import com.gh.gamecenter.wrapper.MainWrapperRepository;
@ -80,8 +80,6 @@ import com.gh.vspace.VHelper;
import com.github.piasy.biv.BigImageViewer;
import com.github.piasy.biv.loader.fresco.FrescoImageLoader;
import com.lg.ndownload.DownloadCore;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.utils.Utils;
import com.llew.huawei.verifier.LoadedApkHuaWei;
import com.shuyu.gsyvideoplayer.cache.CacheFactory;
@ -121,7 +119,7 @@ public class HaloApp extends MultiDexApplication {
public boolean isSkippingThirdParty = false; // 应用是否处于跳转第三方Activity状态
private List<String> webViewAbiList;
private final IFlavorProvider mFlavorProvider = new FlavorProviderImp();
private IFlavorProvider mFlavorProvider = new FlavorProviderImp();
private final ServiceLoader<IApplication> mApplicationList = ServiceLoader.load(IApplication.class, this.getClass().getClassLoader());
private LunchType mLaunchType = null;
@ -332,9 +330,6 @@ public class HaloApp extends MultiDexApplication {
// 获取 settings 配置
com.gh.common.constant.Config.getGhzsSettings();
// 5 秒获取后台配置的获取应用列表限制接口结果超时后,回落到关闭状态
// PackageHelper.INSTANCE.fallbackInstalledPackageApiSwitchAfterTimeout(5000L);
String localTemporaryDeviceId = SPUtils.getString(Constants.SP_TEMPORARY_DEVICE_ID);
if (!TextUtils.isEmpty(localTemporaryDeviceId)) {
HaloApp.getInstance().setLocalTemporaryDeviceId(localTemporaryDeviceId);
@ -344,7 +339,7 @@ public class HaloApp extends MultiDexApplication {
// 必须放在外面,否则不能及时刷新用户数据
UserRepository.getInstance().getLoginUserInfo();
GlobalPriorityChainHelper.INSTANCE.preStart(isNewForThisVersion);
GlobalPriorityChainHelper.INSTANCE.preStart();
MainWrapperRepository.Companion.getInstance().getDataUnion();
@ -371,9 +366,6 @@ public class HaloApp extends MultiDexApplication {
// 初始化畅玩相关数据
retrieveVGameInfoIfNeeded();
// 移除已安装但还在本地数据库中的包(避免因为没有监听到安装结果导致安装包没有删除的问题)
removeInstalledButRemainedPackages();
// 开发环境不要强制捕获相关异常,这些异常通常是需要处理的
if (!BuildConfig.DEBUG) {
RxJavaPlugins.setErrorHandler(throwable -> {
@ -504,7 +496,13 @@ public class HaloApp extends MultiDexApplication {
}
private void initPackageChangesReceiver() {
ProcessLifecycleOwner.get().getLifecycle().addObserver(PackageChangeHelper.INSTANCE);
InstallAndUninstallReceiver receiver = new InstallAndUninstallReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
this.registerReceiver(receiver, intentFilter);
}
private void initConnectivityChangesReceiver() {
@ -576,32 +574,6 @@ public class HaloApp extends MultiDexApplication {
VHelper.init(this);
}
/**
* 移除已安装但还在本地数据库中的包
*/
private void removeInstalledButRemainedPackages() {
AppExecutor.getIoExecutor().execute(() -> {
for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntity()) {
if (downloadEntity.getStatus() != DownloadStatus.done) {
continue;
}
try {
String versionName = downloadEntity.getVersionName();
String packageName = downloadEntity.getPackageName();
// 这里暴力删除会影响畅玩游戏快速安装功能,但先不管了
if (versionName != null
&& packageName != null
&& versionName.equals(PackageUtils.getVersionNameByPackageName(packageName))) {
DownloadManager.getInstance().cancel(downloadEntity.getUrl());
}
} catch (Exception ignored) {
// 不在乎删除的结果,尝试即可
}
}
});
}
public boolean isReinstallTheSameVersion() {
return mIsReinstallTheSameVersion;
}
@ -635,6 +607,12 @@ public class HaloApp extends MultiDexApplication {
return mFlavorProvider;
}
// @NonNull
// @Override
// public Configuration getWorkManagerConfiguration() {
// return new Configuration.Builder().build();
// }
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);

View File

@ -7,8 +7,8 @@ ext {
targetSdkVersion = 30
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 1051
versionName = "5.35.1"
versionCode = 1050
versionName = "5.35.0"
applicationId = "com.gh.gamecenter"
applicationIdGat = "com.gh.gamecenter.intl"
@ -129,7 +129,7 @@ ext {
documentfile = "1.0.1"
csjVersion = "5.8.0.4.0"
csjVersion = "5.6.2.0"
qGameVersion = "1.57.14"
qGameAdVersion = "4.520.1390"

View File

@ -72,19 +72,18 @@ object CsjAdHelper {
*/
override fun getDevOaid(): String = oaid
})
.build())
.build(),
object : TTVfSdk.InitCallback {
override fun success() {
Utils.log(TAG, "穿山甲初始化成功")
mIsInitialed = true
}
TTVfSdk.start(object : TTVfSdk.Callback {
override fun success() {
Utils.log(TAG, "穿山甲初始化成功")
mIsInitialed = true
}
override fun fail(p0: Int, p1: String?) {
Utils.log(TAG, "穿山甲初始化失败, $p0 $p1")
mIsInitialed = false
}
})
override fun fail(p0: Int, p1: String?) {
Utils.log(TAG, "穿山甲初始化失败, $p0 $p1")
mIsInitialed = false
}
})
}
fun updateThemeStatus(isDarkMode: Boolean) {
@ -125,8 +124,8 @@ object CsjAdHelper {
}
mTTVfNative.loadSphVs(adSlot, object : TTVfNative.CSJSplashAdListener {
override fun onSplashLoadSuccess(p0: CSJSplashAd?) {
Utils.log(TAG, "开屏广告加载成功 $p0")
override fun onSplashLoadSuccess() {
Utils.log(TAG, "开屏广告加载成功")
}
override fun onSplashLoadFail(p0: CSJAdError?) {
@ -200,7 +199,7 @@ object CsjAdHelper {
.setCodeId(slotId) // 广告位id
.setSupportDeepLink(true)
.setAdCount(1) // 请求广告数量为1到3条
.setExpressViewAcceptedSize(expressViewAcceptedSize, 0F) // 期望模板广告view的size,宽度最低为375单位dp
.setExpressViewAcceptedSize(expressViewAcceptedSize, 96F) // 期望模板广告view的size,宽度最低为375单位dp
.setAdLoadType(TTAdLoadType.LOAD) // 推荐使用,用于标注此次的广告请求用途为预加载(当做缓存)还是实时加载,方便后续为开发者优化相关策略
.build()

View File

@ -32,12 +32,6 @@
</intent-filter>
</service>
<provider
android:name="cn.jpush.android.service.InitProvider"
android:authorities="${applicationId}.jiguang.InitProvider"
android:exported="false"
tools:node="remove" />
</application>
</manifest>

View File

@ -18,10 +18,8 @@ import android.text.Spanned
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Window
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.R
@ -51,7 +49,6 @@ object PermissionHelper {
@SuppressLint("CheckResult")
fun requestGetInstalledAppsListPermission(
activity: FragmentActivity,
ignorePermanentlyDenied: Boolean = false,
resultCallback: (Boolean) -> Unit
) {
try {
@ -69,12 +66,6 @@ object PermissionHelper {
}
else -> {
// 忽略永久拒绝的提示跳转响应
if (ignorePermanentlyDenied) {
resultCallback.invoke(false)
return@subscribe
}
if (SPUtils.getBoolean(Constants.SP_USER_HAS_PERMANENTLY_DENIED_GET_INSTALL_LIST_PERMISSION)) {
showPermissionPermanentlyDeniedDialog(
activity = activity,
@ -256,10 +247,8 @@ object PermissionHelper {
/**
* 展示获取已安装列表权限提示弹窗并请求权限
*/
fun showGetInstalledAppsListPermissionDialog(
fun showGetInstalledAppsListPermissionDialogAndRequestPermission(
activity: FragmentActivity,
requestPermission: Boolean,
ignorePermanentlyDenied: Boolean = false,
resultCallback: (Boolean) -> Unit
): Dialog? {
val solidContext = activity as? Activity ?: AppManager.getInstance().currentActivity() ?: return null
@ -267,10 +256,6 @@ object PermissionHelper {
val binding = DialogExternalStoragePermissionIntroBinding.inflate(LayoutInflater.from(solidContext))
binding.container.updateLayoutParams<FrameLayout.LayoutParams> {
height = 100F.dip2px()
}
val spannableBuilder = SpannableStringBuilder("当您使用APP时以下场景向您申请已安装列表权限\n")
val liStringList = arrayListOf("游戏更新提醒")
@ -296,15 +281,13 @@ object PermissionHelper {
dialog.window?.setGravity(Gravity.TOP)
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.show()
if (requestPermission) {
requestGetInstalledAppsListPermission(activity, ignorePermanentlyDenied) { isGranted ->
resultCallback.invoke(isGranted)
dialog.dismiss()
}
requestGetInstalledAppsListPermission(activity) { granted ->
resultCallback.invoke(granted)
dialog.dismiss()
}
dialog.show()
return dialog
}
@ -429,7 +412,7 @@ object PermissionHelper {
cancelText = "放弃",
confirmText = "去授权",
cancelClickCallback = null,
confirmClickCallback = { requestGetInstalledAppsListPermission(context, false, resultCallback) },
confirmClickCallback = { requestGetInstalledAppsListPermission(context, resultCallback) },
extraConfig = DialogHelper.Config(hint = HINT_CHECK_USAGE),
uiModificationCallback = {
it.hintTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme))

View File

@ -103,8 +103,6 @@ object SensorsBridge {
private const val KEY_LINK_CONTENT_COLLECTIONE_PATTERN = "link_content_collectione_pattern"
private const val KEY_COLUMN_COLLECTIONE_PATTERN = "column_collectione_pattern"
private const val KEY_SEQUENCE = "sequence"
private const val KEY_NUMBER = "number"
private const val KEY_APP_LIST = "app_list"
private const val EVENT_GAME_DETAIL_PAGE_TAB_SELECT = "GameDetailPageTabSelect"
@ -218,13 +216,6 @@ object SensorsBridge {
private const val EVENT_SUSPENDED_WINDOW_SHOW = "SuspendedWindowShow"
private const val EVENT_SUSPENDED_WINDOW_CLICK = "SuspendedWindowClick"
private const val EVENT_INSTALLED_LIST_PERMISSIONS_DIALOG_SHOW = "InstalledListPermissionsDialogShow"
private const val EVENT_INSTALLED_LIST_PERMISSIONS_CLICK = "InstalledListPermissionsClick"
private const val EVENT_INSTALLED_LIST_PERMISSIONS_CUSTOM_DIALOG_SHOW = "InstalledListPermissionsCustomDialogShow"
private const val EVENT_INSTALLED_LIST_PERMISSIONS_CUSTOM_CLICK = "InstalledListPermissionsCustomClick"
private const val EVENT_INSTALLED_LIST_PERMISSIONS_RESULT = "InstalledListPermissionsResult"
private const val EVENT_NUMBER_OF_INSTALLED_LIST = "NumberOfInstalledList"
private var mIsSensorsEnabled = false
private val mSensor by lazy {
@ -3524,73 +3515,4 @@ object SensorsBridge {
}
trackEvent(EVENT_SUSPENDED_WINDOW_CLICK, json)
}
/**
* 事件IDInstalledListPermissionsDialogShow
* 事件名称:已安装列表权限提示条展示事件
* 触发时机: 授权提示条展示时触发 提示条在底部TAB主页面常驻各TAB切换时不重复上报展示事件
*/
fun trackInstalledListPermissionsDialogShow() {
trackEvent(EVENT_INSTALLED_LIST_PERMISSIONS_DIALOG_SHOW)
}
/**
* 事件IDInstalledListPermissionsClick
* 事件名称:已安装列表权限提示条点击事件
* 触发时机:点击对应按钮时触发上报
*/
fun trackInstalledListPermissionsClick(btnName: String) {
val json = json {
KEY_BUTTON_NAME to btnName
}
trackEvent(EVENT_INSTALLED_LIST_PERMISSIONS_CLICK, json)
}
/**
* 事件IDInstalledListPermissionsCustomDialogShow
* 事件名称:已安装列表权限自定义弹窗展示事件
* 触发时机:自定义授权提示弹窗展示时触发
*/
fun trackInstalledListPermissionsCustomDialogShow() {
trackEvent(EVENT_INSTALLED_LIST_PERMISSIONS_CUSTOM_DIALOG_SHOW)
}
/**
* 事件IDInstalledListPermissionsCustomClick
* 事件名称:已安装列表权限自定义弹窗点击事件
* 触发时机:点击对应按钮时触发上报
*/
fun trackInstalledListPermissionsCustomClick(btnName: String) {
val json = json {
KEY_BUTTON_NAME to btnName
}
trackEvent(EVENT_INSTALLED_LIST_PERMISSIONS_CUSTOM_CLICK, json)
}
/**
* 事件IDInstalledListPermissionsResult
* 事件名称:已安装列表权限获取结果事件
* 触发时机1、用户点击已安装列表自定义弹窗“开启”后上报权限获取的结果
* 2、用户点击授权提示条“去开启”后上报权限获取的结果
*/
fun trackInstalledListPermissionsResult(result: String) {
val json = json {
KEY_RESULT to result
}
trackEvent(EVENT_INSTALLED_LIST_PERMISSIONS_RESULT, json)
}
/**
* 事件IDNumberOfInstalledList
* 事件名称:已安装列表数量
* 触发时机客户端检测到获取已安装列表权限5s上报所读取到的已安装应用的数量
*/
fun trackNumberOfInstalledList(number: Int, packageSet: Set<String>) {
val json = json {
KEY_NUMBER to number
KEY_APP_LIST to packageSet
}
trackEvent(EVENT_NUMBER_OF_INSTALLED_LIST, json)
}
}

View File

@ -6,7 +6,6 @@
android:background="@color/transparent">
<FrameLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"

View File

@ -401,9 +401,9 @@ data class GameEntity(
@IgnoredOnParcel
var name: String?
get() = if (shouldUseMirrorInfo()) {
obtainMirrorData()?.mName?.removeSuffix(".") ?: "mirror unknown"
obtainMirrorData()?.mName?.removeSuffix(".")
} else {
mName?.removeSuffix(".") ?: "unknown"
mName?.removeSuffix(".")
}
set(value) {
mName = value