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(