修复了多次步骤2到步骤3问题
This commit is contained in:
Generated
+1
-1
@@ -4,7 +4,7 @@
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-07-31T00:35:57.879961400Z">
|
||||
<DropdownSelection timestamp="2025-08-05T03:50:06.075639Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=2FD2511004054749" />
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.graphics.Outline
|
||||
import android.graphics.Typeface
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
@@ -54,7 +55,7 @@ class MainActivity : AppCompatActivity() {
|
||||
private var checkedItem: FoodInfo? = null
|
||||
private var imageAnalysis: ImageAnalysis? = null
|
||||
private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
|
||||
private var canIdentify: Boolean = true
|
||||
private var canIdentify: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -132,8 +133,8 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
fun updateCurrentFood(foodInfo: FoodInfo?) {
|
||||
presentation.updateFood(foodInfo)
|
||||
if (foodInfo != null) {
|
||||
presentation.updateFood(foodInfo)
|
||||
binding.tvFoodName.text = foodInfo.foodName
|
||||
binding.previewView.visibility = View.GONE
|
||||
binding.ivImg.visibility = View.VISIBLE
|
||||
@@ -156,7 +157,6 @@ class MainActivity : AppCompatActivity() {
|
||||
// presentation.step2()
|
||||
}
|
||||
}
|
||||
viewModel.getIdentifiedFoodList()
|
||||
SensorScaleUtils.startScale { weight ->
|
||||
// Timber.d("weight = $weight")
|
||||
if (weight > 0.0) {
|
||||
@@ -289,7 +289,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
// 拍照功能
|
||||
private fun takePhoto() {
|
||||
private fun takePhoto(callback: (Uri) -> Unit) {
|
||||
// 临时停止分析以避免干扰
|
||||
isAnalyzing = false
|
||||
|
||||
@@ -306,7 +306,11 @@ class MainActivity : AppCompatActivity() {
|
||||
object : ImageCapture.OnImageSavedCallback {
|
||||
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
||||
runOnUiThread {
|
||||
ToastUtils.showToast("照片保存成功: ${outputFileResults.savedUri}")
|
||||
val savedUri = outputFileResults.savedUri
|
||||
ToastUtils.showToast("照片保存成功: $savedUri")
|
||||
if (savedUri != null) {
|
||||
callback(savedUri)
|
||||
}
|
||||
}
|
||||
// 恢复图像分析
|
||||
isAnalyzing = true
|
||||
|
||||
@@ -75,10 +75,15 @@ class SecondaryScreenPresentation(
|
||||
|
||||
// 当前食物信息
|
||||
private var currentFood: FoodInfo? = null
|
||||
private var lastFood: FoodInfo? = null
|
||||
private var userNutritionData: UserNutritionData? = null
|
||||
private var dinnerType: DinnerTypeInfo? = null
|
||||
private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding
|
||||
private lateinit var stepChangeCallback: (Int) -> Unit
|
||||
private var lastCalcResultInfo: UserNutritionUtils.CalcResultInfo? = null
|
||||
private var startSensorScale: Boolean = false
|
||||
private var lastWeight = 0.0
|
||||
private val debouncer = Debouncer(1000)
|
||||
|
||||
// 当前步骤
|
||||
var currentStep: Int = 0
|
||||
@@ -90,6 +95,7 @@ class SecondaryScreenPresentation(
|
||||
setContentView(binding.root)
|
||||
window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
initView()
|
||||
setupArcCamera()
|
||||
// binding.includeUserHeat.ivHeat.showText("1070千卡")
|
||||
registerDataChange()
|
||||
}
|
||||
@@ -138,22 +144,9 @@ class SecondaryScreenPresentation(
|
||||
* 启用虹软人脸失败
|
||||
*/
|
||||
private fun setupArcCamera() {
|
||||
cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
// 获取摄像头列表
|
||||
cameraIdList = cameraManager.cameraIdList
|
||||
if (cameraIdList.isEmpty()) {
|
||||
Toast.makeText(context, "没有可用的摄像头", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
|
||||
cameraIdList.forEach {
|
||||
Timber.d("摄像头id列表 = ${it}")
|
||||
}
|
||||
|
||||
initArcViewModel()
|
||||
initArcView()
|
||||
openRectInfoDraw = true
|
||||
openCamera(cameraIdList.last())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,9 +160,8 @@ class SecondaryScreenPresentation(
|
||||
binding.ivFaceBg.visibility = View.GONE
|
||||
binding.flPreview.visibility = View.VISIBLE
|
||||
binding.ivImg.visibility = View.VISIBLE
|
||||
binding.flFace.visibility = View.GONE
|
||||
binding.flFace.visibility = View.INVISIBLE
|
||||
pauseCamera()
|
||||
|
||||
binding.tvBottomTip.visibility = View.VISIBLE
|
||||
itemUserNutritionBinding.clNutritionData.visibility = View.GONE
|
||||
stopSensorScale()
|
||||
@@ -186,25 +178,31 @@ class SecondaryScreenPresentation(
|
||||
currentFood = foodInfo
|
||||
resumeCamera()
|
||||
binding.tvFoodInfo.text = foodInfo.foodName
|
||||
binding.ivImg.visibility = View.GONE
|
||||
|
||||
binding.ivFaceBg.visibility = View.VISIBLE
|
||||
binding.flPreview.visibility = View.GONE
|
||||
|
||||
binding.flFace.visibility = View.VISIBLE
|
||||
binding.ivFaceBg.visibility = View.VISIBLE
|
||||
binding.tvFaceTip.visibility = View.VISIBLE
|
||||
|
||||
setupArcCamera()
|
||||
binding.tvBottomTip.visibility = View.VISIBLE
|
||||
itemUserNutritionBinding.clNutritionData.visibility = View.GONE
|
||||
}
|
||||
|
||||
fun updateFood(foodInfo: FoodInfo?) {
|
||||
Timber.d("step2 updateFood")
|
||||
Timber.d("updateFood")
|
||||
currentFood = foodInfo
|
||||
if (foodInfo != null) {
|
||||
if (currentStep != 2) {
|
||||
if (currentStep == 1) {
|
||||
step2(foodInfo)
|
||||
} else {
|
||||
binding.tvFoodInfo.text = foodInfo.foodName
|
||||
GlideUtils.loadRoundCornerImage(
|
||||
context,
|
||||
url = currentFood!!.imgUrl,
|
||||
imageView = binding.ivImg,
|
||||
radius = 12
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +219,7 @@ class SecondaryScreenPresentation(
|
||||
return
|
||||
}
|
||||
binding.tvFoodInfo.text = currentFood!!.foodName
|
||||
|
||||
pauseCamera()
|
||||
startSensorScale()
|
||||
|
||||
GlideUtils.loadRoundCornerImage(
|
||||
@@ -231,31 +229,36 @@ class SecondaryScreenPresentation(
|
||||
radius = 12
|
||||
)
|
||||
binding.flPreview.visibility = View.VISIBLE
|
||||
// binding.previewView.visibility = View.GONE
|
||||
binding.ivImg.visibility = View.VISIBLE
|
||||
binding.flFace.visibility = View.GONE
|
||||
binding.flFace.visibility = View.INVISIBLE
|
||||
binding.ivFaceBg.visibility = View.GONE
|
||||
binding.tvFaceTip.visibility = View.GONE
|
||||
|
||||
binding.tvBottomTip.visibility = View.GONE
|
||||
itemUserNutritionBinding.clNutritionData.visibility = View.VISIBLE
|
||||
|
||||
viewModel.getUserNutritionData(
|
||||
userId = userNutritionData!!.userId!!,
|
||||
foodId = currentFood!!.id!!
|
||||
)
|
||||
}
|
||||
|
||||
private fun startSensorScale() {
|
||||
var lastWeight = 0.0
|
||||
val debouncer = Debouncer(1000)
|
||||
Timber.d("startSensorScale startSensorScale = $startSensorScale")
|
||||
if (startSensorScale) return
|
||||
SensorScaleUtils.startScale { weight ->
|
||||
if (weight == lastWeight) return@startScale
|
||||
if (currentFood == null) {
|
||||
Timber.e("startSensorScale currentFood is null")
|
||||
return@startScale
|
||||
}
|
||||
if (userNutritionData == null) {
|
||||
Timber.e("startSensorScale userNutritionData is null")
|
||||
return@startScale
|
||||
}
|
||||
if (dinnerType == null) {
|
||||
Timber.e("startSensorScale dinnerType is null")
|
||||
return@startScale
|
||||
}
|
||||
// 重量和 当前食物都没变,则不再计算
|
||||
if (weight == lastWeight && lastFood == currentFood) return@startScale
|
||||
Timber.d("registerDataChange weight = $weight")
|
||||
lastFood = currentFood
|
||||
lastWeight = weight
|
||||
if (currentFood == null) return@startScale
|
||||
if (userNutritionData == null) return@startScale
|
||||
if (dinnerType == null) return@startScale
|
||||
debouncer.debounce {
|
||||
val calcResultInfo = UserNutritionUtils.calculateNutrition(
|
||||
currentFood!!,
|
||||
@@ -264,11 +267,16 @@ class SecondaryScreenPresentation(
|
||||
dinnerType = dinnerType!!.dinnerType!!.dinnerType!!
|
||||
)
|
||||
Timber.d("calcResultInfo = $calcResultInfo")
|
||||
if (lastCalcResultInfo == calcResultInfo) {
|
||||
return@debounce
|
||||
}
|
||||
lastCalcResultInfo = calcResultInfo
|
||||
activity.runOnUiThread {
|
||||
val totalKcal = calcResultInfo.totalKcal
|
||||
val grain = calcResultInfo.grain
|
||||
val fruits = calcResultInfo.fruits
|
||||
val meat = calcResultInfo.meat
|
||||
// 设置热量
|
||||
itemUserNutritionBinding.customKcalColumn.setImageDrawable(
|
||||
true,
|
||||
totalKcal.first < totalKcal.second
|
||||
@@ -278,7 +286,7 @@ class SecondaryScreenPresentation(
|
||||
(totalKcal.second / 100).toFloat(),
|
||||
true
|
||||
)
|
||||
|
||||
// 设置主食
|
||||
itemUserNutritionBinding.customFoodColumn.setImageDrawable(
|
||||
false,
|
||||
grain.first < grain.second
|
||||
@@ -288,7 +296,7 @@ class SecondaryScreenPresentation(
|
||||
(grain.second / 100).toFloat(),
|
||||
true
|
||||
)
|
||||
|
||||
// 设置果蔬
|
||||
itemUserNutritionBinding.customVegetableColumn.setImageDrawable(
|
||||
false,
|
||||
fruits.first < fruits.second
|
||||
@@ -298,7 +306,7 @@ class SecondaryScreenPresentation(
|
||||
(fruits.second / 100).toFloat(),
|
||||
true
|
||||
)
|
||||
|
||||
// 设置肉蛋
|
||||
itemUserNutritionBinding.customMeatColumn.setImageDrawable(
|
||||
false,
|
||||
meat.first < meat.second
|
||||
@@ -317,13 +325,28 @@ class SecondaryScreenPresentation(
|
||||
SensorScaleUtils.closeScale()
|
||||
}
|
||||
|
||||
private fun openCamera(cameraId: String) {
|
||||
private fun openCamera() {
|
||||
Timber.d("openCamera")
|
||||
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) !=
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
ToastUtils.showToast("无摄像头权限")
|
||||
return
|
||||
}
|
||||
try {
|
||||
cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
// 获取摄像头列表
|
||||
cameraIdList = cameraManager.cameraIdList
|
||||
if (cameraIdList.isEmpty()) {
|
||||
Toast.makeText(context, "没有可用的摄像头", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
|
||||
cameraIdList.forEach {
|
||||
Timber.d("摄像头id列表 = $it")
|
||||
}
|
||||
val cameraId = cameraIdList.last()
|
||||
Timber.d("openCamera cameraId = $cameraId")
|
||||
cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
|
||||
override fun onOpened(device: CameraDevice) {
|
||||
cameraDevice = device
|
||||
@@ -412,6 +435,7 @@ class SecondaryScreenPresentation(
|
||||
recognizeViewModel.recognizeUserId.observe(activity, Observer { userId: String? ->
|
||||
Timber.i("recognizeUserId observe userId = $userId")
|
||||
if (userId == null) return@Observer
|
||||
|
||||
viewModel.getUserNutritionData(userId = userId, foodId = currentFood!!.id!!)
|
||||
})
|
||||
|
||||
@@ -599,6 +623,7 @@ class SecondaryScreenPresentation(
|
||||
override fun onGlobalLayout() {
|
||||
Timber.d("onGlobalLayout")
|
||||
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this)
|
||||
openCamera()
|
||||
}
|
||||
|
||||
|
||||
@@ -624,7 +649,7 @@ class SecondaryScreenPresentation(
|
||||
}
|
||||
|
||||
fun resumeCamera() {
|
||||
Timber.d("resumeCamera")
|
||||
Timber.d("resumeCamera isRecognition = $isRecognition")
|
||||
isRecognition = true
|
||||
if (rgbCameraHelper != null && rgbCameraHelper!!.isStopped) {
|
||||
rgbCameraHelper!!.start()
|
||||
@@ -632,7 +657,7 @@ class SecondaryScreenPresentation(
|
||||
}
|
||||
|
||||
fun pauseCamera() {
|
||||
Timber.d("pauseCamera")
|
||||
Timber.d("pauseCamera isRecognition = $isRecognition")
|
||||
isRecognition = false
|
||||
|
||||
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
||||
|
||||
@@ -19,6 +19,7 @@ object SensorScaleUtils {
|
||||
const val baudRate = 115200
|
||||
private var mSensorScale: SensorScale? = null
|
||||
private var isOpened: Boolean = false
|
||||
private var isRead: Boolean = false
|
||||
private var callback: Callback? = {}
|
||||
|
||||
private fun init() {
|
||||
@@ -58,6 +59,7 @@ object SensorScaleUtils {
|
||||
* @param autoScale 是否开启自动读取
|
||||
*/
|
||||
fun startScale(autoScale: Boolean = true, callback: Callback?) {
|
||||
Timber.d("startScale isOpened = $isOpened")
|
||||
if (isOpened) {
|
||||
startContinuousRead(callback = callback)
|
||||
return
|
||||
@@ -86,23 +88,24 @@ object SensorScaleUtils {
|
||||
* 开启自动读取重量
|
||||
*/
|
||||
fun startContinuousRead(callback: Callback?) {
|
||||
this.callback = callback
|
||||
Log.d(TAG, "开启自动读取 = $isOpened")
|
||||
if (!isOpened) {
|
||||
Log.d(TAG, "开启自动读取 = $isRead")
|
||||
if (isRead) {
|
||||
return
|
||||
}
|
||||
this.callback = callback
|
||||
mSensorScale?.startContinuousRead()
|
||||
isRead = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动读取重量
|
||||
*/
|
||||
fun readWeight(callback: Callback?) {
|
||||
this.callback = callback
|
||||
Log.d(TAG, "isOpened = $isOpened")
|
||||
if (!isOpened) {
|
||||
return
|
||||
}
|
||||
this.callback = callback
|
||||
mSensorScale?.readWeight()
|
||||
}
|
||||
|
||||
@@ -137,6 +140,7 @@ object SensorScaleUtils {
|
||||
return
|
||||
}
|
||||
mSensorScale?.stopContinuousRead()
|
||||
isRead = false
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.sw.dualscreen.view
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
@@ -82,6 +83,7 @@ class CustomBottomSheetDialog(
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.viewClose.setOnClickListener { dismiss() }
|
||||
adapter = createAdapter()
|
||||
binding.recyclerview.layoutManager = GridLayoutManager(context, 2)
|
||||
// 添加间距装饰(12dp)
|
||||
@@ -131,7 +133,14 @@ class CustomBottomSheetDialog(
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
Timber.d("onCancel")
|
||||
viewModel.cleanSearchFoodInfoList()
|
||||
super.onCancel(dialog)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
Timber.d("dismiss")
|
||||
viewModel.cleanSearchFoodInfoList()
|
||||
super.dismiss()
|
||||
}
|
||||
|
||||
@@ -95,11 +95,17 @@ public class CustomImageView extends androidx.appcompat.widget.AppCompatImageVie
|
||||
}
|
||||
|
||||
public void setCustomHeightPercent(float percent, boolean isAnimation) {
|
||||
// if (percent<= 0){
|
||||
// percent = 0.01f;
|
||||
// }
|
||||
setCustomHeight((int) (percent * MAX_HEIGHT), isAnimation);
|
||||
}
|
||||
|
||||
// 用于设置自定义高度的方法
|
||||
public void setCustomHeight(int height, boolean isAnimation) {
|
||||
if (height > 0) {
|
||||
height += 40;
|
||||
}
|
||||
ViewGroup.LayoutParams layoutParams = getLayoutParams();
|
||||
int height1 = layoutParams.height;
|
||||
if (height1 != height) {
|
||||
|
||||
@@ -179,6 +179,7 @@ class UserViewModel : BaseViewModel() {
|
||||
*/
|
||||
fun getUserNutritionData(userId: String, foodId: String) {
|
||||
Timber.d("getUserNutritionData userId = ${userId}, foodId = $foodId")
|
||||
_nutritionData.value = null
|
||||
launchWithLoading {
|
||||
val response = repository.getUserNutritionData(userId = userId, foodId = foodId)
|
||||
if (parseResponse(response)) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
android:paddingBottom="0dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/view_close"
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="10dp"
|
||||
android:background="@drawable/view_shape_point" />
|
||||
|
||||
Reference in New Issue
Block a user