diff --git a/app/src/main/assets/lottie/install_permission_switch.json b/app/src/main/assets/lottie/install_permission_switch.json new file mode 100644 index 0000000000..accac70aa8 --- /dev/null +++ b/app/src/main/assets/lottie/install_permission_switch.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":180,"w":96,"h":186,"nm":"画板 3","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"椭圆形","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.43],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[20]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":66,"s":[20]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":70,"s":[40]},{"t":80,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[48,150,0],"to":[0,-19,0],"ti":[0,19,0]},{"t":50,"s":[48,36,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":50,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":70,"s":[60,60,100]},{"t":76,"s":[80,80,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.125489994884,0.858824014664,0.956862986088,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":185,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"椭圆形","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4,"s":[0]},{"t":17,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":70,"s":[24,36,0],"to":[8,0,0],"ti":[-8,0,0]},{"t":89,"s":[72,36,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14,14],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":183,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"矩形","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":70,"s":[100]},{"t":83,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[48,36.062,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[32,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":9,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.758267998695,0.88582700491,0.899999976158,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":191,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"矩形","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":168,"s":[100]},{"t":177,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[48,36.062,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[32,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":9,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,0.965,0.8,0.5,0.988,0.851,0.745,1,0.976,0.737,0.69],"ix":9}},"s":{"a":0,"k":[-36.304,0],"ix":5},"e":{"a":0,"k":[16,0],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":66,"op":184,"st":6,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/constant/Config.java b/app/src/main/java/com/gh/common/constant/Config.java index 675a62607c..e543a40e15 100644 --- a/app/src/main/java/com/gh/common/constant/Config.java +++ b/app/src/main/java/com/gh/common/constant/Config.java @@ -5,8 +5,6 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.text.TextUtils; -import androidx.annotation.Nullable; - import com.gh.common.util.GsonUtils; import com.gh.common.util.PackageHelper; import com.gh.common.util.PackageUtils; @@ -25,6 +23,7 @@ import org.greenrobot.eventbus.EventBus; import java.util.List; +import androidx.annotation.Nullable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; @@ -241,6 +240,9 @@ public class Config { public static boolean isGameDomeSwitchOpen() { return getSettings() != null && getSettings().getGameDomeSwitch().equals("on"); } + public static boolean isPermissionPopupSwitchOpen() { + return getSettings() != null && getSettings().getPermissionPopupSwitch().equals("on"); + } public static void fixHideFunction() { SharedPreferences preferences = PreferenceManager. diff --git a/app/src/main/java/com/gh/common/dialog/InstallPermissionDialogFragment.kt b/app/src/main/java/com/gh/common/dialog/InstallPermissionDialogFragment.kt new file mode 100644 index 0000000000..8fd32c7f55 --- /dev/null +++ b/app/src/main/java/com/gh/common/dialog/InstallPermissionDialogFragment.kt @@ -0,0 +1,97 @@ +package com.gh.common.dialog + +import android.app.Activity.RESULT_OK +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.FragmentTransaction +import com.airbnb.lottie.LottieAnimationView +import com.gh.common.constant.Config +import com.gh.common.util.PermissionHelper +import com.gh.common.util.PermissionHelper.INSTALL_PERMISS_CODE +import com.gh.common.util.goneIf +import com.gh.gamecenter.R +import kotlin.random.Random + +class InstallPermissionDialogFragment : BaseTrackableDialogFragment() { + + lateinit var mView: View + var mCallBack: (() -> Unit)? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + mView = inflater.inflate(R.layout.dialog_install_permission, null, false) + return mView + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val closeTv = mView.findViewById(R.id.closeTv) + val closeIv = mView.findViewById(R.id.closeIv) + val activateTv = mView.findViewById(R.id.activateTv) + val switchLottie = mView.findViewById(R.id.switchLottie) + + switchLottie.setAnimation("lottie/install_permission_switch.json") + switchLottie.playAnimation() + + val randomNumber = Random.nextInt(2) + closeTv.goneIf(randomNumber == 0) + closeIv.goneIf(randomNumber != 0) + closeTv.setOnClickListener { + dismiss() + } + closeIv.setOnClickListener { closeTv.performClick() } + activateTv.setOnClickListener { + PermissionHelper.toInstallPermissionSetting(requireActivity()) + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISS_CODE) { + mCallBack?.invoke() + dismiss() + } + } + + override fun getEvent(): String = "安装引导弹窗" + + override fun getKey(): String = "引导弹窗" + + companion object { + @JvmStatic + fun getInstance(activity: AppCompatActivity, callBack: (() -> Unit)?) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + callBack?.invoke() + return + } + if (!Config.isPermissionPopupSwitchOpen()) { + callBack?.invoke() + return + } + val haveInstallPermission = activity.packageManager.canRequestPackageInstalls(); + if (haveInstallPermission) { + callBack?.invoke() + return + + } + var installPermissionDialogFragment = activity.supportFragmentManager.findFragmentByTag(InstallPermissionDialogFragment::class.java.simpleName) as? InstallPermissionDialogFragment + if (installPermissionDialogFragment != null) { + installPermissionDialogFragment.mCallBack = callBack + val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction() + transaction.show(installPermissionDialogFragment) + transaction.commit() + } else { + installPermissionDialogFragment = InstallPermissionDialogFragment().apply { + mCallBack = callBack + } + installPermissionDialogFragment.show(activity.supportFragmentManager, InstallPermissionDialogFragment::class.java.simpleName) + } + } + } +} \ No newline at end of file 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 e4a4362907..7102ea5875 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -5,13 +5,16 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Build +import androidx.appcompat.app.AppCompatActivity import androidx.core.content.FileProvider import com.gh.common.constant.Constants +import com.gh.common.dialog.InstallPermissionDialogFragment import com.gh.common.xapk.XapkInstaller import com.gh.gamecenter.BuildConfig import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity import com.lightgame.download.FileUtils +import com.lightgame.utils.AppManager import com.lightgame.utils.Utils import java.io.File @@ -35,15 +38,17 @@ object PackageInstaller { */ @JvmStatic fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) { - // 取消状态栏下载完成的通知,若存在 - downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES" - DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity) + InstallPermissionDialogFragment.getInstance(AppManager.getInstance().currentActivity() as AppCompatActivity) { + // 取消状态栏下载完成的通知,若存在 + downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES" + DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity) - val pkgPath = downloadEntity.path - if (XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()) { - XapkInstaller.install(context, downloadEntity, showUnzipToast) - } else { - install(context, downloadEntity.path) + val pkgPath = downloadEntity.path + if (XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()) { + XapkInstaller.install(context, downloadEntity, showUnzipToast) + } else { + install(context, downloadEntity.path) + } } } diff --git a/app/src/main/java/com/gh/common/util/PermissionHelper.kt b/app/src/main/java/com/gh/common/util/PermissionHelper.kt index 6f74a7b485..0577383b73 100644 --- a/app/src/main/java/com/gh/common/util/PermissionHelper.kt +++ b/app/src/main/java/com/gh/common/util/PermissionHelper.kt @@ -8,11 +8,14 @@ import android.content.Intent import android.net.Uri import android.os.Build import android.provider.Settings +import androidx.annotation.RequiresApi import androidx.fragment.app.FragmentActivity import com.tbruyelle.rxpermissions2.RxPermissions object PermissionHelper { + const val INSTALL_PERMISS_CODE = 100 + @JvmStatic fun requestReadPhoneStateAndStoragePermissionFromStartUp(context: Context) { if (context is FragmentActivity) { @@ -221,5 +224,18 @@ object PermissionHelper { } + /** + * 开启安装未知来源权限 + */ + fun toInstallPermissionSetting(activity: Activity) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + toSystemConfig(activity) + } else { + val packageURI = Uri.fromParts("package", activity.packageName, null) + val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI) + activity.startActivityForResult(intent, INSTALL_PERMISS_CODE) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt index 3d2e48b21d..f75559b20d 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt @@ -29,7 +29,9 @@ data class SettingsEntity( @SerializedName("video_advertisement") var videoAdvertisement: VideoAds? = null, //新增字段video_advertisement,可能为空,代表广告关闭 @SerializedName("game_dome_switch") - var gameDomeSwitch: String = ""//试玩显示开关,on打开 + var gameDomeSwitch: String = "",//试玩显示开关,on打开 + @SerializedName("permission_popup_switch") + var permissionPopupSwitch: String = "off"//权限引导弹窗开关,on/off ) { fun setCommunityEntrance(communityEntrance: String) { diff --git a/app/src/main/res/drawable-xxhdpi/ic_install_permission_close.png b/app/src/main/res/drawable-xxhdpi/ic_install_permission_close.png new file mode 100644 index 0000000000..281dab00a3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_install_permission_close.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/bg_install_permission.webp b/app/src/main/res/drawable-xxxhdpi/bg_install_permission.webp new file mode 100644 index 0000000000..596f110b58 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/bg_install_permission.webp differ diff --git a/app/src/main/res/drawable/bg_install_permission_btn.xml b/app/src/main/res/drawable/bg_install_permission_btn.xml new file mode 100644 index 0000000000..ce98ce2deb --- /dev/null +++ b/app/src/main/res/drawable/bg_install_permission_btn.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_install_permission.xml b/app/src/main/res/layout/dialog_install_permission.xml new file mode 100644 index 0000000000..5b29ec0562 --- /dev/null +++ b/app/src/main/res/layout/dialog_install_permission.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file