[FIX] 修正商品圖片同步後銷售平台未更新問題及編譯穩定性改善

1. StarCloudAPI:同步商品後強制更新所有 SlotStructure 的物件參考,確保 UI 取到最新資料
2. FontendActivity:在 onResume 中清除 Glide 記憶體快取並呼叫 updateFlowerBuyList(),確保返回銷售平台時圖片即時刷新
3. ImageGlide:新增 clearProductCache() 方法,可實體刪除本地快取圖片目錄,並加入診斷用日誌
4. RecyclerVmcBuyListAdpter:優化 ViewHolder 綁定邏輯,補齊售完遮罩顯示判斷及點擊事件資料驗證
5. SettingActivity:補上遺漏的 ImageGlide import 修正編譯錯誤,並修正 RecyclerView LayoutManager 設定邏輯
6. ProductListActivity:補上遺漏 import
7. compiler-apk.md:Workflow 改為每次執行 clean build 並先終止殘留 Gradle Daemon,避免增量快取遮蔽編譯錯誤
This commit is contained in:
sky121113 2026-05-13 12:42:41 +08:00
parent 028cac10b5
commit 3044314856
7 changed files with 332 additions and 208 deletions

View File

@ -11,9 +11,14 @@ description: 自動編譯 Android APK、輸出至專屬目錄並安裝至實體
```bash
// turbo
# 終止殘留的 Gradle/Java 程序,避免多個 Daemon 互搶資源
pkill -9 -f "gradle" 2>/dev/null; pkill -9 -f "GradleDaemon" 2>/dev/null; sleep 1
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
cd /home/mama/projects/TaiwanStar_general_size_s_Chengwai
./gradlew :app:assembleS_12_XY_U_Standard_Debug
# 使用 clean 確保完整重新編譯,避免舊快取遮蔽 import 缺失等錯誤
./gradlew clean :app:assembleS_12_XY_U_Standard_Debug
```
## 步驟二:導出 APK 到 outputs 資料夾

View File

