Compare commits

..

13 Commits

152 changed files with 4131 additions and 2183 deletions

4
.gitignore vendored
View File

@ -9,4 +9,6 @@ build/
release-app/
test-app/
scripts/apk-channel/
app/src/test/java/com/gh/gamecenter
app/src/test/java/com/gh/gamecenter
app/src/main/assets-debug/
app/src/main/assets-release/

View File

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

6
.gitmodules vendored
View File

@ -5,6 +5,12 @@
[submodule "vspace-bridge"]
path = vspace-bridge
url = ../../../cwzs/android/vspace-bridge.git
[submodule "module_common/src/debug/assets/assistant-android-mock"]
path = module_common/src/debug/assets/assistant-android-mock
url = ../../../halo/android/assistant-android-mock.git
[submodule "ndownload"]
path = ndownload
url = ../../../android/ndownload.git
[submodule "vasdk"]
path = vasdk
url = ../../../sdg/android/vasdk.git

View File

@ -75,7 +75,7 @@ android {
versionName rootProject.ext.versionName
applicationId rootProject.ext.applicationId
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt', rootProject.ext.va_proguard_rules
String CORE_EVENT_GAME_CATEGORY = ""
@ -164,6 +164,15 @@ android {
flavorDimensions("env", "region")
sourceSets {
debug {
assets.srcDirs += 'src/main/assets-debug'
}
release {
assets.srcDirs += 'src/main/assets-release'
}
publish {
java.srcDirs = ['src/main/java', "src/default/java"]
}
@ -368,7 +377,7 @@ dependencies {
kapt "com.alibaba:arouter-compiler:$arouterVersion"
implementation project(':ndownload')
implementation project(':vspace-bridge:vspace')
implementation project(':vspace-bridge')
implementation (project(':module_common')) {
exclude group: 'androidx.swiperefreshlayout'
@ -408,13 +417,22 @@ dependencies {
exclude group: 'androidx.swiperefreshlayout'
}
internalImplementation(project(':module_internal_test'))
// 根据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'
}
implementation(project(":va-lib"))
implementation(project(':va-main')) {
exclude group: 'androidx.swiperefreshlayout'
}
debugImplementation "com.bytedance.tools.codelocator:codelocator-core:2.0.3"
compileOnly project(":va-core")
compileOnly project(":va-plugin-host-lib")
implementation project(":va-plugin-host")
implementation project(":va-archive")
}
File propFile = file('sign.properties')

View File

@ -1,32 +1,79 @@
package com.gh.vspace
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.Keep
import com.gh.gamecenter.R
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.LayoutPersonalOtherItemBinding
import com.gh.vspace.installexternalgames.InstallExternalGameActivity
import com.lg.vspace.VaApp
import com.lg.vspace.plugin.host.PluginHelper
import com.lightgame.utils.Utils
import com.lightgame.utils.toast.ToastHelper
import com.lody.virtual.client.core.VirtualCore
import java.io.File
@Keep
class ExternalGameUsage : IExternalGamesUsage {
override fun addInstallExternalGameButton(viewParent: ViewGroup) {
class ExternalGameUsage : ITestCase {
private fun buttonTemplate(viewParent: ViewGroup, id: Int, fn: (LayoutPersonalOtherItemBinding) -> Unit) {
val context = viewParent.context
viewParent.findViewById<View>(R.id.install_game_from_external) ?: run {
viewParent.findViewById<View>(id) ?: run {
val binding = LayoutPersonalOtherItemBinding.inflate(LayoutInflater.from(context)).apply {
root.id = R.id.install_game_from_external
titleTv.text = context.getString(R.string.title_install_external_game)
iconIv.setImageResource(R.drawable.ic_personal_my_game)
root.setOnClickListener {
VHelper.connectService {
context.startActivity(
InstallExternalGameActivity.getIntent(context)
.apply { flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK })
}
}
root.id = id
fn(this)
}
viewParent.addView(binding.root, 0)
}
}
override fun addInstallExternalGameButton(viewParent: ViewGroup) {
val context = viewParent.context
buttonTemplate(viewParent, R.id.install_game_from_external) {
it.titleTv.text = context.getString(R.string.title_install_external_game)
it.iconIv.setImageResource(R.drawable.ic_personal_my_game)
it.root.setOnClickListener {
VHelper.connectService {
context.startActivity(
InstallExternalGameActivity.getIntent(context)
.apply { flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK })
}
}
}
}
override fun addInstallPluginButton(viewParent: ViewGroup) {
buttonTemplate(viewParent, R.id.install_plugin) {
it.titleTv.text = "安装64位插件"
it.root.setOnClickListener {
val file = File("/data/local/tmp/gh-plugins/artifacts.zip")
if (file.exists()) {
Utils.log(VHelper.LOG_TAG, "有本地更新文件: 64位插件")
// TODO: 补充debug插件更新
ToastUtils.showToast("暂未实现debug功能")
} else {
ToastUtils.showToast("data/local/tmp没有push文件")
}
}
}
}
override fun addInstallPlugin32Button(viewParent: ViewGroup) {
buttonTemplate(viewParent, R.id.install_plugin_32) {
it.titleTv.text = "安装32位插件"
it.root.setOnClickListener {
val file = File("/data/local/tmp/gh-plugins/artifacts32.zip")
if (file.exists()) {
// TODO: 补充debug插件更新
ToastUtils.showToast("暂未实现debug功能")
} else {
ToastUtils.showToast("data/local/tmp没有push文件")
}
}
}
}
}

View File

@ -25,6 +25,11 @@ class ExternalGameAdapter(private val games: List<ExternalGameUiState>, private
路径:${item.apkPath}
""".trimIndent()
}
holder.update.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)
}
holder.install.goneIf(item.isInstalled) {
holder.install.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)

View File

@ -8,4 +8,5 @@ class ExternalGameViewHolder(binding: LayoutExternalGameItemBinding) : RecyclerV
val install = binding.btnInstall
val uninstall = binding.btnUninstall
val start = binding.btnStart
val update = binding.btnUpdate
}

View File

@ -16,6 +16,7 @@ import com.gh.gamecenter.databinding.FragmentInstallExternalGamesBinding
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.VirtualAppManager
import com.lightgame.download.DownloadEntity
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@ -105,6 +106,15 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
private fun install(externalGameUiState: ExternalGameUiState) {
val bit =
externalGameUiState.externalGameEntity.cpuAbi.let { if (it.size == 1 && it.contains("armeabi-v7a")) "32" else "64" }
VHelper.install(requireContext(), DownloadEntity().apply {
externalGameUiState.externalGameEntity.apply {
packageName = apkPackageName
path = apkPath
}
}, true)
if (VHelper.showDialogIfVSpaceIsNeeded(
requireContext(),
"",
@ -144,7 +154,9 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
com.gh.gamecenter.BuildConfig.VERSION_NAME,
HaloApp.getInstance().channel,
"",
""
"",
com.lg.core.BuildConfig.VERSION_NAME,
HaloApp.getInstance().oaid
)
requireActivity().startActivity(intent)
}

View File

@ -24,6 +24,14 @@
android:visibility="gone"
tools:visibility="visible" />
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_update"
android:visibility="visible"
tools:visibility="visible" />
<Button
android:id="@+id/btn_uninstall"
android:layout_width="wrap_content"

View File

@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="install_game_from_external" type="id" />
<item name="install_plugin" type="id" />
<item name="install_plugin_32" type="id" />
</resources>

View File

@ -2,6 +2,7 @@
<resources>
<string name="title_install_external_game">从SD卡安装</string>
<string name="text_install">安装</string>
<string name="text_update">更新</string>
<string name="text_uninstall">卸载</string>
<string name="text_start">启动</string>
</resources>

View File

@ -11,12 +11,6 @@
<package android:name="com.lg.vspace" />
</queries>
<!-- 华为/荣耀角标 -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE "/>
<uses-permission android:name="com.hihonor.android.launcher.permission.CHANGE_BADGE" />
<!-- vivo角标 -->
<uses-permission android:name="com.vivo.notification.permission.BADGE_ICON" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- 允许应用程序访问网络连接 -->
@ -92,7 +86,30 @@
com.tencent.qqmini,
com.tencent.qqmini.minigame.external,
com.tencent.qqmini.minigame.opensdk,
com.tencent.qqmini.union.ad" />
com.tencent.qqmini.union.ad,
com.lg.vspace,
io.lg.va.common,
com.va.floating,
com.lg.cloud,
com.lg.archive,
com.lg.vclient,
com.va.realname,
com.lg.vspace.flavor,
com.lg.update,
com.lg.login,
com.lg.accelerator,
com.lody.virtual,
com.lg.core,
com.lg.ads,
com.lg.common,
com.lg.vspace.network,
com.lody.virtual.lib.res,
com.va.host,
com.lg.vspace.plugin.host,
com.lg.plugin.constant,
com.bytedance.tools.codelocator,
org.chickenhook.restrictionbypass,
com.lody.virtual.sandhook,com.lg.vspace.common" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -783,7 +800,8 @@
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />

View File

@ -6,6 +6,8 @@
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="video-js.min.css">
<!-- <link rel="stylesheet" href="https://static-web.ghzs.com/website-static/lib/video-js.min.css">--> <!--在web页面播放视频-->
<!--<link rel="stylesheet" type="text/css" href="https://resource.ghzs.com/css/halo_app.css">-->
</head>
<body style="overflow-x: hidden; word-break: break-all;">
@ -13,5 +15,8 @@
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="rich_editor.js"></script>
<script type="text/javascript" src="video.min.js"></script>
<!--<script src="https://static-web.ghzs.com/website-static/lib/video.min.js"></script>--> <!--在web页面播放视频-->
<!--<script type="text/javascript" src="content.js"></script>-->
<!--<script type="text/javascript" src="https://resource.ghzs.com/js/halo_app.js"></script>-->
</body>
</html>

View File

@ -34,18 +34,18 @@ try {
var script = document.createElement("script")
document.body.appendChild(script)
if (isDebug) {
script.src = "https://dev-and-static.ghzs66.com/web/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
script.src = "https://resource.ghzs.com/js/halo_app_test.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
script.src = "https://and-static.ghzs66.com/web/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
script.src = "https://resource.ghzs.com/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
var style = document.createElement("link")
style.rel = "stylesheet"
style.type = "text/css"
if (isDebug) {
style.href = "https://dev-and-static.ghzs66.com/web/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
style.href = "https://resource.ghzs.com/css/halo_app_test.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
style.href = "https://and-static.ghzs66.com/web/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
style.href = "https://resource.ghzs.com/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
document.head.appendChild(style)

View File

@ -203,6 +203,10 @@ object AdDelegateHelper {
return mDownloadManagerAd != null && !isMatchAdFreeRule(mDownloadManagerAd) && isMatchDownloadManagerAdDisplayRule()
}
fun shouldShowHelperLaunchAd(): Boolean {
return mVGameLaunchAd != null && !isMatchAdFreeRule(mVGameLaunchAd) && isMatchAdDisplayRule(mVGameLaunchAd, Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME)
}
/**
* 是否需要显示游戏搜索广告
*/
@ -247,10 +251,11 @@ object AdDelegateHelper {
/**
* 是否大于广告管理展示间隔时长
*/
private fun isMatchDownloadManagerAdDisplayRule(): Boolean {
mDownloadManagerAd?.displayRule?.run {
private fun isMatchDownloadManagerAdDisplayRule(): Boolean = isMatchAdDisplayRule(mDownloadManagerAd, Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME)
private fun isMatchAdDisplayRule(adConfig: AdConfig?, spKey: String): Boolean {
adConfig?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, 0L)
val lastShowTime = SPUtils.getLong(spKey, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {

View File

@ -0,0 +1,44 @@
package com.gh.ad
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.lg.vspace.ui.launcher.ILaunchAd
@Route(path = RouteConsts.provider.vaAd, name = "畅玩启动页广告")
class LaunchAdImpl : ILaunchAd {
override fun init(context: Context?) {
}
override fun requestAd(fragment: Fragment, container: ViewGroup, maskView: View) {
if (AdDelegateHelper.shouldShowHelperLaunchAd()) {
val launchAd = AdDelegateHelper.vGameLaunchAd
val showThirdPartyAd = launchAd?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_SDK
val thirdPartyAd = launchAd?.thirdPartyAd
if (showThirdPartyAd && thirdPartyAd != null) {
AdDelegateHelper.requestThirdPartyBannerAd(
fragment,
container,
thirdPartyAd,
DisplayUtils.getScreenWidthInDp(fragment.requireActivity()),
) { isSuccess ->
maskView.goneIf(!isSuccess)
if (isSuccess) {
SPUtils.setLong(Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME, System.currentTimeMillis())
}
}
}
}
}
}

View File

@ -4,7 +4,6 @@ import android.app.Activity
import android.app.Application
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.FloatingBackViewManager
import com.gh.common.xapk.XapkInstaller
@ -15,11 +14,12 @@ import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.authorization.AuthorizationActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.gamecenter.feedback.view.suggest.SuggestionActivity
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.ui.launcher.LaunchActivity
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
@ -40,6 +40,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
&& activity !is SplashAdActivity
&& activity !is SuggestionActivity
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
@ -76,6 +77,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
if (activity is AppCompatActivity
&& activity !is LaunchActivity
&& activity !is LoginActivity
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
@ -84,10 +87,6 @@ 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

@ -45,6 +45,7 @@ import com.gh.gamecenter.login.user.LoginTag
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.gh.gamecenter.login.utils.LoginHelper
import com.gh.gamecenter.login.utils.QuickLoginHelper
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
import com.gh.gamecenter.setting.SettingBridge
@ -129,12 +130,12 @@ class DefaultJsApi(
@JavascriptInterface
fun login(msg: Any) {
// if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
// QuickLoginHelper.startLogin(context, "浏览器")
// } else {
if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
QuickLoginHelper.startLogin(context, "浏览器")
} else {
val intent = LoginActivity.getIntent(context, "浏览器")
context.startActivity(intent)
// }
}
}
@JavascriptInterface
@ -219,7 +220,7 @@ class DefaultJsApi(
runOnUiThread {
// 若畅玩列表中安装了,优先启动畅玩游戏
if (VHelper.isInstalled(packageName)) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "", "", "")) {
VHelper.validateVSpaceBeforeAction(context, packageName, null) {
VHelper.launch(context, packageName)
}
} else {

View File

@ -16,7 +16,7 @@ class ValidateVSpaceHandler : DownloadChainHandler() {
}
if (asVGame) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
closure.invoke()
}
} else {

View File

@ -21,14 +21,17 @@ import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.AppEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
import com.gh.gamecenter.entity.VNewSetting;
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.retrofit.RetrofitManager;
import com.gh.gamecenter.retrofit.service.VApiService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
@ -39,8 +42,12 @@ import org.json.JSONObject;
import java.io.IOException;
import java.util.Locale;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;
import okhttp3.ResponseBody;
public class Config {
@ -57,7 +64,8 @@ public class Config {
public static final String WEIBO_APPKEY = BuildConfig.WEIBO_APPKEY;
public static final String QUICK_LOGIN_APPID = BuildConfig.QUICK_LOGIN_APPID;
public static final String QUICK_LOGIN_APPKEY = BuildConfig.QUICK_LOGIN_APPKEY;
public static final String URL_ARTICLE = "www.ghzs666.com/article/"; // ghzs/ghzs666 统一
// http://www.ghzs666.com/article/${articleId}.html
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
private static final String SETTINGS_KEY = "settingsKey";
@ -68,6 +76,10 @@ public class Config {
private static NewApiSettingsEntity.NightMode mNightModeSetting;
private static SimulatorEntity mNewSimulatorEntity;
private static VSetting mVSetting;
private static VNewSetting mVNewSetting;
private static AppEntity mNew32UpdateEntity;
public static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
private static GameGuidePopupEntity mGameGuidePopupEntity;
private static SharedPreferences mDefaultSharedPreferences;
@ -94,7 +106,8 @@ public class Config {
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
PackageHelper.refreshList();
// 加载完设置后刷新下
PackageHelper.initList();
}
@Nullable
@ -195,6 +208,27 @@ public class Config {
return mVSetting;
}
@Nullable
public static VNewSetting getVNewSettingEntity() {
if (mVNewSetting == null) {
try {
String json = SPUtils.getString(Constants.SP_V_NEW_SETTINGS);
if (!TextUtils.isEmpty(json)) {
mVNewSetting = GsonUtils.fromJson(json, VNewSetting.class);
vNewSettingSubject.onNext(mVNewSetting);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return mVNewSetting;
}
@Nullable
public static AppEntity getNew32UpdateEntity() {
return mNew32UpdateEntity;
}
/**
* 请求网络数据,尝试刷新畅玩相关配置
*/
@ -215,6 +249,36 @@ public class Config {
});
}
@SuppressLint("CheckResult")
public static void getNewSetting() {
VApiService vApi = RetrofitManager.getInstance().getVApi();
vApi.getNewSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT).flatMap(new Function<VNewSetting, SingleSource<AppEntity>>() {
@Override
public SingleSource<AppEntity> apply(VNewSetting data) throws Exception {
mVNewSetting = data;
vNewSettingSubject.onNext(mVNewSetting);
SPUtils.setString(Constants.SP_V_NEW_SETTINGS, GsonUtils.toJson(data));
if (data.getVa() != null && data.getVa().getArch32() != null) {
String versionNameByPackageName = PackageUtils.getVersionNameByPackageName(data.getVa().getArch32().getPackageName());
return vApi.getNewPackageUpdate(
BuildConfig.VERSION_NAME,
versionNameByPackageName != null ? versionNameByPackageName : "",
HaloApp.getInstance().getChannel()
);
}
return Single.error(new IllegalStateException("VNewSetting entity is not expected"));
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<AppEntity>() {
@Override
public void onSuccess(AppEntity data) {
mNew32UpdateEntity = data;
}
});
}
@Nullable
public static GameGuidePopupEntity getGameGuidePopupEntity() {
return mGameGuidePopupEntity;
@ -269,6 +333,7 @@ public class Config {
});
refreshVSettingEntity();
getNewSetting();
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)

View File

@ -19,7 +19,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
@ -60,7 +59,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private val mDuration = 3000
private var mDisposable: Disposable? = null
private var mAdapter: PackageCheckAdapter? = null
private var mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
private var mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
@ -326,7 +325,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onResume() {
super.onResume()
mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
gameEntity?.packageDialog?.let {
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
callBack?.onConfirm()
@ -364,7 +363,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if (busFour.isInstalledOrUninstalled()) {
mAllInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
mAdapter?.notifyDataSetChanged()
}
}
@ -417,7 +416,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
return
}
val allInstalledPackages = PackageHelper.getInstalledPackages(HaloApp.getInstance().application, 0)
val allInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
callBack.onConfirm()
return

View File

@ -8,6 +8,7 @@ import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IFlavorProvider
import com.halo.assistant.HaloApp
import com.va.host.HostUtils
@Route(path = RouteConsts.provider.app, name = "Application暴露服务")
class AppProviderImpl : IAppProvider {
@ -86,4 +87,6 @@ class AppProviderImpl : IAppProvider {
override fun setSkippingThirdParty(isSkippingThirdParty: Boolean) {
HaloApp.getInstance().isSkippingThirdParty = isSkippingThirdParty
}
override fun getPluginVersion(): String = HostUtils.getPluginVersion()
}

View File

@ -22,6 +22,34 @@ class DirectProviderImpl : IDirectProvider {
DirectUtils.directToQqConversation(context, qq)
}
override fun directToCommodityDetail(context: Context, commodityId: String) {
DirectUtils.directToCommodityDetail(context, commodityId)
}
override fun directToEnergyRecord(context: Context) {
DirectUtils.directToEnergyRecord(context)
}
override fun directToEnergyRulePage(context: Context) {
DirectUtils.directToEnergyRulePage(context)
}
override fun directToInviteFriends(context: Context) {
DirectUtils.directToInviteFriends(context)
}
override fun directToExchangeRulePage(context: Context) {
DirectUtils.directToExchangeRulePage(context)
}
override fun directToExchangeCommodityPage(context: Context) {
DirectUtils.directToExchangeCommodityPage(context)
}
override fun directToLotteryParadisePage(context: Context) {
DirectUtils.directToLotteryParadisePage(context)
}
override fun directDouyin(context: Context, userId: String) {
DirectUtils.directDouyin(context, userId)
}
@ -69,6 +97,26 @@ class DirectProviderImpl : IDirectProvider {
DirectUtils.directToAmway(context, fixedTopAmwayCommentId, entrance, path)
}
override fun directToOrderCenter(context: Context) {
DirectUtils.directToOrderCenter(context)
}
override fun directToOrderDetail(context: Context, orderId: String) {
DirectUtils.directToOrderDetail(context, orderId)
}
override fun directToEnergyRecord(context: Context, position: Int) {
DirectUtils.directToEnergyRecord(context, position)
}
override fun directToMyPrizePage(context: Context) {
DirectUtils.directToMyPrizePage(context)
}
override fun directToWinOrderDetail(context: Context, orderId: String, activityId: String) {
DirectUtils.directToWinOrderDetail(context, orderId, activityId)
}
override fun directToQGame(context: Context) {
return DirectUtils.directToQGameHome(context)
}

View File

@ -3,7 +3,6 @@ package com.gh.common.provider
import android.content.Context
import android.content.pm.PackageInfo
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
@ -24,7 +23,7 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
}
override fun getInstalledPackages(context: Context, flag: Int): List<PackageInfo> {
return PackageHelper.getInstalledPackages(context, flag)
return PackageUtils.getInstalledPackages(context, flag)
}
override fun getApkSignatureByPackageName(context: Context, packageName: String): Array<String> {
@ -39,10 +38,6 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
return PackageUtils.isSignedByGh(context, packageName)
}
override fun isInstalledWithLauncherIcon(context: Context, packageName: String): Boolean {
return PackageUtils.isInstalled(context, packageName)
}
override fun getInstalledTime(context: Context, packageName: String): Long {
return PackageUtils.getInstalledTime(context, packageName)
}

View File

@ -166,160 +166,162 @@ class SimulatorDownloadManager private constructor() {
this.gameName = gameName
this.gameType = gameCategoryChinese
PermissionHelper.checkGetInstalledAppsListBeforeAction(context) { _ ->
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
//当没有安装新版本模拟器时候 判断是否隐藏
if (simulator?.active == false && !isInstalledNewSimulator) {
showNoneEmulatorDialog(context)
return@checkGetInstalledAppsListBeforeAction
}
var isInstalled = PackageUtils.isInstalledFromAllPackage(
context,
simulator?.apk?.packageName
)
//模拟器管理界面还是用之前的逻辑
if (isInstalledNewSimulator && location != SimulatorLocation.SIMULATOR_MANAGE) {
isInstalled = isInstalledNewSimulator
}
PermissionHelper.checkGetInstalledAppsListBeforeAction(context, object : EmptyCallback {
override fun onCallback() {
val isInstalledNewSimulator =
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
//当没有安装新版本模拟器时候 判断是否隐藏
if (simulator?.active == false && !isInstalledNewSimulator) {
showNoneEmulatorDialog(context)
return
}
var isInstalled = PackageUtils.isInstalledFromAllPackage(
context,
simulator?.apk?.packageName
)
//模拟器管理界面还是用之前的逻辑
if (isInstalledNewSimulator && location != SimulatorLocation.SIMULATOR_MANAGE) {
isInstalled = isInstalledNewSimulator
}
// val versionFromInstalledApp = PackageUtils.getVersionNameByPackageName(simulator?.apk?.packageName)
val shouldShowUpdate =
PackageUtils.isInstalledApkMatchedMd5(simulator?.apk?.packageName, simulator?.apk?.md5)
val showAlertTag = SPUtils.getString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, "") //当天是否弹过
val todayIsShow = showAlertTag == TimeUtils.getToday()
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
if (downloadType == "update" && todayIsShow && location != SimulatorLocation.SIMULATOR_MANAGE) {
return@checkGetInstalledAppsListBeforeAction
}
if (downloadType == "download" && isInstalled) {
return@checkGetInstalledAppsListBeforeAction
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
val trackableEntity = TrackableEntity(
"模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
val shouldShowUpdate =
PackageUtils.isInstalledApkMatchedMd5(simulator?.apk?.packageName, simulator?.apk?.md5)
val showAlertTag = SPUtils.getString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, "") //当天是否弹过
val todayIsShow = showAlertTag == TimeUtils.getToday()
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
if (downloadType == "update" && todayIsShow && location != SimulatorLocation.SIMULATOR_MANAGE) {
return
}
if (downloadType == "download" && isInstalled) {
return
}
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
val message =
if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
val positiveText =
if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size}" else "下载(${simulator?.apk?.size}"
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
val trackableEntity = TrackableEntity(
"模拟器下载",
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
logShowEvent = true
)
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
message,
positiveText,
negativeText,
trackMtaEvent = true,
cancelClickCallback = {
if (shouldShowUpdate && isInstalled) {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
if (shouldShowUpdate && isInstalled) {
NewFlatLogUtils.logSimulatorUpdateAlertShow()
}
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
} else {
SensorsBridge.trackSimulatorInstallDialogShow(
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
DialogHelper.showDialog(
context,
title,
message,
positiveText,
negativeText,
trackMtaEvent = true,
cancelClickCallback = {
if (shouldShowUpdate && isInstalled) {
cancelCallback?.invoke()
NewFlatLogUtils.logSimulatorUpdateAlertClick("取消")
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = negativeText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
trackableEntity.key,
if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载"
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
if (downloadType == "update" && location != SimulatorLocation.SIMULATOR_MANAGE) {
SPUtils.setString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, TimeUtils.getToday())
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = positiveText,
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
if (downloadType == "update" && location != SimulatorLocation.SIMULATOR_MANAGE) {
SPUtils.setString(SimulatorGameManager.SIMULATOR_UPDATE_SHOW_ALERT_TAG, TimeUtils.getToday())
}
}
}
})
}
fun showDownloadingDialog(

View File

@ -50,8 +50,6 @@ object ArchiveDownloadButtonHelper {
}
downloadBtn.setOnClickListener {
when {
// 检查是否已安装畅玩助手
!VHelper.isVSpaceInstalled(context) -> showVSpaceTipDialog(context, gameEntity)
// 检查是否已安装游戏
!VHelper.isInstalled(packageName) -> {
// 检查游戏是否在安装中

View File

@ -1,11 +1,17 @@
package com.gh.common.util;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.core.utils.CurrentActivityHolder;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
import com.gh.gamecenter.login.view.LoginActivity;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.login.user.UserManager;
import com.lightgame.utils.Utils;
@ -22,15 +28,15 @@ public class CheckLoginUtils {
LogUtils.login("dialog", null, entrance);
LogUtils.login("activity", null, entrance);
// if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
// startQuickLogin(context, entrance);
// } else {
// 有可能App未启动
Bundle bundle = new Bundle();
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
bundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivity(context, bundle);
// }
if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
startQuickLogin(context, entrance);
} else {
// 有可能App未启动
Bundle bundle = new Bundle();
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
bundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivity(context, bundle);
}
} else {
if (listener != null) {
listener.onLogin();
@ -38,16 +44,16 @@ public class CheckLoginUtils {
}
}
// private static void startQuickLogin(Context context, String entrance) {
// // 需要确保传入的 context 不为 application
// if (!(context instanceof Activity)) {
// context = CurrentActivityHolder.getCurrentActivity();
// }
//
// if (context != null) {
// QuickLoginHelper.startLogin(context, entrance);
// }
// }
private static void startQuickLogin(Context context, String entrance) {
// 需要确保传入的 context 不为 application
if (!(context instanceof Activity)) {
context = CurrentActivityHolder.getCurrentActivity();
}
if (context != null) {
QuickLoginHelper.startLogin(context, entrance);
}
}
public static void checkLogin(final Context context, Bundle nextToBundle, boolean isTriggerNextStep, String entrance, OnLoginListener listener) {
if (!isLogin()) {

View File

@ -1625,6 +1625,211 @@ object DirectUtils {
jumpActivityCompat(context, newBundle)
}
/**
* 跳转至商品详情
*/
@JvmStatic
fun directToCommodityDetail(context: Context, commodityId: String) {
var url: String = if (EnvHelper.isDevEnv) {
Constants.COMMODITY_DETAIL_ADDRESS_DEV
} else {
Constants.COMMODITY_DETAIL_ADDRESS
}
url = String.format(
Locale.CHINA,
"%s&shopid=%s&timestamp=%d",
url,
commodityId,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至光能记录默认跳到光能记录第一个Tab
*/
@JvmStatic
fun directToEnergyRecord(context: Context) {
directToEnergyRecord(context, 0)
}
@JvmStatic
fun directToEnergyRecord(context: Context, position: Int) {
var url: String = if (EnvHelper.isDevEnv) {
Constants.ENERGY_RECORD_ADDRESS_DEV
} else {
Constants.ENERGY_RECORD_ADDRESS
}
url = String.format(
Locale.CHINA,
"%s&position=%s&timestamp=%d",
url,
position,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至订单中心
*/
@JvmStatic
fun directToOrderCenter(context: Context) {
val url: String = if (EnvHelper.isDevEnv) {
Constants.ORDER_CENTER_ADDRESS_DEV
} else {
Constants.ORDER_CENTER_ADDRESS
}
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至订单详情
*/
@JvmStatic
fun directToOrderDetail(context: Context, orderId: String) {
var url: String = if (EnvHelper.isDevEnv) {
Constants.ORDER_DETAIL_ADDRESS_DEV
} else {
Constants.ORDER_DETAIL_ADDRESS
}
url = String.format(
Locale.CHINA,
"%s&order_id=%s&timestamp=%d",
url,
orderId,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至邀请好友
*/
@JvmStatic
fun directToInviteFriends(context: Context) {
val url: String = if (EnvHelper.isDevEnv) {
Constants.INVITE_FRIENDS_ADDRESS_DEV
} else {
Constants.INVITE_FRIENDS_ADDRESS
}
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至等级页面
*/
@JvmStatic
fun directToLevelPage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.LEVEL_ADDRESS
} else {
Constants.LEVEL_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s?timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至兑换规则
*/
@JvmStatic
fun directToExchangeRulePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.EXCHANGE_RULE_ADDRESS
} else {
Constants.EXCHANGE_RULE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至光能规则
*/
@JvmStatic
fun directToEnergyRulePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.ENERGY_RULE_ADDRESS
} else {
Constants.ENERGY_RULE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至兑换商品
*/
@JvmStatic
fun directToExchangeCommodityPage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.EXCHANGE_COMMODITY_ADDRESS
} else {
Constants.EXCHANGE_COMMODITY_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至抽奖乐园
*/
@JvmStatic
fun directToLotteryParadisePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.LOTTERY_PARADISE_ADDRESS
} else {
Constants.LOTTERY_PARADISE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至我的奖品
*/
@JvmStatic
fun directToMyPrizePage(context: Context) {
var url: String = if (isPublishEnv()) {
Constants.MY_PRIZE_ADDRESS
} else {
Constants.MY_PRIZE_ADDRESS_DEV
}
url = String.format(Locale.CHINA, "%s&timestamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至中奖订单详情
*/
@JvmStatic
fun directToWinOrderDetail(context: Context, orderId: String, activityId: String) {
var url: String = if (isPublishEnv()) {
Constants.WIN_ORDER_DETAIL_ADDRESS
} else {
Constants.WIN_ORDER_DETAIL_ADDRESS_DEV
}
url = String.format(
Locale.CHINA,
"%s&order_id=%s&activity_id=%s&timestamp=%d",
url,
orderId,
activityId,
(Date().time / 1000 / 1000.toFloat()).roundToInt()
)
directToFullScreenWebPage(context, url, true)
}
/**
* 跳转至地址信息

View File

@ -508,11 +508,18 @@ object DownloadObserver {
"space_schema_type",
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
)
} else if(downloadEntity.gameId == Constants.HALO_FUN_NEW_32_GAME_ID) {
SensorsBridge.trackEvent(
"HaloFunDownloadDone",
"space_schema_type",
"32位(新)"
)
}
if (downloadEntity.gameId != Constants.GHZS_GAME_ID
&& downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD
&& downloadEntity.gameId != Constants.HALO_FUN_GAME_ID
&& downloadEntity.gameId != Constants.HALO_FUN_NEW_32_GAME_ID
) {
val trackJson = downloadEntity.customPageTrackDataJson
val kvs = if (!trackJson.isNullOrBlank()) {

View File

@ -282,7 +282,7 @@ object GameActivityDownloadHelper {
location: String,
traceEvent: ExposureEvent
) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
DialogUtils.checkDownload(
context,

View File

@ -35,6 +35,8 @@ object HomeBottomBarHelper {
text = "游戏库",
name = "游戏库",
position = 2,
iconSelect = "https://resource.ghzs.com/image/game/library/entrance/5e183202913fbd002c75f247.png",
iconUnselect = "https://resource.ghzs.com/image/game/library/entrance/5e1831fd913fbd003024641e.png",
animationCode = animationCode,
default = false,
display = Display()

View File

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

View File

@ -768,7 +768,7 @@ public class LibaoUtils {
}
public static boolean isAppInstalled(Context context, String packageName) {
List<PackageInfo> pinfo = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> pinfo = PackageUtils.getInstalledPackages(context, 0);
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;

View File

@ -93,12 +93,13 @@ object NewFlatLogUtils {
// 畅玩助手更新弹窗展示事件
@JvmStatic
fun logHaloFunUpdateDialogShow(gameId: String, gameName: String, gameArchitecture: String) {
fun logHaloFunUpdateDialogShow(gameId: String, gameName: String, gameArchitecture: String, targetVaVersion: String) {
val json = json {
KEY_EVENT to "halo_fun_update_dialog_show"
"game_id" to gameId
"game_name" to gameName
"game_architecture" to gameArchitecture
"target_va_version" to targetVaVersion
parseAndPutMeta().invoke(this)
}
log(json)
@ -142,12 +143,13 @@ object NewFlatLogUtils {
// 畅玩助手更新弹窗点击事件
@JvmStatic
fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String, architecture: String) {
fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String, architecture: String, targetVaVersion: String) {
val json = json {
KEY_EVENT to "halo_fun_update_dialog_click"
"dialog_type" to dialogType
KEY_BUTTON_TYPE to buttonType
"architecture" to architecture
"target_va_version" to targetVaVersion
parseAndPutMeta().invoke(this)
}
log(json)

View File

@ -2,53 +2,23 @@ package com.gh.common.util
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.os.Build
import android.provider.Settings
import com.gh.common.constant.Config
import com.gh.gamecenter.common.utils.PermissionHelper.isGetInstalledListPermissionDisabled
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
object PackageHelper {
private const val TAG = "PackageHelper"
private const val SP_GET_INSTALLED_API_AGREED = "get_installed_api_agreed"
private const val UNKNOWN = -1
private const val UNSUPPORTED = 0
private const val SUPPORTED = 1
private var lastInstalledPackageListTime = 0L
private var installedPackageList: List<PackageInfo> = arrayListOf()
private var isGetInstalledPackagesApiAgreed = false
private var isGetInstalledListPermissionSupported = UNKNOWN // 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知0 代表不支持, 1 代表支持
// 评论黑名单包名列表,避免用户安装了 Xposed Installer 这样的工具,也能在包含该安装包的游戏详情页评论
private var _commentPackageNameBlackList = arrayListOf<String>()
val commentPackageNameBlackList: ArrayList<String> = _commentPackageNameBlackList
var commentPackageNameBlackList = arrayListOf<String>()
// 关闭下载的包列表
private var _downloadPackageNameBlackList = arrayListOf<String>()
val downloadPackageNameBlackList: ArrayList<String> = _downloadPackageNameBlackList
var downloadPackageNameBlackList = arrayListOf<String>()
// 本地已安装的包去掉关闭下载的包后的列表
private var _validLocalPackageNameSet = hashSetOf<String>()
val validLocalPackageNameSet: HashSet<String> = _validLocalPackageNameSet
var validLocalPackageNameSet = hashSetOf<String>()
// 游戏包名匹配列表
private var _relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
val relatedPackageList: ArrayList<SettingsEntity.GameWithPackages> = _relatedPackageList
var relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
// 本地已安装包的列表
var localPackageNameSet = hashSetOf<String>()
@ -68,26 +38,33 @@ object PackageHelper {
}
@JvmStatic
fun refreshList() {
Config.getSettings()?.gameCommentBlackList?.let { _commentPackageNameBlackList = ArrayList(it) }
Config.getSettings()?.gameDownloadBlackList?.let { _downloadPackageNameBlackList = ArrayList(it) }
Config.getSettings()?.gamePackageMatch?.let { _relatedPackageList = ArrayList(it) }
fun initList() {
Config.getSettings()?.gameCommentBlackList?.let {
commentPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList?.let {
downloadPackageNameBlackList = ArrayList(it)
}
Config.getSettings()?.gamePackageMatch?.let {
relatedPackageList = ArrayList(it)
}
Config.getSettings()?.gameDownloadBlackList
updateValidPackageNameList()
}
private fun updateValidPackageNameList() {
_validLocalPackageNameSet =
validLocalPackageNameSet =
localPackageNameSet.filterNot { p -> downloadPackageNameBlackList.contains(p) }.toHashSet()
}
/**
/*
* 获取所有已安装的软件的包名、版本(非系统应用)
*/
private fun getAllPackageName(context: Context): HashSet<String> {
val set = HashSet<String>()
return try {
val packageInfos = getInstalledPackages(context, 0)
val packageInfos = PackageUtils.getInstalledPackages(context, 0)
for (packageInfo in packageInfos) {
if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
if (context.packageName != packageInfo.packageName) {
@ -102,154 +79,4 @@ object PackageHelper {
}
}
/**
* 弃用已安装列表缓存
*/
fun dumpInstalledListCache() {
lastInstalledPackageListTime = 0
}
/**
* 用户是否已经允许了调用获取已安装应用列表接口
* 优先用内存的值,没有再从 SP 中获取并更新
*/
fun isGetInstalledPackagesApiAgreed(): Boolean {
return isGetInstalledPackagesApiAgreed
|| (SPUtils.getBoolean(SP_GET_INSTALLED_API_AGREED).also { isGetInstalledPackagesApiAgreed = it })
}
/**
* 同意使用已安装应用列表 API
*/
fun agreeOnGetInstalledPackagesApi() {
isGetInstalledPackagesApiAgreed = true
SPUtils.setBoolean(SP_GET_INSTALLED_API_AGREED, true)
}
/**
* 获取已安装应用列表
*/
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 installedPackageList
}
// 简单 debounce 过于频繁的获取已安装应用列表调用
if (System.currentTimeMillis() - lastInstalledPackageListTime < 3000 && installedPackageList.isNotEmpty()) {
Utils.log(TAG, "使用了缓存的已安装应用列表")
return installedPackageList
}
var shouldGetNewInstalledPackagedList = false
// 当前设备是否支持限制获取已安装应用列表的功能
if (isSupportGetInstalledAppsPermission(context!!)) {
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能")
// 当前设备是否支持禁用了获取已安装应用列表
if (!isGetInstalledListPermissionDisabled(context)) {
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能")
shouldGetNewInstalledPackagedList = true
} else {
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能")
}
} else {
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能")
shouldGetNewInstalledPackagedList = true
}
if (shouldGetNewInstalledPackagedList) {
lastInstalledPackageListTime = System.currentTimeMillis()
installedPackageList = getInstalledPackagesInternal(context, flags)
}
return installedPackageList
}
/**
* 是否支持动态获取已安装应用列表权限
*/
fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
// 若存在缓存,直接返回缓存结果。
if (isGetInstalledListPermissionSupported != UNKNOWN) {
return isGetInstalledListPermissionSupported != UNSUPPORTED
}
try {
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
val flag =
Settings.Secure.getInt(context.contentResolver, "oem_installed_apps_runtime_permission_enable", 0)
if (flag == 1) {
isGetInstalledListPermissionSupported = SUPPORTED
return true
}
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
val packageManager = context.packageManager
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) {
isGetInstalledListPermissionSupported = SUPPORTED
return true
} else {
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
} else {
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
} catch (e: PackageManager.NameNotFoundException) {
isGetInstalledListPermissionSupported = UNSUPPORTED
return false
}
}
/**
* 在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
*/
private fun getInstalledPackagesInternal(context: Context, flags: Int): List<PackageInfo> {
Utils.log(TAG, "调用系统 API 获取已安装应用列表")
val pm = context.packageManager
try {
return pm.getInstalledPackages(flags)
} catch (ignored: java.lang.Exception) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
val process: Process
val result: MutableList<PackageInfo> = java.util.ArrayList()
var bufferedReader: BufferedReader? = null
try {
process = Runtime.getRuntime().exec("pm list packages")
bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
var line: String
while ((bufferedReader.readLine().also { line = it }) != null) {
val packageName = line.substring(line.indexOf(':') + 1)
val packageInfo = pm.getPackageInfo(packageName, flags)
result.add(packageInfo)
}
process.waitFor()
} catch (e: java.lang.Exception) {
e.printStackTrace()
if (e is InterruptedException) {
Thread.currentThread().interrupt()
}
} finally {
if (bufferedReader != null) try {
bufferedReader.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
return result
}
}

View File

@ -29,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.PackageFlavorHelper;
import com.gh.gamecenter.common.utils.PermissionHelper;
import com.gh.gamecenter.core.utils.MD5Utils;
import com.gh.gamecenter.core.utils.SentryHelper;
@ -67,8 +68,14 @@ import java.util.zip.ZipFile;
public class PackageUtils {
private static long mLastInstalledPackageListTime = 0L;
private static List<PackageInfo> mInstalledPackageList = null;
private static final String TAG = "PackageUtils";
// 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知0 代表不支持, 1 代表支持
private static int mIsSupportGetInstalledListPermission = -1;
public static String getInstallPackageInfoSourceDir(String packageName) {
try {
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
@ -670,7 +677,7 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageName(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if (!context.getPackageName().equals(packageInfo.packageName)) {
@ -683,7 +690,7 @@ public class PackageUtils {
public static ArrayList<String> getAllPackageNameIncludeGh(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
list.add(packageInfo.packageName);
@ -697,9 +704,11 @@ public class PackageUtils {
*/
public static ArrayList<String> getAllPackageNameIncludeSystemApps(Context context) {
ArrayList<String> list = new ArrayList<>();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
list.add(packageInfo.packageName);
if (!context.getPackageName().equals(packageInfo.packageName)) {
list.add(packageInfo.packageName);
}
}
return list;
}
@ -708,7 +717,7 @@ public class PackageUtils {
JSONArray jsonArray = new JSONArray();
try {
PackageManager pm = context.getPackageManager();
List<PackageInfo> packageInfos = PackageHelper.INSTANCE.getInstalledPackages(context, 0);
List<PackageInfo> packageInfos = getInstalledPackages(context, 0);
for (PackageInfo packageInfo : packageInfos) {
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
JSONObject jsonObject = new JSONObject();
@ -749,6 +758,7 @@ public class PackageUtils {
}
}
/**
* 启动应用
* 请使用 PackageLauncher.launchApp()
@ -768,6 +778,22 @@ public class PackageUtils {
}
}
/*
* 根据包名,获取软件名称
*/
public static String getNameByPackageName(Context context, String packageName) {
try {
PackageManager pm = context.getApplicationContext().getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(
packageName, 0);
return applicationInfo.loadLabel(pm).toString();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* todo 统一判断
* <p>
@ -886,8 +912,8 @@ public class PackageUtils {
String packageName = context.getApplicationContext().getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)
&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appProcess.processName.equals(packageName) && appProcess.importance
== ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
@ -898,6 +924,132 @@ public class PackageUtils {
return false;
}
/**
* 弃用已安装列表缓存
*/
public static void dumpInstalledListCache() {
mLastInstalledPackageListTime = 0;
}
public static List<PackageInfo> getInstalledPackages(Context context, int flags) {
Utils.log(TAG, "即将获取已安装应用列表");
// 简单 debounce 掉过于频繁的调用获取已安装列表调用
if (System.currentTimeMillis() - mLastInstalledPackageListTime < 1000
&& mInstalledPackageList != null
&& mInstalledPackageList.size() > 0) {
Utils.log(TAG, "使用了缓存的已安装应用列表");
return new ArrayList<>(mInstalledPackageList);
}
// 是否需要调用系统 API 获取最新的已安装应用列表
boolean shouldGetNewInstalledPackagedList = false;
// 当前设备是否支持限制获取已安装应用列表的功能
if (isSupportGetInstalledAppsPermission(context)) {
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能");
// 当前设备是否支持禁用了获取已安装应用列表
if (!PermissionHelper.isGetInstalledListPermissionDisabled(context)) {
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能");
shouldGetNewInstalledPackagedList = true;
} else {
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能");
}
} else {
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能");
shouldGetNewInstalledPackagedList = true;
}
if (shouldGetNewInstalledPackagedList) {
mLastInstalledPackageListTime = System.currentTimeMillis();
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
}
if (mInstalledPackageList == null) {
mInstalledPackageList = new ArrayList<>();
}
return mInstalledPackageList;
}
public static boolean isSupportGetInstalledAppsPermission(Context context) {
// 若存在缓存,直接返回缓存结果。为 0 代表不支持,为 1 代表支持
if (mIsSupportGetInstalledListPermission != -1) {
return mIsSupportGetInstalledListPermission != 0;
}
try {
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
int flag = Settings.Secure.getInt(context.getContentResolver(), "oem_installed_apps_runtime_permission_enable", 0);
if (flag == 1) {
mIsSupportGetInstalledListPermission = 1;
return true;
}
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
PackageManager packageManager = context.getPackageManager();
PermissionInfo permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS) {
mIsSupportGetInstalledListPermission = 1;
return true;
} else {
mIsSupportGetInstalledListPermission = 0;
return false;
}
} else {
mIsSupportGetInstalledListPermission = 0;
return false;
}
} catch (NameNotFoundException e) {
mIsSupportGetInstalledListPermission = 0;
return false;
}
}
/**
* 在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
*/
private static List<PackageInfo> getInstalledPackagesInternal(Context context, int flags) {
Utils.log(TAG, "调用系统 API 获取已安装应用列表");
final PackageManager pm = context.getPackageManager();
try {
return pm.getInstalledPackages(flags);
} catch (Exception ignored) {
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
Process process;
List<PackageInfo> result = new ArrayList<>();
BufferedReader bufferedReader = null;
try {
process = Runtime.getRuntime().exec("pm list packages");
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
final String packageName = line.substring(line.indexOf(':') + 1);
final PackageInfo packageInfo = pm.getPackageInfo(packageName, flags);
result.add(packageInfo);
}
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
} finally {
if (bufferedReader != null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static String getWebviewPath(Context context) {
final PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(context);
return webViewPackageInfo != null ? webViewPackageInfo.applicationInfo.sourceDir : null;

View File

@ -28,10 +28,10 @@ import org.json.JSONObject
import java.io.File
import java.net.URLEncoder
import java.util.*
import kotlin.collections.ArrayList
object BrowserInstallHelper {
// 随便选的 32321 居然在部分 vivo 手机上被占用,喷了
private const val PORT = 40705
private const val RESERVE_PORT = 40706
@ -40,12 +40,15 @@ object BrowserInstallHelper {
private val mContext by lazy { HaloApp.getInstance().application }
private var mUseReservePort = false
private var mValidInstalledPackageList: ArrayList<String> = arrayListOf()
private var mValidConditionMatchedCache: Boolean? = null
private val mAllInstalledPackageList: ArrayList<String> by lazy {
PackageUtils.getAllPackageNameIncludeSystemApps(HaloApp.getInstance().applicationContext).apply {
add(HaloApp.getInstance().applicationContext.packageName)
}
}
private fun getServer(port: Int): DownloadServer {
val server = DownloadServer(port)
for (packageName in getAllInstalledPackageList()) {
for (packageName in mAllInstalledPackageList) {
if (packageName.contains("com.freeme") || packageName.contains("com.zhuoyi")) {
server.isBuggyDevice = true
break
@ -54,23 +57,6 @@ object BrowserInstallHelper {
return server
}
private fun getAllInstalledPackageList(): ArrayList<String> {
when {
mValidInstalledPackageList.isNotEmpty() -> {
return mValidInstalledPackageList
}
else -> {
val allInstalledPackageList = PackageUtils.getAllPackageNameIncludeSystemApps(mContext)
if (allInstalledPackageList.isNotEmpty()) {
mValidInstalledPackageList = allInstalledPackageList
}
return mValidInstalledPackageList
}
}
}
fun downloadFile(filePath: String) {
if (!::mServer.isInitialized) mServer = if (mUseReservePort) getServer(RESERVE_PORT) else getServer(PORT)
if (!mServer.isAlive && !startServer()) {
@ -94,7 +80,7 @@ object BrowserInstallHelper {
Base64.encodeToString(URLEncoder.encode(downloadUrl).trim().toByteArray(), Base64.NO_WRAP)
DirectUtils.directToExternalBrowser(
mContext,
"https://down-and.ghzs6.com/redirect?location=base64($encodedString)"
"https://down-and.ghzs.com/redirect?location=base64($encodedString)"
)
} else {
DirectUtils.directToExternalBrowser(mContext, downloadUrl)
@ -251,43 +237,32 @@ object BrowserInstallHelper {
* 是否满足开启浏览器安装的条件
*/
private fun isConditionMatched(settingsEntity: NewSettingsEntity): Boolean {
if (mValidConditionMatchedCache != null) {
return mValidConditionMatchedCache!!
}
val packageList = getAllInstalledPackageList()
if (packageList.isEmpty()) return false
settingsEntity.installModel?.whiteList?.let {
for (packageName in it) {
if (packageList.contains(packageName)) {
mValidConditionMatchedCache = false
break
if (mAllInstalledPackageList.contains(packageName)) {
return false
}
}
}
settingsEntity.installModel?.packages?.let {
for (packageName in it) {
if (packageList.contains(packageName)) {
mValidConditionMatchedCache = true
break
if (mAllInstalledPackageList.contains(packageName)) {
return true
}
}
}
// 匹配部分字符串即可
settingsEntity.installModel?.regexPackages?.let {
for (packageNamePieces in it) {
for (installedPackageName in packageList) {
for (installedPackageName in mAllInstalledPackageList) {
if (installedPackageName.contains(packageNamePieces)) {
mValidConditionMatchedCache = true
break
return true
}
}
}
}
return mValidConditionMatchedCache ?: false
return false
}
fun onApkInstalled(path: String?) {

View File

@ -98,6 +98,7 @@ import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.home.custom.model.CustomPageShareRepository;
import com.gh.gamecenter.home.skip.PackageSkipActivity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.retrofit.RetrofitManager;
@ -136,6 +137,9 @@ import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
@ -281,6 +285,8 @@ public class MainActivity extends BaseActivity {
Config.getGhzsSettings();
} else if (Config.getVSettingEntity() == null) {
Config.refreshVSettingEntity();
} else if (Config.getVNewSettingEntity() == null) {
Config.getNewSetting();
}
// 耗时操作
@ -318,7 +324,8 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel.requestAllDialogData();
// QuickLoginHelper.getPhoneInfo();
// TODO 去掉一键登录?
QuickLoginHelper.getPhoneInfo();
// TODO 搞清楚为什么这里要获取微信相关配置
WechatBindHelper.getWechatConfig(null);
@ -735,14 +742,11 @@ public class MainActivity extends BaseActivity {
ToastUtils.showToast("游戏启动中,请稍后~");
handler.postDelayed(() -> {
VHelper.postOnInitialized(() -> {
if (VHelper.isInstalled(gamePackageName)) {
VHelper.launch(this, gamePackageName, false, true);
} else {
ToastUtils.showToast("应用已被卸载!");
}
return null;
});
if(VHelper.isInnerInstalled(gamePackageName)) {
launchGame(gamePackageName).invoke();
} else {
VHelper.postOnInitialized(launchGame(gamePackageName));
}
}, 500);
break;
case KEY_MARKET_DETAILS:
@ -760,6 +764,18 @@ public class MainActivity extends BaseActivity {
}, 500);
}
@NonNull
private Function0<Unit> launchGame(String gamePackageName) {
return () -> {
if (!VHelper.isInnerInstalled(gamePackageName) && !VHelper.isInstalled(gamePackageName)) {
ToastUtils.showToast("应用已被卸载!");
} else {
VHelper.launch(this, gamePackageName, false, true);
}
return null;
};
}
/**
* 应用跳转
*/
@ -927,6 +943,8 @@ public class MainActivity extends BaseActivity {
Config.getGhzsSettings();
} else if (Config.getVSettingEntity() == null) {
Config.refreshVSettingEntity();
} else if (Config.getVNewSettingEntity() == null) {
Config.getNewSetting();
}
mPackageViewModel.checkData();
@ -937,8 +955,10 @@ public class MainActivity extends BaseActivity {
// 接收登录和登出更新事件统计的 Meta
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBReuse reuse) {
if (reuse.getType().equals(LOGIN_TAG) || reuse.getType().equals(LOGOUT_TAG)) {
boolean isLoginEvent = reuse.getType().equals(LOGIN_TAG);
if (isLoginEvent || reuse.getType().equals(LOGOUT_TAG)) {
MetaUtil.INSTANCE.refreshMeta();
VHelper.INSTANCE.updateAuthorizeInfo(isLoginEvent);
}
}

View File

@ -111,7 +111,7 @@ public class ShareCardActivity extends ToolBarActivity {
String qrBody;
if (!TextUtils.isEmpty(newsId)) {
qrBody = "https://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
qrBody = "http://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
} else {
qrBody = "https://www.ghzs.com/?source=appshare200";
}

View File

@ -166,7 +166,7 @@ public class ShareCardPicActivity extends ToolBarActivity {
String qrBody;
if (!TextUtils.isEmpty(newsId)) {
qrBody = "https://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
qrBody = "http://www.ghzs666.com/article/" + newsId + ".html?source=appshare200";
} else {
qrBody = "https://www.ghzs.com/?source=appshare200";
}

View File

@ -3,6 +3,7 @@ package com.gh.gamecenter;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_BROWSER;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_PUSH;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ANSWER;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ARCHIVE_LOGIN;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ARTICLE;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_CATEGORY;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_COLUMN;
@ -21,6 +22,7 @@ import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_GAME;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_GROUP;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_QUN;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QUESTION;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_RESTART_GAME;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_SUGGESTION;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_TOOLBOX;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_UPLOAD_VIDEO;
@ -64,8 +66,10 @@ import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.entity.VideoLinkEntity;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.login.view.LoginActivity;
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
import com.gh.gamecenter.video.videomanager.VideoManagerActivity;
import com.gh.vspace.VHelper;
import com.gh.vspace.shortcut.OnCreateShortcutResult;
import com.gh.vspace.shortcut.ShortcutManager;
import com.gh.vspace.shortcut.ShortcutPermissionTipsDialog;
@ -405,6 +409,27 @@ public class SkipActivity extends BaseActivity {
} catch (JSONException ignored) {
}
break;
case HOST_ARCHIVE_LOGIN:
String gamePkg = uri.getQueryParameter(EntranceConsts.KEY_GAME_PKG);
if(CheckLoginUtils.isLogin()) {
VHelper.INSTANCE.updateAuthorizeInfo(true);
} else {
Bundle newBundle = new Bundle();
newBundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivity(this, null, newBundle, (resultCode, data) -> {
if(CheckLoginUtils.isLogin()) {
VHelper.INSTANCE.updateAuthorizeInfo(true);
}
VHelper.launch(this, gamePkg, false, false);
finish();
});
return;
}
break;
case HOST_RESTART_GAME:
String restartGamePkg = uri.getQueryParameter(EntranceConsts.KEY_GAME_PKG);
VHelper.launch(this, restartGamePkg, false, true);
break;
default:
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
return;

View File

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

View File

@ -18,7 +18,6 @@ import android.widget.TextView;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.R;
@ -189,7 +188,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
}
private int doType(String packageName) {
List<PackageInfo> pakageinfos = PackageHelper.INSTANCE.getInstalledPackages(mContext, 0);
List<PackageInfo> pakageinfos = PackageUtils.getInstalledPackages(mContext, 0);
for (PackageInfo pi : pakageinfos) {
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
String pi_packageName = pi.packageName;

View File

@ -89,7 +89,7 @@ class AuthorizationActivity : ToolBarActivity() {
}
private fun initData() {
if (mToken.isNotEmpty() || isFinishing) return
if (mToken.isNotEmpty()) return
val loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
mViewModel.getAccessToken(listOf(mContent), {
mToken = it

View File

@ -153,7 +153,7 @@ class NewInstalledGameFragment : ToolbarFragment() {
reuseNoneData.reuseNoneDataDescTv.text = " 及时获悉游戏最新的更新消息"
reuseNoneData.reuseResetLoadTv.text = "去开启"
reuseNoneData.reuseResetLoadTv.setOnClickListener {
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(requireActivity()) {
PermissionHelper.requestGetInstalledAppsListPermission(requireActivity()) {
updateNoDataView()
PackageRepository.initData()
}

View File

@ -4,6 +4,7 @@ import android.view.View
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
@ -11,10 +12,12 @@ import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentGameUpdatableBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
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 org.greenrobot.eventbus.Subscribe
@ -37,6 +40,7 @@ class UpdatableGameFragment : LazyFragment() {
}
}
override fun getRealLayoutId() = R.layout.fragment_game_updatable
override fun onRealLayoutInflated(inflatedView: View) {
mBinding = FragmentGameUpdatableBinding.bind(inflatedView)
@ -100,14 +104,15 @@ class UpdatableGameFragment : LazyFragment() {
noDataContainer.reuseNoneDataDescTv.text = "及时获悉游戏最新的更新消息"
noDataContainer.reuseResetLoadTv.text = "去开启"
noDataContainer.reuseResetLoadTv.setOnClickListener {
PermissionHelper.showGetInstalledAppsListPermissionDialogAndRequestPermission(
requireActivity()
) { isGranted ->
if (isGranted) {
updateNoDataView()
PackageRepository.initData()
}
}
PermissionHelper.requestGetInstalledAppsListPermission(
requireActivity(),
false,
object : EmptyCallback {
override fun onCallback() {
updateNoDataView()
PackageRepository.initData()
}
})
}
} else {
noDataContainer.reuseNoneDataIv.visibility = View.VISIBLE

View File

@ -34,7 +34,9 @@ class AppEntity(
*/
var alert: String? = null,
// 关联64位更新
var relation: AppEntity? = null
var relation: AppEntity? = null,
@SerializedName("_id")
var id: String? = null
) : Parcelable {
fun isAlertEveryTime() = alert == "EVERY_TIME_OPEN"

View File

@ -0,0 +1,42 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
class VNewSetting {
@SerializedName("va")
var va: Va? = null
@SerializedName("va_plugin")
var vaPlugin: VaPlugin? = null
class Va(
@SerializedName("32-bit")
val arch32: VaArch? = null,
)
class VaArch(
val size: String,
@SerializedName("package")
val packageName: String,
@SerializedName("version")
val versionName: String,
@SerializedName("version_code")
val versionCode: Int,
val url: String
)
data class VaPlugin(
@SerializedName("_id")
val id: String?,
@SerializedName("version_name")
val versionName: String?,
@SerializedName("change_log")
var changeLog: String?,
@SerializedName("url_32")
val url32: String?,
@SerializedName("url_64")
val url64: String?,
)
}

View File

@ -413,7 +413,7 @@ class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: At
val shareUrl = if (isPublishEnv()) {
"https://m.ghzs666.com/video/${it.id}"
} else {
"https://dev-and-static.ghzs66.com/page/video_play/video/video.html?video=${it.id}"
"https://resource.ghzs.com/page/video_play/video/video.html?video=${it.id}"
}
val additionalParams = AdditionalParamsEntity().apply {
contentType = "视频帖"

View File

@ -45,12 +45,6 @@ class UpdateDialogFragment : BaseDialogFragment() {
private var mIsDisplayingDownloadingStyle = false // 是否正在显示更新中样式
private val mDataWatcher = object : DataWatcher() {
override fun onDataInit(downloadEntity: DownloadEntity) {
super.onDataInit(downloadEntity)
onDataChanged(downloadEntity)
}
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.name.contains("光环助手")) {
if (mIsDisplayingDownloadingStyle) {
@ -80,11 +74,13 @@ class UpdateDialogFragment : BaseDialogFragment() {
return
}
DownloadManager.getInstance().addObserver(mDataWatcher)
mUpdateEntity = arguments?.getParcelable(UPDATE_ENTITY)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
showUpdateHintStyle(requireContext(), mUpdateEntity!!, true)
showUpdateHintStyle(requireContext(), mUpdateEntity!!)
return mBinding.root
}
@ -113,14 +109,8 @@ class UpdateDialogFragment : BaseDialogFragment() {
mDismissCallback?.onCallback()
}
override fun onStart() {
super.onStart()
DownloadManager.getInstance().addObserver(mDataWatcher)
}
override fun onStop() {
super.onStop()
override fun onDestroyView() {
super.onDestroyView()
DownloadManager.getInstance().removeObserver(mDataWatcher)
}
@ -130,9 +120,7 @@ class UpdateDialogFragment : BaseDialogFragment() {
* @param context 上下文
* @param updateEntity 更新实体
*/
private fun showUpdateHintStyle(context: Context,
updateEntity: AppEntity,
invokeByViewCreated: Boolean) {
private fun showUpdateHintStyle(context: Context, updateEntity: AppEntity) {
mIsDisplayingDownloadingStyle = false
val updateHintBinding = mBinding.updateHintContainerView
@ -212,15 +200,12 @@ class UpdateDialogFragment : BaseDialogFragment() {
)
}
if (invokeByViewCreated) {
SensorsBridge.trackVersionUpdateDialogShow(
keyDialogReminderTime = mUpdateEntity?.alert,
keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
)
DataLogUtils.uploadUpgradeLog(context, "notice") //上传更新通知弹窗数据
}
SensorsBridge.trackVersionUpdateDialogShow(
keyDialogReminderTime = mUpdateEntity?.alert,
keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
)
DataLogUtils.uploadUpgradeLog(context, "notice") //上传更新通知弹窗数据
}
/**
@ -309,8 +294,13 @@ class UpdateDialogFragment : BaseDialogFragment() {
if (DownloadStatus.done == downloadEntity.status) {
DownloadManager.getInstance().cancel(downloadEntity.url, false, true, false)
tryWithDefaultCatch {
showUpdateHintStyle(requireContext(), updateEntity, false)
try {
dismiss()
} catch (ignored: IllegalArgumentException) {
// do nothing
}
if (updateEntity.isForce) {
AppExecutor.uiExecutor.executeWithDelay({ UpdateHelper.exitApp() }, 1000L)
}
} else if (DownloadStatus.neterror == downloadEntity.status) {
ToastUtils.toast("网络错误,请稍后重试")

View File

@ -282,10 +282,10 @@ class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver {
}
}
mBinding.mWebView.addJavascriptObject(DefaultJsApi(this), null)
val url = if (PackageFlavorHelper.IS_TEST_FLAVOR) {
"https://dev-and-static.ghzs66.com/page/comment_tag_editor/index.html?timestamp=${System.currentTimeMillis()}"
val url = if ("internal" == BuildConfig.FLAVOR) {
"https://resource.ghzs.com/page/comment_tag_editor_dev/index.html?timestamp=${System.currentTimeMillis()}"
} else {
"https://and-static.ghzs66.com/page/comment_tag_editor/index.html?timestamp=${System.currentTimeMillis()}"
"https://resource.ghzs.com/page/comment_tag_editor/index.html?timestamp=${System.currentTimeMillis()}"
}
mBinding.mWebView.loadUrl(url)
}

View File

@ -16,6 +16,7 @@ import com.gh.gamecenter.common.retrofit.BiResponse
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.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.SPUtils
@ -26,6 +27,7 @@ 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
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
@ -58,6 +60,8 @@ object PackageRepository {
@Volatile
private var mIsInitialisingData = false
var installedPkgRefreshed = false
var vaPkgRefreshed = false
val gameUpdateLiveData = MutableLiveData<List<GameUpdateEntity>>()
val gameInstalledLiveData = MutableLiveData<List<GameInstall>>()
@ -79,13 +83,20 @@ object PackageRepository {
*/
@JvmStatic
fun initData() {
Utils.log("xxx", "PackageRepository::initData::mIsInitialisingData = $mIsInitialisingData")
if (mIsInitialisingData) return
mIsInitialisingData = true
installedPkgRefreshed = false
vaPkgRefreshed = false
runOnIoThread {
if (gameInstalled.isNotEmpty()) gameInstalled.clear()
if (mInstalledGameList.isNotEmpty()) mInstalledGameList.clear()
if (gameUpdate.isNotEmpty()) gameUpdate.clear()
if (gameUpdate.isNotEmpty()) {
gameUpdate.clear()
Utils.log("xxx", "清除更新数据")
}
if (mInstalledPkgList.isNotEmpty()) mInstalledPkgList.clear()
val list = PackageUtils.getAllPackageName(mApplication)
@ -93,15 +104,38 @@ object PackageRepository {
uploadAppList()
initFilterPackage(list) { filteredList ->
mIsInitialisingData = false
mInstalledPkgList.addAll(filteredList)
notifyInstallPkgData()
loadInstalledGameDigestAndNotifyData(filteredList)
Utils.log("xxx", "PackageRepository::filteredList::${filteredList}")
loadInstalledGameDigestAndNotifyData(filteredList) {
installedPkgRefreshed = true
mIsInitialisingData = !(installedPkgRefreshed && vaPkgRefreshed)
}
}
loadGhzsUpdate()
// 畅玩游戏更新
var allGames = VHelper.getAllVGameSnapshots()
if (allGames.isNullOrEmpty()) {
VHelper.refreshVGameSnapshot()
allGames = VHelper.getAllVGameSnapshots()
}
val allGamePkgNames = allGames.map { it.packageName }.toArrayList()
if (allGamePkgNames.isNotEmpty()) {
notifyInstallPkgData()
updateFilterPackage(allGamePkgNames) {
Utils.log("xxx", "PackageRepository::filteredList::${allGamePkgNames}")
loadInstalledGameDigestAndNotifyData(
filteredList = allGamePkgNames,
onWorkerThreadOnly = false,
isVGame = true
) {
vaPkgRefreshed = true
mIsInitialisingData = !(installedPkgRefreshed && vaPkgRefreshed)
}
}
}
}
}
@ -134,7 +168,8 @@ object PackageRepository {
PackageUtils.getGhVersionName(),
PackageUtils.getGhVersionCode(),
HaloApp.getInstance().channel,
Build.VERSION.SDK_INT)
Build.VERSION.SDK_INT
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<AppEntity>() {
@ -209,6 +244,7 @@ object PackageRepository {
filteredList: ArrayList<String>,
onWorkerThreadOnly: Boolean = false,
isVGame: Boolean = false,
loadFinishCallback: (() -> Unit)? = null
) {
var isNotifyUpdate = false
val maxPageCount = (filteredList.size / PAGE_SIZE) + 1
@ -217,6 +253,7 @@ object PackageRepository {
val latch = ObservableUtil.latch(maxPageCount, {
if (isNotifyUpdate || gameUpdateLiveData.value == null) notifyGameUpdateData()
notifyGameInstallData()
loadFinishCallback?.invoke()
}, Any())
while (++page <= maxPageCount) {

View File

@ -3,9 +3,10 @@ package com.gh.gamecenter.packagehelper
import android.app.Application
import android.text.TextUtils
import androidx.lifecycle.*
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.feature.entity.GameInstall
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import kotlin.collections.set
class PackageViewModel(
@ -79,6 +80,7 @@ class PackageViewModel(
if (mRepository.gameInstalled.size == 0
|| PackageFilterManager.hasPendingPackage()
) {
Utils.log("xxx", "PackageViewModel call initData")
mRepository.initData()
}
}

View File

@ -60,7 +60,7 @@ import com.gh.gamecenter.room.AppDatabase
import com.gh.gamecenter.setting.SettingBridge
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.gh.gamecenter.wrapper.MainWrapperViewModel
import com.gh.vspace.IExternalGamesUsage
import com.gh.vspace.ITestCase
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.HaloApp
import com.jakewharton.rxbinding2.view.RxView
@ -695,7 +695,11 @@ class HaloPersonalFragment : BaseLazyFragment() {
(try {
Class.forName("com.gh.vspace.ExternalGameUsage")?.newInstance()
} catch (e: Exception) {
} as? IExternalGamesUsage)?.addInstallExternalGameButton(mStubBinding.otherItems)
} as? ITestCase)?.apply {
addInstallExternalGameButton(mStubBinding.otherItems)
addInstallPluginButton(mStubBinding.otherItems)
addInstallPlugin32Button(mStubBinding.otherItems)
}
}
mStubBinding.settingItem.run {

View File

@ -90,6 +90,9 @@ class UserHomeFragment : ToolbarFragment() {
getUserInfo()
getBadgeList()
getUserPlayedGameCount()
if (PackageFlavorHelper.IS_TEST_FLAVOR) {
getUserLevel()
}
}
mHomeBinding?.container?.setZoomView(mHomeBinding?.userBackgroundContainer)
@ -164,12 +167,38 @@ class UserHomeFragment : ToolbarFragment() {
if (mUserHomeViewModel.userId == UserManager.getInstance().userId) {
mUserHomeViewModel.availableBadges()
}
// if (mUserHomeViewModel.userId == UserManager.getInstance().userId) {
// mUserHomeViewModel.availableBadges()
// } else {
// mHomeBinding?.userBadgeTips?.visibility = View.VISIBLE
// if (it.isNotEmpty()) {
// mHomeBinding?.userBadge?.visibility = View.VISIBLE
// updateUserBadge(it)
// } else {
// mHomeBinding?.userBadge?.visibility = View.GONE
// }
// }
}
mUserHomeViewModel.availableBadgeCount.observeNonNull(this) {
mHomeBinding?.badgeTips?.visibility = if (it > 0) View.VISIBLE else View.GONE
}
// mUserHomeViewModel.availableBadgeCount.observeNonNull(this) {
// mHomeBinding?.viewBadgeMessageTip?.visibleIf(it > 0)
// if (mUserHomeViewModel.badges.value?.isEmpty() == true && it > 0) {
// mHomeBinding?.userBadgeList?.visibility = View.INVISIBLE
// mHomeBinding?.userBadgeTips?.visibility = View.VISIBLE
// mHomeBinding?.userBadgeTips?.text = "有${it}枚徽章可领取"
// } else if (mUserHomeViewModel.badges.value?.isEmpty() == false) {
// mHomeBinding?.userBadgeList?.visibility = View.VISIBLE
// mHomeBinding?.userBadgeTips?.visibility = View.GONE
// updateUserBadge(mUserHomeViewModel.badges.value!!)
// }
// }
mUserHomeViewModel.networkError.observeNonNull(this) {
mHomeBinding?.container?.visibility = View.GONE
mHomeBinding?.reuseNoConnection?.root?.visibility = View.VISIBLE
@ -185,10 +214,28 @@ class UserHomeFragment : ToolbarFragment() {
mPlayGameCount = it
})
mUserHomeViewModel.level.observeNonNull(this) {
mHomeBinding?.run {
levelContainer.visibility = View.VISIBLE
levelContainer.setOnClickListener {
if (mUserHomeViewModel.userId == UserManager.getInstance().userId) {
IntegralLogHelper.run {
log("click_grade_label", LOCATION)
log("view_grade", "等级中心页")
}
DirectUtils.directToLevelPage(requireContext())
}
}
val levelNum = if (it > 9) 9 else it
levelTv.text = "Lv$levelNum "
}
}
mMessageUnreadViewModel.liveData.observeNonNull(this) {
updateUnreadInfo(it)
}
mUserViewModel.editObsUserinfo.observeNonNull(this) {
it.data?.let { updatedUserInfo ->
if (mUserHomeViewModel.userId == UserManager.getInstance().userId) {
@ -495,6 +542,7 @@ class UserHomeFragment : ToolbarFragment() {
// 跳转更换背景页
userChangeBgBtn.setOnClickListener {
IntegralLogHelper.log("click_change _background", LOCATION)
SPUtils.setBoolean(Constants.SP_HAS_CLICK_CHANGE_BG, false)
changeBgTips.visibility = View.GONE
startActivity(PersonalityBackgroundActivity.getIntent(requireContext()))

View File

@ -33,6 +33,7 @@ class UserHomeViewModel(application: Application, var userId: String) : AndroidV
var availableBadge = MutableLiveData<BadgeEntity>()
var availableBadgeCount = MutableLiveData<Int>()
var playGamesCount = MutableLiveData<Int>()
var level = MutableLiveData<Int>()
fun getUserInfo() {
RetrofitManager.getInstance()
@ -132,6 +133,19 @@ class UserHomeViewModel(application: Application, var userId: String) : AndroidV
})
}
@SuppressLint("CheckResult")
fun getUserLevel() {
RetrofitManager.getInstance()
.api.getUserLevels(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<JsonObject>() {
override fun onSuccess(data: JsonObject) {
level.postValue(data["level"].asInt)
}
})
}
@SuppressLint("CheckResult")
fun postReport(reason: String, desc: String) {
val requestMap = hashMapOf<String, String>()

View File

@ -56,13 +56,13 @@ object ArticleDetailWebCacheManager {
}
val cacheUrlList = mutableListOf(
"https://and-static.ghzs66.com/web/website-static/lib/polyfill.min.js",
"https://and-static.ghzs66.com/web/dplayer/DPlayer.min.js"
"https://static-web.ghzs.com/website-static/lib/polyfill.min.js",
"https://and-static.ghzs.com/web/dplayer/DPlayer.min.js"
)
if (!EnvHelper.isDevEnv) {
cacheUrlList.add("https://and-static.ghzs66.com/web/js/halo.js")
cacheUrlList.add("https://and-static.ghzs66.com/web/css/halo.css")
cacheUrlList.add("https://resource.ghzs.com/js/halo.js")
cacheUrlList.add("https://resource.ghzs.com/css/halo.css")
}
val okHttpClient = OkHttpClient.Builder()
@ -73,7 +73,7 @@ object ArticleDetailWebCacheManager {
val retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://and-static.ghzs66.com")
.baseUrl("https://resource.ghzs.com")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()

View File

@ -27,7 +27,7 @@ class EditorInsertEntity(
entity.type = "answer"
entity.title = answer.questions.title?.eliminateDoubleQuote()
entity.brief = answer.brief?.eliminateDoubleQuote()
entity.icon = "https://and-static.ghzs66.com/web/website-static/images/icon_new_reply.png"
entity.icon = "http://static-web.ghzs.com/website-static/images/icon_new_reply.png"
return entity
}
@ -39,7 +39,7 @@ class EditorInsertEntity(
entity.type = "community_article"
entity.title = article.title.eliminateDoubleQuote()
entity.brief = article.brief.eliminateDoubleQuote()
entity.icon = "https://and-static.ghzs66.com/web/website-static/images/icon_new_article.png"
entity.icon = "http://static-web.ghzs.com/website-static/images/icon_new_article.png"
return entity
}
@ -60,7 +60,7 @@ class EditorInsertEntity(
entity.type = "game_collection"
entity.title = game.title
entity.brief = game.intro
entity.icon = "https://and-static.ghzs66.com/web/website-static/images/icon_game_collection.png"
entity.icon = "https://static-web.ghzs.com/website-static/images/icon_game_collection.png"
return entity
}
@ -71,7 +71,7 @@ class EditorInsertEntity(
entity.type = "video"
entity.title = video.title
entity.brief = video.des
entity.icon = "https://and-static.ghzs66.com/web/website-static/images/icon_video.png"
entity.icon = "https://static-web.ghzs.com/website-static/images/icon_video.png"
return entity
}
}

View File

@ -408,7 +408,7 @@ class ForumTopVideoView @JvmOverloads constructor(context: Context, attrs: Attri
shareUrl = if (isPublishEnv()) {
"https://m.ghzs666.com/video/${it.id}"
} else {
"https://dev-and-static.ghzs66.com/page/video_play/video/video.html?video=${it.id}"
"https://resource.ghzs.com/page/video_play/video/video.html?video=${it.id}"
},
shareIcon = it.poster,
shareTitle = it.title,

View File

@ -41,7 +41,7 @@ public class InstallAndUninstallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PackageHelper.INSTANCE.dumpInstalledListCache();
PackageUtils.dumpInstalledListCache();
ExtensionsKt.doOnMainProcessOnly(() -> {
Utils.log("InstallAndUninstallReceiver:: onReceive->" + intent.getAction() + "==" + intent.getDataString());

View File

@ -2287,6 +2287,12 @@ public interface ApiService {
@POST("users/{user_id}:report")
Single<ResponseBody> reportUser(@Path("user_id") String userId, @Body RequestBody body);
/**
* 获取用户等级
*/
@GET("users/{user_id}/levels")
Single<JsonObject> getUserLevels(@Path("user_id") String userId);
/**
* 获取新分类2.0侧边栏
*/

View File

@ -1,9 +1,11 @@
package com.gh.gamecenter.retrofit.service
import com.gh.gamecenter.entity.AppEntity
import com.gh.gamecenter.entity.VNewSetting
import com.gh.gamecenter.entity.VSetting
import io.reactivex.Single
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query
interface VApiService {
@ -24,4 +26,16 @@ interface VApiService {
@GET("setting")
fun getSettings(@Query("version") version: String?, @Query("android") androidSdkVersion: Int): Single<VSetting>
@GET("new/setting")
fun getNewSettings(
@Query("version") version: String?,
@Query("android") androidSdkVersion: Int,
): Single<VNewSetting>
@GET("new/upgrade")
fun getNewPackageUpdate(
@Query("version") version: String?,
@Query("va_version") vaVersion: String?,
@Query("channel") channel: String,
): Single<AppEntity>
}

View File

@ -5,8 +5,8 @@ import android.app.Application
import android.content.pm.PackageManager
import com.gh.common.constant.Config
import com.gh.common.simulator.SimulatorGameManager
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.common.utils.NetworkUtils
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
@ -56,7 +56,7 @@ class SimulatorManagementViewModel(application: Application) :
return Single.create<List<SimulatorEntity>> { emitter ->
val simulatorEntityList = ArrayList<SimulatorEntity>()
val allInstalledPackages =
PackageHelper.getInstalledPackages(HaloApp.getInstance().application, PackageManager.GET_ACTIVITIES)
PackageUtils.getInstalledPackages(HaloApp.getInstance().application, PackageManager.GET_ACTIVITIES)
allInstalledPackages.forEach {
if (it.packageName.contains("com.gh")) {
val activityInfo =

View File

@ -358,7 +358,7 @@ class DetailPlayerView @JvmOverloads constructor(context: Context, attrs: Attrib
mBinding.censoringContainer.setOnClickListener {
DirectUtils.directToWebView(
context,
context.getString(R.string.upload_protocol_url),
"https://resource.ghzs.com/page/video_rule/video_rule.html",
mEntrance
)
}

View File

@ -3,16 +3,12 @@ package com.gh.gamecenter.wrapper
import android.graphics.PorterDuff
import android.net.Uri
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.view.View
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
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
@ -28,7 +24,6 @@ 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
@ -67,8 +62,6 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
setCurrentItem(mViewModel!!.defaultBottomTabIndex)
}
}
PackageRepository.addInstalledGame("com.woobest.sgwg.aligames")
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -84,10 +77,6 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
mViewModel?.realNameInfoUpdateLiveData?.observe(viewLifecycleOwner) {
updateRealNameErrorContainer()
}
if (!PackageHelper.isGetInstalledPackagesApiAgreed()) {
showInstallApiHintView(mBinding)
}
}
fun setCurrentItem(page: Int) {
@ -266,70 +255,6 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
}
}
private fun showInstallApiHintView(binding: FragmentMainBinding) {
val contentText = SpannableStringBuilder()
.color(R.color.text_theme.toColor(requireContext())) { append("您未授予已安装列表权限,可能") }
.color(R.color.secondary_red.toColor(requireContext())) { append("导致无法安装及更新") }
.color(R.color.text_theme.toColor(requireContext())) { append("建议开启权限!") }
binding.installApiContainer.visibility = View.VISIBLE
binding.installApiContainer.setOnClickListener {
// do nothing
}
binding.installApiCloseIv.enlargeTouchArea()
binding.installApiContentTv.text = contentText
binding.installApiCloseIv.setOnClickListener {
binding.installApiContainer.visibility = View.GONE
}
binding.installApiBtn.setOnClickListener {
val grantedClosure = {
binding.installApiContainer.visibility = View.GONE
PackageHelper.agreeOnGetInstalledPackagesApi()
// 进行包名初始化相关的操作
PackageRepository.initData()
PackageHelper.refreshLocalPackageList()
PackageHelper.refreshList()
}
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()
}
}
}
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
changeBottomTabStyle(mBinding.viewPager.currentItem)

View File

@ -211,7 +211,7 @@ class MainWrapperRepository {
// 如果有优先级更高的选中 tab id则将优先级更高的选中 tab 设置为 default
if (mHighPrioritySelectedTopTabId.isNotEmpty() && mHighPrioritySelectedNavId == multiTabNav?.id) {
val selectedTab = multiTabNav.linkMultiTabNav.firstOrNull {
it.id == mHighPrioritySelectedTopTabId
it.link?.link == mHighPrioritySelectedTopTabId
}
// 将优先级更高的选中 tab 设置为 default
@ -225,7 +225,7 @@ class MainWrapperRepository {
defaultCustomPageId =
multiTabNav?.linkMultiTabNav?.find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
multiTabNavLiveData.value = multiTabNav
multiTabNavLiveData.postValue(multiTabNav)
}
companion object : SingletonHolder<MainWrapperRepository>({ MainWrapperRepository() })

View File

@ -13,7 +13,6 @@ import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.core.graphics.ColorUtils
import androidx.core.view.doOnLayout
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import com.gh.common.constant.Config
@ -403,9 +402,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
val selectTab = it.getContentWithHandled()
if (selectTab is MainSelectedEvent.SelectedTab) {
if (selectTab.topTabIndex != -1) {
mViewPager?.doOnLayout {
mViewPager?.setCurrentItem(selectTab.topTabIndex, false)
}
mViewPager?.setCurrentItem(selectTab.topTabIndex, false)
}
}
}

View File

@ -4,8 +4,10 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
public interface IExternalGamesUsage {
public interface ITestCase {
void addInstallExternalGameButton(@NonNull ViewGroup viewParent);
void addInstallPluginButton(@NonNull ViewGroup viewParent);
void addInstallPlugin32Button(@NonNull ViewGroup viewParent);
}

View File

@ -2,8 +2,11 @@ package com.gh.vspace
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.database.sqlite.SQLiteDiskIOException
import android.os.*
import androidx.annotation.WorkerThread
import com.blankj.utilcode.util.LogUtils
import com.gh.download.simple.DownloadMessageHandler
import com.gh.download.simple.SimpleDownloadManager
import com.gh.gamecenter.common.retrofit.BiResponse
@ -22,7 +25,11 @@ import com.lg.download.DownloadStatus
import com.lg.download.httpclient.DefaultHttpClient
import com.lg.ndownload.DownloadConfigBuilder
import com.lg.vspace.VirtualAppManager
import com.lg.vspace.archive.data.Const
import com.lg.vspace.archive.ui.ArchiveManager
import com.lg.vspace.archive.ui.interfaces.ArchiveProgressPageListener
import com.lightgame.utils.Utils
import com.lody.virtual.client.core.VirtualCore
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import java.io.File
@ -43,6 +50,31 @@ object VArchiveHelper {
// 本地存档存放的位置
val archivePath by lazy { HaloApp.getInstance().filesDir.absolutePath + File.separator }
private var messenger: Messenger? = null
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.what) {
Const.MSG_USE_ARCHIVE -> {
msg.data?.let {
onApplyGameArchiveFinished(
packageName = it.getString(Const.EXTRA_PACKAGE_NAME, ""),
isSuccess = it.getBoolean(Const.EXTRA_IS_SUCCESS, false)
)
}
}
Const.MSG_GENERATE_ARCHIVE -> {
msg.data?.let {
onSaveGameArchiveFinished(
packageName = it.getString(Const.EXTRA_PACKAGE_NAME, ""),
isSuccess = it.getBoolean(Const.EXTRA_IS_SUCCESS, false)
)
}
}
}
messenger = null
}
}
fun init() {
DownloadMessageHandler.registerGlobalStatusChangedListener { simpleDownloadEntity, downloadStatus ->
when (downloadStatus) {
@ -162,8 +194,26 @@ object VArchiveHelper {
mSaveArchiveListener = saveArchiveListener
// 记录最近一次创建的存档文件
mLatestArchiveFile = archiveFile
val intent = VirtualAppManager.getGenerateArchiveIntent(context, config, packageName, archiveFile)
context.startActivity(intent)
if (VHelper.isLegacyInstalled(packageName)) {
val intent = VirtualAppManager.getGenerateArchiveIntent(context, config, packageName, archiveFile)
context.startActivity(intent)
} else {
if (VirtualCore.get().isRunInExtProcess(packageName)) {
val intent = VirtualAppManager.getGenerateArchiveIntent(context, config, packageName, archiveFile)
prepareExtIntent(intent)
context.startActivity(intent)
} else {
ArchiveManager.generatePackage(context, packageName, config, archiveFile,
object : ArchiveProgressPageListener {
override fun onCancel() {
}
override fun completed(isSuccess: Boolean) {
onSaveGameArchiveFinished(packageName, isSuccess)
}
})
}
}
}
/**
@ -179,8 +229,43 @@ object VArchiveHelper {
applyArchiveListener: ((String, Boolean) -> Unit)? = null
) {
mApplyArchiveListener = applyArchiveListener
val intent = VirtualAppManager.getUseArchiveIntent(context, packageName, config, archiveFile)
context.startActivity(intent)
if (VHelper.isLegacyInstalled(packageName)) {
val intent = VirtualAppManager.getUseArchiveIntent(context, packageName, config, archiveFile)
context.startActivity(intent)
} else {
if (VirtualCore.get().isRunInExtProcess(packageName)) {
val intent = VirtualAppManager.getUseArchiveIntent(context, packageName, config, archiveFile)
prepareExtIntent(intent)
context.startActivity(intent)
} else {
ArchiveManager.useArchive(context, packageName, archiveFile, config,
object : ArchiveProgressPageListener {
override fun onCancel() {
}
override fun completed(isSuccess: Boolean) {
LogUtils.d("存档使用 completed : $isSuccess")
if (applyArchiveListener != null) {
applyArchiveListener(packageName, isSuccess)
}
}
})
}
}
}
private fun prepareExtIntent(intent: Intent) {
intent.setClassName(
com.lg.vspace.BuildConfig.EXT_PACKAGE_NAME,
"com.lg.vspace.addon.launcher.RemoteGuideActivity"
)
intent.putExtra("callback", Bundle().also {
messenger = Messenger(handler)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
it.putBinder("messenger", messenger!!.binder)
}
})
}
/**

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,307 @@
package com.gh.vspace
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.gh.common.exposure.ExposureUtils
import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD
import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE
import com.gh.common.util.*
import com.gh.common.util.NewFlatLogUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.DialogVspace32NewBinding
import com.gh.gamecenter.entity.AppEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.view.DownloadButton
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus.*
import com.lightgame.utils.AppManager
import java.io.File
class VSpace32NewDialogFragment : BaseDraggableDialogFragment() {
private var mAppEntity: AppEntity? = null
private var mGameId: String = ""
private var mGameName: String = ""
private val mDownloadUrl by lazy { mAppEntity?.url ?: "" }
private val mBinding by lazy { DialogVspace32NewBinding.inflate(layoutInflater) }
private var mIsLogInstallShow = false
private var mIsLogAutoInstallClick = false
private var mIsClickDownloadThisTime = false // 是否本次弹出Dialog点击的下载按钮
private val mDataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.url == mDownloadUrl && isAdded) {
updateDownloadButton(downloadEntity)
}
}
override fun onDataInit(downloadEntity: DownloadEntity) {
onDataChanged(downloadEntity)
}
}
override fun getRootView(): View = mBinding.root
override fun getDragCloseView(): View = mBinding.dragClose
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAppEntity = arguments?.get(KEY_APP_ENTITY_32) as AppEntity
mGameId = arguments?.getString(EntranceConsts.KEY_GAME_ID) ?: ""
mGameName = arguments?.getString(EntranceConsts.KEY_GAME_NAME) ?: ""
}
@SuppressLint("ClickableViewAccessibility")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mViewModel = viewModelProvider<VSpaceDialogFragment.VSpaceDialogViewModel>()
mViewModel.packageLiveData.observe(this) {
if (it.packageName == VHelper.VSPACE_32BIT_NEW_PACKAGENAME) {
dismissAllowingStateLoss()
}
}
val downloadSnapshot = DownloadManager.getInstance()
.getDownloadEntitySnapshotByPackageName(VHelper.VSPACE_32BIT_NEW_PACKAGENAME)
mBinding.downloadBtn.text = if (downloadSnapshot?.status == done) "安装" else "下载"
mBinding.downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
mBinding.descTv.text = "$mGameName》需安装完整的畅玩服务组件,安装后即可给您带来急速的畅玩体验~"
mBinding.privacyPolicyTv.setOnClickListener {
NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click")
DirectUtils.directToWebView(requireContext(), Constants.SMOOTH_GAME_PRIVACY_POLICY_ADDRESS)
}
if (downloadSnapshot?.status == done) {
NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_show")
SensorsBridge.trackEvent("HaloFunExpandInstallDialogShow")
mIsLogInstallShow = true
} else {
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_download_tip_dialog_show", mGameId, mGameName)
SensorsBridge.trackEvent("HaloFunExpandDownloadDialogShow", "game_id", mGameId, "game_name", mGameName)
}
mBinding.downloadBtn.setOnClickListener {
if (downloadSnapshot?.status == done) {
if (!File(downloadSnapshot.path).exists()) {
ToastUtils.toast("畅玩组件已损坏,即将重新下载")
DownloadManager.getInstance().cancel(downloadSnapshot.url)
DownloadManager.getInstance().add(downloadSnapshot)
} else {
PackageInstaller.install(requireContext(), downloadSnapshot)
NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
}
} else {
val downloadEntity = DownloadEntity()
val name = "畅玩游戏助手V" + mAppEntity?.version
val downloadId = PackageInstaller.createDownloadId(name)
downloadEntity.url = mDownloadUrl
downloadEntity.name = name
downloadEntity.platform = "官方版"
downloadEntity.gameId = Constants.HALO_FUN_NEW_32_GAME_ID
downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk")
downloadEntity.packageName = VHelper.VSPACE_32BIT_NEW_PACKAGENAME
downloadEntity.addMetaExtra(DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200")
val gameEntity = GameEntity(downloadEntity.gameId, downloadEntity.name)
gameEntity.gameVersion = mAppEntity?.version ?: ""
// 确定下载类型
val downloadType =
if (arguments?.getBoolean(VSpaceDialogFragment.KEY_IS_UPDATE) == true) UPDATE else DOWNLOAD
downloadEntity.exposureTrace = ExposureUtils.logADownloadExposureEvent(
gameEntity,
downloadEntity.platform,
null,
downloadType
).toJson()
mIsClickDownloadThisTime = true
AppExecutor.uiExecutor.executeWithDelay({
DownloadManager.getInstance().cancel(mDownloadUrl)
DownloadManager.getInstance().add(downloadEntity)
}, 200)
DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity, "开始")
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_download_tip_dialog_click", mGameId, mGameName)
SensorsBridge.trackEvent("HaloFunExpandDownloadDialogDownloadClick")
}
}
}
override fun onStart() {
super.onStart()
DownloadManager.getInstance().addObserver(mDataWatcher)
// 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
// 手动再检查一下安装状态,避免出现已安装但是没有 dismiss 弹窗的问题
if (PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.VSPACE_32BIT_NEW_PACKAGENAME)) {
dismissAllowingStateLoss()
}
}
override fun onStop() {
super.onStop()
DownloadManager.getInstance().removeObserver(mDataWatcher)
}
private fun updateDownloadButton(downloadEntity: DownloadEntity) {
val downloadBtn = mBinding.downloadBtn
downloadBtn.progress = (downloadEntity.progress * 10).toInt()
when (downloadEntity.status) {
downloading -> {
downloadBtn.setText(R.string.pause)
downloadBtn.progress = (downloadEntity.percent * 10).toInt()
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
downloadBtn.setOnClickListener {
DownloadManager.getInstance().pause(mDownloadUrl)
}
}
pause -> {
downloadBtn.setText(R.string.resume)
downloadBtn.setOnClickListener {
DownloadManager.getInstance().resume(downloadEntity, true)
}
}
overflow,
timeout,
neterror,
diskisfull,
waiting,
subscribe -> {
downloadBtn.setText(R.string.waiting)
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
downloadBtn.setOnClickListener {
DownloadManager.getInstance().resume(downloadEntity, false)
}
}
done -> {
downloadBtn.setText(R.string.install)
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
if (!mIsLogInstallShow) {
NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_show")
NewFlatLogUtils.logHaloFunInstallTipDialogShow("32位")
SensorsBridge.trackEvent("HaloFunExpandInstallDialogShow")
mIsLogInstallShow = true
}
val isVSpace32DownloadOnly =
downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.VSPACE_32_DOWNLOAD_ONLY
val isAutoInstall = SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true)
if (!isVSpace32DownloadOnly && isAutoInstall && !mIsLogAutoInstallClick && mIsClickDownloadThisTime) {
NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
mIsLogAutoInstallClick = true
}
downloadBtn.setOnClickListener {
if (!File(downloadEntity.path).exists()) {
ToastUtils.toast("畅玩组件已损坏,即将重新下载")
DownloadManager.getInstance().cancel(downloadEntity.url)
DownloadManager.getInstance().add(downloadEntity)
} else {
PackageInstaller.install(requireContext(), downloadEntity)
NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
}
}
}
cancel,
hijack,
notfound,
uncertificated,
unqualified -> {
downloadBtn.text = "下载"
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
downloadBtn.setOnClickListener {
DownloadManager.getInstance().resume(downloadEntity, true)
}
}
else -> {
// do nothing
}
}
}
companion object {
const val KEY_APP_ENTITY_32 = "app_entity_32"
@JvmStatic
fun showDownloadDialog(
context: Context?,
appEntity32: AppEntity,
gameId: String = "",
gameName: String = ""
) {
val fragmentActivity: FragmentActivity = if (context is FragmentActivity) {
context
} else {
val currentActivity = AppManager.getInstance().currentActivity()
if (currentActivity is FragmentActivity) {
currentActivity
} else {
throw IllegalStateException("current activity context must be FragmentActivity")
}
}
// 防止重复弹出
if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return
val downloadDialog = VSpace32NewDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_APP_ENTITY_32, appEntity32)
putString(EntranceConsts.KEY_GAME_ID, gameId)
putString(EntranceConsts.KEY_GAME_NAME, gameName)
}
}
downloadDialog.show(
fragmentActivity.supportFragmentManager,
VSpace32NewDialogFragment::class.java.name
)
}
private fun hasDialogDisplayedInCurrentActivity(fragmentActivity: FragmentActivity): Boolean {
val fragments: List<Fragment> = fragmentActivity.supportFragmentManager.fragments
fragments.forEach { fragment ->
if (fragment is VSpace32NewDialogFragment) return true
}
return false
}
}
}

View File

@ -0,0 +1,303 @@
package com.gh.vspace
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.gh.common.exposure.ExposureUtils
import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD
import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.DialogVspaceUpdate32NewBinding
import com.gh.gamecenter.entity.AppEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus.*
import com.lightgame.utils.AppManager
import java.io.File
class VSpaceUpdate32NewDialogFragment : BaseDialogFragment() {
private var mAppEntity: AppEntity? = null
private var mGameId: String = ""
private var mGameName: String = ""
private val mDownloadUrl by lazy { mAppEntity?.url ?: "" }
private val mBinding by lazy { DialogVspaceUpdate32NewBinding.inflate(layoutInflater) }
private val mDataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.url == mDownloadUrl && isAdded) {
updateDownloadButton(downloadEntity)
}
}
override fun onDataInit(downloadEntity: DownloadEntity) {
onDataChanged(downloadEntity)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAppEntity = arguments?.get(KEY_APP_ENTITY_32) as AppEntity
mGameId = arguments?.getString(EntranceConsts.KEY_GAME_ID) ?: ""
mGameName = arguments?.getString(EntranceConsts.KEY_GAME_NAME) ?: ""
}
@SuppressLint("ClickableViewAccessibility")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mViewModel = viewModelProvider<VSpaceDialogFragment.VSpaceDialogViewModel>()
mViewModel.packageLiveData.observe(this) {
if (it.packageName == VHelper.VSPACE_32BIT_NEW_PACKAGENAME) {
dismissAllowingStateLoss()
}
}
val downloadSnapshot = DownloadManager.getInstance()
.getDownloadEntitySnapshotByPackageName(VHelper.VSPACE_32BIT_NEW_PACKAGENAME)
mBinding.downloadBtn.text = if (downloadSnapshot?.status == done) "安装" else "下载"
mBinding.downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
mBinding.contentTv.text = "$mGameName》需安装完整的畅玩服务组件,安装后即可给您带来急速的畅玩体验~"
mBinding.downloadBtn.setOnClickListener {
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_update_tip_dialog_click", mGameId, mGameName)
if (downloadSnapshot?.status == done) {
if (!File(downloadSnapshot.path).exists()) {
ToastUtils.toast("畅玩组件已损坏,即将重新下载")
DownloadManager.getInstance().cancel(downloadSnapshot.url)
DownloadManager.getInstance().add(downloadSnapshot)
} else {
PackageInstaller.install(requireContext(), downloadSnapshot)
}
} else {
val downloadEntity = DownloadEntity()
val name = "畅玩游戏助手V" + mAppEntity?.version
val downloadId = PackageInstaller.createDownloadId(name)
downloadEntity.url = mDownloadUrl
downloadEntity.name = name
downloadEntity.platform = "官方版"
downloadEntity.gameId = Constants.HALO_FUN_NEW_32_GAME_ID
downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk")
downloadEntity.packageName = VHelper.VSPACE_32BIT_NEW_PACKAGENAME
downloadEntity.addMetaExtra(DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200")
val gameEntity = GameEntity(downloadEntity.gameId, downloadEntity.name)
gameEntity.gameVersion = mAppEntity?.version ?: ""
// 确定下载类型
val downloadType =
if (arguments?.getBoolean(VSpaceDialogFragment.KEY_IS_UPDATE) == true) UPDATE else DOWNLOAD
downloadEntity.exposureTrace = ExposureUtils.logADownloadExposureEvent(
gameEntity,
downloadEntity.platform,
null,
downloadType
).toJson()
AppExecutor.uiExecutor.executeWithDelay({
DownloadManager.getInstance().cancel(mDownloadUrl)
DownloadManager.getInstance().add(downloadEntity)
}, 200)
DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity, "开始")
}
}
}
override fun onStart() {
super.onStart()
DownloadManager.getInstance().addObserver(mDataWatcher)
// 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
// 手动再检查一下安装状态,避免出现已安装但是没有 dismiss 弹窗的问题
if (PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.VSPACE_32BIT_NEW_PACKAGENAME)
&& mAppEntity?.version == PackageUtils.getVersionNameByPackageName(VHelper.VSPACE_32BIT_NEW_PACKAGENAME)
) {
dismissAllowingStateLoss()
}
}
override fun onStop() {
super.onStop()
DownloadManager.getInstance().removeObserver(mDataWatcher)
}
private fun updateDownloadButton(downloadEntity: DownloadEntity) {
val downloadBtn = mBinding.downloadBtn
downloadBtn.progress = (downloadEntity.progress * 10).toInt()
when (downloadEntity.status) {
downloading -> {
downloadBtn.setText(R.string.pause)
downloadBtn.progress = (downloadEntity.percent * 10).toInt()
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
downloadBtn.setOnClickListener {
DownloadManager.getInstance().pause(mDownloadUrl)
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_update_tip_dialog_click", mGameId, mGameName)
}
}
pause -> {
downloadBtn.setText(R.string.resume)
downloadBtn.setOnClickListener {
DownloadManager.getInstance().resume(downloadEntity, true)
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_update_tip_dialog_click", mGameId, mGameName)
}
}
overflow,
timeout,
neterror,
diskisfull,
waiting,
subscribe -> {
downloadBtn.setText(R.string.waiting)
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
downloadBtn.setOnClickListener {
DownloadManager.getInstance().resume(downloadEntity, false)
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_update_tip_dialog_click", mGameId, mGameName)
}
}
done -> {
downloadBtn.setText(R.string.install)
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
downloadBtn.setOnClickListener {
if (!File(downloadEntity.path).exists()) {
ToastUtils.toast("畅玩组件已损坏,即将重新下载")
DownloadManager.getInstance().cancel(downloadEntity.url)
DownloadManager.getInstance().add(downloadEntity)
} else {
PackageInstaller.install(requireContext(), downloadEntity)
NewFlatLogUtils.logHaloFun32DialogEvent(
"halo_fun_32_update_tip_dialog_click",
mGameId,
mGameName
)
}
}
}
cancel,
hijack,
notfound,
uncertificated,
unqualified -> {
downloadBtn.text = "下载"
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
downloadBtn.setOnClickListener {
DownloadManager.getInstance().resume(downloadEntity, true)
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_update_tip_dialog_click", mGameId, mGameName)
}
}
else -> {
// do nothing
}
}
}
companion object {
const val KEY_APP_ENTITY_32 = "app_entity_32"
const val KEY_AUTO_DOWNLOAD = "auto_download"
const val KEY_IS_UPDATE = "is_update"
@JvmStatic
fun showDownloadDialog(
context: Context?,
appEntity32: AppEntity,
autoDownload: Boolean = false,
isUpdate: Boolean = false,
gameId: String = "",
gameName: String = ""
) {
val fragmentActivity: FragmentActivity = if (context is FragmentActivity) {
context
} else {
val currentActivity = AppManager.getInstance().currentActivity()
if (currentActivity is FragmentActivity) {
currentActivity
} else {
throw IllegalStateException("current activity context must be FragmentActivity")
}
}
// 防止重复弹出
if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return
NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_update_tip_dialog_show", gameId, gameName)
val downloadDialog = VSpaceUpdate32NewDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_APP_ENTITY_32, appEntity32)
putString(EntranceConsts.KEY_GAME_ID, gameId)
putString(EntranceConsts.KEY_GAME_NAME, gameName)
putBoolean(KEY_AUTO_DOWNLOAD, autoDownload)
putBoolean(KEY_IS_UPDATE, isUpdate)
}
}
downloadDialog.show(
fragmentActivity.supportFragmentManager,
VSpaceUpdate32NewDialogFragment::class.java.name
)
}
@JvmStatic
fun showDownloadDialog(
context: Context?,
appEntity32: AppEntity,
gameEntity: GameEntity?,
autoDownload: Boolean = false,
isUpdate: Boolean = false
) {
showDownloadDialog(
context,
appEntity32,
autoDownload,
isUpdate,
gameEntity?.id ?: "",
gameEntity?.name ?: ""
)
}
private fun hasDialogDisplayedInCurrentActivity(fragmentActivity: FragmentActivity): Boolean {
val fragments: List<Fragment> = fragmentActivity.supportFragmentManager.fragments
fragments.forEach { fragment ->
if (fragment is VSpaceUpdate32NewDialogFragment) return true
}
return false
}
}
}

View File

@ -320,7 +320,7 @@ class GAppsDownloadDialogFragment : BaseBottomDialogFragment<DialogGappsDownload
context?.let {
mIsInstalling = true
VHelper.batchInstall(it, installFileMap)
VHelper.batchInstall(it, installFileMap, mTriggerPackageName)
}
runOnUiThread {

View File

@ -20,6 +20,7 @@ import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.core.BuildConfig
import com.lg.vspace.VirtualAppManager
import com.muugi.shortcut.core.Executor
import com.muugi.shortcut.core.Shortcut
@ -89,8 +90,8 @@ class ShortcutManager private constructor() {
* 知道游戏id和包名创建桌面图标
*/
fun tryCreateShortCut(context: Context, gameId: String, gamePkg: String, result: OnCreateShortcutResult) {
VHelper.postOnInitialized {
val downloadEntity = VHelper.getVDownloadEntitySnapshot(gameId, gamePkg)
val downloadEntity = VHelper.getVDownloadEntitySnapshot(gameId, gamePkg)
val createShortcutLambda = {
runOnUiThread {
if (downloadEntity == null) {
result.failed()
@ -100,6 +101,11 @@ class ShortcutManager private constructor() {
}
}
}
if (VHelper.isInnerInstalled(gamePkg)) {
createShortcutLambda.invoke()
} else {
VHelper.postOnInitialized(createShortcutLambda)
}
}
@ -185,25 +191,7 @@ class ShortcutManager private constructor() {
}
}
/**
* 获取游戏快捷方式跳转Intent
* 直接启动游戏
*/
private fun getIntent(gameEntity: GameEntity): Intent {
val intent = mDelegateManager.getStartGameIntent(
gameEntity.getUniquePackageName(),
gameEntity.id,
gameEntity.name ?: "unknown",
gameEntity.icon ?: "",
MetaUtil.getBase64EncodedAndroidId(),
HaloApp.getInstance().gid,
com.gh.gamecenter.BuildConfig.VERSION_NAME,
HaloApp.getInstance().channel,
"", ""
)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
return intent
}
/**
* 获取游戏快捷方式跳转Intent

View File

@ -46,6 +46,7 @@ import com.gh.common.videolog.VideoRecordUtils;
import com.gh.download.simple.DownloadMessageHandler;
import com.gh.download.simple.SimpleDownloadDatabase;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.Injection;
import com.gh.gamecenter.common.constant.Config;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.RouteConsts;
@ -80,8 +81,11 @@ 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.lg.ndownload.DownloadDbManager;
import com.lg.vspace.VaApp;
import com.lightgame.utils.Utils;
import com.llew.huawei.verifier.LoadedApkHuaWei;
import com.lody.virtual.client.core.VirtualCore;
import com.shuyu.gsyvideoplayer.cache.CacheFactory;
import com.shuyu.gsyvideoplayer.player.PlayerFactory;
@ -207,6 +211,7 @@ public class HaloApp extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
VaApp.get().onCreate(this);
initArouter();
mInstance = this;
@ -350,7 +355,7 @@ public class HaloApp extends MultiDexApplication {
PackageRepository.initData();
PackageHelper.refreshLocalPackageList();
PackageHelper.refreshList();
PackageHelper.initList();
initReceiver();
initPackageChangesReceiver();
@ -375,6 +380,7 @@ public class HaloApp extends MultiDexApplication {
});
}
}, delay);
VaApp.get().startSensorLogService();
}
private void initArouter() {
@ -525,6 +531,7 @@ public class HaloApp extends MultiDexApplication {
LoadedApkHuaWei.hookHuaWeiVerifier(this);
DownloadMessageHandler.INSTANCE.init(SimpleDownloadDatabase.getInstance().downloadDao());
VHelper.INSTANCE.preparePluginUpdate();
});
}
@ -616,6 +623,7 @@ public class HaloApp extends MultiDexApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
VaApp.get().attachBaseContext(this, base);
for (IApplication application : mApplicationList) {
application.attachBaseContext();
}

View File

@ -118,7 +118,7 @@ class RealNameInfoFragment : ToolbarFragment() {
) {
DirectUtils.directToWebView(
requireContext(),
"https://and-static.ghzs66.com/page/privacy_policies/Identity_information.html",
"https://resource.ghzs.com/page/privacy_policies/Identity_information.html",
"(实名认证)"
)
}

View File

@ -153,7 +153,7 @@ class UserInfoFragment : ToolbarFragment() {
MtaHelper.onEvent("个人主页详情", "个人中心", "账号安全指南")
DirectUtils.directToWebView(
requireContext(),
"https://and-static.ghzs66.com/page/guide_page/safety_guide.html",
"https://resource.ghzs.com/page/guide_page/safety_guide.html",
"(个人中心)"
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

View File

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="6dp"
android:viewportWidth="12"
android:viewportHeight="6">
<path
android:strokeWidth="1"
android:pathData="M10,1L6,5L2,1"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="@color/text_neutral"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="6dp"
android:viewportWidth="8"
android:viewportHeight="6">
<path
android:strokeWidth="1"
android:pathData="M7,1.5L4,4.5L1,1.5"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="@color/text_neutral"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="6dp"
android:height="12dp"
android:viewportWidth="6"
android:viewportHeight="12">
<path
android:strokeWidth="1"
android:pathData="M1,2L5,6L1,10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="@color/text_neutral"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="5dp"
android:height="8dp"
android:viewportWidth="5"
android:viewportHeight="8">
<path
android:strokeWidth="1"
android:pathData="M1,1L4,4L1,7"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="@color/text_neutral"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<group>
<clip-path
android:pathData="M0,0h12v12h-12z"/>
<path
android:pathData="M1.646,1.646C1.842,1.451 2.158,1.451 2.354,1.646L6,5.293L9.646,1.646C9.842,1.451 10.158,1.451 10.354,1.646C10.549,1.842 10.549,2.158 10.354,2.354L6.707,6L10.354,9.646C10.549,9.842 10.549,10.158 10.354,10.354C10.158,10.549 9.842,10.549 9.646,10.354L6,6.707L2.354,10.354C2.158,10.549 1.842,10.549 1.646,10.354C1.451,10.158 1.451,9.842 1.646,9.646L5.293,6L1.646,2.354C1.451,2.158 1.451,1.842 1.646,1.646Z"
android:fillColor="@color/text_neutral"
android:fillType="evenOdd"/>
</group>
</vector>

View File

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportWidth="8"
android:viewportHeight="8">
<group>
<clip-path
android:pathData="M0,0h8v8h-8z"/>
<path
android:pathData="M0.6464,0.6465C0.8417,0.4512 1.1583,0.4512 1.3535,0.6465L4,3.2929L6.6465,0.6465C6.8417,0.4512 7.1583,0.4512 7.3535,0.6465C7.5488,0.8417 7.5488,1.1583 7.3535,1.3536L4.7071,4L7.3535,6.6465C7.5488,6.8417 7.5488,7.1583 7.3535,7.3536C7.1583,7.5488 6.8417,7.5488 6.6465,7.3536L4,4.7071L1.3535,7.3536C1.1583,7.5488 0.8417,7.5488 0.6464,7.3536C0.4512,7.1583 0.4512,6.8417 0.6464,6.6465L3.2929,4L0.6464,1.3536C0.4512,1.1583 0.4512,0.8417 0.6464,0.6465Z"
android:fillColor="@color/text_neutral"
android:fillType="evenOdd"/>
</group>
</vector>

View File

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<group>
<clip-path
android:pathData="M0,0h12v12h-12z"/>
<path
android:pathData="M6,1C6.276,1 6.5,1.224 6.5,1.5V5.5H10.5C10.776,5.5 11,5.724 11,6C11,6.276 10.776,6.5 10.5,6.5H6.5V10.5C6.5,10.776 6.276,11 6,11C5.724,11 5.5,10.776 5.5,10.5V6.5H1.5C1.224,6.5 1,6.276 1,6C1,5.724 1.224,5.5 1.5,5.5H5.5V1.5C5.5,1.224 5.724,1 6,1Z"
android:fillColor="@color/text_neutral"
android:fillType="evenOdd"/>
</group>
</vector>

View File

@ -1,14 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportWidth="8"
android:viewportHeight="8">
<group>
<clip-path
android:pathData="M0,0h8v8h-8z"/>
<path
android:pathData="M4,0C4.2761,0 4.5,0.2239 4.5,0.5V3.5H7.5C7.7761,3.5 8,3.7239 8,4C8,4.2761 7.7761,4.5 7.5,4.5H4.5V7.5C4.5,7.7761 4.2761,8 4,8C3.7239,8 3.5,7.7761 3.5,7.5V4.5H0.5C0.2239,4.5 0,4.2761 0,4C0,3.7239 0.2239,3.5 0.5,3.5H3.5V0.5C3.5,0.2239 3.7239,0 4,0Z"
android:fillColor="@color/text_neutral"
android:fillType="evenOdd"/>
</group>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportWidth="8"
android:viewportHeight="8">
<path
android:pathData="M6.4395,2C7.0684,2 7.418,2.7274 7.0252,3.2185L4.5856,6.2679C4.2854,6.6432 3.7146,6.6432 3.4144,6.2679L0.9748,3.2185C0.582,2.7274 0.9316,2 1.5605,2H6.4395Z"
android:fillColor="@color/text_neutral"/>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportWidth="8"
android:viewportHeight="8">
<path
android:pathData="M6.4395,6C7.0684,6 7.418,5.2726 7.0252,4.7815L4.5856,1.7321C4.2854,1.3568 3.7146,1.3568 3.4144,1.7321L0.9748,4.7815C0.582,5.2726 0.9316,6 1.5605,6H6.4395Z"
android:fillColor="@color/text_neutral"/>
</vector>

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/background_shape_white_radius_12_top_only"
android:descendantFocusability="blocksDescendants">
<View
android:id="@+id/bgView"
android:layout_width="match_parent"
android:layout_height="98dp"
android:background="@drawable/vspace_dialog_top_background"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="88dp"
android:layout_height="20dp"
android:layout_marginTop="39dp"
android:src="@drawable/ic_smooth_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/descTv"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:includeFontPadding="false"
android:lineSpacingExtra="4dp"
android:textColor="@color/text_subtitle"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bgView"
tools:text="《XXX》需安装完整的畅玩服务组件安装后即可给您带来急速的畅玩体验~" />
<LinearLayout
android:id="@+id/downloadContainer"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/descTv">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="8dp"
android:background="@drawable/bg_shape_space_radius_8"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<TextView
android:id="@+id/vspace32Tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="32位组件"
android:textColor="@color/text_title"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.gh.gamecenter.feature.view.DownloadButton
android:id="@+id/downloadBtn"
android:layout_width="56dp"
android:layout_height="28dp"
app:download_button_show_progress="true"
app:download_button_text_size="@dimen/secondary_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<TextView
android:id="@+id/privacyPolicyTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="40dp"
android:text="《畅玩助手服务组件隐私协议》"
android:textColor="@color/theme_font"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/downloadContainer" />
<View
android:id="@+id/drag_close"
android:layout_width="match_parent"
android:layout_height="64dp"
android:clickable="false"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/default_dialog_width"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/background_shape_white_radius_8">
<TextView
android:id="@+id/titleTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginTop="24dp"
android:layout_marginRight="24dp"
android:drawablePadding="4dp"
android:gravity="center"
android:text="服务工具更新提示"
android:textColor="@color/text_title"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/contentTv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginTop="12dp"
android:layout_marginRight="24dp"
android:lineSpacingExtra="7dp"
android:textColor="@color/text_subtitle"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleTv"
tools:text="这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文,这里是正文。" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contentTv"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="8dp"
android:background="@drawable/bg_shape_space_radius_8"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<TextView
android:id="@+id/vspace32Tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="32位组件"
android:textColor="@color/text_title"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.gh.gamecenter.feature.view.DownloadButton
android:id="@+id/downloadBtn"
android:layout_width="56dp"
android:layout_height="28dp"
app:download_button_show_progress="true"
app:download_button_text_size="@dimen/secondary_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -122,6 +122,41 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/user_name">
<LinearLayout
android:id="@+id/levelContainer"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_marginRight="8dp"
android:background="@drawable/bg_user_level"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:layout_width="10dp"
android:layout_height="10dp"
android:src="@drawable/ic_level" />
<TextView
android:id="@+id/levelTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:paddingLeft="1dp"
android:textColor="@color/white"
android:textSize="10sp"
android:textStyle="bold|italic"
tools:text="Lv0" />
<ImageView
android:layout_width="6dp"
android:layout_height="8dp"
android:src="@drawable/ic_user_more" />
</LinearLayout>
<RelativeLayout
android:id="@+id/badge_container"
android:layout_width="wrap_content"

View File

@ -1,6 +1,5 @@
<com.gh.gamecenter.common.view.MaterializedConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
@ -30,7 +29,7 @@
android:layout_height="40dp"
android:background="@color/home_realname_error"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/installApiContainer"
app:layout_constraintBottom_toTopOf="@+id/bottomTabContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
@ -42,8 +41,7 @@
android:src="@drawable/ic_realname_error_hint"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/realNameErrorHintTv"
@ -79,60 +77,6 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/installApiContainer"
android:layout_width="0dp"
android:layout_height="52dp"
android:background="@color/ui_surface"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/bottomTabContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primary_theme_10" />
<ImageView
android:id="@+id/installApiCloseIv"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginStart="16dp"
android:src="@drawable/ic_install_api_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/installApiContentTv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:text="您未授予已安装列表权限,可能导致无法安装及更新等异常情况,建议开启权限!"
android:textSize="@dimen/secondary_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/installApiBtn"
app:layout_constraintStart_toEndOf="@id/installApiCloseIv"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/installApiBtn"
style="@style/BtnSmallStyle"
android:layout_width="64dp"
android:layout_height="28dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_common_button_fill_gradient_blue"
android:text="去开启"
android:textColor="@color/text_aw_primary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/bottomTabContainer"
android:layout_width="0dp"

View File

@ -197,9 +197,9 @@
<string name="concern_cancel_failure">取消失敗,請稍後再試</string>
<string name="third_party_sdk_title">光環助手接入第三方SDK目錄</string>
<string name="third_party_sdk_statement_url">https://and-static.ghzs66.com/page/third_party_sdk/index.html</string>
<string name="third_party_sdk_statement_url">https://resource.ghzs.com/page/third_party_sdk/index.html</string>
<string name="comment_rules_title">光環助手評論規則</string>
<string name="comment_rules_url">https://and-static.ghzs66.com/page/rule_page/comment_rules.html</string>
<string name="comment_rules_url">https://resource.ghzs.com/page/rule_page/comment_rules.html</string>
<string name="collection_cancel">取消收藏</string>
<string name="collection_cancel_failure">取消收藏失敗</string>
<string name="collection_success">收藏成功</string>
@ -307,14 +307,14 @@
<string name="share_news_article_url">https://m.ghzs666.com/article/%1$s</string>
<string name="comment_hide_hint">該內容已被刪除</string>
<string name="personal_home_rating_command">%1$s 在 <Data><![CDATA[<font color="#1383EB">%2$s</font>]]></Data> 發表了評論</string>
<string name="upload_game_policy_url">https://and-static.ghzs66.com/page/game_rule/game_rule.html</string>
<string name="info_list_url">https://and-static.ghzs66.com/page/privacy_policies/Personal_information_collection_list.html</string>
<string name="sdk_list_url">https://and-static.ghzs66.com/page/privacy_policies/sdk_directory.html</string>
<string name="permission_and_usage_url">https://and-static.ghzs66.com/page/privacy_policies/Permission_Usage.html</string>
<string name="upload_game_policy_url">https://resource.ghzs.com/page/game_rule/game_rule.html</string>
<string name="info_list_url">https://resource.ghzs.com/page/privacy_policies/Personal_information_collection_list.html</string>
<string name="sdk_list_url">https://resource.ghzs.com/page/privacy_policies/sdk_directory.html</string>
<string name="permission_and_usage_url">https://resource.ghzs.com/page/privacy_policies/Permission_Usage.html</string>
<string name="children_policy_url">https://resource.junrui66.com/page/privacy_policies/Child_privacy_statement_GA.html</string>
<string name="community_rule_title">問答版塊規則</string>
<string name="community_rule_url">https://and-static.ghzs66.com/page/section_rule/section_rule.html</string>
<string name="community_rule_url">https://resource.ghzs.com/page/section_rule/section_rule.html</string>
<string name="upload_protocol">我已閱讀並同意《視頻上傳服務準則》</string>
@ -327,7 +327,7 @@
<string name="upload_game_category_hint">分類<Data><![CDATA[<font color="#ff4147">*</font>]]></Data></string>
<string name="upload_game_video_source_hint">視頻來源<Data><![CDATA[<font color="#ff4147">*</font>]]></Data></string>
<string name="upload_protocol_url"> https://and-static.ghzs66.com/page/video_rule/video_rule.html</string>
<string name="upload_protocol_url"> https://resource.ghzs.com/page/video_rule/video_rule.html</string>
<string name="upload_protocol_title">視頻上傳服務準則</string>
<string name="video_upload_draft_dialog_content">草稿保存之後會關閉視頻上傳頁面!下次可在<Data><![CDATA[<font color="#151515"><b>視頻投稿-草稿箱</b></font>]]></Data>中繼續上傳</string>

View File

@ -199,9 +199,9 @@
<string name="concern_cancel_failure">取消失败,请稍后再试</string>
<string name="third_party_sdk_title">光环助手接入第三方SDK目录</string>
<string name="third_party_sdk_statement_url">https://and-static.ghzs66.com/page/third_party_sdk/index.html</string>
<string name="third_party_sdk_statement_url">https://resource.ghzs.com/page/third_party_sdk/index.html</string>
<string name="comment_rules_title">光环助手评论规则</string>
<string name="comment_rules_url">https://and-static.ghzs66.com/page/rule_page/comment_rules.html</string>
<string name="comment_rules_url">https://resource.ghzs.com/page/rule_page/comment_rules.html</string>
<string name="collection_cancel">取消收藏</string>
<string name="collection_cancel_failure">取消收藏失败</string>
<string name="collection_success">收藏成功</string>
@ -309,14 +309,14 @@
<string name="share_news_article_url">https://m.ghzs666.com/article/%1$s</string>
<string name="comment_hide_hint">该内容已被删除</string>
<string name="personal_home_rating_command">%1$s 在 <Data><![CDATA[<font color="#1383EB">%2$s</font>]]></Data> 发表了评论</string>
<string name="upload_game_policy_url">https://and-static.ghzs66.com/page/game_rule/game_rule.html</string>
<string name="info_list_url">https://and-static.ghzs66.com/page/privacy_policies/Personal_information_collection_list.html</string>
<string name="sdk_list_url">https://and-static.ghzs66.com/page/privacy_policies/sdk_directory.html</string>
<string name="permission_and_usage_url">https://and-static.ghzs66.com/page/privacy_policies/Permission_Usage.html</string>
<string name="children_policy_url">https://and-static.ghzs66.com/page/privacy_policies/Child_privacy_statement.html</string>
<string name="upload_game_policy_url">https://resource.ghzs.com/page/game_rule/game_rule.html</string>
<string name="info_list_url">https://resource.ghzs.com/page/privacy_policies/Personal_information_collection_list.html</string>
<string name="sdk_list_url">https://resource.ghzs.com/page/privacy_policies/sdk_directory.html</string>
<string name="permission_and_usage_url">https://resource.ghzs.com/page/privacy_policies/Permission_Usage.html</string>
<string name="children_policy_url">https://resource.ghzs.com/page/privacy_policies/Child_privacy_statement.html</string>
<string name="community_rule_title">问答版块规则</string>
<string name="community_rule_url">https://and-static.ghzs66.com/page/section_rule/section_rule.html</string>
<string name="community_rule_url">https://resource.ghzs.com/page/section_rule/section_rule.html</string>
<string name="upload_protocol">我已阅读并同意《视频上传服务准则》</string>
@ -329,7 +329,7 @@
<string name="upload_game_category_hint">分类<Data><![CDATA[<font color="#ff4147">*</font>]]></Data></string>
<string name="upload_game_video_source_hint">视频来源<Data><![CDATA[<font color="#ff4147">*</font>]]></Data></string>
<string name="upload_protocol_url"> https://and-static.ghzs66.com/page/video_rule/video_rule.html</string>
<string name="upload_protocol_url"> https://resource.ghzs.com/page/video_rule/video_rule.html</string>
<string name="upload_protocol_title">视频上传服务准则</string>
<string name="video_upload_draft_dialog_content">草稿保存之后会关闭视频上传页面!下次可在<Data><![CDATA[<font color="#151515"><b>视频投稿-草稿箱</b></font>]]></Data>中继续上传</string>

View File

@ -5,11 +5,18 @@ apply from: 'vspace-bridge/config.gradle'
buildscript {
ext.kotlin_version = '1.7.20'
ext.shadow_version = '1.0.5'
repositories {
google()
jcenter()
mavenCentral()
maven {
url "https://nexus.shanqu.cc/repository/lightgame-public/"
credentials {
username("lg_android")
password("u9gZYH4MQEwLLQZK")
}
}
maven { url 'https://jitpack.io' }
maven { url "https://maven.google.com" }
}
@ -20,6 +27,7 @@ buildscript {
// 使用了 1.2.21 在蓝叠模拟器上无法进入首页? 但是不使用又会出现触发 V3 签名...
classpath 'io.github.leon406:AndResGuard-gradle-plugin:1.2.23'
classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:3.5.3'
classpath "com.lg.shadow.core:gradle-plugin:$shadow_version"
}
}
@ -48,11 +56,13 @@ allprojects {
maven { url 'https://developer.huawei.com/repo/' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
subprojects {
subproject ->
afterEvaluate {
if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
if (!project.name.startsWith("va-") && (subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
if (!android.compileSdkVersion) {
android {
compileSdkVersion rootProject.ext.compileSdkVersion

View File

@ -125,7 +125,7 @@ ext {
composeCompilerVersion = "1.3.2"
constraintlayoutCompose = "1.0.1"
sensorsDataVersion = "6.8.0"
sensorsDataVersion = "6.7.10"
documentfile = "1.0.1"
@ -138,4 +138,8 @@ ext {
acloudPush = "3.8.8.1"
jpushVersion = "5.2.4"
}
}
apply from: 'dependencies_vasdk.gradle'
apply from: "${pluginBasePath}/PluginConfig.gradle"
apply from: "${pluginBasePath}/VaConfig.gradle"

30
dependencies_vasdk.gradle Normal file
View File

@ -0,0 +1,30 @@
ext {
vaCompileSdkVersion = 33
vaMinSdkVersion = 21
vaTargetSdkVersion = 28
}
ext {
signing_storeFile = "${rootDir}/app/gh.keystore"
signing_storePassword = "20150318"
signing_keyAlias = "gh.keystore"
signing_keyPassword = "20150318"
va_proguard_rules = "${rootDir}/vasdk/proguard/proguard-rules.pro"
}
// android dependencies
// 光环助手dependencies.gradle已经有的就不用重复定义了
ext {
shadow_version = '1.0.5'
swipeRefresh = "1.1.0"
glide = "4.12.0"
mmkv = "1.2.8"
flycoTablayout = "3.0.0"
smartRefresh = "2.0.3"
versionCompare = "1.4.1"
boltsTasks = "1.4.0"
utilcodex = "com.blankj:utilcodex:1.30.4"
}

View File

@ -41,9 +41,5 @@ class ACloudPushProviderImpl : IPushProvider {
return ""
}
override fun cleanBadgeNumber(applicationContext: Context) {
// do nothing
}
override fun init(p0: Context?) {}
}

View File

@ -15,8 +15,6 @@ import com.lightgame.utils.Utils
object JPushHelper {
const val TAG = "JPushHelper"
private var badgeCount = 0 // 角标计数
fun init(applicationContext: Context) {
JPushInterface.setDebugMode(BuildConfig.DEBUG)
JPushInterface.init(applicationContext)
@ -47,20 +45,4 @@ object JPushHelper {
Utils.log(TAG, "bind error $it")
})
}
// 角标+1
fun appendBadgeNumber(applicationContext: Context) {
JPushInterface.setBadgeNumber(applicationContext, ++badgeCount)
}
// 角标-1
fun subtractBadgeNumber(applicationContext: Context) {
JPushInterface.setBadgeNumber(applicationContext, if (badgeCount > 0) --badgeCount else 0)
}
// 清除角标
fun cleanBadgeNumber(applicationContext: Context) {
badgeCount = 0
JPushInterface.setBadgeNumber(applicationContext, badgeCount)
}
}

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