[FEAT] 新增 CMUH 客製初始畫面跳轉與多處頁面重啟邏輯優化
1. 新增 AppEntry 工具類別,集中管理 Cmuh 專案判斷與動態初始 Activity 的獲取邏輯。 2. 於 HomeActivity 中新增 Cmuh 專案判斷,若為 CMUH 則直接導向至 FontendActivity 以跳過一般首頁。 3. 將 MainActivity、MqttService 與 FontendActivity 中的硬編碼 HomeActivity 導向重構為呼叫 AppEntry.initialActivity()。 4. 新增 Cmuh 專屬之 activity_fontend.xml 佈局檔案。 5. 遞增 app/build.gradle 中的修補版號 verPatch 至 35。
This commit is contained in:
parent
f3867dcb4b
commit
7b9b96ce66
@ -9,7 +9,7 @@ plugins {
|
||||
// 避免不同尺寸機台間版本號產生衝突。
|
||||
// =========================================================================
|
||||
def verMinor = 1
|
||||
def verPatch = 34
|
||||
def verPatch = 35
|
||||
|
||||
|
||||
android {
|
||||
|
||||
267
app/src/Cmuh/res/layout/activity_fontend.xml
Normal file
267
app/src/Cmuh/res/layout/activity_fontend.xml
Normal file
@ -0,0 +1,267 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/light_gray"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout5"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:background="@color/red"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textVersion"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="20250108ver1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textThreadCount"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="TC:0"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
<TextView
|
||||
android:id="@+id/btnswitchlanTW"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="中"
|
||||
android:visibility="gone"
|
||||
android:textSize="30sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnswitchlanEn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="En"
|
||||
android:visibility="gone"
|
||||
android:textSize="30sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnswitchlanJa"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="日"
|
||||
android:visibility="gone"
|
||||
android:textSize="30sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textTemperature"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end"
|
||||
android:text="0 ℃"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textTime"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end"
|
||||
android:text="1911/01/01 01:01:01"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textNetwork"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical|end"
|
||||
android:text="@string/no_internet"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/relativeLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:background="@color/black"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fragment_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/linearLayout5">
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/videoView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:show_subtitle_button="true"
|
||||
app:use_artwork="true"
|
||||
app:use_controller="false" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageAd"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitXY"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="500dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/relativeLayout" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_navigation"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/buttonVmc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/drinksale"
|
||||
app:cornerRadius="12dp"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
app:strokeColor="@color/gray"
|
||||
android:textSize="38sp"
|
||||
app:strokeWidth="2dp"
|
||||
android:visibility="gone"
|
||||
android:layout_margin="4dp"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/buttonElectric"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/board_games"
|
||||
app:cornerRadius="12dp"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
app:strokeColor="@color/gray"
|
||||
android:textSize="38sp"
|
||||
android:visibility="gone"
|
||||
app:strokeWidth="2dp"
|
||||
android:layout_margin="4dp"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/buttonOther"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"
|
||||
android:text="@string/other"
|
||||
app:cornerRadius="12dp"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
app:strokeColor="@color/gray"
|
||||
android:textSize="38sp"
|
||||
app:strokeWidth="2dp"
|
||||
android:layout_margin="4dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/floatButtonPickupCode"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="150dp"
|
||||
android:text="取\n貨\n碼"
|
||||
android:textSize="28sp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="80dp"
|
||||
android:backgroundTint="@color/gray"
|
||||
android:textColor="@color/black"
|
||||
android:alpha="0.8"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@+id/floatButtonShoppingCart"
|
||||
app:layout_constraintEnd_toEndOf="@+id/bottom_navigation"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/floatButtonShoppingCart"
|
||||
android:layout_width="58dp"
|
||||
android:layout_height="51dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="80dp"
|
||||
android:contentDescription="TODO"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/gray"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/fragment_container"
|
||||
app:layout_constraintEnd_toEndOf="@+id/bottom_navigation"
|
||||
app:maxImageSize="60dp"
|
||||
app:srcCompat="@drawable/baseline_add_shopping_cart_24" />
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnTopRight"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="100dp"
|
||||
android:text="進入後台"
|
||||
android:textSize="24sp"
|
||||
android:backgroundTint="@color/red"
|
||||
android:textColor="@android:color/white"
|
||||
android:alpha="1"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="60dp"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
16
app/src/main/java/com/unibuy/smartdevice/AppEntry.java
Normal file
16
app/src/main/java/com/unibuy/smartdevice/AppEntry.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.unibuy.smartdevice;
|
||||
|
||||
import com.unibuy.smartdevice.ui.FontendActivity;
|
||||
|
||||
public final class AppEntry {
|
||||
private AppEntry() {
|
||||
}
|
||||
|
||||
public static boolean isCmuh() {
|
||||
return "Cmuh".equalsIgnoreCase(BuildConfig.FLAVOR_project);
|
||||
}
|
||||
|
||||
public static Class<?> initialActivity() {
|
||||
return isCmuh() ? FontendActivity.class : HomeActivity.class;
|
||||
}
|
||||
}
|
||||
@ -239,6 +239,14 @@ public class HomeActivity extends AppCompatActivityAbstract {
|
||||
}
|
||||
settingsDao.close();
|
||||
|
||||
if (AppEntry.isCmuh()) {
|
||||
Intent intent = new Intent(this, FontendActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
binding = ActivityHomeBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
@ -312,7 +320,7 @@ public class HomeActivity extends AppCompatActivityAbstract {
|
||||
getLogs().info("🔄HomeActivity - Scheduled Hard App restarting via gracefulDisconnect...");
|
||||
com.unibuy.smartdevice.external.mqtt.MqttManager.getInstance().gracefulDisconnect(() -> {
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> {
|
||||
Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
|
||||
Intent intent = new Intent(getApplicationContext(), AppEntry.initialActivity());
|
||||
// 清空所有 Task,重新啟動
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
|
||||
@ -649,7 +649,7 @@ public class MainActivity extends AppCompatActivityAbstract {
|
||||
getLogs().info("🔄MainActivity - Manual App restarting via gracefulDisconnect...");
|
||||
com.unibuy.smartdevice.external.mqtt.MqttManager.getInstance().gracefulDisconnect(() -> {
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> {
|
||||
Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
|
||||
Intent intent = new Intent(getApplicationContext(), AppEntry.initialActivity());
|
||||
// 清空所有 Task,重新啟動
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
|
||||
@ -15,7 +15,7 @@ import android.util.Log;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.unibuy.smartdevice.HomeActivity;
|
||||
import com.unibuy.smartdevice.AppEntry;
|
||||
import com.unibuy.smartdevice.R;
|
||||
import com.unibuy.smartdevice.MyApp;
|
||||
import com.unibuy.smartdevice.devices.SlotField;
|
||||
@ -57,7 +57,7 @@ public class MqttService extends Service {
|
||||
createNotificationChannel();
|
||||
|
||||
// 2. 啟動為前台服務(確保不被系統殺掉)
|
||||
Intent notificationIntent = new Intent(this, HomeActivity.class);
|
||||
Intent notificationIntent = new Intent(this, AppEntry.initialActivity());
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(this,
|
||||
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
@ -118,7 +118,7 @@ public class MqttService extends Service {
|
||||
.postDelayed(() -> mqttManager.gracefulDisconnect(() -> {
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> {
|
||||
Intent restartIntent = new Intent(getApplicationContext(),
|
||||
com.unibuy.smartdevice.HomeActivity.class);
|
||||
AppEntry.initialActivity());
|
||||
restartIntent.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(restartIntent);
|
||||
@ -160,12 +160,12 @@ public class MqttService extends Service {
|
||||
mqttManager.publishCommandAck(cmdId, "success", "Machine unlocked, restarting...");
|
||||
|
||||
// 🚩 優雅重啟:先 gracefulDisconnect(不觸發 LWT),再 killProcess
|
||||
// 解鎖後重啟到初始畫面 (HomeActivity)
|
||||
// 解鎖後重啟到目前版本的初始畫面
|
||||
new android.os.Handler(android.os.Looper.getMainLooper())
|
||||
.postDelayed(() -> mqttManager.gracefulDisconnect(() -> {
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> {
|
||||
Intent restartIntent = new Intent(getApplicationContext(),
|
||||
com.unibuy.smartdevice.HomeActivity.class);
|
||||
AppEntry.initialActivity());
|
||||
restartIntent.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(restartIntent);
|
||||
|
||||
@ -33,8 +33,8 @@ import android.widget.Toast;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.unibuy.smartdevice.AppCompatActivityAbstract;
|
||||
import com.unibuy.smartdevice.AppEntry;
|
||||
import com.unibuy.smartdevice.FragmentAbstract;
|
||||
import com.unibuy.smartdevice.HomeActivity;
|
||||
import com.unibuy.smartdevice.MainActivity;
|
||||
import com.unibuy.smartdevice.MyApp;
|
||||
|
||||
@ -436,7 +436,7 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl
|
||||
}
|
||||
|
||||
public void ReSetAPP() {
|
||||
Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
|
||||
Intent intent = new Intent(getApplicationContext(), AppEntry.initialActivity());
|
||||
// 清空所有 Task,重新啟動
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
@ -449,7 +449,7 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl
|
||||
}
|
||||
|
||||
public void ReSetAPP2() {
|
||||
Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
|
||||
Intent intent = new Intent(getApplicationContext(), AppEntry.initialActivity());
|
||||
// 清空所有 Task,重新啟動
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
@ -522,9 +522,9 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl
|
||||
resetIdleTimer();
|
||||
return;
|
||||
}
|
||||
getLogs().info("⚠️ 無操作 3 分鐘,自動返回首頁(清空購物車)");
|
||||
getLogs().info("⚠️ 無操作 3 分鐘,自動返回初始畫面(清空購物車)");
|
||||
MyApp.getInstance().getBuyList().clear(); // 🚩 逾時返回首頁時,務必清空購物車,避免機台進入永久忙碌狀態
|
||||
Intent intent = new Intent(FontendActivity.this, HomeActivity.class);
|
||||
Intent intent = new Intent(FontendActivity.this, AppEntry.initialActivity());
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
@ -840,7 +840,7 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl
|
||||
|
||||
/**
|
||||
* 【現代化重啟】不再使用 sleep 等待,直接確認閒置秒數後執行真重啟。
|
||||
* - 只要閒置 >= 90 秒,立刻啟動 HomeActivity 並 killProcess。
|
||||
* - 只要閒置 >= 90 秒,立刻啟動目前版本的初始畫面並 killProcess。
|
||||
* - 若有人正在使用(閒置 < 90 秒),則等待 5 秒後再重新判斷,最多等待 10 分鐘。
|
||||
*/
|
||||
private class RestartAPP2 extends HandlerMainScheduler {
|
||||
@ -864,7 +864,7 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl
|
||||
getLogs().info("RestartAPP2:執行真重啟 (MQTT 優雅斷線模式)");
|
||||
com.unibuy.smartdevice.external.mqtt.MqttManager.getInstance().gracefulDisconnect(() -> {
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).post(() -> {
|
||||
Intent intent = new Intent(getApplicationContext(), com.unibuy.smartdevice.HomeActivity.class);
|
||||
Intent intent = new Intent(getApplicationContext(), AppEntry.initialActivity());
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
|
||||
@ -1235,4 +1235,4 @@ public class FontendActivity extends AppCompatActivityAbstract implements SaleFl
|
||||
reportOnScheduler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user