From 3441bbc8f0e32e9f92cf1d214f2396aaef58b4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A8=E7=9A=84=E5=90=8D=E5=AD=97?= <您的邮箱> Date: Tue, 28 Oct 2025 20:25:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=81=A2=E5=A4=8D=20JSON=20=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E6=A3=80=E6=B5=8B=E6=9B=B4=E6=96=B0=EF=BC=8CGitHub=20?= =?UTF-8?q?API=20=E4=BD=9C=E4=B8=BA=E5=A4=87=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优先使用 XMBOX-Release 仓库的 JSON 文件检测更新 - JSON 检测失败时回退到 GitHub Releases API - 修复 v3.0.9 无法检测更新的问题 - 提升更新检测的兼容性和稳定性 --- .../java/com/fongmi/android/tv/Updater.java | 111 ++++++++++++++---- .../java/com/fongmi/android/tv/Updater.java | 96 +++++++++++---- 2 files changed, 161 insertions(+), 46 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/Updater.java b/app/src/leanback/java/com/fongmi/android/tv/Updater.java index 71eeedf5..f9583643 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/Updater.java +++ b/app/src/leanback/java/com/fongmi/android/tv/Updater.java @@ -20,6 +20,7 @@ import com.github.catvod.utils.Logger; import com.github.catvod.utils.Path; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import org.json.JSONArray; import org.json.JSONObject; import java.io.File; @@ -33,6 +34,7 @@ public class Updater implements Download.Callback { private boolean dev; private boolean forceCheck; // 是否为手动检查 private String latestVersion; // 存储检测到的最新版本 + private String releaseApkUrl; // 从 GitHub Release 获取的 APK 下载链接 private File getFile() { return Path.root("Download", "XMBOX-update.apk"); @@ -43,6 +45,12 @@ public class Updater implements Download.Callback { } private String getApk() { + // 优先使用从 GitHub Release 获取的 APK URL + if (releaseApkUrl != null && !releaseApkUrl.isEmpty()) { + Logger.d("APK download URL from Release: " + releaseApkUrl); + return releaseApkUrl; + } + // 使用JSON中指定的具体下载路径 try { String response = OkHttp.string(getJson()); @@ -56,14 +64,18 @@ public class Updater implements Download.Callback { String baseUrl = Github.useCnMirror() ? "https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" : "https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main"; - return baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath; + String fullUrl = baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath; + Logger.d("APK download URL: " + fullUrl); + return fullUrl; } } } catch (Exception e) { Logger.e("Failed to get download path from JSON: " + e.getMessage()); } // 回退到原来的方式 - return Github.getApk(dev, BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi); + String fallbackUrl = Github.getApk(dev, BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi); + Logger.d("APK fallback URL: " + fallbackUrl); + return fallbackUrl; } public static Updater create() { @@ -106,13 +118,60 @@ public class Updater implements Download.Callback { } private void doInBackground(Activity activity) { + Logger.d("Updater: Starting update check..."); + try { + // 优先使用 JSON 方式检测更新(兼容性更好) + String response = OkHttp.string(getJson()); + JSONObject object = new JSONObject(response); + String name = object.optString("name"); + String desc = object.optString("desc"); + int code = object.optInt("code"); + + Logger.d("Updater: JSON Remote version: " + name + ", code: " + code); + Logger.d("Updater: Local version: " + BuildConfig.VERSION_NAME + ", code: " + BuildConfig.VERSION_CODE); + + // 使用 JSON 中的版本信息 + if (need(code, name)) { + Logger.d("Updater: Update needed (from JSON), showing dialog"); + this.latestVersion = name; // 保存最新版本号 + + // 从 JSON 获取下载链接 + JSONObject downloads = object.optJSONObject("downloads"); + if (downloads != null) { + String abi = BuildConfig.FLAVOR_abi; + String downloadPath = downloads.optString(abi); + if (!downloadPath.isEmpty()) { + String baseUrl = Github.useCnMirror() ? + "https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" : + "https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main"; + this.releaseApkUrl = baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath; + Logger.d("Updater: APK URL from JSON: " + this.releaseApkUrl); + } + } + + App.post(() -> show(activity, name, desc)); + } else { + Logger.d("Updater: No update needed (from JSON)"); + if (forceCheck) { + App.post(() -> Notify.show("已是最新版本 " + name)); + } + } + } catch (Exception e) { + Logger.e("Updater: JSON check failed, trying GitHub API: " + e.getMessage()); + // JSON 检测失败,尝试使用 GitHub Releases API + checkViaGitHubAPI(activity); + } + } + + private void checkViaGitHubAPI(Activity activity) { try { - // 直接使用GitHub Releases API检测最新版本 String releasesUrl = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest"; + Logger.d("Updater: Trying GitHub Releases API: " + releasesUrl); + String response = OkHttp.string(releasesUrl); - // 检查响应是否包含错误信息 if (response.contains("rate limit exceeded")) { + Logger.e("Updater: Rate limit exceeded"); if (forceCheck) { App.post(() -> Notify.show("检查更新失败:API请求过于频繁,请稍后重试")); } @@ -120,8 +179,9 @@ public class Updater implements Download.Callback { } if (response.contains("Not Found") || response.contains("404")) { + Logger.e("Updater: Release not found"); if (forceCheck) { - App.post(() -> Notify.show("检查更新失败:更新服务暂时不可用")); + App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); } return; } @@ -129,32 +189,33 @@ public class Updater implements Download.Callback { JSONObject release = new JSONObject(response); String tagName = release.optString("tag_name"); String body = release.optString("body"); - - // 提取版本号(去掉v前缀) String version = tagName.startsWith("v") ? tagName.substring(1) : tagName; - if (needUpdate(version)) { - this.latestVersion = version; // 保存最新版本号 - App.post(() -> show(activity, version, body)); - } else { - if (forceCheck) { - App.post(() -> Notify.show("已是最新版本 " + version)); + Logger.d("Updater: GitHub API Remote version: " + version); + + // 从 assets 中查找 APK + JSONArray assets = release.optJSONArray("assets"); + if (assets != null) { + String targetApkName = BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi + "-v" + version + ".apk"; + for (int i = 0; i < assets.length(); i++) { + JSONObject asset = assets.getJSONObject(i); + if (targetApkName.equals(asset.optString("name"))) { + this.releaseApkUrl = asset.optString("browser_download_url"); + break; + } } } + + if (needUpdate(version)) { + this.latestVersion = version; + App.post(() -> show(activity, version, body)); + } else if (forceCheck) { + App.post(() -> Notify.show("已是最新版本 " + version)); + } } catch (Exception e) { - e.printStackTrace(); + Logger.e("Updater: GitHub API check failed: " + e.getMessage()); if (forceCheck) { - App.post(() -> { - String errorMsg = "检查更新失败"; - if (e.getMessage() != null && e.getMessage().contains("rate limit")) { - errorMsg = "检查更新失败:请求过于频繁,请稍后重试"; - } else if (e.getMessage() != null && e.getMessage().contains("Not Found")) { - errorMsg = "检查更新失败:更新服务暂时不可用"; - } else { - errorMsg = "检查更新失败,请稍后重试"; - } - Notify.show(errorMsg); - }); + App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); } } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/Updater.java b/app/src/mobile/java/com/fongmi/android/tv/Updater.java index fc71f363..1f059064 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/Updater.java +++ b/app/src/mobile/java/com/fongmi/android/tv/Updater.java @@ -20,6 +20,7 @@ import com.github.catvod.utils.Logger; import com.github.catvod.utils.Path; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import org.json.JSONArray; import org.json.JSONObject; import java.io.File; @@ -33,6 +34,7 @@ public class Updater implements Download.Callback { private boolean dev; private boolean forceCheck; // 是否为手动检查 private String latestVersion; // 存储检测到的最新版本 + private String releaseApkUrl; // 从 GitHub Release 获取的 APK 下载链接 private File getFile() { return Path.root("Download", "XMBOX-update.apk"); @@ -43,6 +45,12 @@ public class Updater implements Download.Callback { } private String getApk() { + // 优先使用从 GitHub Release 获取的 APK URL + if (releaseApkUrl != null && !releaseApkUrl.isEmpty()) { + Logger.d("APK download URL from Release: " + releaseApkUrl); + return releaseApkUrl; + } + // 使用JSON中指定的具体下载路径 try { String response = OkHttp.string(getJson()); @@ -112,14 +120,56 @@ public class Updater implements Download.Callback { private void doInBackground(Activity activity) { Logger.d("Updater: Starting update check..."); try { - // 直接使用GitHub Releases API检测最新版本 + // 优先使用 JSON 方式检测更新(兼容性更好) + String response = OkHttp.string(getJson()); + JSONObject object = new JSONObject(response); + String name = object.optString("name"); + String desc = object.optString("desc"); + int code = object.optInt("code"); + + Logger.d("Updater: JSON Remote version: " + name + ", code: " + code); + Logger.d("Updater: Local version: " + BuildConfig.VERSION_NAME + ", code: " + BuildConfig.VERSION_CODE); + + // 使用 JSON 中的版本信息 + if (need(code, name)) { + Logger.d("Updater: Update needed (from JSON), showing dialog"); + this.latestVersion = name; // 保存最新版本号 + + // 从 JSON 获取下载链接 + JSONObject downloads = object.optJSONObject("downloads"); + if (downloads != null) { + String abi = BuildConfig.FLAVOR_abi; + String downloadPath = downloads.optString(abi); + if (!downloadPath.isEmpty()) { + String baseUrl = Github.useCnMirror() ? + "https://gitee.com/ochenoktochen/XMBOX-Release/raw/main" : + "https://raw.githubusercontent.com/Tosencen/XMBOX-Release/main"; + this.releaseApkUrl = baseUrl + "/apk/" + (dev ? "dev" : "release") + "/" + downloadPath; + Logger.d("Updater: APK URL from JSON: " + this.releaseApkUrl); + } + } + + App.post(() -> show(activity, name, desc)); + } else { + Logger.d("Updater: No update needed (from JSON)"); + if (forceCheck) { + App.post(() -> Notify.show("已是最新版本 " + name)); + } + } + } catch (Exception e) { + Logger.e("Updater: JSON check failed, trying GitHub API: " + e.getMessage()); + // JSON 检测失败,尝试使用 GitHub Releases API + checkViaGitHubAPI(activity); + } + } + + private void checkViaGitHubAPI(Activity activity) { + try { String releasesUrl = "https://api.github.com/repos/Tosencen/XMBOX/releases/latest"; - Logger.d("Updater: GitHub Releases API URL: " + releasesUrl); + Logger.d("Updater: Trying GitHub Releases API: " + releasesUrl); String response = OkHttp.string(releasesUrl); - Logger.d("Updater: API response length: " + response.length()); - // 检查响应是否包含错误信息 if (response.contains("rate limit exceeded")) { Logger.e("Updater: Rate limit exceeded"); if (forceCheck) { @@ -131,7 +181,7 @@ public class Updater implements Download.Callback { if (response.contains("Not Found") || response.contains("404")) { Logger.e("Updater: Release not found"); if (forceCheck) { - App.post(() -> Notify.show("检查更新失败:更新服务暂时不可用")); + App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); } return; } @@ -139,29 +189,33 @@ public class Updater implements Download.Callback { JSONObject release = new JSONObject(response); String tagName = release.optString("tag_name"); String body = release.optString("body"); - - // 提取版本号(去掉v前缀) String version = tagName.startsWith("v") ? tagName.substring(1) : tagName; - Logger.d("Updater: Remote version: " + version); - Logger.d("Updater: Local version: " + BuildConfig.VERSION_NAME); + Logger.d("Updater: GitHub API Remote version: " + version); - // 比较版本号 - if (needUpdate(version)) { - Logger.d("Updater: Update needed, showing dialog"); - this.latestVersion = version; // 保存最新版本号 - App.post(() -> show(activity, version, body)); - } else { - Logger.d("Updater: No update needed"); - if (forceCheck) { - App.post(() -> Notify.show("已是最新版本 " + version)); + // 从 assets 中查找 APK + JSONArray assets = release.optJSONArray("assets"); + if (assets != null) { + String targetApkName = BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_abi + "-v" + version + ".apk"; + for (int i = 0; i < assets.length(); i++) { + JSONObject asset = assets.getJSONObject(i); + if (targetApkName.equals(asset.optString("name"))) { + this.releaseApkUrl = asset.optString("browser_download_url"); + break; + } } } + + if (needUpdate(version)) { + this.latestVersion = version; + App.post(() -> show(activity, version, body)); + } else if (forceCheck) { + App.post(() -> Notify.show("已是最新版本 " + version)); + } } catch (Exception e) { - Logger.e("Updater: Exception during update check: " + e.getMessage()); - e.printStackTrace(); + Logger.e("Updater: GitHub API check failed: " + e.getMessage()); if (forceCheck) { - App.post(() -> Notify.show("检查更新失败:网络连接异常")); + App.post(() -> Notify.show("检查更新失败:无法连接到更新服务器")); } } }