[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:
parent
028cac10b5
commit
3044314856
@ -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 資料夾
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user