From 1f1c3804ac5ec358338187dd26d9574d58e4b32c Mon Sep 17 00:00:00 2001 From: zxj <275873859@qq.com> Date: Thu, 7 Aug 2025 16:23:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E7=95=8C=E9=9D=A2=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E4=BA=BA=E8=84=B8=E6=95=B0=E6=8D=AE=E6=9B=B4=E6=96=B0=E5=90=8E?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E8=AF=86=E5=88=AB=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 5 + app/src/main/java/com/sw/dualscreen/MyApp.kt | 3 +- .../sw/dualscreen/activity/BaseActivity.kt | 84 +++++++++++++++ .../sw/dualscreen/activity/InitActivity.kt | 37 ++++--- .../sw/dualscreen/activity/MainActivity.kt | 31 +++--- .../SecondaryScreenPresentation.kt | 47 ++++++--- .../com/sw/dualscreen/utils/QRCodeUtil.kt | 99 ++++++++++++++++++ .../com/sw/dualscreen/view/CustomDialog.java | 88 ++++++++++++++++ .../dualscreen/viewmodel/DeviceViewModel.kt | 3 +- .../sw/dualscreen/viewmodel/UserViewModel.kt | 23 ++-- app/src/main/res/drawable/bg_init_button.xml | 7 ++ app/src/main/res/drawable/dialog_waiting.xml | 6 ++ app/src/main/res/layout/activity_init.xml | 95 ++++++++++++++--- app/src/main/res/layout/dialog_waiting.xml | 31 ++++++ app/src/main/res/mipmap-xhdpi/img_init.png | Bin 0 -> 1023089 bytes app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/themes.xml | 14 +++ gradle/libs.versions.toml | 4 + 18 files changed, 509 insertions(+), 70 deletions(-) create mode 100644 app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt create mode 100644 app/src/main/java/com/sw/dualscreen/utils/QRCodeUtil.kt create mode 100644 app/src/main/java/com/sw/dualscreen/view/CustomDialog.java create mode 100644 app/src/main/res/drawable/bg_init_button.xml create mode 100644 app/src/main/res/drawable/dialog_waiting.xml create mode 100644 app/src/main/res/layout/dialog_waiting.xml create mode 100644 app/src/main/res/mipmap-xhdpi/img_init.png diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 43dc4b9..ec03b2b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import org.gradle.kotlin.dsl.implementation + plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) @@ -104,4 +106,7 @@ dependencies { implementation(libs.androidx.fragment.ktx) // 图片加载 implementation(libs.glide) + + implementation(libs.core) + implementation(libs.android.core) } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/MyApp.kt b/app/src/main/java/com/sw/dualscreen/MyApp.kt index 1ef5329..5610913 100644 --- a/app/src/main/java/com/sw/dualscreen/MyApp.kt +++ b/app/src/main/java/com/sw/dualscreen/MyApp.kt @@ -12,8 +12,9 @@ class MyApp : App() { override fun onCreate() { super.onCreate() Timber.plant(Timber.DebugTree()) - val deviceId = AppUtil.getUDID(this) + var deviceId = AppUtil.getUDID(this) Timber.d("UDID = ${AppUtil.getUDID(this)}") + deviceId = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e" GlobalData.deviceId = deviceId } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt new file mode 100644 index 0000000..951b75e --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt @@ -0,0 +1,84 @@ +package com.sw.dualscreen.activity + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.text.TextUtils +import android.view.View +import android.view.WindowManager +import android.widget.TextView +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.WindowCompat +import androidx.lifecycle.lifecycleScope +import androidx.viewbinding.ViewBinding +import com.sw.dualscreen.R +import com.sw.dualscreen.view.CustomDialog +import com.sw.dualscreen.viewmodel.BaseViewModel +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import timber.log.Timber + +abstract class BaseActivity : AppCompatActivity() { + protected lateinit var binding: VB + protected lateinit var context: Context + private var mDialogWaiting: CustomDialog? = null + private lateinit var viewModel: BaseViewModel + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + context = this + + //保持亮屏 + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + + binding = inflateViewBinding() + setContentView(binding.root) + viewModel = getViewModel() + initialize() + registerDataChange() + } + + abstract fun getViewModel(): BaseViewModel + + protected abstract fun inflateViewBinding(): VB + + open fun initialize() { + + } + + open fun registerDataChange() { + lifecycleScope.launch { + viewModel.showLoading.collect { + Timber.d("registerDataChange 用户 showLoading = $it") + if (it) { + showWaitingDialog("") + } else { + hideWaitingDialog() + } + } + } + } + + /** + * 显示等待提示框 + */ + fun showWaitingDialog(tip: String?): Dialog? { + hideWaitingDialog() + val view = View.inflate(this, R.layout.dialog_waiting, null) + if (!TextUtils.isEmpty(tip)) (view.findViewById(R.id.tvTip) as TextView).text = tip + mDialogWaiting = CustomDialog(this, view, R.style.MyDialog) + mDialogWaiting!!.show() + mDialogWaiting!!.setCancelable(true) + return mDialogWaiting + } + + /** + * 隐藏等待提示框 + */ + fun hideWaitingDialog() { + mDialogWaiting?.dismiss() + mDialogWaiting = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt index e9e79ca..dd9a3f5 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt @@ -5,35 +5,48 @@ import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat.startActivity import androidx.lifecycle.lifecycleScope +import com.sw.dualscreen.GlobalData import com.sw.dualscreen.databinding.ActivityInitBinding +import com.sw.dualscreen.utils.QRCodeUtil +import com.sw.dualscreen.viewmodel.BaseViewModel import com.sw.dualscreen.viewmodel.DeviceViewModel import com.sw.plate.utils.AppUtil import kotlinx.coroutines.flow.drop import kotlinx.coroutines.launch -class InitActivity : AppCompatActivity() { - private lateinit var binding: ActivityInitBinding +class InitActivity : BaseActivity() { private val viewModel by viewModels() - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - binding = ActivityInitBinding.inflate(layoutInflater) - setContentView(binding.root) - val deviceId = AppUtil.getUDID(this) + override fun getViewModel(): BaseViewModel { + return viewModel + } + + override fun inflateViewBinding(): ActivityInitBinding { + return ActivityInitBinding.inflate(layoutInflater) + } + + override fun initialize() { + super.initialize() val isSuccess = viewModel.checkEquipmentInfo() if (isSuccess) { goMainActivity() + return } - binding.tvDeviceId.text = deviceId - binding.btConfirm.setOnClickListener { + binding.imgQr.setImageBitmap( + QRCodeUtil.generateQRCode( + content = GlobalData.deviceId, + size = 200 + ) + ) + binding.initButton.setOnClickListener { viewModel.getDeviceToken() } - registerDataChange() } - private fun registerDataChange() { + override fun registerDataChange() { + super.registerDataChange() lifecycleScope.launch { viewModel.deviceInfoResult.drop(1).collect { if (it != true) return@collect diff --git a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt index 9ba0568..ff193be 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt @@ -36,6 +36,8 @@ import com.sw.dualscreen.presentation.SecondaryScreenPresentation import com.sw.dualscreen.sdk.SensorScaleUtils import com.sw.dualscreen.utils.GlideUtils import com.sw.dualscreen.view.CustomBottomSheetDialog +import com.sw.dualscreen.view.CustomDialog +import com.sw.dualscreen.viewmodel.BaseViewModel import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel @@ -44,8 +46,7 @@ import timber.log.Timber import java.io.File import java.util.concurrent.Executors -class MainActivity : AppCompatActivity() { - private lateinit var binding: ActivityMainBinding +class MainActivity : BaseActivity() { private val viewModel by viewModels() private var imageCapture: ImageCapture? = null private var isAnalyzing = true // 控制是否进行图像分析 @@ -59,12 +60,16 @@ class MainActivity : AppCompatActivity() { private var bottomSheetDialog: CustomBottomSheetDialog? = null private var lastWeight: Double = 0.0 - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.main) + override fun getViewModel(): BaseViewModel { + return viewModel + } + override fun inflateViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun initialize() { + super.initialize() initView() setupSecondaryDisplay() setupCamera() @@ -94,7 +99,7 @@ class MainActivity : AppCompatActivity() { val spinnerAdapter = ArrayAdapter( this, R.layout.item_for_custom_spinner, - arrayOf("即放即取", "持续取餐") + arrayOf("即放即取", "余量取餐") ) binding.spinner.adapter = spinnerAdapter binding.spinner.setSelection(0) @@ -105,12 +110,10 @@ class MainActivity : AppCompatActivity() { position: Int, id: Long ) { - + presentation.updateMealPickupMode(position) } - override fun onNothingSelected(parent: AdapterView<*>?) { - - } + override fun onNothingSelected(parent: AdapterView<*>?) {} } adapter = createAdapter() binding.recyclerview.layoutManager = GridLayoutManager(this, 2) @@ -126,7 +129,6 @@ class MainActivity : AppCompatActivity() { binding.tvFoodName.setOnClickListener { SensorScaleUtils.zero() } - registerDataChange() } fun updateCurrentFood(foodInfo: FoodInfo?) { @@ -154,7 +156,8 @@ class MainActivity : AppCompatActivity() { } } - private fun registerDataChange() { + override fun registerDataChange() { + super.registerDataChange() lifecycleScope.launch { viewModel.identifiedFoodInfoList.collect { list -> binding.recyclerview diff --git a/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt index d3f6b31..ef98254 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/SecondaryScreenPresentation.kt @@ -11,7 +11,6 @@ import android.hardware.Camera import android.os.Build import android.os.Bundle import android.util.DisplayMetrics -import android.util.Log import android.view.Display import android.view.View import android.view.ViewGroup @@ -69,19 +68,18 @@ class SecondaryScreenPresentation( // 当前食物信息 private var currentFood: FoodInfo? = null - private var lastFood: FoodInfo? = null private var userNutritionData: UserNutritionData? = null private var dinnerTypeInfo: DinnerTypeInfo? = null private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding private lateinit var stepChangeCallback: (Int) -> Unit // 上一次的计算热量结果 - private var lastCalcResultInfo: UserNutritionUtils.CalcResultInfo? = null private var lastWeight = 0.0 private val debouncer = Debouncer(500) - private var faceTime: Long = 0L // 人脸识别时的时间 + private var recognitionTime: Long = 0L // 人脸识别时的时间 private var recognitionWeight: Double = 0.0 // 人脸识别时的重量 private var lastFaceTrackId: Int = 0 // 上一次的人脸信息 + private var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐 // 当前步骤 var currentStep: Int = 0 @@ -99,6 +97,13 @@ class SecondaryScreenPresentation( } private fun registerDataChange() { + activity.lifecycleScope.launch { + viewModel.loadFaceResult.collect { needUpdate -> + if (needUpdate){ + recognizeViewModel.refreshFaceList() + } + } + } activity.lifecycleScope.launch { viewModel.nutritionData.collect { Timber.d("registerDataChange nutritionData = $it") @@ -161,8 +166,6 @@ class SecondaryScreenPresentation( dinnerTypeInfo = null currentFood = null userNutritionData = null - lastFood = null - lastCalcResultInfo = null recognitionWeight = 0.0 stepChangeCallback(currentStep) @@ -182,6 +185,11 @@ class SecondaryScreenPresentation( fun step2(foodInfo: FoodInfo) { Timber.d("step2") currentStep = 2 + + dinnerTypeInfo = null + userNutritionData = null + recognitionWeight = 0.0 + stepChangeCallback(currentStep) currentFood = foodInfo viewModel.getDinnerType() @@ -262,6 +270,14 @@ class SecondaryScreenPresentation( calculateNutrition(recognitionWeight - lastWeight) } + /** + * 余量取餐 + */ + fun updateMealPickupMode(mode: Int) { + Timber.d("updateMealPickupMode mode = $mode") + mealPickupMode = mode + } + private fun calculateNutrition(weight: Double) { debouncer.debounce { Timber.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight") @@ -274,11 +290,6 @@ class SecondaryScreenPresentation( dinnerType = dinnerType ) Timber.d("calculateNutrition calcResultInfo = $calcResultInfo") - if (lastCalcResultInfo == calcResultInfo) { - Timber.d("calculateNutrition 与上次计算结果无变化") - return@debounce - } - lastCalcResultInfo = calcResultInfo val columnMax = UserNutritionUtils.getMaxInt(calcResultInfo) activity.runOnUiThread { @@ -346,7 +357,7 @@ class SecondaryScreenPresentation( } try { val cameraCount = Camera.getNumberOfCameras() - if (cameraCount < 3){ + if (cameraCount < 3) { ToastUtils.showToast("摄像头数量异常") return } @@ -418,14 +429,14 @@ class SecondaryScreenPresentation( Timber.i("recognizeConfiguration: observe = ${recognizeConfiguration.toString()}") }) recognizeViewModel.recognizeNotice.observe(activity, Observer { notice: String? -> -// Timber.i("recognizeNotice observe notice = $notice") + Timber.i("recognizeNotice observe notice = $notice") }) recognizeViewModel.recognizeUserId.observe( activity, Observer { compareResult: CompareResult -> Timber.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}") - faceTime = System.currentTimeMillis() + recognitionTime = System.currentTimeMillis() recognitionWeight = lastWeight lastFaceTrackId = compareResult.trackId val faceEntity = compareResult.faceEntity @@ -701,7 +712,11 @@ class SecondaryScreenPresentation( Timber.i("$lastFaceTrackId 用户离开") lastFaceTrackId = 0 postUserData() - step1() + if (mealPickupMode == 0) { + step1() + }else{ + step2(currentFood!!) + } } } } @@ -715,7 +730,7 @@ class SecondaryScreenPresentation( val userNutritionParam = UserNutritionParam( userId = userNutritionData?.userId!!, foodId = currentFood?.id!!, - faceTime = faceTime, + faceTime = recognitionTime, faceEndTime = System.currentTimeMillis(), eatWeight = recognitionWeight - lastWeight, foodWeight = lastWeight diff --git a/app/src/main/java/com/sw/dualscreen/utils/QRCodeUtil.kt b/app/src/main/java/com/sw/dualscreen/utils/QRCodeUtil.kt new file mode 100644 index 0000000..bdc8ac5 --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/utils/QRCodeUtil.kt @@ -0,0 +1,99 @@ +package com.sw.dualscreen.utils + +import android.graphics.Bitmap +import android.graphics.Color +import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType +import com.google.zxing.WriterException +import com.google.zxing.common.BitMatrix +import com.google.zxing.qrcode.QRCodeWriter +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel + +/** + * 二维码生成工具类 + */ +object QRCodeUtil { + + /** + * 生成二维码(默认大小) + * @param content 二维码内容 + * @return 生成的二维码Bitmap + */ + @JvmOverloads + fun generateQRCode(content: String, size: Int = 500): Bitmap? { + return generateQRCode(content, size, Color.BLACK, Color.WHITE) + } + + /** + * 生成二维码(自定义颜色) + * @param content 二维码内容 + * @param size 二维码边长(像素) + * @param colorCode 二维码颜色 + * @param backgroundColor 背景颜色 + * @return 生成的二维码Bitmap + */ + fun generateQRCode( + content: String, + size: Int, + colorCode: Int, + backgroundColor: Int + ): Bitmap? { + if (content.isEmpty()) { + return null + } + + return try { + val hints = mutableMapOf().apply { + put(EncodeHintType.CHARACTER_SET, "UTF-8") + put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H) // 纠错级别 + put(EncodeHintType.MARGIN, 1) // 边距 + } + + val bitMatrix = QRCodeWriter().encode( + content, + BarcodeFormat.QR_CODE, + size, + size, + hints + ) + + val pixels = IntArray(size * size).apply { + for (y in 0 until size) { + for (x in 0 until size) { + this[y * size + x] = if (bitMatrix.get(x, y)) colorCode else backgroundColor + } + } + } + + Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply { + setPixels(pixels, 0, size, 0, 0, size, size) + } + + } catch (e: WriterException) { + e.printStackTrace() + null + } + } + + /** + * 生成带Logo的二维码 + * @param content 二维码内容 + * @param size 二维码边长(像素) + * @param logo Logo Bitmap + * @return 带Logo的二维码Bitmap + */ + fun generateQRCodeWithLogo(content: String, size: Int, logo: Bitmap?): Bitmap? { + val qrCode = generateQRCode(content, size) ?: return null + logo ?: return qrCode + + val logoSize = size / 5 // Logo大小约为二维码的1/5 + val scaledLogo = Bitmap.createScaledBitmap(logo, logoSize, logoSize, false) + + val offset = (size - logoSize) / 2 + return Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply { + val canvas = android.graphics.Canvas(this) + canvas.drawBitmap(qrCode, 0f, 0f, null) + canvas.drawBitmap(scaledLogo, offset.toFloat(), offset.toFloat(), null) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java b/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java new file mode 100644 index 0000000..4250438 --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java @@ -0,0 +1,88 @@ +package com.sw.dualscreen.view; + +import android.app.Dialog; +import android.content.Context; +import android.content.res.Resources; +import android.os.Build; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +public class CustomDialog extends Dialog { + + + /** + * 宽高由布局文件中指定(但是最底层的宽度无效,可以多嵌套一层解决) + */ + public CustomDialog(Context context, View layout, int style) { + + super(context, style); + + setContentView(layout); + + Window window = getWindow(); + + WindowManager.LayoutParams params = window.getAttributes(); + + params.gravity = Gravity.CENTER; + + window.setAttributes(params); + + } + + /** + * 宽高由该方法的参数设置 + */ + public CustomDialog(Context context, int width, int height, View layout, + int style) { + super(context, style); + // 设置内容 + setContentView(layout); + // 设置窗口属性 + Window window = getWindow(); + WindowManager.LayoutParams params = window.getAttributes(); + // 设置宽度、高度、密度、对齐方式 + float density = getDensity(context); + params.width = (int) (width * density); + params.height = (int) (height * density); + params.gravity = Gravity.CENTER; + window.setAttributes(params); + + } + + /** + * 获取显示密度 + * + * @param context + * @return + */ + public float getDensity(Context context) { + Resources res = context.getResources(); + DisplayMetrics dm = res.getDisplayMetrics(); + return dm.density; + } + + private void fullScreenImmersive(View view) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_FULLSCREEN; + view.setSystemUiVisibility(uiOptions); + } + + } + + @Override + + public void show() { + this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + super.show(); +// fullScreenImmersive(getWindow().getDecorView()); +// this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/viewmodel/DeviceViewModel.kt b/app/src/main/java/com/sw/dualscreen/viewmodel/DeviceViewModel.kt index 37e5483..9250309 100644 --- a/app/src/main/java/com/sw/dualscreen/viewmodel/DeviceViewModel.kt +++ b/app/src/main/java/com/sw/dualscreen/viewmodel/DeviceViewModel.kt @@ -1,5 +1,6 @@ package com.sw.dualscreen.viewmodel +import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.model.response.EquipmentInfo import com.sw.dualscreen.utils.GsonUtils @@ -18,7 +19,7 @@ class DeviceViewModel : BaseViewModel() { /** * 获取token */ - fun getDeviceToken(deviceId: String = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e") { + fun getDeviceToken(deviceId: String = GlobalData.deviceId) { launchWithLoading { val response = repository.getDeviceToken(deviceId) if (parseResponse(response)) { diff --git a/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt b/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt index 503e822..57515ce 100644 --- a/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt +++ b/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt @@ -45,11 +45,17 @@ class UserViewModel : BaseViewModel() { private val _dinnerTypeInfo = MutableStateFlow(null) val dinnerTypeInfo: StateFlow = _dinnerTypeInfo + /** + * 人脸加载完成 + */ + private val _loadFaceResult = MutableStateFlow(false) + val loadFaceResult : StateFlow = _loadFaceResult + /** * 获取token */ - fun getEquipmentToken(qrcodeId: String = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e") { + fun getEquipmentToken(qrcodeId: String = GlobalData.deviceId) { Timber.d("getEquipmentToken") launchWithLoading { val response = repository.getEquipmentToken(qrcodeId) @@ -70,6 +76,7 @@ class UserViewModel : BaseViewModel() { fun getUserFaceCache(index: Int = 0) { Timber.d("getUserFaceCache index = $index") launch { + _loadFaceResult.value = false val response = repository.getUserFaceCache(index) if (parseResponse(response)) { // 获取成功一次后缓存状态 @@ -80,11 +87,12 @@ class UserViewModel : BaseViewModel() { FaceEntity(it.userId, null, Base64.decode(it.faceFeatureString)) } faceApi.updateFaceData(index, faceEntity) - activeEngine() } val nextPageIndex = response.result?.nextPageIndex ?: -1 if (nextPageIndex > 0) { getUserFaceCache(nextPageIndex) + } else{ + _loadFaceResult.value = true } } } @@ -129,13 +137,6 @@ class UserViewModel : BaseViewModel() { }) } - /** - * 重置用户信息 - */ - fun resetUserInfo() { - Timber.d("resetUserInfo") - } - fun getIdentifiedFoodList() { Timber.d("identifiedFoodList") launchWithLoading { @@ -180,7 +181,7 @@ class UserViewModel : BaseViewModel() { fun getUserNutritionData(userId: String, foodId: String) { Timber.d("getUserNutritionData userId = ${userId}, foodId = $foodId") _nutritionData.value = null - launchWithLoading { + launch { val response = repository.getUserNutritionData(userId = userId, foodId = foodId) if (parseResponse(response)) { _nutritionData.value = response.result @@ -191,7 +192,7 @@ class UserViewModel : BaseViewModel() { fun getDinnerType() { Timber.d("getDinnerType") _dinnerTypeInfo.value = null - launchWithLoading { + launch { val response = repository.getDinnerType() if (parseResponse(response)) { _dinnerTypeInfo.value = response.result diff --git a/app/src/main/res/drawable/bg_init_button.xml b/app/src/main/res/drawable/bg_init_button.xml new file mode 100644 index 0000000..02f2a03 --- /dev/null +++ b/app/src/main/res/drawable/bg_init_button.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/dialog_waiting.xml b/app/src/main/res/drawable/dialog_waiting.xml new file mode 100644 index 0000000..b47a21c --- /dev/null +++ b/app/src/main/res/drawable/dialog_waiting.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_init.xml b/app/src/main/res/layout/activity_init.xml index 57b8d3a..b1b816b 100644 --- a/app/src/main/res/layout/activity_init.xml +++ b/app/src/main/res/layout/activity_init.xml @@ -1,23 +1,90 @@ + android:orientation="vertical"> - + -