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 7905038..e68bb07 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt @@ -43,6 +43,9 @@ import timber.log.Timber import java.io.File import java.util.concurrent.Executors +/** + * 服务员显示界面 + */ class MainActivity : BaseActivity() { private val viewModel by viewModels() private var imageCapture: ImageCapture? = null diff --git a/app/src/main/java/com/sw/dualscreen/network/interceptor/RequestInterceptor.kt b/app/src/main/java/com/sw/dualscreen/network/interceptor/RequestInterceptor.kt index 5375e5d..0a9ccc3 100644 --- a/app/src/main/java/com/sw/dualscreen/network/interceptor/RequestInterceptor.kt +++ b/app/src/main/java/com/sw/dualscreen/network/interceptor/RequestInterceptor.kt @@ -2,7 +2,7 @@ package com.sw.dualscreen.network.interceptor import android.text.TextUtils import com.sw.dualscreen.GlobalKey -import com.sw.inbound.utils.SPUtil +import com.sw.dualscreen.utils.SPUtil import com.sw.plate.App import okhttp3.Interceptor import okhttp3.Request diff --git a/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt b/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt index 0fccc3a..35f0ad3 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/UserNutritionUtils.kt @@ -7,8 +7,10 @@ import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.UserNutritionData import timber.log.Timber import kotlin.math.max -import kotlin.math.min +/** + * 用户营养信息计算工具 + */ object UserNutritionUtils { /** diff --git a/app/src/main/java/com/sw/dualscreen/utils/Debouncer.kt b/app/src/main/java/com/sw/dualscreen/utils/Debouncer.kt index 914a4b1..ebc0068 100644 --- a/app/src/main/java/com/sw/dualscreen/utils/Debouncer.kt +++ b/app/src/main/java/com/sw/dualscreen/utils/Debouncer.kt @@ -1,5 +1,8 @@ package com.sw.dualscreen.utils +/** + * 防抖工具 + */ class Debouncer(private val delayMillis: Long = 2000) { private var lastActionTime = 0L diff --git a/app/src/main/java/com/sw/dualscreen/utils/FileUtils.kt b/app/src/main/java/com/sw/dualscreen/utils/FileUtils.kt deleted file mode 100644 index 666d70b..0000000 --- a/app/src/main/java/com/sw/dualscreen/utils/FileUtils.kt +++ /dev/null @@ -1,156 +0,0 @@ -package com.sw.dualscreen.utils - -import android.content.ContentUris -import android.content.Context -import android.net.Uri -import android.os.Build -import android.provider.MediaStore -import androidx.annotation.RequiresApi -import okhttp3.MediaType.Companion.toMediaTypeOrNull -import okhttp3.MultipartBody -import okhttp3.RequestBody.Companion.asRequestBody -import timber.log.Timber -import java.io.File - -object FileUtils { - /** - * 从Uri获取File - * example: file:///data/user/0/com.sw.inbound/cache/IMG_17515262353556856678814444882273.jpg - */ - private fun getFileFromUri(context: Context, uri: Uri): File? { - Timber.d("getFileFromUri uri = ${uri.scheme}") - return when (uri.scheme) { - "file" -> File(uri.path ?: return null) - "content" -> { - try { - val inputStream = context.contentResolver.openInputStream(uri) ?: return null - val cacheDir = context.cacheDir - val file = File.createTempFile( - "upload_${System.currentTimeMillis()}", - ".jpg", - cacheDir - ) - file.outputStream().use { output -> - inputStream.copyTo(output) - } - file - } catch (e: Exception) { - Timber.e(e) - null - } - } - - else -> null - } - } - - /** - * 通过uri生成http请求体 - */ - fun genRequestPart(context: Context, imageUri: Uri): MultipartBody.Part? { - Timber.d("genRequestPart imageUri = $imageUri") - // 1. 从Uri获取文件 - val file = getFileFromUri(context, imageUri) - if (file == null) { - Timber.e("getFileFromUri file is null") - return null - } - // 2. 创建请求体 - val requestFile = file - .asRequestBody("application/octet-stream".toMediaTypeOrNull()) - val imagePart = MultipartBody.Part.createFormData( - "file", - file.name, - requestFile - ) - return imagePart - } - - /** - * 通过Uri删除文件 - * @param context 上下文 - * @param uri 文件Uri - * @return Boolean 是否删除成功 - */ - fun deleteFileWithUri(context: Context, uri: Uri): Boolean { - Timber.d("deleteFileWithUri uri = ${uri.scheme}") - return when { - // 1. 处理 content:// 类型的Uri (MediaStore) - uri.scheme.equals("content", ignoreCase = true) -> { - deleteContentUriFile(context, uri) - } - // 2. 处理 file:// 类型的Uri - uri.scheme.equals("file", ignoreCase = true) -> { - deleteFileUriFile(uri) - } - // 3. 其他情况尝试直接解析路径 - else -> { - deleteFileFromPath(uri.path ?: return false) - } - } - } - - // 删除Content Uri文件 - private fun deleteContentUriFile(context: Context, uri: Uri): Boolean { - Timber.d("deleteContentUriFile uri = ${uri.scheme}") - return try { - context.contentResolver.delete(uri, null, null) > 0 - } catch (e: SecurityException) { - // Android 10+需要特殊处理 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - deleteMediaStoreFile(context, uri) - } else { - false - } - } catch (e: Exception) { - Timber.e(e) - false - } - } - - // Android 10+删除MediaStore文件 - @RequiresApi(Build.VERSION_CODES.Q) - private fun deleteMediaStoreFile(context: Context, uri: Uri): Boolean { - Timber.d("deleteMediaStoreFile uri = ${uri.scheme}") - val contentResolver = context.contentResolver - val projection = arrayOf(MediaStore.MediaColumns._ID) - - return try { - contentResolver.query(uri, projection, null, null, null)?.use { cursor -> - if (cursor.moveToFirst()) { - val id = - cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)) - val contentUri = ContentUris.withAppendedId(uri, id) - contentResolver.delete(contentUri, null, null) > 0 - } else { - false - } - } ?: false - } catch (e: Exception) { - Timber.e(e) - false - } - } - - // 删除File Uri文件 - private fun deleteFileUriFile(uri: Uri): Boolean { - Timber.d("deleteFileUriFile uri = $uri") - return try { - File(uri.path ?: return false).delete() - } catch (e: Exception) { - Timber.e(e) - false - } - } - - // 直接通过路径删除文件 - private fun deleteFileFromPath(path: String): Boolean { - Timber.d("deleteFileFromPath path = $path") - return try { - File(path).delete() - } catch (e: Exception) { - Timber.e(e) - false - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/utils/SPUtil.kt b/app/src/main/java/com/sw/dualscreen/utils/SPUtil.kt index bf13ea7..8927a10 100644 --- a/app/src/main/java/com/sw/dualscreen/utils/SPUtil.kt +++ b/app/src/main/java/com/sw/dualscreen/utils/SPUtil.kt @@ -1,4 +1,4 @@ -package com.sw.inbound.utils +package com.sw.dualscreen.utils import android.content.Context import androidx.core.content.edit @@ -9,6 +9,9 @@ import kotlinx.coroutines.flow.map import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty +/** + * 持久化工具 + */ class SPUtil private constructor(context: Context, private val spName: String) { companion object { diff --git a/app/src/main/java/com/sw/dualscreen/utils/ScreenUtils.kt b/app/src/main/java/com/sw/dualscreen/utils/ScreenUtils.kt deleted file mode 100644 index a3ef7e1..0000000 --- a/app/src/main/java/com/sw/dualscreen/utils/ScreenUtils.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.sw.dualscreen.utils - -import android.content.Context -import android.util.DisplayMetrics -import android.view.WindowManager -import timber.log.Timber -import kotlin.math.sqrt - -object ScreenUtils { - fun printScreenInfo(context: Context, tag: String) { - val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager - val displayMetrics = DisplayMetrics() - - // 方法 1:获取应用可用区域(排除系统装饰,如状态栏) - windowManager.defaultDisplay.getMetrics(displayMetrics) - - // 方法 2:获取整个屏幕的物理尺寸(包括状态栏和导航栏) - // windowManager.defaultDisplay.getRealMetrics(displayMetrics) - - val screenWidthPx = displayMetrics.widthPixels // 屏幕宽度(像素) - val screenHeightPx = displayMetrics.heightPixels // 屏幕高度(像素) - val density = displayMetrics.density // 逻辑密度(1.0 = mdpi, 2.0 = xhdpi) - val densityDpi = displayMetrics.densityDpi // 屏幕 DPI 分类(160 = mdpi, 320 = xhdpi) - val xdpi = displayMetrics.xdpi // 物理水平 DPI - val ydpi = displayMetrics.ydpi // 物理垂直 DPI - - // 打印信息 - Timber.d("$tag 屏幕信息") - Timber.d("屏幕分辨率(像素): ${screenWidthPx}x${screenHeightPx}") - Timber.d("逻辑密度: $density") - Timber.d("DPI 分类: $densityDpi") - Timber.d("物理 DPI (x/y): $xdpi / $ydpi") - - // 计算屏幕物理尺寸(英寸) - val screenWidthInches = screenWidthPx / xdpi - val screenHeightInches = screenHeightPx / ydpi - val diagonalInches = sqrt( - (screenWidthInches * screenWidthInches + screenHeightInches * screenHeightInches).toDouble() - ) - Timber.d( - "屏幕物理尺寸(英寸): %.1f x %.1f (对角线: %.1f\")".format( - screenWidthInches, screenHeightInches, diagonalInches - ) - ) - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/view/CustomBottomSheetDialog.kt b/app/src/main/java/com/sw/dualscreen/view/CustomBottomSheetDialog.kt index 0e6d904..95345d8 100644 --- a/app/src/main/java/com/sw/dualscreen/view/CustomBottomSheetDialog.kt +++ b/app/src/main/java/com/sw/dualscreen/view/CustomBottomSheetDialog.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.view.inputmethod.EditorInfo import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import com.google.android.material.bottomsheet.BottomSheetDialogFragment @@ -25,6 +24,9 @@ import com.sw.dualscreen.viewmodel.UserViewModel import kotlinx.coroutines.launch import timber.log.Timber +/** + * 底部搜索结果弹窗 + */ class CustomBottomSheetDialog( val viewModel: UserViewModel, val itemClickCallback: (FoodInfo) -> Unit diff --git a/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java b/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java index 4250438..131bdec 100644 --- a/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java +++ b/app/src/main/java/com/sw/dualscreen/view/CustomDialog.java @@ -10,6 +10,9 @@ import android.view.View; import android.view.Window; import android.view.WindowManager; +/** + * 加载进度条弹窗 + */ public class CustomDialog extends Dialog { diff --git a/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java b/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java index 118d34a..f09c132 100644 --- a/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java +++ b/app/src/main/java/com/sw/dualscreen/view/CustomImageView.java @@ -18,6 +18,9 @@ import com.sw.plate.utils.AppUtil; import timber.log.Timber; +/** + * 自定义柱状图 + */ public class CustomImageView extends androidx.appcompat.widget.AppCompatImageView { private AlphaAnimation alphaAnimation; private String textToDraw; diff --git a/app/src/main/java/com/sw/dualscreen/view/CustomSpinner.kt b/app/src/main/java/com/sw/dualscreen/view/CustomSpinner.kt index dc1cacf..c1d1464 100644 --- a/app/src/main/java/com/sw/dualscreen/view/CustomSpinner.kt +++ b/app/src/main/java/com/sw/dualscreen/view/CustomSpinner.kt @@ -15,6 +15,9 @@ import androidx.appcompat.widget.AppCompatSpinner import androidx.core.content.ContextCompat import com.sw.dualscreen.R +/** + * spinner控件 + */ class CustomSpinner @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, diff --git a/app/src/main/java/com/sw/dualscreen/view/CylinderDrawView.kt b/app/src/main/java/com/sw/dualscreen/view/CylinderDrawView.kt deleted file mode 100644 index 58ffa12..0000000 --- a/app/src/main/java/com/sw/dualscreen/view/CylinderDrawView.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.sw.dualscreen.view - -import android.content.Context -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.util.AttributeSet -import android.view.View - -class CylinderDrawView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : View(context, attrs, defStyleAttr) { - - // 圆柱属性(默认红色) - var cylinderColor: Int = Color.RED - set(value) { - field = value - invalidate() - } - var cylinderWidth: Int = 120 // 默认宽度(px) - set(value) { - field = value - requestLayout() - } - var cylinderHeight: Int = 360 // 默认高度(px) - set(value) { - field = value - requestLayout() - } - - private val paint = Paint().apply { - isAntiAlias = true // 抗锯齿 - style = Paint.Style.FILL // 填充模式 - } - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - val measuredWidth = resolveSize(cylinderWidth, widthMeasureSpec) - val measuredHeight = resolveSize(cylinderHeight, heightMeasureSpec) - setMeasuredDimension(measuredWidth, measuredHeight) - } - - override fun onDraw(canvas: Canvas) { - super.onDraw(canvas) - paint.color = cylinderColor - // 绘制圆角矩形(半径=宽度的一半,形成圆柱效果) - val radius = cylinderWidth / 2f - canvas.drawRoundRect( - 0f, 0f, - cylinderWidth.toFloat(), cylinderHeight.toFloat(), - radius, radius, - paint - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/view/CylinderView.kt b/app/src/main/java/com/sw/dualscreen/view/CylinderView.kt deleted file mode 100644 index 5bddde2..0000000 --- a/app/src/main/java/com/sw/dualscreen/view/CylinderView.kt +++ /dev/null @@ -1,104 +0,0 @@ -package com.sw.dualscreen.view - -import android.content.Context -import android.graphics.Color -import android.util.AttributeSet -import android.view.LayoutInflater -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.TextView -import com.sw.dualscreen.R - -class CylinderView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : FrameLayout(context, attrs, defStyleAttr) { - - private val valueText: TextView - private val unitText: TextView - private val cylinderDrawView: CylinderDrawView - private val topImage: ImageView - private val bottomImage: ImageView - private val bottomText: TextView - - init { - // 加载内部布局 - LayoutInflater.from(context).inflate(R.layout.view_cylinder, this, true) - - // 绑定控件 - valueText = findViewById(R.id.valueText) - unitText = findViewById(R.id.unitText) - cylinderDrawView = findViewById(R.id.cylinderDrawView) - topImage = findViewById(R.id.topImage) - bottomImage = findViewById(R.id.bottomImage) - bottomText = findViewById(R.id.bottomText) - - // 解析自定义属性 - context.obtainStyledAttributes(attrs, R.styleable.CylinderView).apply { - // 顶部文字:数值+单位合并 - val value = getString(R.styleable.CylinderView_valueText) ?: "" - val unit = getString(R.styleable.CylinderView_unitText) ?: "" - valueText.text = value - valueText.textSize = getDimension(R.styleable.CylinderView_valueTextSize, 20f) - valueText.setTextColor( - getColor( - R.styleable.CylinderView_valueTextColor, - 0xFFFFFFFF.toInt() - ) - ) - - unitText.text = unit - unitText.textSize = getDimension(R.styleable.CylinderView_valueTextSize, 10f) - unitText.setTextColor( - getColor( - R.styleable.CylinderView_valueTextColor, - 0xFFFFFFFF.toInt() - ) - ) - - // 圆柱属性 - cylinderDrawView.cylinderColor = - getColor(R.styleable.CylinderView_cylinderColor, Color.RED) - cylinderDrawView.cylinderWidth = - getDimensionPixelSize(R.styleable.CylinderView_cylinderWidth, 60) - cylinderDrawView.cylinderHeight = - getDimensionPixelSize(R.styleable.CylinderView_cylinderHeight, 180) - - getResourceId(R.styleable.CylinderView_topImageSrc, -1).takeIf { it != -1 }?.let { - topImage.setImageResource(it) -// val layoutParams = cylinderDrawView.layoutParams -// layoutParams.height = (layoutParams.width / 2.45).toInt() -// topImage.layoutParams = layoutParams - } - - // 底部图片 - getResourceId(R.styleable.CylinderView_bottomImageSrc, -1).takeIf { it != -1 }?.let { - bottomImage.setImageResource(it) -// val layoutParams = cylinderDrawView.layoutParams -// layoutParams.height = 44 -// bottomImage.layoutParams = layoutParams - } - - // 底部文字 - bottomText.text = getString(R.styleable.CylinderView_bottomText) ?: "热量" - bottomText.textSize = getDimension(R.styleable.CylinderView_bottomTextSize, 16f) - bottomText.setTextColor( - getColor( - R.styleable.CylinderView_bottomTextColor, - 0xFFFFFFFF.toInt() - ) - ) - - recycle() // 回收属性 - } - } - - fun setToImageSize() { -// topImage.layoutParams = LayoutParams. - } - - fun setBottomSize() { - - } -} \ 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 9250309..587e08d 100644 --- a/app/src/main/java/com/sw/dualscreen/viewmodel/DeviceViewModel.kt +++ b/app/src/main/java/com/sw/dualscreen/viewmodel/DeviceViewModel.kt @@ -4,7 +4,7 @@ import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.model.response.EquipmentInfo import com.sw.dualscreen.utils.GsonUtils -import com.sw.inbound.utils.SPUtil +import com.sw.dualscreen.utils.SPUtil import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import timber.log.Timber 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 c228bbf..212eebb 100644 --- a/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt +++ b/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt @@ -9,7 +9,7 @@ import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.UserFaceModel import com.sw.dualscreen.model.response.UserNutritionData -import com.sw.inbound.utils.SPUtil +import com.sw.dualscreen.utils.SPUtil import com.sw.plate.App import com.sw.plate.utils.Base64 import com.sw.plate.utils.ToastUtils diff --git a/app/src/main/res/layout/view_cylinder.xml b/app/src/main/res/layout/view_cylinder.xml deleted file mode 100644 index 058baec..0000000 --- a/app/src/main/res/layout/view_cylinder.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file