diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 987ac2bafd..f6e1031bdb 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -295,7 +295,7 @@ public class PackageUtils { * 根据路径,获取apk的包名 */ public static String getPackageNameByPath(Context context, String path) { - + // 部分设备 (已知 vivo 5.1.1) 在调用 packageManager.getPackageArchiveInfo 获取比较大的 APK 文件时会出现 ANR // 大于 1G 的 APK 就走另类方法 if (isDeviceUnableToHandleBigApkFile(path)) { @@ -305,17 +305,17 @@ public class PackageUtils { } return getPackageNameByPathAlternative(path); } - + PackageManager packageManager = context.getApplicationContext().getPackageManager(); PackageInfo info = packageManager.getPackageArchiveInfo(path, 0); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; return appInfo.packageName; } - + return null; } - + /** * 此设备是否不能调用 packageManager.getPackageArchiveInfo 来获取 APK 信息 * @@ -323,17 +323,17 @@ public class PackageUtils { */ public static boolean isDeviceUnableToHandleBigApkFile(String path) { if ("vivo".equals(Build.MANUFACTURER) - && (Build.VERSION_CODES.LOLLIPOP == Build.VERSION.SDK_INT) || Build.VERSION_CODES.LOLLIPOP_MR1 == Build.VERSION.SDK_INT) { + && (Build.VERSION_CODES.LOLLIPOP == Build.VERSION.SDK_INT) || Build.VERSION_CODES.LOLLIPOP_MR1 == Build.VERSION.SDK_INT) { File file = new File(path); - + if (file != null && file.length() > 1024 * 1024 * 1024) { return true; } } - + return false; } - + /** * 从 APK 文件里读包名的另类方法 * 部分设备 (已知 vivo 5.1.1) 在调用 packageManager.getPackageArchiveInfo 获取比较大的 APK 文件时会出现 ANR @@ -344,7 +344,6 @@ public class PackageUtils { * 3. demo 里 manifest 中 application 配置和 targetSdk 也改成与光环一样也不会出现 ANR * * 大概是光环的某个配置触发了系统的 bug ? - * */ private static String getPackageNameByPathAlternative(String path) { ApkFile apkParser = null; @@ -446,6 +445,20 @@ public class PackageUtils { return list; } + /* + * 获取所有已安装的软件的包名(包括系统应用) + */ + public static ArrayList getAllPackageNameIncludeSystemApps(Context context) { + ArrayList list = new ArrayList<>(); + List packageInfos = getInstalledPackages(context, 0); + for (PackageInfo packageInfo : packageInfos) { + if (!context.getPackageName().equals(packageInfo.packageName)) { + list.add(packageInfo.packageName); + } + } + return list; + } + public static JSONArray getAppList(Context context) { JSONArray jsonArray = new JSONArray(); try { diff --git a/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt b/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt index 777da18ce5..a11eee5087 100644 --- a/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt +++ b/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt @@ -1,6 +1,8 @@ package com.gh.download.server import android.content.Context +import android.os.Build +import android.util.Base64 import com.gh.common.constant.Config import com.gh.common.constant.Constants import com.gh.common.exposure.ExposureEntity @@ -8,13 +10,13 @@ import com.gh.common.exposure.ExposureEvent import com.gh.common.loghub.LoghubUtils import com.gh.common.util.* import com.gh.gamecenter.ShellActivity -import com.gh.gamecenter.manager.PackagesManager import com.google.gson.JsonObject import com.halo.assistant.HaloApp import com.lightgame.utils.Utils import org.json.JSONArray import org.json.JSONObject import java.io.File +import java.net.URLEncoder import java.util.* object BrowserInstallHelper { @@ -26,12 +28,22 @@ object BrowserInstallHelper { private val mContext by lazy { HaloApp.getInstance().application } fun downloadFile(filePath: String) { - val fileName = filePath.substringAfterLast(File.separator).removeSuffix(DownloadServer.APK_SUFFIX) + var fileName = filePath.substringAfterLast(File.separator) + // 山寨机没有 .apk 后缀但有 Content-Type 管用,还是给它补上 .apk 后缀 + if (!mServer.isBuggyDevice) { + fileName = fileName.removeSuffix(DownloadServer.APK_SUFFIX) + } + val downloadUrl = "http://127.0.0.1:$PORT/$fileName" if (!mServer.isAlive) startServer() mFileNameSet.add(fileName) - DirectUtils.directToExternalBrowser(mContext, "http://127.0.0.1:$PORT/$fileName") + if (mServer.isBuggyDevice) { + val encodedString = Base64.encodeToString(URLEncoder.encode(downloadUrl).trim().toByteArray(), Base64.NO_WRAP) + DirectUtils.directToExternalBrowser(mContext, "https://down-and.ghzs.com/redirect?location=base64($encodedString)") + } else { + DirectUtils.directToExternalBrowser(mContext, downloadUrl) + } } @JvmStatic @@ -57,11 +69,11 @@ object BrowserInstallHelper { fun shouldShowGameDetailUseBrowserToInstallHint(): Boolean { return if (isUseBrowserToInstallEnabled()) { - if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { - false - } else { +// if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { +// false +// } else { SPUtils.getBoolean(Constants.SP_SHOULD_SHOW_GAMEDETAIL_USE_BROWSER_TO_INSTALL_HINT, true) - } +// } } else { false } @@ -80,10 +92,17 @@ object BrowserInstallHelper { logOrdinaryBrowserEvent(Type.SWITCH_INSTALL_DIALOG) SPUtils.setBoolean(Constants.SP_SHOULD_SHOW_USE_BROWSER_TO_INSTALL_HINT, false) + + val manufacturer = Build.MANUFACTURER.toUpperCase(Locale.CHINA) + var contentText = "当前安装方式为助手安装,如果出现游戏无法安装的问题,可选择切换安装方式为“浏览器安装”" + if (manufacturer == "OPPO" || manufacturer == "VIVO") { + contentText = "当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”" + } + DialogHelper.showDialog( context, title = "温馨提示", - content = "当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”", + content = contentText, confirmText = "切换安装方式", cancelText = "继续下载", confirmClickCallback = { @@ -120,7 +139,7 @@ object BrowserInstallHelper { settingsEntity.installModel.packages?.let { for (packageName in it) { - if (PackagesManager.isInstalled(packageName)) { + if (mServer.allInstalledPackageList.contains(packageName)) { return true } } diff --git a/app/src/main/java/com/gh/download/server/DownloadServer.kt b/app/src/main/java/com/gh/download/server/DownloadServer.kt index 8a35b1fd28..a7e2dd9f56 100644 --- a/app/src/main/java/com/gh/download/server/DownloadServer.kt +++ b/app/src/main/java/com/gh/download/server/DownloadServer.kt @@ -2,6 +2,7 @@ package com.gh.download.server import com.gh.common.constant.Constants import com.gh.common.exposure.ExposureEvent +import com.gh.common.util.PackageUtils import com.gh.common.util.getMetaExtra import com.gh.common.util.toObject import com.gh.download.DownloadManager @@ -19,6 +20,10 @@ class DownloadServer(port: Int) : NanoHTTPD(port) { private val mPublishSubject: PublishSubject = PublishSubject.create() private val mCompositeDisposable: CompositeDisposable = CompositeDisposable() + val allInstalledPackageList by lazy { PackageUtils.getAllPackageNameIncludeSystemApps(HaloApp.getInstance().applicationContext) } + + // 是否是山寨机 + var isBuggyDevice: Boolean = false init { // 某些浏览器会开启多线程下载,如果不 throttle 的话会出现多次调用 @@ -29,6 +34,14 @@ class DownloadServer(port: Int) : NanoHTTPD(port) { .subscribe({ logBrowserDownload(it, false) }, {}) + + for (packageName in allInstalledPackageList) { + if (packageName.contains("com.freeme") || packageName.contains("com.zhuoyi")) { + isBuggyDevice = true + break + } + } + mCompositeDisposable.add(disposable) } @@ -37,7 +50,10 @@ class DownloadServer(port: Int) : NanoHTTPD(port) { headers: MutableMap?, parms: MutableMap?, files: MutableMap?): Response { - val filePath = FileUtils.getDownloadDir(HaloApp.getInstance()) + fileName + APK_SUFFIX + var filePath = FileUtils.getDownloadDir(HaloApp.getInstance()) + fileName + if (!filePath.contains(APK_SUFFIX)) { + filePath += APK_SUFFIX + } val file = File(filePath) mPublishSubject.onNext(filePath) @@ -45,7 +61,15 @@ class DownloadServer(port: Int) : NanoHTTPD(port) { return if (file.exists()) { val fileType = FileUtils.getFileMimeType(HaloApp.getInstance().applicationContext, filePath) ?: "application/vnd.android.package-archive" - newFixedLengthResponse(Response.Status.OK, fileType, DownloadFileInputStream(file), file.length()) + + // TODO 山寨机给了文件长度会下载失败,有空再看看为什么 + if (isBuggyDevice) { + newChunkedResponse(Response.Status.OK, fileType, DownloadFileInputStream(file)).apply { + addHeader("Content-Disposition", "inline; filename=\"$filePath") + } + } else { + newFixedLengthResponse(Response.Status.OK, fileType, DownloadFileInputStream(file), file.length()) + } } else { newFixedLengthResponse("找不到文件") } @@ -57,7 +81,7 @@ class DownloadServer(port: Int) : NanoHTTPD(port) { fun logBrowserDownload(path: String, isDownloadComplete: Boolean) { for (download in DownloadManager.getInstance(HaloApp.getInstance()).allDownloadEntity) { if (download.path == path) { - download.exposureTrace.toObject()?.let { + download.exposureTrace?.toObject()?.let { BrowserInstallHelper.logWebDownloadStarted(it, download.getMetaExtra(Constants.DOWNLOAD_ID), isDownloadComplete) } break