[FEAT] 實作遠端更新商品指令與圖片顯示優化
1. 在 MqttService 中新增 update_products 指令處理,支援遠端觸發商品資料同步。 2. 優化 ImageGlide 邏輯,移除從網路載入圖片時的淡化濾鏡,確保圖片即時顯示原色。 3. 改進 ProductListActivity 的圖片預載機制,支援逐張商品即時刷新 UI 提升互動感。 4. 更新 .gitignore 以排除 .idea 目錄及 Agent 產生的規劃檔案。 5. 配合環境調整 Gradle 配置與 SDK 路徑。
This commit is contained in:
parent
8ae4ae9c14
commit
45853d0b9d
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,12 +1,7 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
/.idea/
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownSettings">
|
||||
<option name="previewPanelProviderInfo">
|
||||
<ProviderInfo name="Compose (experimental)" className="com.intellij.markdown.compose.preview.ComposePanelProvider" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/TaiwanStar_general_size_s_Chengwai.iml" filepath="$PROJECT_DIR$/.idea/TaiwanStar_general_size_s_Chengwai.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "interactive"
|
||||
}
|
||||
6
app/src/main/java/com/unibuy/smartdevice/.idea/misc.xml
Normal file
6
app/src/main/java/com/unibuy/smartdevice/.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/smartdevice.iml" filepath="$PROJECT_DIR$/smartdevice.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/../../../../../../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@ -24,12 +24,15 @@ import com.unibuy.smartdevice.external.mqtt.MqttManager;
|
||||
import com.unibuy.smartdevice.structure.BuyStructure;
|
||||
import com.unibuy.smartdevice.structure.ReportFlowInfoStructure;
|
||||
import com.unibuy.smartdevice.structure.SlotStructure;
|
||||
import com.unibuy.smartdevice.structure.ProductStructure;
|
||||
import com.unibuy.smartdevice.structure.mqtt.TransactionFinalizePayload;
|
||||
import com.unibuy.smartdevice.tools.TransactionFinalizeBuilder;
|
||||
import com.unibuy.smartdevice.ui.tools.ImageGlide;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -274,6 +277,62 @@ public class MqttService extends Service {
|
||||
};
|
||||
// 使用新架構 StarCloudAPI 執行同步
|
||||
new com.unibuy.smartdevice.external.StarCloudAPI(adHandler, adHandler).downloadAdvertisement();
|
||||
} else if ("update_products".equals(cmd)) {
|
||||
logs.info("Executing remote product sync command...");
|
||||
|
||||
// 📢 在主執行緒顯示 Toast 提示使用者
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() ->
|
||||
android.widget.Toast.makeText(getApplicationContext(),
|
||||
"📢 商品更新中...", android.widget.Toast.LENGTH_SHORT).show());
|
||||
|
||||
com.unibuy.smartdevice.tools.HandlerMain productHandler = new com.unibuy.smartdevice.tools.HandlerMain(
|
||||
getApplicationContext(), logs) {
|
||||
@Override
|
||||
protected void execute(Context context, int code, String message) {
|
||||
logs.info("Product sync event: [" + code + "] " + message);
|
||||
if (code == 200 && "商品下載成功".equals(message)) {
|
||||
// 背景預載圖片
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<ProductStructure> products = MyApp.getInstance().getProductList();
|
||||
int total = products.size();
|
||||
logs.info("Starting image preloading for " + total + " products...");
|
||||
|
||||
for (int i = 0; i < total; i++) {
|
||||
ProductStructure p = products.get(i);
|
||||
if (p.getProductImg() != null && !p.getProductImg().isEmpty()) {
|
||||
try {
|
||||
new ImageGlide(getApplicationContext()).preload(p.getProductImg());
|
||||
} catch (Exception e) {
|
||||
logs.info("Failed to preload image for product " + p.getProductID() + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logs.info("Product sync and image preloading completed.");
|
||||
mqttManager.publishCommandAck(cmdId, "success", "Product sync completed successfully");
|
||||
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() ->
|
||||
android.widget.Toast.makeText(context,
|
||||
"✅ 商品更新完成", android.widget.Toast.LENGTH_SHORT).show());
|
||||
} catch (Exception e) {
|
||||
logs.error(com.unibuy.smartdevice.exception.ErrorCode.UNKNOWN_ERROR, "Error during image preloading: " + e.getMessage());
|
||||
mqttManager.publishCommandAck(cmdId, "failed", "Image preloading error: " + e.getMessage());
|
||||
}
|
||||
}).start();
|
||||
} else if (code >= 400) {
|
||||
mqttManager.publishCommandAck(cmdId, "failed", "Product sync failed: " + message);
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() ->
|
||||
android.widget.Toast.makeText(context,
|
||||
"❌ 商品更新失敗: " + message, android.widget.Toast.LENGTH_LONG).show());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 1. 清除舊圖片快取
|
||||
ImageGlide.clearProductCache(getApplicationContext());
|
||||
// 2. 開始下載資料
|
||||
new com.unibuy.smartdevice.external.StarCloudAPI(productHandler, productHandler).downloadProductInfo();
|
||||
} else if ("update_inventory".equals(cmd)) {
|
||||
logs.info("Executing update_inventory command...");
|
||||
try {
|
||||
|
||||
@ -201,6 +201,9 @@ public class ProductListActivity extends AppCompatActivityAbstract {
|
||||
|
||||
try {
|
||||
new ImageGlide(handlerMain.getContext()).preload(product.getProductImg());
|
||||
// 下載完成後,立即刷新該項目的 UI (使 ImageGlide 重新判斷檔案存在,由淡變亮)
|
||||
final int index = i;
|
||||
runOnUiThread(() -> recyclerProductListAdpter.notifyItemChanged(index));
|
||||
} catch (LogsEmptyException e) {
|
||||
getLogs().warning(e);
|
||||
}
|
||||
|
||||
@ -62,7 +62,6 @@ public class ImageGlide {
|
||||
Glide.with(imageView).load(urlString)
|
||||
.placeholder(R.drawable.loading)
|
||||
.error(R.drawable.loading)
|
||||
.transform(new WhiteTintTransformation(128))
|
||||
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.signature(new ObjectKey(System.currentTimeMillis())) // 強制更新
|
||||
.into(imageView);
|
||||
@ -71,7 +70,6 @@ public class ImageGlide {
|
||||
Glide.with(imageView).load(urlString)
|
||||
.placeholder(R.drawable.loading)
|
||||
.error(R.drawable.loading)
|
||||
.transform(new WhiteTintTransformation(128))
|
||||
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.signature(new ObjectKey(System.currentTimeMillis())) // 強制更新
|
||||
.into(imageView);
|
||||
@ -103,7 +101,6 @@ public class ImageGlide {
|
||||
Glide.with(context.getApplicationContext()).load(urlString)
|
||||
.placeholder(R.drawable.loading)
|
||||
.error(R.drawable.loading)
|
||||
.transform(new WhiteTintTransformation(128))
|
||||
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.preload();
|
||||
}
|
||||
|
||||
@ -1,2 +1,12 @@
|
||||
#toolchainVendor=jetbrains
|
||||
#toolchainVersion=21
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/65aaef917b9f394804f058f1861225c9/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/c728c5388b044fbdbbc44b0c6acee0df/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/65aaef917b9f394804f058f1861225c9/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/c728c5388b044fbdbbc44b0c6acee0df/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/dc463b4a8183dbcaa1b32544189c7f03/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/cb7dc109dd590ebca2d703734d23c9d3/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/65aaef917b9f394804f058f1861225c9/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/c728c5388b044fbdbbc44b0c6acee0df/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/43ee83889b87bacad5d3071ae7bbd349/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/2d57bdd1e17a18f83ff073919daa35ba/redirect
|
||||
toolchainVersion=17
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.9.0"
|
||||
agp = "8.13.2"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.2.1"
|
||||
espressoCore = "3.6.1"
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Sat Mar 22 19:54:26 CST 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Loading…
Reference in New Issue
Block a user