@ -648,6 +648,32 @@ public class StarCloudAPI {
productsDao.close();
Log.i(TAG, "Synced and persisted " + products.length() + " products from star-cloud.");
// 🔹 重要同步更新 MyApp 貨道中的商品引用
// 因為貨道資料是在 App 啟動時載入的它們握著舊的 ProductStructure 物件
// 如果不手動更新銷售平台會一直看到舊的圖片網址
for (SlotField slotField : SlotField.values()) {
List<SlotStructure> slotList = MyApp.getInstance().getSlotList(slotField.getField());
if (slotList != null) {
for (SlotStructure slot : slotList) {
if (slot.getProduct() != null) {
String pid = slot.getProduct().getProductID();
// 在新下載的清單中尋找匹配的商品
for (ProductStructure newP : MyApp.getInstance().getProductList()) {
if (newP.getProductID().equals(pid)) {
slot.setProduct(newP); // 更新引用
break;
}
}
}
}
}
}
Log.i(TAG, "Updated product references in all slots.");
// 🔹 發送廣播通知所有監聽者如銷售平台商品與貨道資料已更新
android.content.Intent intent = new android.content.Intent("com.unibuy.smartdevice.ACTION_SLOT_UPDATED");
handlerMain.getContext().sendBroadcast(intent);
}
/**

View File

@ -164,7 +164,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
switch (option) {
case TOAST:
super.execute(context, commandCode, message);
super.execute(context, commandCode, message);
break;
case BUY_DIALOG_OPEN:
start(getClass().getSimpleName(), Option.STOP_COUNTDOWN.getOption(), "stop countdown");
@ -181,26 +181,32 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
addProductOnCountdown = new AddProductOnCountdown(getHandlerMain());
addProductOnCountdown.start(40);
((FragmentAbstract) vmcFragment).getHandlerMain().start(getClass().getSimpleName(), VmcFragment.Option.ADD_PRODUCT_OPEN.getOption(), "add product open");
((FragmentAbstract) vmcFragment).getHandlerMain().start(getClass().getSimpleName(),
VmcFragment.Option.ADD_PRODUCT_OPEN.getOption(), "add product open");
if (MyApp.getInstance().getDevSet().isElectic()) {
((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.ADD_PRODUCT_OPEN.getOption(), "add product open");
((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(),
ElectricFragment.Option.ADD_PRODUCT_OPEN.getOption(), "add product open");
}
break;
case STOP_COUNTDOWN:
if (addProductOnCountdown != null && addProductOnCountdown.getCountdown() > 0)
addProductOnCountdown.shutdown();
((FragmentAbstract) vmcFragment).getHandlerMain().start(getClass().getSimpleName(), VmcFragment.Option.ADD_PRODUCT_CLOSE.getOption(), "add product close");
((FragmentAbstract) vmcFragment).getHandlerMain().start(getClass().getSimpleName(),
VmcFragment.Option.ADD_PRODUCT_CLOSE.getOption(), "add product close");
if (MyApp.getInstance().getDevSet().isElectic()) {
((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.ADD_PRODUCT_CLOSE.getOption(), "add product close");
((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(),
ElectricFragment.Option.ADD_PRODUCT_CLOSE.getOption(), "add product close");
}
break;
case RESET_DATA:
((FragmentAbstract) vmcFragment).getHandlerMain().start(getClass().getSimpleName(), VmcFragment.Option.SHIPPED_PRODUCT.getOption(), "shipped product");
((FragmentAbstract) vmcFragment).getHandlerMain().start(getClass().getSimpleName(),
VmcFragment.Option.SHIPPED_PRODUCT.getOption(), "shipped product");
if (MyApp.getInstance().getDevSet().isElectic()) {
((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.SHIPPED_PRODUCT.getOption(), "shipped product");
((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(),
ElectricFragment.Option.SHIPPED_PRODUCT.getOption(), "shipped product");
}
saveData();
setBottomNavigation();//這一個方法是在消費完後它會呼叫本方法更新銷售平台的商品列長fragment
setBottomNavigation();// 這一個方法是在消費完後它會呼叫本方法更新銷售平台的商品列長fragment
break;
case REPORT_AND_SHOT_TIME:
String ver = "";
@ -211,7 +217,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
ver = "0";
}
binding.textVersion.setText(MyApp.getInstance().getMachine().getMachineID()+" Ver " + ver);
binding.textVersion.setText(MyApp.getInstance().getMachine().getMachineID() + " Ver " + ver);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String timeByNow = sdf.format(new Date());
@ -238,21 +244,23 @@ public class FontendActivity extends AppCompatActivityAbstract {
new RestartAPP2(this).start();
}
// 這裡判斷每5分鐘去跑連線下位機的狀態
// String minutePart = timeByM.split(":")[1]; // 取得 "mm" 部分
// if (minutePart.equals("00") || minutePart.equals("05") ||
// minutePart.equals("10") || minutePart.equals("15") ||
// minutePart.equals("20") || minutePart.equals("25") || minutePart.equals("30")
// || minutePart.equals("35")||
// minutePart.equals("40") || minutePart.equals("45") || minutePart.equals("50")
// || minutePart.equals("55")) {
// getLogs().info("當前時間:" + timeByM + ",符合條件,執行 RunToADPage...");
// new RunToADPage(this).start();
// }
//這裡判斷每5分鐘去跑連線下位機的狀態
// String minutePart = timeByM.split(":")[1]; // 取得 "mm" 部分
// if (minutePart.equals("00") || minutePart.equals("05") || minutePart.equals("10") || minutePart.equals("15") ||
// minutePart.equals("20") || minutePart.equals("25") || minutePart.equals("30") || minutePart.equals("35")||
// minutePart.equals("40") || minutePart.equals("45") || minutePart.equals("50") || minutePart.equals("55")) {
// getLogs().info("當前時間:" + timeByM + ",符合條件,執行 RunToADPage...");
// new RunToADPage(this).start();
// }
//每半小時主動連線下位機一次
// 每半小時主動連線下位機一次
String minutePart = timeByM.split(":")[1]; // 取得 "mm" 部分
if (minutePart.equals("00") || minutePart.equals("30")) {
getLogs().info("當前時間:" + timeByM + ",符合條件,執行 CMUHAutoRun...");
// new CMUHAutoRun(this).start();
// new CMUHAutoRun(this).start();
}
getLogs().update("ThreadCount", String.valueOf(Tools.threadCount()));
@ -266,12 +274,12 @@ public class FontendActivity extends AppCompatActivityAbstract {
String networkDevice = getNetworkDevice();
getLogs().update("Network", networkDevice);
binding.textNetwork.setText(getString(R.string.network)+""+getLogs().getMessage());
binding.textNetwork.setText(getString(R.string.network) + "" + getLogs().getMessage());
getLogs().clearMessage();
DevXinYuanController.setVersion(ver);
getLogs().update("Temperature", String.valueOf(DevXinYuanController.getTemperature()),"");
binding.textTemperature.setText(getString(R.string.temp)+":" + getLogs().getMessage());
getLogs().update("Temperature", String.valueOf(DevXinYuanController.getTemperature()), "");
binding.textTemperature.setText(getString(R.string.temp) + ":" + getLogs().getMessage());
getLogs().clearMessage();
try {
@ -281,25 +289,30 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
String timeByS = new SimpleDateFormat("ss").format(new Date());
timeByS = String.valueOf(Integer.valueOf(timeByS)/10*10);
timeByS = String.valueOf(Integer.valueOf(timeByS) / 10 * 10);
getLogs().debug("timeByS:" + timeByS);
// if (timeByS.equals("0") || timeByS.equals("10") || timeByS.equals("20") || timeByS.equals("30") || timeByS.equals("40") || timeByS.equals("50")) {
// if (MyApp.getInstance().getDevSet().isElectic()) {
// ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.BUY_ON_THREAD_TIMER_TASK.getOption(), "BUY_ON_THREAD_TIMER_TASK");
// }
// }
//
// if (timeByS.equals("30")) {
// if (MyApp.getInstance().getDevSet().isElectic()) {
// ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.SHIPPED_PRODUCT.getOption(), "BUY_ON_THREAD_TIMER_TASK");
// }
// }
// if (timeByS.equals("0") || timeByS.equals("10") || timeByS.equals("20") ||
// timeByS.equals("30") || timeByS.equals("40") || timeByS.equals("50")) {
// if (MyApp.getInstance().getDevSet().isElectic()) {
// ((FragmentAbstract)
// electricFragment).getHandlerMain().start(getClass().getSimpleName(),
// ElectricFragment.Option.BUY_ON_THREAD_TIMER_TASK.getOption(),
// "BUY_ON_THREAD_TIMER_TASK");
// }
// }
//
// if (timeByS.equals("30")) {
// if (MyApp.getInstance().getDevSet().isElectic()) {
// ((FragmentAbstract)
// electricFragment).getHandlerMain().start(getClass().getSimpleName(),
// ElectricFragment.Option.SHIPPED_PRODUCT.getOption(),
// "BUY_ON_THREAD_TIMER_TASK");
// }
// }
/// /機器B022 API
// 在的定時任務中
String[] timeParts = timeByM.split(":");
if (timeParts.length >= 2) {
@ -320,7 +333,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
break;
case SET_NETWORK:
getLogs().info("網路:"+message);
getLogs().info("網路:" + message);
binding.textNetwork.setText(message);
break;
case RESET_SLOTNO:
@ -331,11 +344,11 @@ public class FontendActivity extends AppCompatActivityAbstract {
break;
case HIDDEN_MULTILANGUAGE_BUTTON:
getLogs().info("隱藏多國語按紐");
// hiddenMultiLanguageButton();
// hiddenMultiLanguageButton();
break;
case SHOW_MULTILANGUAGE_BUTTON:
getLogs().info("顯示多國語按紐");
// showMultiLanguageButton();
// showMultiLanguageButton();
break;
}
}
@ -348,7 +361,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 讀取最後設定語言的設定
// LanguageHelper.applySavedLanguage(this);
// LanguageHelper.applySavedLanguage(this);
binding = ActivityFontendBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@ -357,7 +370,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
this.connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
setBottomNavigation();
// startOnSwitchFragment();
// startOnSwitchFragment();
getHandlerMain().getHandler().postDelayed(new Runnable() {
@Override
public void run() {
@ -376,7 +389,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
MyApp.getInstance().updateLastInteraction();
}
public void ReSetAPP(){
public void ReSetAPP() {
Intent intent = new Intent(getApplicationContext(), FontendActivity.class);
// 清空所有 Task重新啟動
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
@ -389,7 +402,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
// 完全不需要 killProcess()
}
public void ReSetAPP2(){
public void ReSetAPP2() {
Intent intent = new Intent(getApplicationContext(), FontendActivity.class);
// 清空所有 Task重新啟動
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
@ -400,7 +413,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
finishAffinity();
// 建議先 log kill
getLogs().info("🔄MainActivity - App restarting...");
Process.killProcess(Process.myPid());
}
@ -422,7 +435,8 @@ public class FontendActivity extends AppCompatActivityAbstract {
getHandlerMain().getHandler().postDelayed(() -> {
if (videoEoxPlayer != null) {
// videoEoxPlayer.playMedia(binding.videoView, binding.imageAd); // 傳入 view 開始播放
// videoEoxPlayer.playMedia(binding.videoView, binding.imageAd); // 傳入 view
// 開始播放
try {
videoEoxPlayer.playMediaByFlag("1", binding.videoView, binding.imageAd); // 同時支援影片與圖片輪播
} catch (LogsFileNullException e) {
@ -442,7 +456,6 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
}
private void resetIdleTimer() {
if (idleHandler != null && idleRunnable != null) {
idleHandler.removeCallbacks(idleRunnable);
@ -481,7 +494,8 @@ public class FontendActivity extends AppCompatActivityAbstract {
signalStrength = capabilities.getSignalStrength();
}
if (signalStrength > 0) {
signalStrengthString = signalStrength > -100 ? ":"+getString(R.string.powerful) : ":"+getString(R.string.weak);
signalStrengthString = signalStrength > -100 ? ":" + getString(R.string.powerful)
: ":" + getString(R.string.weak);
signalStrengthString += "(" + signalStrength + ")";
}
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
@ -494,7 +508,8 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
}
}
} else if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
} else if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
networkDevice = getString(R.string.network_device_str_unsupport);
}
return networkDevice;
@ -502,7 +517,8 @@ public class FontendActivity extends AppCompatActivityAbstract {
private boolean checkPermissionByAccessFineLocation() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
return ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
return true; // SDK < 23 時權限已在安裝時授予
}
@ -540,10 +556,13 @@ public class FontendActivity extends AppCompatActivityAbstract {
((FragmentAbstract) activeFragment).setUseStartOnSwitchFragment(true);
getSupportFragmentManager().beginTransaction().add(binding.fragmentContainer.getId(), vmcFragment, "VMC").hide(vmcFragment).commit();
getSupportFragmentManager().beginTransaction().add(binding.fragmentContainer.getId(), vmcFragment, "VMC")
.hide(vmcFragment).commit();
if (MyApp.getInstance().getDevSet().isElectic()) {
getSupportFragmentManager().beginTransaction().add(binding.fragmentContainer.getId(), electricFragment, "ELECTRIC").hide(electricFragment).commit();
getSupportFragmentManager().beginTransaction()
.add(binding.fragmentContainer.getId(), electricFragment, "ELECTRIC").hide(electricFragment)
.commit();
}
getSupportFragmentManager().beginTransaction()
@ -568,31 +587,31 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
}
binding.buttonVmc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
binding.buttonVmc.setBackgroundColor(Color.BLACK);
binding.buttonVmc.setTextColor(Color.WHITE);
if (MyApp.getInstance().getDevSet().isElectic()) {
binding.buttonElectric.setBackgroundColor(Color.TRANSPARENT);
binding.buttonElectric.setTextColor(Color.BLACK);
}
switchFragment(activeFragment, vmcFragment);
}
});
binding.buttonVmc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
binding.buttonVmc.setBackgroundColor(Color.BLACK);
binding.buttonVmc.setTextColor(Color.WHITE);
if (MyApp.getInstance().getDevSet().isElectic()) {
binding.buttonElectric.setBackgroundColor(Color.TRANSPARENT);
binding.buttonElectric.setTextColor(Color.BLACK);
}
switchFragment(activeFragment, vmcFragment);
}
});
binding.buttonElectric.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
binding.buttonVmc.setBackgroundColor(Color.TRANSPARENT);
binding.buttonVmc.setTextColor(Color.BLACK);
if (MyApp.getInstance().getDevSet().isElectic()) {
binding.buttonElectric.setBackgroundColor(Color.BLACK);
binding.buttonElectric.setTextColor(Color.WHITE);
}
switchFragment(activeFragment, electricFragment);
}
});
binding.buttonElectric.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
binding.buttonVmc.setBackgroundColor(Color.TRANSPARENT);
binding.buttonVmc.setTextColor(Color.BLACK);
if (MyApp.getInstance().getDevSet().isElectic()) {
binding.buttonElectric.setBackgroundColor(Color.BLACK);
binding.buttonElectric.setTextColor(Color.WHITE);
}
switchFragment(activeFragment, electricFragment);
}
});
if (MyApp.getInstance().getDevSet().isElectic()) {
binding.buttonElectric.setVisibility(VISIBLE);
@ -606,9 +625,10 @@ public class FontendActivity extends AppCompatActivityAbstract {
binding.floatButtonPickupCode.setVisibility(View.GONE);
binding.floatButtonShoppingCart.setOnClickListener(view -> {
getHandlerMain().start(getClass().getSimpleName(), Option.BUY_DIALOG_OPEN.getOption(), getString(R.string.detect_shopping_cart));
});
binding.floatButtonShoppingCart.setOnClickListener(view -> {
getHandlerMain().start(getClass().getSimpleName(), Option.BUY_DIALOG_OPEN.getOption(),
getString(R.string.detect_shopping_cart));
});
if (MyApp.getInstance().getDevSet().isShoppingCar()) {
binding.floatButtonShoppingCart.setVisibility(VISIBLE);
@ -616,19 +636,18 @@ public class FontendActivity extends AppCompatActivityAbstract {
binding.floatButtonShoppingCart.setVisibility(View.GONE);
}
if (reportOnScheduler != null) {
reportOnScheduler.shutdown();
}
if (reportOnScheduler != null) {
reportOnScheduler.shutdown();
}
reportOnScheduler = new ReportShotTimeByScheduler(getHandlerMain());
reportOnScheduler.start(1L, 10L, TimeUnit.SECONDS);
// binding.btnswitchlanTW.setOnClickListener(v -> switchLanguage("tw"));
//
// binding.btnswitchlanEn.setOnClickListener(v -> switchLanguage("en"));
//
// binding.btnswitchlanJa.setOnClickListener(v -> switchLanguage("ja"));
// binding.btnswitchlanTW.setOnClickListener(v -> switchLanguage("tw"));
//
// binding.btnswitchlanEn.setOnClickListener(v -> switchLanguage("en"));
//
// binding.btnswitchlanJa.setOnClickListener(v -> switchLanguage("ja"));
// 🛠 隱藏後門長按網路狀態文字 2 秒進入主控台
final Handler networkHandler = new Handler();
@ -670,13 +689,13 @@ public class FontendActivity extends AppCompatActivityAbstract {
startOnSwitchFragment();
}
private void hiddenMultiLanguageButton(){
private void hiddenMultiLanguageButton() {
binding.btnswitchlanTW.setVisibility(View.GONE);
binding.btnswitchlanEn.setVisibility(View.GONE);
binding.btnswitchlanJa.setVisibility(View.GONE);
}
private void showMultiLanguageButton(){
private void showMultiLanguageButton() {
binding.btnswitchlanTW.setVisibility(VISIBLE);
binding.btnswitchlanEn.setVisibility(VISIBLE);
binding.btnswitchlanJa.setVisibility(VISIBLE);
@ -684,6 +703,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
private class RestartHost extends HandlerMainScheduler {
private int testCount = 0;
public RestartHost(HandlerMain handlerMain) {
super(handlerMain);
testCount = 0;
@ -696,7 +716,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
@Override
protected void execute(HandlerMain handlerMain) {
for (int testIndex=0; testIndex < 30; testIndex++) {
for (int testIndex = 0; testIndex < 30; testIndex++) {
if (testCount < 3) {
if (!MyApp.getInstance().isMachineBusy()) {
getLogs().debug("RestartHost testCount:" + testCount);
@ -706,7 +726,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
try {
Thread.sleep(1000*20);
Thread.sleep(1000 * 20);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@ -736,15 +756,22 @@ public class FontendActivity extends AppCompatActivityAbstract {
public RestartAPP(HandlerMain handlerMain) {
super(handlerMain);
}
@Override
protected HandlerMain setHandlerMain() { return getSrcHandlerMain(); }
protected HandlerMain setHandlerMain() {
return getSrcHandlerMain();
}
@Override
protected void execute(HandlerMain handlerMain) {
// 直接委派給 RestartAPP2 的邏輯
new RestartAPP2(getSrcHandlerMain()).start();
}
@Override
protected Class<?> setCls() { return getClass(); }
protected Class<?> setCls() {
return getClass();
}
}
/**
@ -756,8 +783,12 @@ public class FontendActivity extends AppCompatActivityAbstract {
public RestartAPP2(HandlerMain handlerMain) {
super(handlerMain);
}
@Override
protected HandlerMain setHandlerMain() { return getSrcHandlerMain(); }
protected HandlerMain setHandlerMain() {
return getSrcHandlerMain();
}
@Override
protected void execute(HandlerMain handlerMain) {
// 最多等待 10 分鐘120 * 5 確保機台有機會重啟
@ -771,13 +802,13 @@ public class FontendActivity extends AppCompatActivityAbstract {
Intent intent = new Intent(getApplicationContext(), com.unibuy.smartdevice.HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
});
return;
}
getLogs().debug("RestartAPP2閒置 " + idle + " 秒,尚未達 90 秒,等待 5 秒後重新判斷(第 " + (i+1) + " 次)");
getLogs().debug("RestartAPP2閒置 " + idle + " 秒,尚未達 90 秒,等待 5 秒後重新判斷(第 " + (i + 1) + " 次)");
try {
Thread.sleep(5000); // 5 秒檢查一次
} catch (InterruptedException e) {
@ -786,12 +817,16 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
getLogs().info("RestartAPP2等待超過 10 分鐘仍有使用者互動,放棄本次重啟");
}
@Override
protected Class<?> setCls() { return getClass(); }
protected Class<?> setCls() {
return getClass();
}
}
private static class NfcCheckout extends HandlerMainScheduler {
private int testCount = 0;
public NfcCheckout(HandlerMain handlerMain) {
super(handlerMain);
testCount = 0;
@ -804,7 +839,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
@Override
protected void execute(HandlerMain handlerMain) {
for (int testIndex=0; testIndex < 30; testIndex++) {
for (int testIndex = 0; testIndex < 30; testIndex++) {
if (testCount < 3) {
if (!MyApp.getInstance().isShowDialog()) {
getLogs().debug("NfcCheckout testCount:" + testCount);
@ -814,7 +849,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
try {
Thread.sleep(1000*20);
Thread.sleep(1000 * 20);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@ -874,6 +909,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
private class CMUHAutoRun extends HandlerMainScheduler {
private int testCount = 0;
public CMUHAutoRun(HandlerMain handlerMain) {
super(handlerMain);
testCount = 0;
@ -886,8 +922,8 @@ public class FontendActivity extends AppCompatActivityAbstract {
@Override
protected void execute(HandlerMain handlerMain) {
Looper.prepare(); // 確保這個執行緒有 Looper
for (int testIndex=0; testIndex < 30; testIndex++) {
Looper.prepare(); // 確保這個執行緒有 Looper
for (int testIndex = 0; testIndex < 30; testIndex++) {
if (testCount < 3) {
if (!MyApp.getInstance().isShowDialog()) {
getLogs().debug("CMUHAutoRun testCount:" + testCount);
@ -897,7 +933,7 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
try {
Thread.sleep(1000*20);
Thread.sleep(1000 * 20);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@ -911,10 +947,10 @@ public class FontendActivity extends AppCompatActivityAbstract {
}
getLogs().info("CMUHAutoRun - 11111111111111111");
MyApp.getInstance().getDevXinYuanController().addSendBuffer(
MyApp.getInstance().getDevXinYuanController().getDevXinYuan().syncPackNo((byte)0x01));
MyApp.getInstance().getDevXinYuanController().getDevXinYuan().syncPackNo((byte) 0x01));
getLogs().info("CMUHAutoRun - 22222222222222222");
//Looper.loop(); // 啟動事件迴圈
// Looper.loop(); // 啟動事件迴圈
// 👇 安全地結束 Looper釋放這個 Thread
Objects.requireNonNull(Looper.myLooper()).quitSafely(); // quit() 根據需求
@ -964,9 +1000,9 @@ public class FontendActivity extends AppCompatActivityAbstract {
@Override
protected void execute(long countdown, HandlerMain handlerMain) {
// if (countdown == 20 || countdown == 10) {
// handlerMain.start(getClass().getSimpleName(), "剩餘"+countdown+"");
// }
// if (countdown == 20 || countdown == 10) {
// handlerMain.start(getClass().getSimpleName(), "剩餘"+countdown+"");
// }
}
@Override
@ -1063,6 +1099,13 @@ public class FontendActivity extends AppCompatActivityAbstract {
} else {
registerReceiver(slotUpdateReceiver, filter);
}
// 🔹 從設定頁面或其他頁面回到銷售平台時強制刷新商品列表確保新圖片能顯示
// 先清除 Glide 記憶體快取避免拿到舊的 Bitmap
Glide.get(this).clearMemory();
if (vmcFragment instanceof VmcFragment) {
((VmcFragment) vmcFragment).updateFlowerBuyList();
}
}
@Override

View File

@ -138,6 +138,7 @@ public class ProductListActivity extends AppCompatActivityAbstract {
binding.progressLayout.setVisibility(View.VISIBLE);
updateProgressUI(0, getCtx().getString(R.string.downloading_product_data));
});
ImageGlide.clearProductCache(ProductListActivity.this);
starCloudAPI.downloadProductInfo();
} catch (Exception e) {
getLogs().warning(e);

View File

@ -21,6 +21,7 @@ import com.unibuy.smartdevice.tools.HandlerMainSchedulerOnClick;
import com.unibuy.smartdevice.tools.ToastHandlerMain;
import com.unibuy.smartdevice.tools.Tools;
import com.unibuy.smartdevice.ui.recycler.RecyclerSettingListAdpter;
import com.unibuy.smartdevice.ui.tools.ImageGlide;
import com.unibuy.smartdevice.ui.tools.VideoImageMixedPlayer;
import com.unibuy.smartdevice.utils.LanguageHelper;
@ -108,13 +109,13 @@ public class SettingActivity extends AppCompatActivityAbstract {
super.execute(context, commandCode, message);
binding.progressLayout.setVisibility(View.GONE);
binding.buttonBack.setVisibility(View.VISIBLE);
// 綁定成功後自動連動執行 B012 同步商品
if ("綁定成功".equals(message)) {
binding.progressLayout.setVisibility(View.VISIBLE); // 顯示進度條因為要同步商品
starCloudAPI.downloadProductInfo();
}
checkSetting();
saveStatusList(context);
break;
@ -141,7 +142,7 @@ public class SettingActivity extends AppCompatActivityAbstract {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 讀取最後設定語言的設定
// LanguageHelper.applySavedLanguage(this);
// LanguageHelper.applySavedLanguage(this);
binding = ActivitySettingBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@ -153,7 +154,8 @@ public class SettingActivity extends AppCompatActivityAbstract {
recyclerSettingListAdpter = new RecyclerSettingListAdpter(statusList);
binding.recyclerSettingList.setAdapter(recyclerSettingListAdpter);
binding.recyclerSettingList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
binding.recyclerSettingList
.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
MyApp.getInstance().initialSettingData();
@ -164,13 +166,13 @@ public class SettingActivity extends AppCompatActivityAbstract {
if (statusList.isEmpty()) {
SettinglogsDao settinglogsDao = new SettinglogsDao(this);
for (String data: settinglogsDao.getAll()) {
for (String data : settinglogsDao.getAll()) {
statusList.add(data);
}
}
if (!statusList.isEmpty()) {
recyclerSettingListAdpter.notifyItemInserted(statusList.size() -1);
recyclerSettingListAdpter.notifyItemInserted(statusList.size() - 1);
}
binding.buttonBack.setOnClickListener(v -> {
@ -185,10 +187,11 @@ public class SettingActivity extends AppCompatActivityAbstract {
}
// 開始綁定 顯示進度條
// showLoading(true);
// showLoading(true);
binding.progressLayout.setVisibility(View.VISIBLE);
VideoImageMixedPlayer.clearAdsCache(this);
getLogs().info("刪除廣告暫存檔");
ImageGlide.clearProductCache(this);
getLogs().info("刪除廣告與商品暫存檔");
getHandlerMain().start("ButtonReloadOnClick", Option.DATA_RELOAD.getOption(), "data reload");
});
@ -205,7 +208,8 @@ public class SettingActivity extends AppCompatActivityAbstract {
public static void updateProgressUI(int percent, String message) {
SettingActivity activity = instance.get();
if (activity == null) return;
if (activity == null)
return;
activity.runOnUiThread(() -> {
if (activity.progressBar != null) {
@ -224,54 +228,52 @@ public class SettingActivity extends AppCompatActivityAbstract {
if (!MyApp.getInstance().getMachine().getMachineID().isEmpty()) {
statusList.add("download maching data:"
+ MyApp.getInstance().getMachine().getMachineID()
+"/"
+Tools.randomReplace(MyApp.getInstance().getMachine().getApiKey(), 0.3)
);
+ MyApp.getInstance().getMachine().getMachineID()
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getMachine().getApiKey(), 0.3));
}
if (MyApp.getInstance().getGreenInvoice().getGreenMerchantID() != null) {
statusList.add("download greenpay Invoice data:"
+Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenMerchantID()), 0.3)
+"/"
+Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenHashKey()), 0.3)
+"/"
+Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenHashIV()), 0.3)
+"/"
+Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenEmail()), 0.3)
);
+ Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenMerchantID()),
0.3)
+ "/"
+ Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenHashKey()), 0.3)
+ "/"
+ Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenHashIV()), 0.3)
+ "/"
+ Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenInvoice().getGreenEmail()), 0.3));
}
if (!MyApp.getInstance().getEsunpay().getStoreID().isEmpty()) {
statusList.add("download esunpay data:"
+Tools.randomReplace(MyApp.getInstance().getEsunpay().getStoreID(), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getEsunpay().getTermID(), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getEsunpay().getHash(), 0.3)
);
+ Tools.randomReplace(MyApp.getInstance().getEsunpay().getStoreID(), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getEsunpay().getTermID(), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getEsunpay().getHash(), 0.3));
}
if (MyApp.getInstance().getGreenpaySetting().getAppKey() != null && !MyApp.getInstance().getGreenpaySetting().getAppKey().isEmpty()) {
if (MyApp.getInstance().getGreenpaySetting().getAppKey() != null
&& !MyApp.getInstance().getGreenpaySetting().getAppKey().isEmpty()) {
statusList.add("download greenpay data:"
+Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenpaySetting().getAppId()), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getGreenpaySetting().getAppKey(), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getGreenpaySetting().getPartnerKey(), 0.3)
);
+ Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenpaySetting().getAppId()), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getGreenpaySetting().getAppKey(), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getGreenpaySetting().getPartnerKey(), 0.3));
statusList.add("download greenpay merchant data:"
+Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenpayMerchant().getLineMerchantId()), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getPsMerchantId(), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getEasyMerchantId(), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getPiMerchantId(), 0.3)
+"/"
+Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getJkoMerchantId(), 0.3)
);
+ Tools.randomReplace(String.valueOf(MyApp.getInstance().getGreenpayMerchant().getLineMerchantId()),
0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getPsMerchantId(), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getEasyMerchantId(), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getPiMerchantId(), 0.3)
+ "/"
+ Tools.randomReplace(MyApp.getInstance().getGreenpayMerchant().getJkoMerchantId(), 0.3));
}
if (!MyApp.getInstance().getProductList().isEmpty()) {
@ -284,7 +286,7 @@ public class SettingActivity extends AppCompatActivityAbstract {
statusList.add("download ad url data:" + size);
}
recyclerSettingListAdpter.notifyItemInserted(statusList.size() -1);
recyclerSettingListAdpter.notifyItemInserted(statusList.size() - 1);
updateProgressUI(100, "下載中...");
binding.progressLayout.setVisibility(View.GONE);

View File

@ -37,7 +37,7 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
private Context context;
private final List<SlotStructure> SlotList;
private FragmentAbstract fragment;
private boolean haveThings,doorError;
private boolean haveThings, doorError;
public RecyclerVmcBuyListAdpter(FragmentAbstract fragment, List<SlotStructure> slotList) {
this.logs = new Logs(this.getClass());
@ -59,7 +59,8 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 使用 ViewBinding 來綁定佈局
RecyclerVmcBuyListBinding binding = RecyclerVmcBuyListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
RecyclerVmcBuyListBinding binding = RecyclerVmcBuyListBinding.inflate(LayoutInflater.from(parent.getContext()),
parent, false);
return new ViewHolder(binding);
}
@ -76,7 +77,7 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
this.logs.warning(e);
}
holder.binding.textSlot.setText(String.format("%03d", slot.getSlot()));
//多國語的判斷
// 多國語的判斷
String currentLang = LanguageHelper.getSavedLanguage(context);
holder.binding.textProductName.setText(slot.getProduct().getProductName());
switch (currentLang) {
@ -91,7 +92,6 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
break;
}
int machinePrice = slot.getProduct().getMachinePrice();
int sellingPrice = slot.getProduct().getSellingPrice();
int memberPrice = slot.getProduct().getMemberPrice();
@ -99,16 +99,16 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
int count = slot.getCount();
boolean isLock = slot.isLock();
int price = machinePrice > 0? machinePrice: sellingPrice;
int price = machinePrice > 0 ? machinePrice : sellingPrice;
holder.binding.textPrice.setText("NT$ "+price);
holder.binding.textPrice.setText("NT$ " + price);
holder.binding.mask.setVisibility(View.GONE);
holder.binding.textMask.setText("");
if (count <= 0) {
holder.binding.mask.setVisibility(View.VISIBLE);
holder.binding.textMask.setText("補貨中");//已經售完
holder.binding.textMask.setText("補貨中");// 已經售完
}
if (isLock) {
@ -118,13 +118,13 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
if (count > 0 && !isLock) {
holder.binding.imageProductPicture.setFocusable(false);
holder.binding.imageProductPicture.setFocusableInTouchMode(false);
holder.binding.imageProductPicture.setOnClickListener(new imageProductPictureOnClickListener(position));
holder.binding.imageProductPicture.setFocusableInTouchMode(false);
holder.binding.imageProductPicture.setOnClickListener(new imageProductPictureOnClickListener(position));
} else {
holder.binding.imageProductPicture.setOnClickListener(null);
}
//devRunVMC(0);
// devRunVMC(0);
}
@Override
@ -134,7 +134,7 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
public void addSlotData(SlotStructure slotStructure) {
SlotList.add(slotStructure);
notifyItemInserted(SlotList.size() -1);
notifyItemInserted(SlotList.size() - 1);
}
public class imageProductPictureOnClickListener implements View.OnClickListener {
@ -147,8 +147,10 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
@Override
public void onClick(View v) {
SlotStructure slotProduct = SlotList.get(position);
if (slotProduct.isLock()) return;
if (MyApp.getInstance().isShowDialog()) return;
if (slotProduct.isLock())
return;
if (MyApp.getInstance().isShowDialog())
return;
// 即時庫存檢查防止 MQTT 更新後 UI 尚未刷新的時間差
try {
@ -165,25 +167,30 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
// 查詢失敗時不阻擋讓原流程繼續
}
BuyStructure buyProduct = new BuyStructure(slotProduct.getField(), slotProduct.getSlot(), slotProduct.getProduct(), 1);
BuyStructure buyProduct = new BuyStructure(slotProduct.getField(), slotProduct.getSlot(),
slotProduct.getProduct(), 1);
MyApp.getInstance().getBuyList().add(buyProduct);
fragment.getSrcHandlerMain().start(getClass().getSimpleName(), FontendActivity.Option.STOP_COUNTDOWN.getOption(), "stop countdown");
fragment.getSrcHandlerMain().start(getClass().getSimpleName(),
FontendActivity.Option.STOP_COUNTDOWN.getOption(), "stop countdown");
new MemberCardPickupDialog(context, fragment.getSrcHandlerMain()).show();
}
}
public void checkSlotHaveProduct(int slotnum, int slotcount) {
logs.info("RecyclerDialogBuyListAdpter 111111111111111" + slotnum);
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new DevCheckSlotByVMC(handlerMain));
logs.info("RecyclerDialogBuyListAdpter 222222222222222"+slotcount);
MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().checkSlotPre(slotnum,slotcount));
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
// DevCheckSlotByVMC(handlerMain));
logs.info("RecyclerDialogBuyListAdpter 222222222222222" + slotcount);
MyApp.getInstance().getDevXinYuanController().addSendBuffer(
MyApp.getInstance().getDevXinYuanController().getDevXinYuan().checkSlotPre(slotnum, slotcount));
logs.info("RecyclerDialogBuyListAdpter 333333333333333");
MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().checkSlot(slotnum));
MyApp.getInstance().getDevXinYuanController()
.addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().checkSlot(slotnum));
logs.info("RecyclerDialogBuyListAdpter 444444444444444");
MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new DevCheckSlotByVMC(fragment.getSrcHandlerMain()));
MyApp.getInstance().getDevXinYuanController()
.getReadBufferByNow(new DevCheckSlotByVMC(fragment.getSrcHandlerMain()));
}
public class DevCheckSlotByVMC extends DevController.ReadBufferOnScheduler {
public DevCheckSlotByVMC(HandlerMain handlerMain) {
super(handlerMain);
@ -203,13 +210,13 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
// 每次檢查前先重置門狀態旗標
doorError = false;
for (byte[] buffer: devController.getReadBufferByMax()) {
for (byte[] buffer : devController.getReadBufferByMax()) {
if (buffer[0] == 0x02) {
getLogs().info("xxxxxxxxxxxxxxxxxxxxxxxxXinYuan Read:" + PortTools.showHex(buffer));
if (buffer[1] == 0x05) {
haveThings = true;
break;
}else if (buffer[1] == 0x06 || buffer[1] == 0x09) {
} else if (buffer[1] == 0x06 || buffer[1] == 0x09) {
// 0x06取貨口門沒關上
// 0x09微波爐取貨口門關閉錯誤
getLogs().info("檢測到取貨口門未正常關閉,狀態碼=" + String.format("%02X", buffer[1]));
@ -219,7 +226,7 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
}
}
if(haveThings){
if (haveThings) {
// 使用主執行緒顯示 AlertDialog
new Handler(Looper.getMainLooper()).post(() -> {
AlertDialog dialog = new AlertDialog.Builder(context)
@ -228,7 +235,8 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
.setCancelable(false)
.setPositiveButton(R.string.i_knew, (d, which) -> {
d.dismiss();
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(), "force close");
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
"force close");
})
.create();
@ -238,11 +246,12 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (dialog.isShowing()) {
dialog.dismiss();
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(), "force close");
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
"force close");
}
}, 10_000); // 10 10000 毫秒
});
}else if (doorError) {
} else if (doorError) {
// 取貨口門未關閉提示使用者並阻止後續購買流程
doorError = false;
handlerMain.start("RecycleFlowerBuyListAdpter", "取貨口門未正常關閉,請先確認門已關好");
@ -254,7 +263,8 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
.setCancelable(false)
.setPositiveButton(R.string.i_knew, (d, which) -> {
d.dismiss();
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(), "force close");
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
"force close");
})
.create();
@ -264,7 +274,8 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (dialog.isShowing()) {
dialog.dismiss();
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(), "force close");
handlerMain.start(getClass().getSimpleName(), BuyDialog.Option.FORCE_CLOSE.getOption(),
"force close");
}
}, 10_000); // 10 10000 毫秒
});
@ -292,24 +303,28 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
@Override
public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
for (byte[] buffer: devController.getReadBufferByMax()) {
if (buffer[0] == 0x02 && buffer[1] == 0x01 || buffer[0] == 0x02 && buffer[1] == 0x02 || buffer[0] == 0x02 && buffer[1] == 0x04) {
for (byte[] buffer : devController.getReadBufferByMax()) {
if (buffer[0] == 0x02 && buffer[1] == 0x01 || buffer[0] == 0x02 && buffer[1] == 0x02
|| buffer[0] == 0x02 && buffer[1] == 0x04) {
SlotStructure slotProduct = SlotList.get(position);
BuyStructure buyProduct = new BuyStructure(slotProduct.getField(), slotProduct.getSlot(), slotProduct.getProduct(), 1);
BuyStructure buyProduct = new BuyStructure(slotProduct.getField(), slotProduct.getSlot(),
slotProduct.getProduct(), 1);
MyApp.getInstance().getBuyList().add(buyProduct);
handlerMain.start(getClass().getSimpleName(), FontendActivity.Option.STOP_COUNTDOWN.getOption(), "stop countdown");
handlerMain.start(getClass().getSimpleName(), FontendActivity.Option.STOP_COUNTDOWN.getOption(),
"stop countdown");
new BuyDialog(context, fragment.getSrcHandlerMain()).show();
return;
}
}
handlerMain.start(getClass().getSimpleName(), "@貨道尚未準備好,三秒後再點選");//@貨道尚未準備好三秒後再點選
handlerMain.start(getClass().getSimpleName(), "@貨道尚未準備好,三秒後再點選");// @貨道尚未準備好三秒後再點選
}
}
private void devRunVMC(int slot){
MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new DevSelectSlotByMICO(fragment.getHandlerMain(), slot, false, false));
private void devRunVMC(int slot) {
MyApp.getInstance().getDevXinYuanController()
.getReadBufferByNow(new DevSelectSlotByMICO(fragment.getHandlerMain(), slot, false, false));
}
private int testCount;
@ -317,6 +332,7 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
private boolean isCMD;
private boolean inTheMiddle;
private boolean isSuccess;
private void initDev() {
testCount = 0;
checkCount = 0;
@ -350,7 +366,7 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
@Override
public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
for (byte[] buffer: devController.getReadBufferByMax()) {
for (byte[] buffer : devController.getReadBufferByMax()) {
getLogs().info("DevSelectSlotByMICO:" + PortTools.showHex(buffer));
if (buffer[0] == 0x02) {
@ -374,29 +390,37 @@ public class RecyclerVmcBuyListAdpter extends RecyclerView.Adapter<RecyclerVmcBu
if (isCMD) {
if (isSuccess) {
initDev();
// getSrcHandlerMain().start(getClass().getSimpleName(), DispatchDialog.Option.SET_MESSAGE_TEXT.getOption(), "檢測貨道可出貨");
// if (isMico) {
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new DevMicoInfo65ByMICO(getHandlerMain(), slot, isHeading));
// MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMicoHeating(isHeading));
// } else {
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new DevGetProductByMICO(getHandlerMain(), slot));
// MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().getProduct(slot));
// }
// getSrcHandlerMain().start(getClass().getSimpleName(),
// DispatchDialog.Option.SET_MESSAGE_TEXT.getOption(), "檢測貨道可出貨");
// if (isMico) {
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
// DevMicoInfo65ByMICO(getHandlerMain(), slot, isHeading));
// MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().setMicoHeating(isHeading));
// } else {
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
// DevGetProductByMICO(getHandlerMain(), slot));
// MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().getProduct(slot));
// }
} else {
if (checkCount > 15) {
getSrcHandlerMain().start(getClass().getSimpleName(), DispatchDialog.Option.ERROR_PROCESS_GOODS.getOption(), "請檢查商品有無取出再確認取貨");
getSrcHandlerMain().start(getClass().getSimpleName(),
DispatchDialog.Option.ERROR_PROCESS_GOODS.getOption(), "請檢查商品有無取出再確認取貨");
} else {
// getSrcHandlerMain().start(getClass().getSimpleName(), Option.SET_MESSAGE_TEXT.getOption(), "檢查中");
// MyApp.getInstance().getDevXinYuanController().getReadBuffer(new DevSelectSlotByMICO(getHandlerMain(), slot, isMico, isHeading));
// getSrcHandlerMain().start(getClass().getSimpleName(),
// Option.SET_MESSAGE_TEXT.getOption(), "檢查中");
// MyApp.getInstance().getDevXinYuanController().getReadBuffer(new
// DevSelectSlotByMICO(getHandlerMain(), slot, isMico, isHeading));
checkCount++;
}
}
} else {
if (testCount > 15) {
// getSrcHandlerMain().start(getClass().getSimpleName(), DispatchDialog.Option.ERROR_PROCESS_GOODS.getOption(), "下位機無回應 請等3秒後再重試");
// getSrcHandlerMain().start(getClass().getSimpleName(),
// DispatchDialog.Option.ERROR_PROCESS_GOODS.getOption(), "下位機無回應 請等3秒後再重試");
} else {
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new DevSelectSlotByMICO(getHandlerMain(), slot, isMico, isHeading));
// MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().selectSlot(slot));
// MyApp.getInstance().getDevXinYuanController().getReadBufferByNow(new
// DevSelectSlotByMICO(getHandlerMain(), slot, isMico, isHeading));
// MyApp.getInstance().getDevXinYuanController().addSendBuffer(MyApp.getInstance().getDevXinYuanController().getDevXinYuan().selectSlot(slot));
testCount++;
}
}

View File

@ -22,6 +22,8 @@ import com.unibuy.smartdevice.exception.LogsFileNullException;
import com.unibuy.smartdevice.exception.LogsIOException;
import com.unibuy.smartdevice.exception.LogsMalformedURLException;
import com.unibuy.smartdevice.tools.HttpConnect;
import com.unibuy.smartdevice.tools.Tools;
import android.util.Log;
import java.io.File;
import java.security.MessageDigest;
@ -33,8 +35,9 @@ public class ImageGlide {
this.context = context;
}
public void fileload(String urlString, ImageView imageView) throws LogsEmptyException{
if (imageView == null) return;
public void fileload(String urlString, ImageView imageView) throws LogsEmptyException {
if (imageView == null)
return;
Context ctx = imageView.getContext();
if (ctx instanceof Activity) {
@ -45,7 +48,6 @@ public class ImageGlide {
}
}
HttpConnect httpConnect = new HttpConnect();
try {
File imageFile = httpConnect.getFileFromUrl(urlString);
@ -158,4 +160,25 @@ public class ImageGlide {
messageDigest.update((byte) alpha);
}
}
/**
* 清理商品圖片暫存 (Tools.getExternalFilesDir())
*/
public static void clearProductCache(Context context) {
File dir = Tools.getExternalFilesDir();
if (dir != null && dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
String name = file.getName().toLowerCase();
if (name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg")
|| name.endsWith(".webp")) {
if (file.delete()) {
Log.i("ImageGlide", "Deleted product cache: " + name);
}
}
}
}
}
}
}