From 569cfeac09ae1e6955cde28fd9cbb952a68eee3a Mon Sep 17 00:00:00 2001 From: terrylee Date: Wed, 15 Jul 2026 12:37:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(app-ui):=20APP=20UI=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=20Phase=201=20app=20=E7=AB=AF=20=E2=80=94=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20B014=20UISet=20+=20A1=20=E6=BB=BF=E7=89=88?= =?UTF-8?q?=E5=A5=97=E5=9C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UiSkin:解析/落地(SettingsDao UISkin)/預抓(ImageGlide.preload)/套用(fileload) - StarCloudAPI.saveSettings 加 UISet 解析 - A1(頁面跳轉中)套到 restart 畫面 restartImage(RestartHost/Restart) - A2/A3 已在下發+落地管線,待定位對應畫面再接 UiSkin.apply Co-Authored-By: Claude Opus 4.8 (1M context) --- .../smartdevice/external/StarCloudAPI.java | 7 ++ .../smartdevice/ui/RestartActivity.java | 3 + .../smartdevice/ui/RestartHostActivity.java | 3 + .../unibuy/smartdevice/ui/tools/UiSkin.java | 102 ++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 app/src/main/java/com/unibuy/smartdevice/ui/tools/UiSkin.java diff --git a/app/src/main/java/com/unibuy/smartdevice/external/StarCloudAPI.java b/app/src/main/java/com/unibuy/smartdevice/external/StarCloudAPI.java index eca7f13..dfa3504 100644 --- a/app/src/main/java/com/unibuy/smartdevice/external/StarCloudAPI.java +++ b/app/src/main/java/com/unibuy/smartdevice/external/StarCloudAPI.java @@ -1288,6 +1288,13 @@ public class StarCloudAPI { } } + // 6e. UISet:後台「APP UI 元素設定」下發(部位 part_key → 圖片 URL)。 + // 落地供各部位 UiSkin.apply 套用;缺整個物件→不動本地既有換膚。 + JSONObject uiSet = config.optJSONObject("UISet"); + if (uiSet != null) { + com.unibuy.smartdevice.ui.tools.UiSkin.save(handlerMain.getContext(), uiSet); + } + if (devSet != null || cashSet != null || funcSet != null || hardwareSet != null || hasShoppingMode || langSet != null) { MyApp.saveSystemSet(handlerMain.getContext()); } diff --git a/app/src/main/java/com/unibuy/smartdevice/ui/RestartActivity.java b/app/src/main/java/com/unibuy/smartdevice/ui/RestartActivity.java index cf2eaa3..9a77d05 100644 --- a/app/src/main/java/com/unibuy/smartdevice/ui/RestartActivity.java +++ b/app/src/main/java/com/unibuy/smartdevice/ui/RestartActivity.java @@ -83,6 +83,9 @@ public class RestartActivity extends AppCompatActivityAbstract { binding = ActivityRestartBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + // A1(頁面跳轉中):套用後台「APP UI 元素設定」下發的滿版圖,未設定則保留預設 unibuy_transfer_page + com.unibuy.smartdevice.ui.tools.UiSkin.apply("A1", binding.restartImage); + // 🚩 重啟前統一釋放所有資源 DeviceResourceManager.getInstance().releaseAllDevices(); // 延遲幾秒後執行 App 重啟 diff --git a/app/src/main/java/com/unibuy/smartdevice/ui/RestartHostActivity.java b/app/src/main/java/com/unibuy/smartdevice/ui/RestartHostActivity.java index d7c6d8d..de23bbf 100644 --- a/app/src/main/java/com/unibuy/smartdevice/ui/RestartHostActivity.java +++ b/app/src/main/java/com/unibuy/smartdevice/ui/RestartHostActivity.java @@ -103,6 +103,9 @@ public class RestartHostActivity extends AppCompatActivityAbstract { binding = ActivityRestartHostBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + // A1(頁面跳轉中):套用後台「APP UI 元素設定」下發的滿版圖,未設定則保留預設 unibuy_transfer_page + com.unibuy.smartdevice.ui.tools.UiSkin.apply("A1", binding.restartImage); + httpAPI = new HttpAPI(getHandlerMain()); starCloudAPI = new com.unibuy.smartdevice.external.StarCloudAPI(getHandlerMain(), getHandlerMain()); diff --git a/app/src/main/java/com/unibuy/smartdevice/ui/tools/UiSkin.java b/app/src/main/java/com/unibuy/smartdevice/ui/tools/UiSkin.java new file mode 100644 index 0000000..208f8a0 --- /dev/null +++ b/app/src/main/java/com/unibuy/smartdevice/ui/tools/UiSkin.java @@ -0,0 +1,102 @@ +package com.unibuy.smartdevice.ui.tools; + +import android.content.Context; +import android.widget.ImageView; + +import com.unibuy.smartdevice.database.SettingsDao; +import com.unibuy.smartdevice.structure.SettingStructure; + +import org.json.JSONObject; + +import java.util.Iterator; +import java.util.List; + +/** + * 後台「APP UI 元素設定」換膚:把 B014 下發的 UISet(部位 part_key → 圖片 URL) + * 落地到 SettingsDao,並提供把某部位圖片套到任一 ImageView 的方法。 + * + * 儲存格式:settingId = {@link #SETTING_ID},每個部位一列 data = [part_key, url]。 + * 部位無設定時保留該 view 原本的 XML 預設圖(不覆蓋)。 + */ +public class UiSkin { + public static final String SETTING_ID = "UISkin"; + + /** + * 解析並落地 B014 的 UISet。整組覆蓋(先刪後寫),並預抓圖片到本地快取。 + */ + public static void save(Context ctx, JSONObject uiSet) { + if (ctx == null || uiSet == null) { + return; + } + + SettingsDao dao = new SettingsDao(ctx); + try { + dao.deleteWhere(SETTING_ID); + + Iterator keys = uiSet.keys(); + while (keys.hasNext()) { + String partKey = keys.next(); + String url = uiSet.optString(partKey, ""); + if (partKey == null || partKey.isEmpty() || url == null || url.isEmpty()) { + continue; + } + + dao.insertOne(new SettingStructure(SETTING_ID, new String[]{partKey, url})); + + // 預先下載到本地檔(force=true 確保更新後重抓);失敗不阻斷,套用時仍會退回以 URL 直載。 + try { + new ImageGlide(ctx).preload(url, true); + } catch (Exception ignore) { + } + } + } catch (Exception ignore) { + } finally { + dao.close(); + } + } + + /** + * 取某部位設定的圖片 URL;未設定回傳 null。 + */ + public static String getUrl(Context ctx, String partKey) { + if (ctx == null || partKey == null || partKey.isEmpty()) { + return null; + } + + SettingsDao dao = new SettingsDao(ctx); + try { + List list = dao.getWhere(SETTING_ID); + if (list != null) { + for (SettingStructure s : list) { + if (partKey.equals(s.getData(0))) { + String url = s.getData(1); + return (url != null && !url.isEmpty()) ? url : null; + } + } + } + } catch (Exception ignore) { + } finally { + dao.close(); + } + return null; + } + + /** + * 把某部位的後台設定圖套到指定 ImageView;未設定則不動(保留 XML 預設圖)。 + */ + public static void apply(String partKey, ImageView imageView) { + if (imageView == null) { + return; + } + + String url = getUrl(imageView.getContext(), partKey); + if (url == null) { + return; + } + + try { + new ImageGlide(imageView.getContext()).fileload(url, imageView); + } catch (Exception ignore) { + } + } +}