diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a2f324c320..d464bfaa65 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,6 +11,8 @@
+
diff --git a/app/src/main/java/com/gh/common/dialog/ManagerAllFilesPermissionDialogFragment.kt b/app/src/main/java/com/gh/common/dialog/ManagerAllFilesPermissionDialogFragment.kt
new file mode 100644
index 0000000000..8487e0f285
--- /dev/null
+++ b/app/src/main/java/com/gh/common/dialog/ManagerAllFilesPermissionDialogFragment.kt
@@ -0,0 +1,68 @@
+package com.gh.common.dialog
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.provider.Settings
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.RequiresApi
+import androidx.appcompat.app.AppCompatActivity
+import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding
+import com.lightgame.dialog.BaseDialogFragment
+
+@RequiresApi(Build.VERSION_CODES.R)
+class ManagerAllFilesPermissionDialogFragment : BaseDialogFragment() {
+ private val mBinding by lazy { DialogAlertDefaultBinding.inflate(layoutInflater) }
+ private var mCallBack: (() -> Unit)? = null
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ return mBinding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mBinding.run {
+ titleTv.text = "请求权限"
+ titleTv.gravity = Gravity.CENTER
+ contentTv.text = "需要所有文件访问权限,请打开权限设置页面"
+
+ confirmTv.setOnClickListener {
+ val intent = Intent().apply {
+ action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
+ data = Uri.fromParts("package", requireContext().packageName, null)
+ }
+ requireActivity().startActivityForResult(intent, REQUEST_CODE)
+ }
+ cancelTv.setOnClickListener {
+ dismissAllowingStateLoss()
+ }
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == REQUEST_CODE && Environment.isExternalStorageManager()) {
+ mCallBack?.invoke()
+ dismissAllowingStateLoss()
+ }
+ }
+
+ companion object {
+ const val REQUEST_CODE = 1000
+
+ @JvmStatic
+ fun show(activity: AppCompatActivity, callback: () -> Unit) {
+ ManagerAllFilesPermissionDialogFragment().apply {
+ mCallBack = callback
+ }.show(
+ activity.supportFragmentManager,
+ ManagerAllFilesPermissionDialogFragment::class.java.name
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/xapk/XapkInstaller.kt b/app/src/main/java/com/gh/common/xapk/XapkInstaller.kt
index 1f19298b4a..342e7d2c91 100644
--- a/app/src/main/java/com/gh/common/xapk/XapkInstaller.kt
+++ b/app/src/main/java/com/gh/common/xapk/XapkInstaller.kt
@@ -4,8 +4,12 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
+import android.os.Environment
import android.provider.Settings
+import androidx.appcompat.app.AppCompatActivity
import com.gh.common.constant.Config
+import com.gh.common.dialog.ManagerAllFilesPermissionDialogFragment
+import com.gh.common.util.*
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadNotificationHelper
import com.gh.common.util.PackageInstaller
@@ -15,6 +19,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
+import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.xapk.XApkUnZipper
@@ -22,10 +27,7 @@ import com.gh.gamecenter.xapk.core.XApkFile
import com.gh.gamecenter.xapk.core.XApkUnZipCallback
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
-import com.gh.gamecenter.xapk.io.NonSplitApksOutput
-import com.gh.gamecenter.xapk.io.OBBFileOutput
-import com.gh.gamecenter.xapk.io.SplitApksOutput
-import com.gh.gamecenter.xapk.io.XApkFileOutput
+import com.gh.gamecenter.xapk.io.*
import com.gh.gamecenter.xapk.pi.IPackageInstaller
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
@@ -112,19 +114,38 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
return
}
- DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
- ?.let {
- unzipXapkFile(it)
- if (showUnzipToast) {
- Utils.toast(mContext, "解压过程请勿退出光环助手!")
+ if (checkPermission(downloadEntity, showUnzipToast)) {
+ DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
+ ?.let {
+ unzipXapkFile(it)
+ if (showUnzipToast) {
+ Utils.toast(mContext, "解压过程请勿退出光环助手!")
+ }
}
- }
+ }
} else {
throwExceptionInDebug("如果是Apk包请使用PackageInstaller进行安装")
PackageInstaller.install(mContext, downloadEntity)
}
}
+ private fun checkPermission(downloadEntity: DownloadEntity, showUnzipToast: Boolean = false): Boolean {
+ // 安卓11以上系统需要开启所有文件访问权限
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
+ && !Environment.isExternalStorageManager()) {
+ CurrentActivityHolder.getCurrentActivity()?.let {
+ ManagerAllFilesPermissionDialogFragment.show(it as AppCompatActivity) {
+ unzipXapkFile(downloadEntity)
+ if (showUnzipToast) {
+ Utils.toast(mContext, "解压过程请勿退出光环助手!")
+ }
+ }
+ }
+ return false
+ }
+ return true
+ }
+
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
mXApkUnZipper.unzip(
XApkUnZipEntry(