添加了初始化界面,修复了人脸数据更新后不能识别的问题
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import org.gradle.kotlin.dsl.implementation
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.kotlin.android)
|
alias(libs.plugins.kotlin.android)
|
||||||
@@ -104,4 +106,7 @@ dependencies {
|
|||||||
implementation(libs.androidx.fragment.ktx)
|
implementation(libs.androidx.fragment.ktx)
|
||||||
// 图片加载
|
// 图片加载
|
||||||
implementation(libs.glide)
|
implementation(libs.glide)
|
||||||
|
|
||||||
|
implementation(libs.core)
|
||||||
|
implementation(libs.android.core)
|
||||||
}
|
}
|
||||||
@@ -12,8 +12,9 @@ class MyApp : App() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
Timber.plant(Timber.DebugTree())
|
Timber.plant(Timber.DebugTree())
|
||||||
val deviceId = AppUtil.getUDID(this)
|
var deviceId = AppUtil.getUDID(this)
|
||||||
Timber.d("UDID = ${AppUtil.getUDID(this)}")
|
Timber.d("UDID = ${AppUtil.getUDID(this)}")
|
||||||
|
deviceId = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e"
|
||||||
GlobalData.deviceId = deviceId
|
GlobalData.deviceId = deviceId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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<VB : ViewBinding> : 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<View?>(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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,35 +5,48 @@ import android.os.Bundle
|
|||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.sw.dualscreen.GlobalData
|
||||||
import com.sw.dualscreen.databinding.ActivityInitBinding
|
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.dualscreen.viewmodel.DeviceViewModel
|
||||||
import com.sw.plate.utils.AppUtil
|
import com.sw.plate.utils.AppUtil
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class InitActivity : AppCompatActivity() {
|
class InitActivity : BaseActivity<ActivityInitBinding>() {
|
||||||
private lateinit var binding: ActivityInitBinding
|
|
||||||
private val viewModel by viewModels<DeviceViewModel>()
|
private val viewModel by viewModels<DeviceViewModel>()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun getViewModel(): BaseViewModel {
|
||||||
super.onCreate(savedInstanceState)
|
return viewModel
|
||||||
enableEdgeToEdge()
|
}
|
||||||
binding = ActivityInitBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
override fun inflateViewBinding(): ActivityInitBinding {
|
||||||
val deviceId = AppUtil.getUDID(this)
|
return ActivityInitBinding.inflate(layoutInflater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize() {
|
||||||
|
super.initialize()
|
||||||
val isSuccess = viewModel.checkEquipmentInfo()
|
val isSuccess = viewModel.checkEquipmentInfo()
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
goMainActivity()
|
goMainActivity()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
binding.tvDeviceId.text = deviceId
|
binding.imgQr.setImageBitmap(
|
||||||
binding.btConfirm.setOnClickListener {
|
QRCodeUtil.generateQRCode(
|
||||||
|
content = GlobalData.deviceId,
|
||||||
|
size = 200
|
||||||
|
)
|
||||||
|
)
|
||||||
|
binding.initButton.setOnClickListener {
|
||||||
viewModel.getDeviceToken()
|
viewModel.getDeviceToken()
|
||||||
}
|
}
|
||||||
registerDataChange()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerDataChange() {
|
override fun registerDataChange() {
|
||||||
|
super.registerDataChange()
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
viewModel.deviceInfoResult.drop(1).collect {
|
viewModel.deviceInfoResult.drop(1).collect {
|
||||||
if (it != true) return@collect
|
if (it != true) return@collect
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ import com.sw.dualscreen.presentation.SecondaryScreenPresentation
|
|||||||
import com.sw.dualscreen.sdk.SensorScaleUtils
|
import com.sw.dualscreen.sdk.SensorScaleUtils
|
||||||
import com.sw.dualscreen.utils.GlideUtils
|
import com.sw.dualscreen.utils.GlideUtils
|
||||||
import com.sw.dualscreen.view.CustomBottomSheetDialog
|
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.dualscreen.viewmodel.UserViewModel
|
||||||
import com.sw.plate.utils.ToastUtils
|
import com.sw.plate.utils.ToastUtils
|
||||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||||
@@ -44,8 +46,7 @@ import timber.log.Timber
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||||
private lateinit var binding: ActivityMainBinding
|
|
||||||
private val viewModel by viewModels<UserViewModel>()
|
private val viewModel by viewModels<UserViewModel>()
|
||||||
private var imageCapture: ImageCapture? = null
|
private var imageCapture: ImageCapture? = null
|
||||||
private var isAnalyzing = true // 控制是否进行图像分析
|
private var isAnalyzing = true // 控制是否进行图像分析
|
||||||
@@ -59,12 +60,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private var bottomSheetDialog: CustomBottomSheetDialog? = null
|
private var bottomSheetDialog: CustomBottomSheetDialog? = null
|
||||||
private var lastWeight: Double = 0.0
|
private var lastWeight: Double = 0.0
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun getViewModel(): BaseViewModel {
|
||||||
super.onCreate(savedInstanceState)
|
return viewModel
|
||||||
enableEdgeToEdge()
|
}
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.main)
|
|
||||||
|
|
||||||
|
override fun inflateViewBinding(): ActivityMainBinding {
|
||||||
|
return ActivityMainBinding.inflate(layoutInflater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize() {
|
||||||
|
super.initialize()
|
||||||
initView()
|
initView()
|
||||||
setupSecondaryDisplay()
|
setupSecondaryDisplay()
|
||||||
setupCamera()
|
setupCamera()
|
||||||
@@ -94,7 +99,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
val spinnerAdapter = ArrayAdapter<String>(
|
val spinnerAdapter = ArrayAdapter<String>(
|
||||||
this,
|
this,
|
||||||
R.layout.item_for_custom_spinner,
|
R.layout.item_for_custom_spinner,
|
||||||
arrayOf("即放即取", "持续取餐")
|
arrayOf("即放即取", "余量取餐")
|
||||||
)
|
)
|
||||||
binding.spinner.adapter = spinnerAdapter
|
binding.spinner.adapter = spinnerAdapter
|
||||||
binding.spinner.setSelection(0)
|
binding.spinner.setSelection(0)
|
||||||
@@ -105,12 +110,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
position: Int,
|
position: Int,
|
||||||
id: Long
|
id: Long
|
||||||
) {
|
) {
|
||||||
|
presentation.updateMealPickupMode(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
adapter = createAdapter()
|
adapter = createAdapter()
|
||||||
binding.recyclerview.layoutManager = GridLayoutManager(this, 2)
|
binding.recyclerview.layoutManager = GridLayoutManager(this, 2)
|
||||||
@@ -126,7 +129,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
binding.tvFoodName.setOnClickListener {
|
binding.tvFoodName.setOnClickListener {
|
||||||
SensorScaleUtils.zero()
|
SensorScaleUtils.zero()
|
||||||
}
|
}
|
||||||
registerDataChange()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateCurrentFood(foodInfo: FoodInfo?) {
|
fun updateCurrentFood(foodInfo: FoodInfo?) {
|
||||||
@@ -154,7 +156,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerDataChange() {
|
override fun registerDataChange() {
|
||||||
|
super.registerDataChange()
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
viewModel.identifiedFoodInfoList.collect { list ->
|
viewModel.identifiedFoodInfoList.collect { list ->
|
||||||
binding.recyclerview
|
binding.recyclerview
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import android.hardware.Camera
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
|
||||||
import android.view.Display
|
import android.view.Display
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@@ -69,19 +68,18 @@ class SecondaryScreenPresentation(
|
|||||||
|
|
||||||
// 当前食物信息
|
// 当前食物信息
|
||||||
private var currentFood: FoodInfo? = null
|
private var currentFood: FoodInfo? = null
|
||||||
private var lastFood: FoodInfo? = null
|
|
||||||
private var userNutritionData: UserNutritionData? = null
|
private var userNutritionData: UserNutritionData? = null
|
||||||
private var dinnerTypeInfo: DinnerTypeInfo? = null
|
private var dinnerTypeInfo: DinnerTypeInfo? = null
|
||||||
private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding
|
private lateinit var itemUserNutritionBinding: ItemUserNutritionBinding
|
||||||
private lateinit var stepChangeCallback: (Int) -> Unit
|
private lateinit var stepChangeCallback: (Int) -> Unit
|
||||||
|
|
||||||
// 上一次的计算热量结果
|
// 上一次的计算热量结果
|
||||||
private var lastCalcResultInfo: UserNutritionUtils.CalcResultInfo? = null
|
|
||||||
private var lastWeight = 0.0
|
private var lastWeight = 0.0
|
||||||
private val debouncer = Debouncer(500)
|
private val debouncer = Debouncer(500)
|
||||||
private var faceTime: Long = 0L // 人脸识别时的时间
|
private var recognitionTime: Long = 0L // 人脸识别时的时间
|
||||||
private var recognitionWeight: Double = 0.0 // 人脸识别时的重量
|
private var recognitionWeight: Double = 0.0 // 人脸识别时的重量
|
||||||
private var lastFaceTrackId: Int = 0 // 上一次的人脸信息
|
private var lastFaceTrackId: Int = 0 // 上一次的人脸信息
|
||||||
|
private var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐
|
||||||
|
|
||||||
// 当前步骤
|
// 当前步骤
|
||||||
var currentStep: Int = 0
|
var currentStep: Int = 0
|
||||||
@@ -99,6 +97,13 @@ class SecondaryScreenPresentation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerDataChange() {
|
private fun registerDataChange() {
|
||||||
|
activity.lifecycleScope.launch {
|
||||||
|
viewModel.loadFaceResult.collect { needUpdate ->
|
||||||
|
if (needUpdate){
|
||||||
|
recognizeViewModel.refreshFaceList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
activity.lifecycleScope.launch {
|
activity.lifecycleScope.launch {
|
||||||
viewModel.nutritionData.collect {
|
viewModel.nutritionData.collect {
|
||||||
Timber.d("registerDataChange nutritionData = $it")
|
Timber.d("registerDataChange nutritionData = $it")
|
||||||
@@ -161,8 +166,6 @@ class SecondaryScreenPresentation(
|
|||||||
dinnerTypeInfo = null
|
dinnerTypeInfo = null
|
||||||
currentFood = null
|
currentFood = null
|
||||||
userNutritionData = null
|
userNutritionData = null
|
||||||
lastFood = null
|
|
||||||
lastCalcResultInfo = null
|
|
||||||
recognitionWeight = 0.0
|
recognitionWeight = 0.0
|
||||||
|
|
||||||
stepChangeCallback(currentStep)
|
stepChangeCallback(currentStep)
|
||||||
@@ -182,6 +185,11 @@ class SecondaryScreenPresentation(
|
|||||||
fun step2(foodInfo: FoodInfo) {
|
fun step2(foodInfo: FoodInfo) {
|
||||||
Timber.d("step2")
|
Timber.d("step2")
|
||||||
currentStep = 2
|
currentStep = 2
|
||||||
|
|
||||||
|
dinnerTypeInfo = null
|
||||||
|
userNutritionData = null
|
||||||
|
recognitionWeight = 0.0
|
||||||
|
|
||||||
stepChangeCallback(currentStep)
|
stepChangeCallback(currentStep)
|
||||||
currentFood = foodInfo
|
currentFood = foodInfo
|
||||||
viewModel.getDinnerType()
|
viewModel.getDinnerType()
|
||||||
@@ -262,6 +270,14 @@ class SecondaryScreenPresentation(
|
|||||||
calculateNutrition(recognitionWeight - lastWeight)
|
calculateNutrition(recognitionWeight - lastWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 余量取餐
|
||||||
|
*/
|
||||||
|
fun updateMealPickupMode(mode: Int) {
|
||||||
|
Timber.d("updateMealPickupMode mode = $mode")
|
||||||
|
mealPickupMode = mode
|
||||||
|
}
|
||||||
|
|
||||||
private fun calculateNutrition(weight: Double) {
|
private fun calculateNutrition(weight: Double) {
|
||||||
debouncer.debounce {
|
debouncer.debounce {
|
||||||
Timber.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
Timber.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
||||||
@@ -274,11 +290,6 @@ class SecondaryScreenPresentation(
|
|||||||
dinnerType = dinnerType
|
dinnerType = dinnerType
|
||||||
)
|
)
|
||||||
Timber.d("calculateNutrition calcResultInfo = $calcResultInfo")
|
Timber.d("calculateNutrition calcResultInfo = $calcResultInfo")
|
||||||
if (lastCalcResultInfo == calcResultInfo) {
|
|
||||||
Timber.d("calculateNutrition 与上次计算结果无变化")
|
|
||||||
return@debounce
|
|
||||||
}
|
|
||||||
lastCalcResultInfo = calcResultInfo
|
|
||||||
val columnMax = UserNutritionUtils.getMaxInt(calcResultInfo)
|
val columnMax = UserNutritionUtils.getMaxInt(calcResultInfo)
|
||||||
|
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
@@ -346,7 +357,7 @@ class SecondaryScreenPresentation(
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val cameraCount = Camera.getNumberOfCameras()
|
val cameraCount = Camera.getNumberOfCameras()
|
||||||
if (cameraCount < 3){
|
if (cameraCount < 3) {
|
||||||
ToastUtils.showToast("摄像头数量异常")
|
ToastUtils.showToast("摄像头数量异常")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -418,14 +429,14 @@ class SecondaryScreenPresentation(
|
|||||||
Timber.i("recognizeConfiguration: observe = ${recognizeConfiguration.toString()}")
|
Timber.i("recognizeConfiguration: observe = ${recognizeConfiguration.toString()}")
|
||||||
})
|
})
|
||||||
recognizeViewModel.recognizeNotice.observe(activity, Observer { notice: String? ->
|
recognizeViewModel.recognizeNotice.observe(activity, Observer { notice: String? ->
|
||||||
// Timber.i("recognizeNotice observe notice = $notice")
|
Timber.i("recognizeNotice observe notice = $notice")
|
||||||
})
|
})
|
||||||
|
|
||||||
recognizeViewModel.recognizeUserId.observe(
|
recognizeViewModel.recognizeUserId.observe(
|
||||||
activity,
|
activity,
|
||||||
Observer { compareResult: CompareResult ->
|
Observer { compareResult: CompareResult ->
|
||||||
Timber.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}")
|
Timber.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}")
|
||||||
faceTime = System.currentTimeMillis()
|
recognitionTime = System.currentTimeMillis()
|
||||||
recognitionWeight = lastWeight
|
recognitionWeight = lastWeight
|
||||||
lastFaceTrackId = compareResult.trackId
|
lastFaceTrackId = compareResult.trackId
|
||||||
val faceEntity = compareResult.faceEntity
|
val faceEntity = compareResult.faceEntity
|
||||||
@@ -701,7 +712,11 @@ class SecondaryScreenPresentation(
|
|||||||
Timber.i("$lastFaceTrackId 用户离开")
|
Timber.i("$lastFaceTrackId 用户离开")
|
||||||
lastFaceTrackId = 0
|
lastFaceTrackId = 0
|
||||||
postUserData()
|
postUserData()
|
||||||
step1()
|
if (mealPickupMode == 0) {
|
||||||
|
step1()
|
||||||
|
}else{
|
||||||
|
step2(currentFood!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -715,7 +730,7 @@ class SecondaryScreenPresentation(
|
|||||||
val userNutritionParam = UserNutritionParam(
|
val userNutritionParam = UserNutritionParam(
|
||||||
userId = userNutritionData?.userId!!,
|
userId = userNutritionData?.userId!!,
|
||||||
foodId = currentFood?.id!!,
|
foodId = currentFood?.id!!,
|
||||||
faceTime = faceTime,
|
faceTime = recognitionTime,
|
||||||
faceEndTime = System.currentTimeMillis(),
|
faceEndTime = System.currentTimeMillis(),
|
||||||
eatWeight = recognitionWeight - lastWeight,
|
eatWeight = recognitionWeight - lastWeight,
|
||||||
foodWeight = lastWeight
|
foodWeight = lastWeight
|
||||||
|
|||||||
@@ -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<EncodeHintType, Any>().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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sw.dualscreen.viewmodel
|
package com.sw.dualscreen.viewmodel
|
||||||
|
|
||||||
|
import com.sw.dualscreen.GlobalData
|
||||||
import com.sw.dualscreen.GlobalKey
|
import com.sw.dualscreen.GlobalKey
|
||||||
import com.sw.dualscreen.model.response.EquipmentInfo
|
import com.sw.dualscreen.model.response.EquipmentInfo
|
||||||
import com.sw.dualscreen.utils.GsonUtils
|
import com.sw.dualscreen.utils.GsonUtils
|
||||||
@@ -18,7 +19,7 @@ class DeviceViewModel : BaseViewModel() {
|
|||||||
/**
|
/**
|
||||||
* 获取token
|
* 获取token
|
||||||
*/
|
*/
|
||||||
fun getDeviceToken(deviceId: String = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e") {
|
fun getDeviceToken(deviceId: String = GlobalData.deviceId) {
|
||||||
launchWithLoading {
|
launchWithLoading {
|
||||||
val response = repository.getDeviceToken(deviceId)
|
val response = repository.getDeviceToken(deviceId)
|
||||||
if (parseResponse(response)) {
|
if (parseResponse(response)) {
|
||||||
|
|||||||
@@ -45,11 +45,17 @@ class UserViewModel : BaseViewModel() {
|
|||||||
private val _dinnerTypeInfo = MutableStateFlow<DinnerTypeInfo?>(null)
|
private val _dinnerTypeInfo = MutableStateFlow<DinnerTypeInfo?>(null)
|
||||||
val dinnerTypeInfo: StateFlow<DinnerTypeInfo?> = _dinnerTypeInfo
|
val dinnerTypeInfo: StateFlow<DinnerTypeInfo?> = _dinnerTypeInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸加载完成
|
||||||
|
*/
|
||||||
|
private val _loadFaceResult = MutableStateFlow<Boolean>(false)
|
||||||
|
val loadFaceResult : StateFlow<Boolean> = _loadFaceResult
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取token
|
* 获取token
|
||||||
*/
|
*/
|
||||||
fun getEquipmentToken(qrcodeId: String = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e") {
|
fun getEquipmentToken(qrcodeId: String = GlobalData.deviceId) {
|
||||||
Timber.d("getEquipmentToken")
|
Timber.d("getEquipmentToken")
|
||||||
launchWithLoading {
|
launchWithLoading {
|
||||||
val response = repository.getEquipmentToken(qrcodeId)
|
val response = repository.getEquipmentToken(qrcodeId)
|
||||||
@@ -70,6 +76,7 @@ class UserViewModel : BaseViewModel() {
|
|||||||
fun getUserFaceCache(index: Int = 0) {
|
fun getUserFaceCache(index: Int = 0) {
|
||||||
Timber.d("getUserFaceCache index = $index")
|
Timber.d("getUserFaceCache index = $index")
|
||||||
launch {
|
launch {
|
||||||
|
_loadFaceResult.value = false
|
||||||
val response = repository.getUserFaceCache(index)
|
val response = repository.getUserFaceCache(index)
|
||||||
if (parseResponse(response)) {
|
if (parseResponse(response)) {
|
||||||
// 获取成功一次后缓存状态
|
// 获取成功一次后缓存状态
|
||||||
@@ -80,11 +87,12 @@ class UserViewModel : BaseViewModel() {
|
|||||||
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureString))
|
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureString))
|
||||||
}
|
}
|
||||||
faceApi.updateFaceData(index, faceEntity)
|
faceApi.updateFaceData(index, faceEntity)
|
||||||
activeEngine()
|
|
||||||
}
|
}
|
||||||
val nextPageIndex = response.result?.nextPageIndex ?: -1
|
val nextPageIndex = response.result?.nextPageIndex ?: -1
|
||||||
if (nextPageIndex > 0) {
|
if (nextPageIndex > 0) {
|
||||||
getUserFaceCache(nextPageIndex)
|
getUserFaceCache(nextPageIndex)
|
||||||
|
} else{
|
||||||
|
_loadFaceResult.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,13 +137,6 @@ class UserViewModel : BaseViewModel() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置用户信息
|
|
||||||
*/
|
|
||||||
fun resetUserInfo() {
|
|
||||||
Timber.d("resetUserInfo")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getIdentifiedFoodList() {
|
fun getIdentifiedFoodList() {
|
||||||
Timber.d("identifiedFoodList")
|
Timber.d("identifiedFoodList")
|
||||||
launchWithLoading {
|
launchWithLoading {
|
||||||
@@ -180,7 +181,7 @@ class UserViewModel : BaseViewModel() {
|
|||||||
fun getUserNutritionData(userId: String, foodId: String) {
|
fun getUserNutritionData(userId: String, foodId: String) {
|
||||||
Timber.d("getUserNutritionData userId = ${userId}, foodId = $foodId")
|
Timber.d("getUserNutritionData userId = ${userId}, foodId = $foodId")
|
||||||
_nutritionData.value = null
|
_nutritionData.value = null
|
||||||
launchWithLoading {
|
launch {
|
||||||
val response = repository.getUserNutritionData(userId = userId, foodId = foodId)
|
val response = repository.getUserNutritionData(userId = userId, foodId = foodId)
|
||||||
if (parseResponse(response)) {
|
if (parseResponse(response)) {
|
||||||
_nutritionData.value = response.result
|
_nutritionData.value = response.result
|
||||||
@@ -191,7 +192,7 @@ class UserViewModel : BaseViewModel() {
|
|||||||
fun getDinnerType() {
|
fun getDinnerType() {
|
||||||
Timber.d("getDinnerType")
|
Timber.d("getDinnerType")
|
||||||
_dinnerTypeInfo.value = null
|
_dinnerTypeInfo.value = null
|
||||||
launchWithLoading {
|
launch {
|
||||||
val response = repository.getDinnerType()
|
val response = repository.getDinnerType()
|
||||||
if (parseResponse(response)) {
|
if (parseResponse(response)) {
|
||||||
_dinnerTypeInfo.value = response.result
|
_dinnerTypeInfo.value = response.result
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<solid android:color="#ff08C6DC" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
<solid android:color="@color/black" />
|
||||||
|
</shape>
|
||||||
@@ -1,23 +1,90 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/main"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
tools:context=".activity.InitActivity">
|
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/tv_deviceId"
|
android:id="@+id/welcomeLayout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
tools:text="1111" />
|
android:background="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<Button
|
<ImageView
|
||||||
android:id="@+id/bt_confirm"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:src="@mipmap/ic_launcher" />
|
||||||
android:layout_marginTop="24dp"
|
</LinearLayout>
|
||||||
android:text="获取" />
|
<RelativeLayout
|
||||||
|
android:id="@+id/initRelLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:padding="48dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/mainImgView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="200dp"
|
||||||
|
android:src="@mipmap/img_init" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/okButton"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="52dp"
|
||||||
|
android:layout_below="@+id/mainImgView"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:background="@drawable/bg_init_button"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="连接服务器"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/initButton"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/mainImgView"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="160dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="@drawable/bg_init_button"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="设备初始化"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/activeArcsoft"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="68dp"
|
||||||
|
android:layout_below="@+id/okButton"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="40dp"
|
||||||
|
android:background="@drawable/bg_init_button"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="虹软激活"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="32sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imgQr"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="240dp"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:background="@drawable/dialog_waiting">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:text="请稍等"
|
||||||
|
android:textSize="22sp" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginRight="30dp"
|
||||||
|
android:layout_toLeftOf="@id/tvTip"
|
||||||
|
android:indeterminateTint="@color/teal_200"
|
||||||
|
android:indeterminateTintMode="src_atop" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</FrameLayout>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 999 KiB |
@@ -7,7 +7,7 @@
|
|||||||
<color name="beige_ECE7D0">#ECE7D0</color>
|
<color name="beige_ECE7D0">#ECE7D0</color>
|
||||||
<color name="blue_6498DD">#6498DD</color>
|
<color name="blue_6498DD">#6498DD</color>
|
||||||
<color name="black_031127">#031127</color>
|
<color name="black_031127">#031127</color>
|
||||||
|
<color name="teal_200">#FF03DAC5</color>
|
||||||
<color name="identify_checked">#031127</color>
|
<color name="identify_checked">#031127</color>
|
||||||
<color name="identify_normal">#6498DD</color>
|
<color name="identify_normal">#6498DD</color>
|
||||||
<color name="search_checked">#FF9900</color>
|
<color name="search_checked">#FF9900</color>
|
||||||
|
|||||||
@@ -116,4 +116,18 @@
|
|||||||
<item name="android:textStyle">bold</item>
|
<item name="android:textStyle">bold</item>
|
||||||
<item name="android:layout_centerHorizontal">true</item>
|
<item name="android:layout_centerHorizontal">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!--圆角Dialog-->
|
||||||
|
<style name="MyDialog" parent="@android:style/Theme.Dialog">
|
||||||
|
<item name="android:windowFrame">@null</item>
|
||||||
|
<item name="android:windowIsFloating">true</item>
|
||||||
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
<item name="android:background">@android:color/transparent</item>
|
||||||
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
|
<item name="android:backgroundDimEnabled">true</item>
|
||||||
|
<item name="android:backgroundDimAmount">0.6</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.10.1"
|
agp = "8.10.1"
|
||||||
|
core = "3.4.1"
|
||||||
|
androidCore = "3.3.0"
|
||||||
glide = "4.16.0"
|
glide = "4.16.0"
|
||||||
kotlin = "2.0.21"
|
kotlin = "2.0.21"
|
||||||
coreKtx = "1.10.1"
|
coreKtx = "1.10.1"
|
||||||
@@ -25,6 +27,8 @@ lifecycleViewmodelKtx = "2.8.3"
|
|||||||
lifecycleRuntimeKtx = "2.8.3"
|
lifecycleRuntimeKtx = "2.8.3"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
||||||
|
core = { module = "com.google.zxing:core", version.ref = "core" }
|
||||||
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||||
|
|||||||
Reference in New Issue
Block a user