diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 09456e3115..108e915f1f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -165,7 +165,8 @@ android:screenOrientation="portrait" /> + android:name="com.gh.gamecenter.WebActivity" + android:screenOrientation="portrait"/> Unit)? = null + var mCallBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { mView = inflater.inflate(R.layout.dialog_install_permission, null, false) @@ -56,7 +57,7 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() { closeTv.setOnClickListener { MtaHelper.onEvent(getEvent(), getKey(), "文案样式_点击以后再说") if (isXapk) { - mCallBack?.invoke() + mCallBack?.invoke(false) } dismiss() } @@ -77,9 +78,11 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) { - SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "") - SPUtils.setString(Constants.SP_XAPK_URL, "") - mCallBack?.invoke() + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "") + SPUtils.setString(Constants.SP_XAPK_URL, "") + } + mCallBack?.invoke(true) dismiss() } } @@ -90,27 +93,27 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() { companion object { @JvmStatic - fun show(activity: AppCompatActivity, downloadEntity: DownloadEntity, callBack: (() -> Unit)?) { + fun show(activity: AppCompatActivity, downloadEntity: DownloadEntity, callBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)?) { val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == downloadEntity.path.getExtension() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - callBack?.invoke() + callBack?.invoke(false) return } val haveInstallPermission = activity.packageManager.canRequestPackageInstalls() if (haveInstallPermission) { - callBack?.invoke() + callBack?.invoke(false) return } if (isXapk) { val xapkUnzipVersions = Config.getSettings()?.permissionPopupAppliedVersions?.xapkUnzip if (xapkUnzipVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) { - callBack?.invoke() + callBack?.invoke(false) return } } else { val installVersions = Config.getSettings()?.permissionPopupAppliedVersions?.install if (installVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) { - callBack?.invoke() + callBack?.invoke(false) return } } diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index b9aae9125e..69b22b6c14 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -53,15 +53,23 @@ object PackageInstaller { // TODO 此处可能遇到 activity 是 WXEntryActivity // TODO 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装! if (currentActivity is AppCompatActivity && !currentActivity.isFinishing) { - InstallPermissionDialogFragment.show(currentActivity, downloadEntity) { + InstallPermissionDialogFragment.show(currentActivity, downloadEntity) { isFromPermissionGrantedCallback -> // 取消状态栏下载完成的通知,若存在 downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES" DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity) - if (isXapk) { - XapkInstaller.install(context, downloadEntity, showUnzipToast) + if (isFromPermissionGrantedCallback && Build.VERSION.SDK_INT >= 31) { + val pm = context.packageManager + val intent = pm.getLaunchIntentForPackage(context.packageName) + val mainIntent = Intent.makeRestartActivityTask(intent!!.component) + context.startActivity(mainIntent) + Runtime.getRuntime().exit(0) } else { - install(context, downloadEntity.isPlugin, downloadEntity.path) + if (isXapk) { + XapkInstaller.install(context, downloadEntity, showUnzipToast) + } else { + install(context, downloadEntity.isPlugin, downloadEntity.path) + } } } } diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index 3e91730a04..05a3f6cd53 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -294,11 +294,6 @@ public class MainActivity extends BaseActivity { checkDialog(); } -// handler.postDelayed(() -> { -// PushHelper.postPushClickAction(this.getApplicationContext(), null); -// }, 2000); - - // 耗时操作 AppExecutor.getIoExecutor().execute(() -> { // 上传数据 @@ -311,9 +306,6 @@ public class MainActivity extends BaseActivity { // 初始化PlatformUtils PlatformUtils.getInstance(getApplicationContext()); -// // 友盟记录启动 -// PushAgent.getInstance(this).onAppStart(); - HomePluggableHelper.activationFilterData(); }); @@ -335,6 +327,9 @@ public class MainActivity extends BaseActivity { postAttentionVideoRecord(); deleteSimulatorGame(); + // 检查是否需要触发 XAPK 安装 + AppExecutor.getUiExecutor().executeWithDelay(this::resumeXapkInstallIfNeeded, 150); + QuickLoginHelper.getPhoneInfo(this); WechatBindHelper.getWechatConfig(null); initWBSDK(); @@ -1032,6 +1027,25 @@ public class MainActivity extends BaseActivity { } } + /** + * 重新触发 XAPK 安装流程 + * 因为 Android 12 起授予应用安装未知应用权限以后不触发进程重启,导致应用一直无法读写 android/data 目录 + * 所以这里再手动重启应用进程时再触发一回安装 + */ + private void resumeXapkInstallIfNeeded() { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { + String xapkUrl = SPUtils.getString(Constants.SP_XAPK_URL); + if (!TextUtils.isEmpty(xapkUrl)) { + DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(xapkUrl); + if (downloadEntity != null) { + PackageInstaller.install(this, downloadEntity, false); + } + } + SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, ""); + SPUtils.setString(Constants.SP_XAPK_URL, ""); + } + } + @Override protected boolean isAutoResetViewBackgroundEnabled() { return true; diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java index 6b895f7ba1..dcf91f31f8 100644 --- a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java +++ b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java @@ -5,6 +5,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.TextUtils; @@ -174,8 +175,10 @@ public class SplashScreenActivity extends BaseActivity { launchMainActivity(); } - SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, ""); - SPUtils.setString(Constants.SP_XAPK_URL, ""); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, ""); + SPUtils.setString(Constants.SP_XAPK_URL, ""); + } } private void showPrivacyDialog(ViewPager guideLayout) { diff --git a/app/src/main/java/com/gh/gamecenter/WebActivity.kt b/app/src/main/java/com/gh/gamecenter/WebActivity.kt index 5b13c74b9b..c915a2e006 100644 --- a/app/src/main/java/com/gh/gamecenter/WebActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/WebActivity.kt @@ -28,9 +28,6 @@ open class WebActivity : NormalActivity() { if (mIsFullScreen) { setTheme(R.style.AppFullScreenTheme) } - if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O) { - requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT - } super.onCreate(savedInstanceState) if (mIsFullScreen) { hideToolbar(true) diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt index 997e459533..de716158b7 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt @@ -38,7 +38,7 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) binding.horizontalRv.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING) binding.horizontalRv.isNestedScrollingEnabled = false - if (subjectEntity.data?.first()?.test?.testTime != null && mLastScrolledPosition == 0) { + if (subjectEntity.data?.firstOrNull()?.test?.testTime != null && mLastScrolledPosition == 0) { scrollToSpecificItemForTheFirstTime(subjectEntity) } } else { @@ -48,7 +48,7 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) if (mLastScrolledPosition != adapterPosition) { val offset = offsetable.getOffset(adapterPosition) if (offset == 0) { - if (subjectEntity.data?.first()?.test?.testTime != null && mLastScrolledPosition == 0) { + if (subjectEntity.data?.firstOrNull()?.test?.testTime != null && mLastScrolledPosition == 0) { scrollToSpecificItemForTheFirstTime(subjectEntity) } else { binding.horizontalRv.scrollToPosition(0) diff --git a/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt b/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt index 5e288849e2..cd992c946c 100644 --- a/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt @@ -1,13 +1,17 @@ package com.halo.assistant.fragment import android.annotation.SuppressLint +import android.app.Application import android.app.Dialog +import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Build import android.os.Bundle import android.provider.Settings import android.view.View +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModelProvider import com.airbnb.lottie.LottieAnimationView import com.gh.common.constant.Config @@ -51,6 +55,8 @@ class SettingsFragment : NormalFragment() { private var loadingDialog: Dialog? = null private var mUsageStatus = false + private val mViewModel: SettingViewModel by lazy { viewModelProvider() } + override fun getLayoutId() = 0 override fun getInflatedLayout() = FragmentSettingBinding.inflate(layoutInflater).apply { mBinding = this }.root @@ -94,13 +100,12 @@ class SettingsFragment : NormalFragment() { //判断隐私政策是否有更新 mBinding.privacyPolicyItem.redDot.visibility = if (checkPrivacyIsSame()) View.GONE else View.VISIBLE - runOnIoThread { - val cacheSize = getCacheSize() - runOnUiThread { - mBinding.cacheItem.contentTv.text = cacheSize - } + mViewModel.cacheSizeLiveData.observe(this) { + mBinding.cacheItem.contentTv.text = it } + mViewModel.getCacheSize() + mBinding.personalRecommendItem.switchLottie.setSwitchAnimation(SPUtils.getBoolean(PERSONAL_RECOMMEND_SP_KEY, true)) checkSizeIndex = SPUtils.getInt(FONT_SIZE_SP_KEY, 1) @@ -430,7 +435,7 @@ class SettingsFragment : NormalFragment() { if (loadingDialog != null) { loadingDialog!!.dismiss() } - mBinding.cacheItem.contentTv.text = getCacheSize() + mViewModel.getCacheSize() Utils.toast(context, "缓存清除成功") } @@ -499,43 +504,50 @@ class SettingsFragment : NormalFragment() { return currentMd5 == privacyMd5 } - // 获取缓存大小 - private fun getCacheSize(): String { - val ecDir = requireContext().externalCacheDir - var cacheLength: Long = getFolderSize(requireContext().cacheDir) - if (ecDir != null) { - cacheLength += getFolderSize(ecDir) - } - return long2Size(cacheLength) - } + class SettingViewModel(application: Application): AndroidViewModel(application) { + val cacheSizeLiveData = MutableLiveData() - private fun getFolderSize(folder: File): Long { - var size: Long = 0 - //忽略视频缓存 - if (folder.name == "video-cache" || folder.name == "exo") return size - size += folder.length() - if (folder.isDirectory) { - val files = folder.listFiles() - if (files == null || files.isEmpty()) return size - for (file in files) { - size += if (file.isDirectory) { - getFolderSize(file) - } else { - file.length() + // 获取缓存大小 + fun getCacheSize() { + runOnIoThread { + val ecDir = getApplication().externalCacheDir + var cacheLength: Long = getFolderSize(getApplication().cacheDir) + if (ecDir != null) { + cacheLength += getFolderSize(ecDir) } + cacheSizeLiveData.postValue(long2Size(cacheLength)) } } - return size - } - private fun long2Size(length: Long): String { - val m = length / 1024f / 1024f - var str = m.toString() - val index = str.lastIndexOf(".") - if (index != -1 && str.length > index + 3) { - str = str.substring(0, index + 3) + private fun long2Size(length: Long): String { + val m = length / 1024f / 1024f + var str = m.toString() + val index = str.lastIndexOf(".") + if (index != -1 && str.length > index + 3) { + str = str.substring(0, index + 3) + } + return str + "M" } - return str + "M" + + private fun getFolderSize(folder: File): Long { + var size: Long = 0 + //忽略视频缓存 + if (folder.name == "video-cache" || folder.name == "exo") return size + size += folder.length() + if (folder.isDirectory) { + val files = folder.listFiles() + if (files == null || files.isEmpty()) return size + for (file in files) { + size += if (file.isDirectory) { + getFolderSize(file) + } else { + file.length() + } + } + } + return size + } + } override fun onNightModeChange() { diff --git a/app/src/main/res/values-v26/style.xml b/app/src/main/res/values-v26/style.xml new file mode 100644 index 0000000000..2ef10712de --- /dev/null +++ b/app/src/main/res/values-v26/style.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file