diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 34fb441..ea2679f 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -30,7 +30,7 @@ android {
}
// 设置输出APK文件名格式
- setProperty("archivesBaseName", "菜品配比终端v${versionName}")
+ setProperty("archivesBaseName", "pbc_v${versionName}")
}
signingConfigs {
create("debug_507") {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a7fc2ef..23ff004 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
+
+
+
+ android:exported="true"
+ android:directBootAware="true">
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt
index 55a28f9..d708ecf 100644
--- a/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt
+++ b/app/src/main/java/com/shuwei/dish/match/ui/MasterScaleActivity.kt
@@ -9,6 +9,7 @@ import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.shuwei.dish.match.R
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityMasterScaleBinding
import com.shuwei.dish.match.databinding.ListItemScaleDataBinding
@@ -16,6 +17,7 @@ import com.shuwei.dish.match.scale.ScaleData
import com.shuwei.dish.match.scale.ScaleServiceManager
import com.shuwei.dish.match.utils.NetworkUtil
import com.shuwei.dish.match.utils.WeightUtil
+import com.shuwei.dish.match.utils.ext.dp
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -138,7 +140,7 @@ class MasterScaleActivity : BaseActivity() {
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
- ).also { it.topMargin = 4.dpToPx() }
+ ).also { it.topMargin = 4.dp }
}
row.addView(makeTextView("秤 ${scale.address}", 22, weight = 1f))
row.addView(makeTextView("${scale.weight} g", 26, bold = true, weight = 2f))
@@ -158,15 +160,11 @@ class MasterScaleActivity : BaseActivity() {
textSize = spSize.toFloat()
if (bold) setTypeface(null, android.graphics.Typeface.BOLD)
setTextColor(
- if (bold) getColor(com.shuwei.dish.match.R.color.home_title)
- else getColor(com.shuwei.dish.match.R.color.home_sub_title)
+ if (bold) getColor(R.color.home_title)
+ else getColor(R.color.home_sub_title)
)
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, weight)
}
}
-
- /** dp 转 px 工具 */
- private fun Int.dpToPx(): Int =
- (this * resources.displayMetrics.density + 0.5f).toInt()
}
diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt
index 3768583..6e9c3d7 100644
--- a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt
+++ b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt
@@ -81,9 +81,9 @@ class SettingActivity : BaseActivity() {
updateButtonColors(isDeviceConfigSelected = false)
}
- // 设备角色只读展示,角色由设备 ID 决定,不可手动切换
- updateRoleButtonText()
- binding.btnDeviceRole.isEnabled = false
+// // 设备角色只读展示,角色由设备 ID 决定,不可手动切换
+// updateRoleButtonText()
+// binding.btnDeviceRole.isEnabled = false
// 主设备显示「秤数据监控」入口
if (GlobalData.deviceRole == DeviceRole.MASTER) {
@@ -97,11 +97,11 @@ class SettingActivity : BaseActivity() {
updateButtonColors(isDeviceConfigSelected = true)
}
- /** 刷新角色按钮文字 */
- private fun updateRoleButtonText() {
- val roleLabel = if (GlobalData.deviceRole == DeviceRole.MASTER) "主设备" else "子设备"
- binding.btnDeviceRole.text = "设备角色:$roleLabel"
- }
+// /** 刷新角色按钮文字 */
+// private fun updateRoleButtonText() {
+// val roleLabel = if (GlobalData.deviceRole == DeviceRole.MASTER) "主设备" else "子设备"
+// binding.btnDeviceRole.text = "设备角色:$roleLabel"
+// }
/**
* 更新底部菜单按钮的颜色状态
diff --git a/app/src/main/java/com/shuwei/dish/match/utils/BootReceiver.kt b/app/src/main/java/com/shuwei/dish/match/utils/BootReceiver.kt
index 35f6830..a2a5ee3 100644
--- a/app/src/main/java/com/shuwei/dish/match/utils/BootReceiver.kt
+++ b/app/src/main/java/com/shuwei/dish/match/utils/BootReceiver.kt
@@ -3,15 +3,25 @@ package com.shuwei.dish.match.utils
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import com.shuwei.dish.match.ui.InitActivity
class BootReceiver : BroadcastReceiver() {
+
+ companion object {
+ /** 兼容多种设备的开机广播 action 集合 */
+ private val BOOT_ACTIONS = setOf(
+ Intent.ACTION_BOOT_COMPLETED,
+ "android.intent.action.QUICKBOOT_POWERON",
+ "android.intent.action.LOCKED_BOOT_COMPLETED"
+ )
+ }
+
override fun onReceive(context: Context, intent: Intent) {
- if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
- // 启动服务或Activity
- val launchIntent = Intent(context, InitActivity::class.java)
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- context.startActivity(launchIntent)
+ val action = intent.action ?: return
+ if (action in BOOT_ACTIONS) {
+ // Android 10+ 禁止在后台直接启动 Activity
+ // 改为启动前台服务,由 BootService 负责拉起 InitActivity
+ val serviceIntent = Intent(context, BootService::class.java)
+ context.startForegroundService(serviceIntent)
}
}
}
diff --git a/app/src/main/java/com/shuwei/dish/match/utils/BootService.kt b/app/src/main/java/com/shuwei/dish/match/utils/BootService.kt
new file mode 100644
index 0000000..7275c18
--- /dev/null
+++ b/app/src/main/java/com/shuwei/dish/match/utils/BootService.kt
@@ -0,0 +1,95 @@
+package com.shuwei.dish.match.utils
+
+import android.app.ActivityManager
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Intent
+import android.content.pm.ServiceInfo
+import android.os.Build
+import android.os.IBinder
+import com.shuwei.dish.match.R
+import com.shuwei.dish.match.ui.InitActivity
+
+/**
+ * 开机自启中转前台服务
+ * 用于绕过 Android 10+ 对后台直接启动 Activity 的限制
+ * 执行流程:BootReceiver → startForegroundService() → 本服务 → setFullScreenIntent → InitActivity
+ */
+class BootService : Service() {
+
+ companion object {
+ /** 通知渠道 ID */
+ private const val CHANNEL_ID = "boot_channel"
+ /** 前台通知 ID */
+ private const val NOTIFICATION_ID = 1001
+ }
+
+ override fun onBind(intent: Intent?): IBinder? = null
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ // 若 App 进程已在前台运行(主设备系统签名场景),则不重复启动,避免闪退
+ val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
+ val isAppForeground = activityManager.runningAppProcesses?.any {
+ it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
+ && it.processName == packageName
+ } ?: false
+
+ // App 未运行时才设置 fullScreenIntent,由系统自动启动 Activity
+ // 直接调用 startActivity() 在部分 Android 10 设备上会被 ActivityTaskManager 拦截
+ val pendingIntent = if (!isAppForeground) createLaunchPendingIntent() else null
+
+ // Android 14+ startForeground 需要传入 foregroundServiceType
+ val notification = buildNotification(pendingIntent)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+ } else {
+ startForeground(NOTIFICATION_ID, notification)
+ }
+
+ stopSelf()
+ return START_NOT_STICKY
+ }
+
+ /** 创建启动 InitActivity 的 PendingIntent */
+ private fun createLaunchPendingIntent(): PendingIntent {
+ val launchIntent = Intent(this, InitActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ return PendingIntent.getActivity(
+ this, 0, launchIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ }
+
+ /**
+ * 构建前台服务通知
+ * fullScreenIntent 不为空时设置全屏意图,系统会在显示通知时自动启动 Activity
+ * 通知渠道必须为 IMPORTANCE_HIGH,否则 fullScreenIntent 不会触发
+ */
+ private fun buildNotification(fullScreenIntent: PendingIntent?): Notification {
+ val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+ val channel = NotificationChannel(
+ CHANNEL_ID,
+ "开机自启动",
+ NotificationManager.IMPORTANCE_HIGH
+ ).apply {
+ description = "应用开机自动启动通知渠道"
+ setShowBadge(false)
+ }
+ manager.createNotificationChannel(channel)
+
+ return Notification.Builder(this, CHANNEL_ID)
+ .setContentTitle("正在启动应用")
+ .setSmallIcon(R.mipmap.ic_logo512)
+ .apply {
+ if (fullScreenIntent != null) {
+ setFullScreenIntent(fullScreenIntent, true)
+ }
+ }
+ .build()
+ }
+}
+
diff --git a/app/src/main/res/layout/activity_master_scale.xml b/app/src/main/res/layout/activity_master_scale.xml
index 6373dce..86a2c62 100644
--- a/app/src/main/res/layout/activity_master_scale.xml
+++ b/app/src/main/res/layout/activity_master_scale.xml
@@ -11,7 +11,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:layout_marginTop="20dp"
+ android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="全设备秤数据监控"
android:textColor="@color/home_title"
@@ -36,6 +36,7 @@
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never"
- android:padding="16dp" />
+ android:padding="16dp"
+ tools:listitem="@layout/list_item_scale_data"/>
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
index d1d36cb..c3b0d8d 100644
--- a/app/src/main/res/layout/activity_setting.xml
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -37,14 +37,14 @@
android:textSize="26sp"
android:background="@android:color/transparent" />
-
+
+
+
+
+
+
+
+
+ android:paddingTop="10dp">
@@ -37,4 +37,10 @@
android:orientation="vertical"
android:layout_marginTop="5dp" />
+
+