调整了餐盘在不同设备提示

This commit is contained in:
zxj
2025-07-24 08:40:36 +08:00
parent 7fd2ccb960
commit 082011a939
17 changed files with 198 additions and 35 deletions
+6
View File
@@ -8,6 +8,12 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application
android:name=".MyApp"
@@ -14,7 +14,7 @@ object GlobalData {
/**
* 横排数量
*/
var arrayCross: Int = 2
var arrayCross: Int = 3
/**
* 竖排数量
@@ -24,7 +24,7 @@ object GlobalData {
/**
* 排列方式 0 垂直 1 水平
*/
var arrayMode: Int = 1
var arrayMode: Int = 0
}
@@ -13,7 +13,6 @@ import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.sw.inbound.utils.DateTimeUtils
@@ -51,9 +50,9 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
context = this
disableSystemUICompletely()
// disableSystemUICompletely()
// 确保内容延伸到导航栏区域
WindowCompat.setDecorFitsSystemWindows(window, false)
// WindowCompat.setDecorFitsSystemWindows(window, false)
binding = inflateViewBinding()
headerBinding = inflateTitleBinding()
@@ -60,8 +60,8 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
override fun initialize() {
// 请求权限
checkCameraPermission()
// viewModel.activeEngine()
initArcViewModel()
initArcView()
openRectInfoDraw = true
@@ -88,9 +88,11 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
private fun checkCameraPermission() {
Timber.i("checkCameraPermission")
val permissionHelper =
PermissionHelper.with(this, REQUIRED_PERMISSIONS, CAMERA_PERMISSION_REQUEST_CODE)
.onGranted {
Timber.d("checkCameraPermission 权限已允许")
// 权限已授予
recognizeViewModel.init()
initRgbCamera()
@@ -175,12 +177,14 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
/**
* 调整View的宽高,使2个预览同时显示
* 调整View的宽高,使预览显示正常且采集框固定为380x380
*
* @param rgbPreview RGB预览View
* @param previewView 显示预览数据的view
* @param faceRectView 画框的view
* @param faceRectView 画框的view (380x380)
* @param previewSize 预览大小
* @param displayOrientation 相机旋转角度
* @param scale 缩放比例
* @return 调整后的LayoutParams
*/
private fun adjustPreviewViewSize(
@@ -345,10 +349,8 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
override fun onGlobalLayout() {
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this)
recognizeViewModel.init()
initRgbCamera()
resumeCamera()
// countDownTimer.start();
// 请求权限
checkCameraPermission()
}
@@ -19,6 +19,13 @@ object DateTimeUtils {
return SimpleDateFormat("yyyy年M月d日 EEEE", Locale.CHINA).format(date)
}
/**
* 获取标准时间格式
*/
fun getDateTimeString(date: Date = Date()): String {
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(date)
}
/**
* 获取带时间的完整中文格式(示例:2025年6月11日 星期三 14:30
*/
@@ -30,7 +30,7 @@ class PermissionHelper private constructor(
/**
* 检查是否已授予所有权限
*/
fun areAllPermissionsGranted(context: Context, permissions: Array<String>): Boolean {
fun checkPermissions(context: Context, permissions: Array<String>): Boolean {
return permissions.all { permission ->
ContextCompat.checkSelfPermission(
context,
@@ -121,7 +121,7 @@ class PermissionHelper private constructor(
* 检查并请求权限
*/
fun checkAndRequest() {
if (areAllPermissionsGranted(context, permissions)) {
if (checkPermissions(context, permissions)) {
onGranted?.invoke()
} else {
requestPermissions()
@@ -0,0 +1,124 @@
package com.sw.platecabinet.utils
import android.os.Handler
import android.os.Looper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.coroutines.CoroutineContext
/**
* 多功能线程工具类
* 结合协程、Handler和线程池实现线程切换
*/
object ThreadUtils : CoroutineScope {
// 主线程Handler
private val mainHandler by lazy { Handler(Looper.getMainLooper()) }
// 后台线程池(IO密集型任务)
private val ioThreadPool: ExecutorService by lazy {
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2)
}
// CPU密集型线程池
private val cpuThreadPool: ExecutorService by lazy {
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
}
// 协程Job管理
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
// ========== Handler相关方法 ==========
/**
* 在主线程执行任务
* @param delayMillis 延迟时间(毫秒)
*/
fun runOnUiThread(delayMillis: Long = 0, block: () -> Unit) {
if (delayMillis > 0) {
mainHandler.postDelayed(block, delayMillis)
} else {
if (isOnMainThread()) {
block()
} else {
mainHandler.post(block)
}
}
}
/**
* 移除主线程任务
*/
fun removeUiThreadTask(block: () -> Unit) {
mainHandler.removeCallbacks(block)
}
// ========== 线程池相关方法 ==========
/**
* 在IO线程执行任务
*/
fun runOnIoThread(block: () -> Unit) {
ioThreadPool.execute(block)
}
/**
* 在CPU计算线程执行任务
*/
fun runOnCpuThread(block: () -> Unit) {
cpuThreadPool.execute(block)
}
// ========== 协程相关方法 ==========
/**
* 启动协程(默认在主线程)
*/
fun launch(block: suspend CoroutineScope.() -> Unit): Job {
return launch(coroutineContext, block = block)
}
/**
* 在IO线程启动协程
*/
fun launchOnIo(block: suspend CoroutineScope.() -> Unit): Job {
return launch(Dispatchers.IO, block = block)
}
/**
* 切换到主线程(协程环境)
*/
suspend fun <T> switchToMain(block: suspend CoroutineScope.() -> T): T {
return withContext(Dispatchers.Main, block)
}
/**
* 切换到IO线程(协程环境)
*/
suspend fun <T> switchToIo(block: suspend CoroutineScope.() -> T): T {
return withContext(Dispatchers.IO, block)
}
/**
* 是否在主线程
*/
fun isOnMainThread(): Boolean {
return Looper.myLooper() == Looper.getMainLooper()
}
/**
* 释放资源
*/
fun release() {
job.cancel()
ioThreadPool.shutdown()
cpuThreadPool.shutdown()
}
}
@@ -1,5 +1,6 @@
package com.sw.platecabinet.viewmodel
import com.sw.inbound.utils.DateTimeUtils
import com.sw.plate.utils.ToastUtils
import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.GlobalData.globalEquipmentCode
@@ -43,7 +44,7 @@ class SettingViewModel : BaseViewModel() {
EquipmentParam(appVersion = GlobalData.appVersion, equipmentCode = equipmentCode)
val response = repository.getEquipmentList(param)
if (parseResponse(response)) {
_equipmentList.value = response.data?.plus(response.data) ?: emptyList()
_equipmentList.value = response.data ?: emptyList()
}
}
}
@@ -94,6 +95,13 @@ class SettingViewModel : BaseViewModel() {
)
val response = repository.bindEquipment(bindParam)
if (parseResponse(response)) {
val userInfo = response.data
userInfo?.let {
if (it.isOtherEquipment()) {
ToastUtils.showToast("餐盘已在${it.equipmentName}绑定")
return@launchWithLoading
}
}
_bindStateChange.value = true to ErrorInfo()
} else {
_bindStateChange.value = true to ErrorInfo(response.code, response.msg.toString())
@@ -132,15 +140,20 @@ class SettingViewModel : BaseViewModel() {
)
val response = repository.findByPlateNumber(bindParam)
if (response.code == 200) {
if (response.data?.isOtherEquipment() == true) {
ToastUtils.showToast("")
return@launchWithLoading
val userInfo = response.data
userInfo?.let {
if (it.isOtherEquipment()) {
ToastUtils.showToast("餐盘已在${it.equipmentName}绑定")
return@launchWithLoading
}
}
_currentUserInfo.value = response.data
} else {
_currentUserInfo.value = EquipmentUserInfo(
plateNumber = plateNumber,
equipmentCode = equipmentCode
equipmentCode = equipmentCode,
updateTime = DateTimeUtils.getDateTimeString()
)
}
}
@@ -13,6 +13,7 @@ import com.sw.platecabinet.GlobalKey
import com.sw.platecabinet.model.request.LoginParam
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.UserFaceModel
import com.sw.platecabinet.utils.ThreadUtils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import timber.log.Timber
@@ -63,7 +64,8 @@ class UserViewModel : BaseViewModel() {
/**
* 激活人脸识别引擎
*/
private fun activeEngine() {
fun activeEngine() {
Timber.d("activeEngine")
var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj"
var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k"
var activeKey = "085F-118G-Q391-53YL"
@@ -75,23 +77,27 @@ class UserViewModel : BaseViewModel() {
object : FaceApi.ActiveCallback {
override fun onSuccess(activeCode: Int) {
Timber.d("activeEngine activeCode = $activeCode")
when (activeCode) {
ErrorInfo.MOK -> {
ToastUtils.showToast("激活引擎成功")
}
ThreadUtils.launch {
when (activeCode) {
ErrorInfo.MOK -> {
ToastUtils.showToast("激活引擎成功")
}
ErrorInfo.MERR_ASF_ALREADY_ACTIVATED -> {
ToastUtils.showToast("引擎已激活,无需再次激活")
}
ErrorInfo.MERR_ASF_ALREADY_ACTIVATED -> {
// ToastUtils.showToast("引擎已激活,无需再次激活")
}
else -> {
ToastUtils.showToast("激活引擎失败($activeCode)")
else -> {
ToastUtils.showToast("激活引擎失败($activeCode)")
}
}
}
}
override fun onFail(e: Exception?) {
ToastUtils.showToast("激活引擎异常,${e?.message}")
ThreadUtils.launch {
ToastUtils.showToast("激活引擎异常,${e?.message}")
}
}
})
}
@@ -5,8 +5,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#14141E"
android:orientation="vertical"
android:fitsSystemWindows="false"
android:orientation="vertical"
tools:context=".activity.LoginByFaceActivity">
<include
@@ -44,7 +44,8 @@
<TextureView
android:id="@+id/dual_camera_texture_preview_rgb"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
android:layout_margin="10dp" />
<com.sw.plate.utils.arcface.FaceRectView
android:id="@+id/dual_camera_face_rect_view"
@@ -15,6 +15,7 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="@color/white"
android:text="请稍等"
android:textSize="22sp" />
<ProgressBar
@@ -5,6 +5,7 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="80dp"
tools:context=".fragment.PlateCabinetFullFragment">
<ImageView
@@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:paddingBottom="80dp"
android:orientation="vertical">
<FrameLayout
@@ -9,6 +9,7 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mainRecyclerView"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />