This commit is contained in:
2025-12-19 17:34:31 +08:00
parent af56fb4aeb
commit 960b429e69
18 changed files with 294 additions and 181 deletions
+13 -9
View File
@@ -40,7 +40,8 @@
</receiver>
<activity
android:name=".activity.InitActivity"
android:exported="true">
android:exported="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -51,15 +52,18 @@
android:name=".activity.MainActivity"
android:exported="true">
</activity>
<activity
android:name=".activity.FoodCollectionActivity"
android:exported="true">
<!-- <activity-->
<!-- android:name=".activity.FoodCollectionActivity"-->
<!-- android:exported="true">-->
</activity>
<activity android:name="com.sw.dualscreen.activity.CollectedDataActivity" />
<activity android:name="com.sw.dualscreen.activity.SettingActivity" />
<activity android:name="com.sw.dualscreen.activity.CollectedFoodActivity" />
<activity android:name="com.sw.dualscreen.activity.PayActivity" />
<!-- </activity>-->
<!-- <activity android:name="com.sw.dualscreen.activity.CollectedDataActivity" />-->
<activity android:name="com.sw.dualscreen.activity.SettingActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<activity android:name="com.sw.dualscreen.activity.CollectedFoodActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<activity android:name="com.sw.dualscreen.activity.PayActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<provider
android:name="androidx.core.content.FileProvider"
@@ -1,11 +1,11 @@
package com.sw.dualscreen.activity
import android.app.Dialog
import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.hardware.display.DisplayManager
import android.os.Bundle
import android.text.TextUtils
import android.view.Display
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
@@ -13,19 +13,17 @@ import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.sw.dualscreen.R
import com.sw.dualscreen.databinding.DialogWaitingBinding
import com.sw.dualscreen.model.IActivityResult
import com.sw.dualscreen.model.response.PostEvent
import com.sw.dualscreen.view.CustomDialog
import com.sw.dualscreen.viewmodel.BaseViewModel
import kotlinx.coroutines.launch
import com.sw.plate.utils.ToastUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import timber.log.Timber
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
@@ -84,17 +82,14 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
/**
* 显示等待提示框
*/
fun showWaitingDialog(tip: String?){
fun showWaitingDialog(tip: String?) {
runOnUiThread {
hideWaitingDialog()
val view = View.inflate(this, R.layout.dialog_waiting, null)
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).text =
tip
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog).apply {
setCancelable(true)
setCanceledOnTouchOutside(true)
show()
}
//val view = View.inflate(this, R.layout.dialog_waiting, null)
val dialogBinding = DialogWaitingBinding.inflate(LayoutInflater.from(this))
dialogBinding.tvTip.text = tip
mDialogWaiting = CustomDialog(this, dialogBinding.root)
mDialogWaiting?.show()
}
}
@@ -113,8 +108,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
hideWaitingDialog()
val view = View.inflate(this, R.layout.dialog_waiting, null)
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog)
mDialogWaiting!!.show()
mDialogWaiting!!.setCancelable(true)
mDialogWaiting?.show()
}
val contentView = mDialogWaiting?.findViewById<ViewGroup>(android.R.id.content)
val tvTip = contentView?.findViewById<TextView>(R.id.tvTip)
@@ -32,6 +32,7 @@ import com.sw.dualscreen.ext.gone
import com.sw.dualscreen.ext.load
import com.sw.dualscreen.ext.visible
import com.sw.dualscreen.model.response.ChargeModeEvent
import com.sw.dualscreen.model.response.ClickBackEvent
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.FoodOrder
import com.sw.dualscreen.model.response.PaySuccessEvent
@@ -114,6 +115,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
private var isRecognitionFood = true
private var isFirstOpen = true
private var isStartRecognize = false
override fun getViewModel(): BaseViewModel {
return viewModel
}
@@ -240,17 +243,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
pauseAnalysis()
recognizeWeight = lastWeight
Timber.tag(TAG)
.d("registerDataChange,副屏updateFood调用前耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
presentation?.updateFood(foodInfo)
binding.tvFoodName.text = foodInfo.foodName
binding.previewView.gone()
binding.ivImg.visible()
if (foodInfo.foodImg.isNullOrBlank()) {
takePhoto { imgUri ->
takePhoto(successCallback = { imgUri ->
binding.ivImg.load(imgUri)
presentation?.updateFood(foodInfo.copy(foodImg = imgUri.toString()))
}
}, failureCallback = {
})
} else {
binding.ivImg.load(foodInfo.foodImg)
}
binding.ivImg.load(foodInfo.foodImg ?: foodInfo.photoUri)
//pauseAnalysis()
}
@@ -283,6 +292,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
SensorScaleUtils.addWeightListener { weight ->
Timber.d("registerDataChange weight = $weight")
if (isPageVisible.not() || isStartRecognize.not()) return@addWeightListener
val isWeightChange = weight - lastWeight > 0.05
recognizeByWeight(weight, isWeightChange)
}
@@ -308,15 +318,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
lastWeight = weight
}
private var startTime = 0L
fun recognizeFood() {
startTime = System.currentTimeMillis()
LightManager.openRedLight()
LightManager.openGreenLight()
takePhoto { photoUri ->
showWaitingDialog("识别中,请稍后……")
takePhoto(successCallback = { photoUri ->
lastPhotoUri = photoUri
Timber.tag(TAG).d("main,takePhoto耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
Timber.d("registerDataChange photoUri = ${photoUri.path}")
// viewModel.getIdentifiedFoodList()
ImageUtil.uriToBitmap(this, photoUri)?.let { bitmap ->
Timber.tag(TAG).d("main,uriToBitmap耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
Timber.d("registerDataChange photoUri 拿到bitmap")
// val bmp = BitmapCropper.cropCenter(bitmap, 1300, 900)
Timber.d("registerDataChange photoUri bitmap裁剪完成")
@@ -325,19 +343,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
this,
"IMG_CROP_${System.currentTimeMillis()}.jpg"
)
Timber.tag(TAG)
.d("main,saveToAppFilesDir耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
Timber.d("registerDataChange photoUri bitmap保存文件路径:${file?.absolutePath}")
//val nameList = FoodModule.queryFood(bitmap)
val scoreList = FoodModule.getFoodScoreList(bitmap)
Timber.d(
"registerDataChange photoUri 拿到识别数据:${
GsonUtils.toJson(
scoreList
)
}"
)
val recDataJson = GsonUtils.toJson(scoreList)
Timber.tag(TAG)
.d("main,getFoodScoreList耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
Timber.d("registerDataChange photoUri 拿到识别数据:$recDataJson")
val nameList = scoreList.map { it.name }
val foodName = nameList.joinToString(separator = ",")
hideWaitingDialog()
Timber.d("registerDataChange photoUri 识别数据名称:$foodName")
if (TextUtils.isEmpty(foodName)) {
LightManager.closeGreenLight()
@@ -350,15 +370,28 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
} else {
//binding.layoutRescan.visibility = View.GONE
showWaitingDialog("正在查询菜品信息,请稍后……")
viewModel.getFoodInfo(foodName) { list ->
runOnUiThread {
hideWaitingDialog()
Timber.tag(TAG)
.d("main,getFoodInfo耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
updateFoodInfo(list.toMutableList(), scoreList)
}
}
}
}
}
}, failureCallback = {
runOnUiThread {
hideWaitingDialog()
ToastUtils.showToast("拍照异常,请手动放置后重新识别")
}
// binding.root.postDelayed({
// recognizeFood()
// }, 500)
})
}
@SuppressLint("NotifyDataSetChanged")
@@ -447,6 +480,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
if (isAnalyzing) {
val bitmap = imageProxy.toBitmap()
presentation?.updateImage(bitmap) // 更新副屏
isStartRecognize = true
}
imageProxy.close() // 必须关闭以释放资源
}
@@ -518,7 +552,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
// 拍照功能
private fun takePhoto(callback: (Uri) -> Unit) {
private fun takePhoto(successCallback: (Uri) -> Unit, failureCallback: () -> Unit) {
Timber.d("takePhoto")
// 临时停止分析以避免干扰
isAnalyzing = false
@@ -545,7 +579,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
Timber.d("takePhoto savedUri = $savedUri")
// ToastUtils.showToast("照片保存成功: $savedUri")
if (savedUri != null) {
callback(savedUri)
successCallback(savedUri)
}
}
// 恢复图像分析
@@ -554,6 +588,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onError(exception: ImageCaptureException) {
Timber.e("拍照失败: ${exception.message}")
failureCallback()
//runOnUiThread {
// ToastUtils.showToast("拍照失败: ${exception.message}")
//}
@@ -631,14 +666,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.tvTitleTime.text = dateTime
}
private var isPageVisible = true
override fun onResume() {
super.onResume()
Timber.tag("onResume").d("=================onResume================")
isPageVisible = true
// 启动定时器
handler.postDelayed(timeoutRunnable, TIME_OUT)
if (isFirstOpen) {
//首次
//首次
setupSecondaryDisplay()
presentation?.step1FoodRecognizing()
isFirstOpen = false
@@ -650,11 +687,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
setupSecondaryDisplay()
presentation?.step1FoodRecognizing()
} else {
//已显示副屏,则进行更新
val weight = lastWeight
lastWeight = 0.0
presentation?.hideRecImage()
recognizeByWeight(weight, true)
if (isRefreshPage) {
//已显示副屏,则进行更新
val weight = lastWeight
lastWeight = 0.0
presentation?.hideRecImage()
recognizeByWeight(weight, true)
}
isRefreshPage = !isRefreshPage
}
}
@@ -674,6 +714,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onPause() {
super.onPause()
isPageVisible = false
// 取消定时器
handler.removeCallbacks(timeoutRunnable)
}
@@ -770,16 +811,24 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onPaySuccessEvent(event: PaySuccessEvent) {
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)?:0
isRefreshPage = true
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
presentation?.hideNutritionView(chargeMode)
presentation?.cancel()
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onChargeModeEvent(event: ChargeModeEvent) {
isRefreshPage = true
isStartRecognize = false
presentation?.hideNutritionView(event.chargeMode)
// presentation?.cancel()
}
private var isRefreshPage = false
@Subscribe(threadMode = ThreadMode.MAIN)
fun onClickBackEvent(event: ClickBackEvent) {
isRefreshPage = false
}
private fun clickPayButton() {
if (checkedItem == null) {
@@ -1,5 +1,6 @@
package com.sw.dualscreen.activity
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import com.sw.dualscreen.R
@@ -7,8 +8,10 @@ import com.sw.dualscreen.activity.fragment.BusinessFragment
import com.sw.dualscreen.activity.fragment.CollectFragment
import com.sw.dualscreen.databinding.ActivitySettingBinding
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.ClickBackEvent
import com.sw.dualscreen.viewmodel.BaseViewModel
import com.sw.dualscreen.viewmodel.UserViewModel
import org.greenrobot.eventbus.EventBus
class SettingActivity : BaseActivity<ActivitySettingBinding>() {
@@ -28,10 +31,12 @@ class SettingActivity : BaseActivity<ActivitySettingBinding>() {
override fun initialize() {
super.initialize()
initBackDispatcher()
binding.include.let {
it.ivPageBack.setOnClickListener {
// val intent = Intent(this, MainActivity::class.java)
// startActivity(intent)
EventBus.getDefault().post(ClickBackEvent())
finish()
}
it.tvPageTitle.text = "设置"
@@ -65,4 +70,17 @@ class SettingActivity : BaseActivity<ActivitySettingBinding>() {
viewModel.searchByFoodName(foodName, action)
}
private lateinit var backPressedCallback: OnBackPressedCallback
private fun initBackDispatcher() {
// 创建回调,true表示初始启用状态
backPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
EventBus.getDefault().post(ClickBackEvent())
}
}
// 注册回调,使用lifecycleOwner确保生命周期安全
onBackPressedDispatcher.addCallback(this, backPressedCallback)
}
}
@@ -45,8 +45,9 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
companion object {
private const val TAG = "CollectFragment"
const val MAX_COUNT = 102
const val MAX_COUNT = 15
}
private var selectedFoodId: String? = ""
private var selectedFoodName: String? = ""
@@ -58,17 +59,17 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
}
private val searchFoodList = mutableListOf<FoodInfo>()
private var settingActivity: SettingActivity?=null
private var settingActivity: SettingActivity? = null
private var checkedItem: FoodInfo? = null
private val searchFoodAdapter by lazy {
SearchFoodAdapter(searchFoodList).apply {
setOnItemClickListener { adapter, view, position ->
checkedItem = searchFoodList[position]
selectedFoodId = checkedItem!!.foodId
selectedFoodName = checkedItem!!.foodName
val isChecked = checkedItem!!.isChecked
searchFoodList[position].isChecked = isChecked.not()
notifyItemChanged(position)
selectedFoodId = checkedItem!!.foodId
selectedFoodName = checkedItem!!.foodName
}
}
}
@@ -85,6 +86,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
it.bitmap = null
it.imageVector = null
it.imageFile = null
it.imageUri = null
it.isShowCamera = true
it.isFinish = false
it.uploadSuccess = false
@@ -93,6 +95,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
}
}
}
override fun inflateViewBinding(): FragmentCollectBinding {
return FragmentCollectBinding.inflate(LayoutInflater.from(context))
}
@@ -104,14 +107,25 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
if (index == -1) {
ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
settingActivity?.hideWaitingDialog()
rerurn@cameraCallback
rerurn@ cameraCallback
}
activity?.runOnUiThread {
foodCollectionList[index].let {
it.imageVector = null
it.bitmap = null
it.isShowCamera = false
it.imageFile = null
it.imageUri = uri
}
collectionAdapter.notifyItemChanged(index)
}
// settingActivity?.hideWaitingDialog()
ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
// val cropBitmap = BitmapCropper.cropCenter(
// original = bitmap,
// targetWidth = 1300, targetHeight = 900,
// //offsetX = 30, offsetY = 100
// )
// val cropBitmap = BitmapCropper.cropCenter(
// original = bitmap,
// targetWidth = 1300, targetHeight = 900,
// //offsetX = 30, offsetY = 100
// )
initBox()
val imageVector = try {
FoodModule.bitmap2FloatArray(bitmap)
@@ -154,7 +168,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
}
settingActivity?.showWaitingDialog("拍照中……")
cameraUtils.takePhoto(cameraCallback) { errMsg ->
ToastUtils.showToast(errMsg)
ToastUtils.showToast("拍照异常,请重新操作")
settingActivity?.hideWaitingDialog()
}
}
@@ -173,7 +187,8 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
cameraUtils.setPreviewController(previewView)
binding.rvFoodList.let {
it.layoutManager = GridLayoutManager(requireActivity(), 3, GridLayoutManager.VERTICAL, false)
it.layoutManager =
GridLayoutManager(requireActivity(), 3, GridLayoutManager.VERTICAL, false)
it.adapter = collectionAdapter
}
@@ -182,12 +197,12 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
}
binding.btnSave.setOnClickListener {
if (selectedFoodName.isNullOrBlank()) {
Toast.makeText(requireActivity(), "请选择菜品名称", Toast.LENGTH_SHORT).show()
if (checkedItem == null || checkedItem!!.isChecked.not()) {
ToastUtils.showToast("请选择菜品名称")
return@setOnClickListener
}
if (foodCollectionList.size <= 1) {
Toast.makeText(requireActivity(), "请拍摄菜品照片", Toast.LENGTH_SHORT).show()
ToastUtils.showToast("请拍摄菜品照片")
return@setOnClickListener
}
upload()
@@ -235,9 +250,12 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
//params["foodVector"] = foodVector.toRequestBody()
ImageUploader(
totalList = foodCollectionList,
uploadImage = { batch->
uploadImage = { batch ->
val files = batch.map { it.imageFile }
(requireActivity() as SettingActivity).viewModel.uploadCollectFoodPics(files,params)
(requireActivity() as SettingActivity).viewModel.uploadCollectFoodPics(
files,
params
)
},
onProgress = { count, batch ->
activity?.runOnUiThread {
@@ -347,6 +365,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
it.bitmap = null
it.imageVector = null
it.imageFile = null
it.imageUri = null
it.isShowCamera = true
it.isFinish = false
it.uploadSuccess = false
@@ -39,7 +39,11 @@ class FoodCollectionAdapter (var list: MutableList<FoodCollectionBean>) :
scaleType = ImageView.ScaleType.CENTER_CROP
//setImageURI(it.imageUri)
//setImageBitmap(it.bitmap)
load(it.imageFile)
if (it.imageUri!=null) {
setImageURI(it.imageUri)
} else {
load(it.imageFile)
}
// it.bitmap?.let { bitmap ->
// GlideUtils.loadRoundCornerWitBitmap(
// context,
@@ -126,4 +126,8 @@ data class PaySuccessEvent(
data class ChargeModeEvent(
var chargeMode:Int = 0
)
data class ClickBackEvent(
var name: String = ""
)
@@ -19,6 +19,7 @@ data class FoodClassInfo(
data class FoodCollectionBean(
var imageFile: File? = null,
var imageUri: Uri? = null,
var bitmap: Bitmap? = null,
var imageVector: FloatArray? = null,
var isShowCamera: Boolean = false,
@@ -92,6 +92,7 @@ object FoodModule {
}
fun queryFoodNameScore(floatArray: FloatArray, queryCount: Int = 15): List<IdNameScore> {
val startTime = System.currentTimeMillis()
val query: Query<Food> =
box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
//查询比较分数
@@ -101,11 +102,14 @@ object FoodModule {
idScoreList.forEach {
nameScoreList.add(IdNameScore(id = it.id, name = box.get(it.id).name?:"", score = it.score))
}
Timber.tag("FoodModule").d("registerDataChange,queryFood数据:${GsonUtils.toJson(nameScoreList)}")
val nameScoreData = GsonUtils.toJson(nameScoreList)
Timber.tag("FoodModule").d("registerDataChange,queryFood,耗时:${System.currentTimeMillis()-startTime},数据:$nameScoreData")
return nameScoreList
}
fun getFoodScoreList(bitmap: Bitmap, queryCount: Int = 15): List<IdNameScore> {
val startTime = System.currentTimeMillis()
val floatArray = bitmap2FloatArray(bitmap)
Timber.tag("FoodModule").d("registerDataChange,bitmap2FloatArray,耗时:${System.currentTimeMillis()-startTime}")
val nameScoreList = queryFoodNameScore(floatArray, queryCount)
if (nameScoreList.isEmpty()) {
return emptyList()
@@ -118,6 +118,7 @@ class MainScreenPresentation(
initView()
setupArcCamera()
registerDataChange()
startTime = System.currentTimeMillis()
}
private var isFirstGetWeight = true
@@ -261,19 +262,34 @@ class MainScreenPresentation(
/**
* 显示识别出的菜品信息
*/
fun step3ShowRecognizeResult() {
Timber.tag(TAG).d("step3")
fun step3ShowRecognizeResult(userId: String) {
Timber.tag(TAG).d("main,step3,耗时:${System.currentTimeMillis() - startTime}")
LightManager.closeRedLight()
LightManager.openGreenLight()
currentStep = 3
stepChangeCallback(currentStep)
if (currentFood == null) {
ToastUtils.showToast("选中物品为空")
return
}
// updateFoodInfo(currentFood!!)
//foodRecSuccess(currentFood!!)
//根据接口数据更新热量数据--------------------------
userViewModel.getUserNutritionData(userId = userId) { nutrition ->
activity.runOnUiThread {
if (nutrition == null) {
activity.hideWaitingDialog()
ToastUtils.showToast("未查询到营养数据")
return@runOnUiThread
}
this@MainScreenPresentation.userNutrition = nutrition
loadUnbilledMode()
val imageUrl =
if (currentFood!!.foodImg.isNullOrBlank()) currentFood!!.photoUri else currentFood!!.foodImg
binding.ivRecImage.let {
it.visible()
it.load(imageUrl)
}
activity.updateImage(imageUrl)
activity.hideWaitingDialog()
}
}
}
private fun initView() {
@@ -392,14 +408,19 @@ class MainScreenPresentation(
calculateNutrition(recognitionWeight - lastWeight)
}
private var isFirstOpen = true
var startTime = 0L
/**
* 餐品识别中
*/
fun step1FoodRecognizing() {
Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
hideStandbyScreen()
activity.resetTouchTime()
activity.resumeAnalysis()
Timber.tag(TAG).d("step1")
if (isFirstOpen.not()) {
activity.resumeAnalysis()
}
//if (abs(lastWeight.toInt()) <= 5) {
// activity.runOnUiThread {
// ToastUtils.showToast("秤上重量几乎为0,请确认")
@@ -426,11 +447,11 @@ class MainScreenPresentation(
binding.flCameraView.visible()
binding.ivRecImage.gone()
binding.ivPreviewImage.visible()
binding.ivFrame.visible()
binding.ivFaceRecMask.gone()
binding.tvFaceTip.gone()
binding.llPriceInfo.gone()
binding.flFace.gone()
binding.ivFrame.gone()
binding.flRecognizeIr.gone()
pauseCamera()
@@ -458,7 +479,8 @@ class MainScreenPresentation(
*/
fun step2FaceRecognizing(foodInfo: FoodInfo) {
isGoStep1 = true
Timber.tag(TAG).d("step2")
Timber.tag(TAG).d("main,step2,耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
currentStep = 2
LightManager.closeRedLight()
@@ -497,7 +519,8 @@ class MainScreenPresentation(
// 当前食物信息
private var currentFood: FoodInfo? = null
fun updateFood(foodInfo: FoodInfo?) {
Timber.tag(TAG).d("updateFood")
Timber.tag(TAG).d("main,updateFood,耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis()
currentFood = foodInfo
if (foodInfo == null) {
return
@@ -513,6 +536,8 @@ class MainScreenPresentation(
if (foodInfo.foodImg.isNullOrBlank()) foodInfo.photoUri else foodInfo.foodImg
it.load(imageUrl)
}
} else {
binding.ivRecImage.gone()
}
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
if (mode == 0) {
@@ -793,28 +818,7 @@ class MainScreenPresentation(
return@runOnUiThread
}
}
step3ShowRecognizeResult()
//根据接口数据更新热量数据--------------------------
userViewModel.getUserNutritionData(userId = userId) { nutrition ->
activity.runOnUiThread {
if (nutrition == null) {
activity.hideWaitingDialog()
ToastUtils.showToast("未查询到营养数据")
return@runOnUiThread
}
this@MainScreenPresentation.userNutrition = nutrition
loadUnbilledMode()
val imageUrl =
if (currentFood!!.foodImg.isNullOrBlank()) currentFood!!.photoUri else currentFood!!.foodImg
binding.ivRecImage.let {
it.visible()
it.load(imageUrl)
}
activity.updateImage(imageUrl)
activity.hideWaitingDialog()
}
}
step3ShowRecognizeResult(userId)
})
recognizeViewModel.drawRectInfoText.observe(activity, Observer { info ->
@@ -1140,10 +1144,9 @@ class MainScreenPresentation(
}
fun postUserData() {
Timber.tag(TAG).d("postUserData")
if (userNutrition == null || currentFood == null) {
Timber.tag(TAG)
.d("postUserData userNutritionData = ${userNutrition == null}, currentFood = ${currentFood == null}")
Timber.tag(TAG)
.d("postUserData userNutritionData是否null ${userNutrition == null}, currentFood是否null: ${currentFood == null}currentUserId是否null${currentUserId == null}", )
if (userNutrition == null || currentFood == null || currentUserId == null) {
return
}
createOrder()
@@ -3,14 +3,14 @@ package com.sw.dualscreen.view;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import com.sw.dualscreen.R;
/**
@@ -18,78 +18,86 @@ import com.sw.dualscreen.R;
*/
public class CustomDialog extends Dialog {
/**
* 宽高由布局文件中指定(但是最底层的宽度无效,可以多嵌套一层解决)
*/
public CustomDialog(Context context, View layout) {
super(context, R.style.LoadingDialog);
setContentView(layout);
initConfig();
}
public CustomDialog(Context context, View layout, int style) {
super(context, style);
setContentView(layout);
initConfig();
}
private void initConfig() {
setCancelable(true);
setCanceledOnTouchOutside(true);
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);
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.CENTER;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
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);
}
// @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);
// }
}
+1 -1
View File
@@ -2,5 +2,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFF3232"/>
<corners android:radius="6dp"/>
<corners android:radius="10dp"/>
</shape>
+4 -3
View File
@@ -58,7 +58,7 @@
android:id="@+id/tv_food_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:layout_marginTop="50dp"
android:textStyle="bold"
android:textSize="52sp"
android:textColor="#FF0A1428"
@@ -67,9 +67,9 @@
<FrameLayout
android:id="@+id/foodDisplayLayout"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_height="560dp"
android:layout_marginHorizontal="28dp"
android:layout_marginTop="100dp"
android:layout_marginTop="80dp"
android:visibility="visible">
<androidx.camera.view.PreviewView
@@ -100,6 +100,7 @@
android:layout_height="0dp"
app:spanCount="2"
tools:itemCount="8"
android:overScrollMode="never"
tools:listitem="@layout/list_item_search_food"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
android:layout_marginHorizontal="14dp"
+2 -1
View File
@@ -11,7 +11,8 @@
android:layout_width="39dp"
android:layout_height="39dp"
android:indeterminateTint="@color/teal_200"
android:indeterminateTintMode="src_atop" />
android:indeterminateTintMode="src_atop"
android:focusable="false"/>
<TextView
android:id="@+id/tvTip"
@@ -187,7 +187,7 @@
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnConfirm"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_height="87dp"
android:layout_marginHorizontal="32dp"
android:layout_marginBottom="48dp"
android:text="确定"
+1 -1
View File
@@ -175,7 +175,7 @@
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnSave"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_height="87dp"
android:layout_marginHorizontal="32dp"
android:layout_marginBottom="48dp"
android:text="保存"
+1 -1
View File
@@ -1,6 +1,6 @@
<resources>
<!-- Base application theme. -->
<style name="Base.Theme.DualScreen" parent="Theme.Material3.DayNight.NoActionBar">
<style name="Theme.DualScreen" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your dark theme here. -->
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
</style>
+6 -3
View File
@@ -1,13 +1,11 @@
<resources>
<!-- Base application theme. -->
<!-- <style name="Base.Theme.DualScreen" parent="Theme.Material3.DayNight.NoActionBar">-->
<style name="Base.Theme.DualScreen" parent="Theme.AppCompat.Light.NoActionBar">
<style name="Theme.DualScreen" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.DualScreen" parent="Base.Theme.DualScreen" />
<style name="text_title_blob">
<item name="android:layout_width">match_parent</item>
<item name="android:textColor">@color/beige_ECE7D0</item>
@@ -177,4 +175,9 @@
<item name="cornerFamily">rounded</item>
<item name="cornerSize">10dp</item>
</style>
<style name="LoadingDialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowIsFloating">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
</resources>