设备联调优化

This commit is contained in:
马增飞
2025-11-06 19:29:18 +08:00
parent a355828bab
commit 647ec0dcb7
22 changed files with 488 additions and 174 deletions
@@ -9,6 +9,7 @@ import android.os.Looper
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
import android.util.SparseArray import android.util.SparseArray
import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -19,7 +20,9 @@ import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.shuwei.intelligent.shelves.adapter.ShelfAdapter import com.shuwei.intelligent.shelves.adapter.ShelfAdapter
import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.base.BaseActivity
import com.shuwei.intelligent.shelves.databinding.ActivityHomeBinding import com.shuwei.intelligent.shelves.databinding.ActivityHomeBinding
import com.shuwei.intelligent.shelves.model.ClearShelfEvent
import com.shuwei.intelligent.shelves.model.SendWeightEvent import com.shuwei.intelligent.shelves.model.SendWeightEvent
import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.model.ShelfModel import com.shuwei.intelligent.shelves.model.ShelfModel
import com.shuwei.intelligent.shelves.model.ShelfResult import com.shuwei.intelligent.shelves.model.ShelfResult
import com.shuwei.intelligent.shelves.model.WeightEvent import com.shuwei.intelligent.shelves.model.WeightEvent
@@ -27,16 +30,21 @@ import com.shuwei.intelligent.shelves.net.Loading
import com.shuwei.intelligent.shelves.net.NetViewModel import com.shuwei.intelligent.shelves.net.NetViewModel
import com.shuwei.intelligent.shelves.net.RespData import com.shuwei.intelligent.shelves.net.RespData
import com.shuwei.intelligent.shelves.net.UiState import com.shuwei.intelligent.shelves.net.UiState
import com.shuwei.intelligent.shelves.net.apiService
import com.shuwei.intelligent.shelves.serial.SerialPortManager import com.shuwei.intelligent.shelves.serial.SerialPortManager
import com.shuwei.intelligent.shelves.task.SyncTask
import com.shuwei.intelligent.shelves.task.TaskManager import com.shuwei.intelligent.shelves.task.TaskManager
import com.shuwei.intelligent.shelves.utils.binaryToHex import com.shuwei.intelligent.shelves.utils.binaryToHex
import com.shuwei.intelligent.shelves.utils.ext.gone import com.shuwei.intelligent.shelves.utils.ext.gone
import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import com.shuwei.intelligent.shelves.utils.ext.toast import com.shuwei.intelligent.shelves.utils.ext.toast
import com.shuwei.intelligent.shelves.utils.ext.visible import com.shuwei.intelligent.shelves.utils.ext.visible
import com.shuwei.intelligent.shelves.utils.f2C import com.shuwei.intelligent.shelves.utils.f2C
import com.shuwei.intelligent.shelves.utils.hexToBinary import com.shuwei.intelligent.shelves.utils.hexToBinary
import com.shuwei.intelligent.shelves.utils.hexToDec import com.shuwei.intelligent.shelves.utils.hexToDec
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
@@ -56,8 +64,8 @@ class HomeActivity : BaseActivity() {
//协议尾 //协议尾
const val FOOTER = "FFFF" const val FOOTER = "FFFF"
const val ACTIVE_CMD = // const val ACTIVE_CMD =
"${HEADER}000281C5D70A7D428A4FA67B50F7DACA241938938B4B9CBD73673E9C8E7F2E15062D${FOOTER}" // "${HEADER}000281C5D70A7D428A4FA67B50F7DACA241938938B4B9CBD73673E9C8E7F2E15062D${FOOTER}"
const val LEFT_SHELF_OPEN_CMD = const val LEFT_SHELF_OPEN_CMD =
"${HEADER}020101000000000000000000000000000000000000${FOOTER}" "${HEADER}020101000000000000000000000000000000000000${FOOTER}"
@@ -68,12 +76,27 @@ class HomeActivity : BaseActivity() {
const val DEVICE_INFO_CMD = "${HEADER}0301000000000000000000000000${FOOTER}" const val DEVICE_INFO_CMD = "${HEADER}0301000000000000000000000000${FOOTER}"
const val ACTIVE_CMD =
"${HEADER}000281C5D70A7D428948AD7254FADBB1516738938B4B9CBD73673E9D8E7F2E15062D${FOOTER}"
//开灯(开 继电器1
const val LIGHT_CLOSE = "${HEADER}020102020102020000000000000000000000000000${FOOTER}"
const val LIGHT_OPEN = "${HEADER}020102020002020000000000000000000000000000${FOOTER}"
// const val LIGHT_CLOSE = "${HEADER}020102020101010000000000000000000000000000${FOOTER}"
// const val LIGHT_OPEN = "${HEADER}020102020000000000000000000000000000000000${FOOTER}"
// const val LIGHT_CLOSE2 = "${HEADER}020102020102020000000000000000000000000000${FOOTER}"
// const val LIGHT_OPEN2 = "${HEADER}020102020002020000000000000000000000000000${FOOTER}"
// const val LIGHT_CLOSE3 = "${HEADER}020102020102020000000000000000000000000000${FOOTER}"
// const val LIGHT_OPEN3 = "${HEADER}020102020002020000000000000000000000000000${FOOTER}"
val list: MutableList<ShelfModel> = mutableListOf() val list: MutableList<ShelfModel> = mutableListOf()
val weightArray = SparseArray<Double?>() val weightArray = SparseArray<Double?>()
var shelfIndex = 0 var shelfIndex = 0
// public fun getRealWeight():Double = weightArray[shelfIndex]?:0.0
// public fun getRealWeight():Double = weightArray[shelfIndex]?:0.0
// 温度 // 温度
var showTemperatureC = "0" var showTemperatureC = "0"
// 湿度 // 湿度
var showHumidity = "0" var showHumidity = "0"
} }
@@ -146,7 +169,9 @@ class HomeActivity : BaseActivity() {
// Log.d(TAG, "onCreate: swDpValue=$swDpValue") // Log.d(TAG, "onCreate: swDpValue=$swDpValue")
viewModel.getAccessToken(App.deviceId) // viewModel.getAccessToken(App.deviceId)
viewModel.getShelfList(deviceId = App.deviceId)
// repeat(100) { // repeat(100) {
// lifecycleScope.launch { // lifecycleScope.launch {
@@ -178,11 +203,32 @@ class HomeActivity : BaseActivity() {
// delay(500) // delay(500)
// } // }
// } // }
lightSwitchClick()
}
fun switchLight(isOpen: Boolean) {
val tag = getLeftView().tag?.toString()?.toBoolean() ?: true
if(tag == isOpen) {
return
}
lifecycleScope.launch {
SerialPortManager.send(if (isOpen) LIGHT_OPEN else LIGHT_CLOSE)
}
getLeftView().tag = isOpen
}
private fun lightSwitchClick() {
switchLight(true)
addLeftClick {
val tag = getLeftView().tag?.toString()?.toBoolean() ?: true
switchLight(tag.not())
}
} }
private fun getTokenSuccess(data: RespData<*>) { private fun getTokenSuccess(data: RespData<*>) {
Log.d(TAG, "getTokenSuccess: $data") Log.d(TAG, "getTokenSuccess: $data")
data.result?.let { data.data?.let {
App.accessToken = it.toString() App.accessToken = it.toString()
//UIUtils.toast(it.toString()) //UIUtils.toast(it.toString())
viewModel.getShelfList(deviceId = App.deviceId) viewModel.getShelfList(deviceId = App.deviceId)
@@ -196,25 +242,25 @@ class HomeActivity : BaseActivity() {
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
private fun updateUI(data: RespData<*>) { private fun updateUI(data: RespData<*>) {
binding.include?.root?.gone() binding.include?.root?.gone()
window?.decorView?.postDelayed({Loading.dismiss()},500) window?.decorView?.postDelayed({ Loading.dismiss() }, 500)
if (data.result !is ShelfResult) { if (data.data !is ShelfResult) {
loadEmptyView() loadEmptyView()
return return
} }
App.canteenId = data.result.canteenId App.canteenId = data.data.placeId
val tempList = data.result.containerGoodsList val tempList = data.data.containerGoodsList
if (tempList.isNullOrEmpty()) { if (tempList.isNullOrEmpty()) {
loadEmptyView() loadEmptyView()
return return
} }
if (tempList.size < 10) { // if (tempList.size < 10) {
toast("数据错误") // toast("数据错误")
return // return
} // }
list.clear() list.clear()
val subList01 = tempList.subList(0, 5) val subList01 = tempList.subList(0, tempList.size / 2)
val subList02 = tempList.subList(5, 10) val subList02 = tempList.subList(tempList.size / 2, tempList.size)
repeat(5) { index -> repeat(tempList.size / 2) { index ->
list.add(subList01[index].also { it.deviceId = App.deviceId }) list.add(subList01[index].also { it.deviceId = App.deviceId })
list.add(subList02[index].also { it.deviceId = App.deviceId }) list.add(subList02[index].also { it.deviceId = App.deviceId })
} }
@@ -253,6 +299,10 @@ class HomeActivity : BaseActivity() {
val cmd = data.substring(HEADER.length, HEADER.length + 4) val cmd = data.substring(HEADER.length, HEADER.length + 4)
when (cmd) { when (cmd) {
"0001" -> {
}
"0101" -> { "0101" -> {
//心跳-01 //心跳-01
Log.d(TAG, "receiveSerialPortData:心跳01: $data") Log.d(TAG, "receiveSerialPortData:心跳01: $data")
@@ -263,10 +313,11 @@ class HomeActivity : BaseActivity() {
// Log.d(TAG, "receiveSerialPortData:心跳08: $data") // Log.d(TAG, "receiveSerialPortData:心跳08: $data")
// heartBeat(data) // heartBeat(data)
// } // }
"0202" -> { // "0202" -> {
//开关锁反馈 // //开关锁反馈
lockFeedback(data) // lockFeedback(data)
} // }
"0302" -> { "0302" -> {
//获取设备状态 //获取设备状态
getDeviceInfo(data) getDeviceInfo(data)
@@ -325,7 +376,7 @@ class HomeActivity : BaseActivity() {
val percent = 10 * list.count { it.goodsName.isNullOrBlank().not() } val percent = 10 * list.count { it.goodsName.isNullOrBlank().not() }
updateLeftStatus("1-1冷藏柜 ${showTemperatureC}°C / ${percent}%") updateLeftStatus("1-1冷藏柜 [$temperatureHex] ${showTemperatureC}°C / ${percent}%")
}.onFailure { }.onFailure {
it.printStackTrace() it.printStackTrace()
} }
@@ -413,15 +464,15 @@ class HomeActivity : BaseActivity() {
setOnDebouncedItemClick { adapter, view, position -> setOnDebouncedItemClick { adapter, view, position ->
shelfIndex = position shelfIndex = position
lifecycleScope.launch { lifecycleScope.launch {
val openCmd = if (list[position].deviceNo in 1..5) // val openCmd = if (list[position].deviceNo in 1..5)
LEFT_SHELF_OPEN_CMD // LEFT_SHELF_OPEN_CMD
else // else
RIGHT_SHELF_OPEN_CMD // RIGHT_SHELF_OPEN_CMD
val openState = SerialPortManager.send(openCmd) // val openState = SerialPortManager.send(openCmd)
if (openState.not()) { // if (openState.not()) {
toast("${list[position].goodsName}柜门开启失败") // toast("${list[position].goodsName}柜门开启失败")
return@launch // return@launch
} // }
launch(Intent(this@HomeActivity, ShelfActivity::class.java).also { launch(Intent(this@HomeActivity, ShelfActivity::class.java).also {
it.putExtra(ShelfActivity.SHELF_MODEL, list[position]) it.putExtra(ShelfActivity.SHELF_MODEL, list[position])
}) { }) {
@@ -437,6 +488,25 @@ class HomeActivity : BaseActivity() {
} }
} }
notifyItemChanged(position) notifyItemChanged(position)
try {
val submitList = list.sortedBy { it.deviceNo }
val body = ShelfBody().also {
it.deviceId = App.deviceId ?: ""
it.canteenId = App.canteenId
it.temperature = showTemperatureC
it.humidity = showHumidity
it.goodsList = submitList
}
Log.d("mzf", "performSync: body:${body.toJsonString()}")
lifecycleScope.launch {
val resp = apiService.saveShelfGoodsList(body = body)
Log.d("mzf", "performSync: resp:${resp.toJsonString()}")
}
} catch (e: Exception) {
e.printStackTrace()
}
} }
} }
} }
@@ -502,4 +572,17 @@ class HomeActivity : BaseActivity() {
public fun weightEvent(event: WeightEvent) { public fun weightEvent(event: WeightEvent) {
} }
@Subscribe(threadMode = ThreadMode.MAIN)
public fun clearEmptyShelf(event: ClearShelfEvent) {
val item = list.firstOrNull { it.deviceNo == event.shelfNo }
item?.apply {
goodsId = ""
goodsName = null
weight = null
createTime = null
overdueDay = null
}
shelfAdapter.notifyItemChanged(list.indexOf(item))
}
} }
@@ -51,11 +51,9 @@ class InitActivity : BaseActivity() {
binding = ActivityInitBinding.inflate(layoutInflater) binding = ActivityInitBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
// 获取 ANDROID_ID
val androidId = App.deviceId = AppUtil.getUDID( this)
Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) SpTool.put(SpTool.DEVICE_ID, App.deviceId)
App.deviceId = androidId
SpTool.put(SpTool.DEVICE_ID, androidId)
App.configUrl = UrlConfig.BASE_URL App.configUrl = UrlConfig.BASE_URL
App.canteenId = "0" App.canteenId = "0"
@@ -115,7 +113,7 @@ class InitActivity : BaseActivity() {
when (state) { when (state) {
is UiState.Loading -> {} is UiState.Loading -> {}
is UiState.Success<*> -> { is UiState.Success<*> -> {
state.data.result?.let { deviceToken -> state.data.data?.let { deviceToken ->
Log.d(TAG, "initConfig: $deviceToken") Log.d(TAG, "initConfig: $deviceToken")
viewModel.getDeviceConfig( viewModel.getDeviceConfig(
deviceId = App.deviceId, deviceId = App.deviceId,
@@ -133,7 +131,7 @@ class InitActivity : BaseActivity() {
when (state) { when (state) {
is UiState.Loading -> {} is UiState.Loading -> {}
is UiState.Success<*> -> { is UiState.Success<*> -> {
state.data.result?.let { state.data.data?.let {
if (it is DeviceConfigInfo) { if (it is DeviceConfigInfo) {
SpTool.put(SpTool.DEVICE_CONFIG_CACHE, it.toJsonString()) SpTool.put(SpTool.DEVICE_CONFIG_CACHE, it.toJsonString())
App.configUrl = it.appPackageUrl?:"" App.configUrl = it.appPackageUrl?:""
@@ -20,6 +20,7 @@ import com.shuwei.intelligent.shelves.HomeActivity.Companion.DEVICE_INFO_CMD
import com.shuwei.intelligent.shelves.adapter.SearchAdapter import com.shuwei.intelligent.shelves.adapter.SearchAdapter
import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.base.BaseActivity
import com.shuwei.intelligent.shelves.databinding.ActivityShelfBinding import com.shuwei.intelligent.shelves.databinding.ActivityShelfBinding
import com.shuwei.intelligent.shelves.model.ClearShelfEvent
import com.shuwei.intelligent.shelves.model.GoodsModel import com.shuwei.intelligent.shelves.model.GoodsModel
import com.shuwei.intelligent.shelves.model.GoodsRecord import com.shuwei.intelligent.shelves.model.GoodsRecord
import com.shuwei.intelligent.shelves.model.SendWeightEvent import com.shuwei.intelligent.shelves.model.SendWeightEvent
@@ -135,27 +136,17 @@ class ShelfActivity : BaseActivity() {
finish() finish()
} }
binding.root.setOnClickListener { v -> binding.root.setOnClickListener { v ->
KeyboardUtil.hideKeyboard(v.context, v) KeyboardUtil.hideKeyboard(v)
} }
binding.btnClearZero.setOnClickListener { v -> binding.btnClearZero.setOnClickListener {
lifecycleScope.launch { clearZero()
val shelfNo = shelfModel?.deviceNo ?: 0
val hex = shelfNo.toString(16).padStart(2, '0').uppercase()
Log.d(TAG, "onCreate: hex=$hex")
val zeroClearingCmd = "${HomeActivity.HEADER}0401${hex}${HomeActivity.FOOTER}"
Log.d(TAG, "onCreate: zeroClearingCmd=$zeroClearingCmd")
SerialPortManager.send(zeroClearingCmd)
//清零
realWeight = 0
// binding.tvFoodWeight.text = "${realWeight}克"
SerialPortManager.send(DEVICE_INFO_CMD)
Loading.show(this@ShelfActivity)
v.postDelayed({ Loading.dismiss() }, 5000)
} }
KeyboardUtil.hideKeyboard(v.context, v) binding.btnClearEmpty?.setOnClickListener {
clearZero()
binding.tvFoodName.text = "-"
binding.tvFoodWeight.text = "0克"
EventBus.getDefault().post(ClearShelfEvent(shelfModel!!.deviceNo))
} }
lifecycleScope.launch { lifecycleScope.launch {
SerialPortManager.send(DEVICE_INFO_CMD) SerialPortManager.send(DEVICE_INFO_CMD)
@@ -219,45 +210,44 @@ class ShelfActivity : BaseActivity() {
finishRefresh() finishRefresh()
binding.root.postDelayed({ Loading.dismiss() }, 200) binding.root.postDelayed({ Loading.dismiss() }, 200)
Log.d(TAG, "updateUI: ${data.toJsonString()}") Log.d(TAG, "updateUI: ${data.toJsonString()}")
if (data.result !is GoodsRecord) {
val goodsList = data.data as MutableList<GoodsModel>
if (data.data.isNullOrEmpty()) {
if (pageNo == 1) { if (pageNo == 1) {
loadEmptyView() loadEmptyView()
} }
return return
} }
if (data.result.records.isNullOrEmpty()) { if(pageNo == 1){
if (pageNo == 1) {
loadEmptyView()
}
return
}
var firstOne:GoodsModel?=null
if (pageNo == 1) {
if (shelfModel?.goodsId.isNullOrBlank().not()) {
firstOne = list.firstOrNull { it.goodsId == shelfModel?.goodsId }
if (firstOne == null) {
firstOne = GoodsModel(
goodsId = shelfModel?.goodsId,
goodsName = shelfModel?.goodsName,
isClicked = true
)
}
}
list.clear() list.clear()
} }
val records = data.result.records // var firstOne:GoodsModel?=null
if (pageNo == 1) { // if (pageNo == 1) {
firstOne?.let { one -> // if (shelfModel?.goodsId.isNullOrBlank().not()) {
val filterResult = records.firstOrNull{one.goodsId == it.goodsId } // firstOne = list.firstOrNull { it.goodsId == shelfModel?.goodsId }
if (filterResult != null) { // if (firstOne == null) {
records.remove(filterResult) // firstOne = GoodsModel(
} // goodsId = shelfModel?.goodsId,
clickIndex = 0 // goodsName = shelfModel?.goodsName,
list.add(one) // isClicked = true
} // )
} // }
list.addAll(records) // }
val enableLoadMore = records.size >= PAGE_SIZE // list.clear()
// }
// val records = data.data.records
// if (pageNo == 1) {
// firstOne?.let { one ->
// val filterResult = records.firstOrNull{one.goodsId == it.goodsId }
// if (filterResult != null) {
// records.remove(filterResult)
// }
// clickIndex = 0
// list.add(one)
// }
// }
list.addAll(goodsList)
val enableLoadMore = goodsList.size >= PAGE_SIZE
binding.refreshLayout.setEnableLoadMore(enableLoadMore) binding.refreshLayout.setEnableLoadMore(enableLoadMore)
if (enableLoadMore) { if (enableLoadMore) {
pageNo++ pageNo++
@@ -371,4 +361,23 @@ class ShelfActivity : BaseActivity() {
} }
} }
private fun clearZero() {
lifecycleScope.launch {
val shelfNo = shelfModel?.deviceNo ?: 0
val hex = shelfNo.toString(16).padStart(2, '0').uppercase()
Log.d(TAG, "onCreate: hex=$hex")
val zeroClearingCmd = "${HomeActivity.HEADER}0401${hex}${HomeActivity.FOOTER}"
Log.d(TAG, "onCreate: zeroClearingCmd=$zeroClearingCmd")
SerialPortManager.send(zeroClearingCmd)
//清零
realWeight = 0
// binding.tvFoodWeight.text = "${realWeight}克"
SerialPortManager.send(DEVICE_INFO_CMD)
Loading.show(this@ShelfActivity)
window.decorView.postDelayed({ Loading.dismiss() }, 5000)
}
KeyboardUtil.hideKeyboard(window.decorView)
}
} }
@@ -14,6 +14,7 @@ import com.shuwei.intelligent.shelves.utils.DateTimeUtil
import com.shuwei.intelligent.shelves.utils.ext.gone import com.shuwei.intelligent.shelves.utils.ext.gone
import com.shuwei.intelligent.shelves.utils.ext.visible import com.shuwei.intelligent.shelves.utils.ext.visible
import java.util.Date import java.util.Date
import kotlin.math.roundToInt
class ShelfAdapter(list: MutableList<ShelfModel>) : class ShelfAdapter(list: MutableList<ShelfModel>) :
BaseQuickAdapter<ShelfModel, ShelfAdapter.VH>(list) { BaseQuickAdapter<ShelfModel, ShelfAdapter.VH>(list) {
@@ -61,8 +62,8 @@ class ShelfAdapter(list: MutableList<ShelfModel>) :
//?.setImageResource() //?.setImageResource()
binding.tvFoodWeight.run { binding.tvFoodWeight.run {
setTextColor(getColor(R.color.food_weight_orange)) setTextColor(getColor(R.color.food_weight_orange))
val showWeight = if (weight == 0.toDouble()) "0" else "%.3f".format(weight) //val showWeight = if (weight == 0.toDouble()) "0克" else "%.3f千克".format(weight)
text = "${showWeight}" text = "${(weight*1000).roundToInt()}"
} }
//val isBlankShelf = weight <= 0 //val isBlankShelf = weight <= 0
val isBlankShelf = item.goodsName.isNullOrBlank() val isBlankShelf = item.goodsName.isNullOrBlank()
@@ -3,17 +3,19 @@ package com.shuwei.intelligent.shelves.base
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View import android.view.View
import android.view.WindowInsets import android.view.WindowInsets
import android.view.WindowInsetsController import android.view.WindowInsetsController
import android.widget.TextView import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.gyf.immersionbar.BarHide import com.gyf.immersionbar.BarHide
import com.gyf.immersionbar.ImmersionBar import com.gyf.immersionbar.ImmersionBar
import com.shuwei.intelligent.shelves.HomeActivity
import com.shuwei.intelligent.shelves.R import com.shuwei.intelligent.shelves.R
import com.shuwei.intelligent.shelves.databinding.ActivityBaseBinding import com.shuwei.intelligent.shelves.databinding.ActivityBaseBinding
@@ -91,5 +93,53 @@ open class BaseActivity : AppCompatActivity() {
binding.tvRightStatus.text = data binding.tvRightStatus.text = data
} }
fun addViewClick(view:View, click: () -> Unit) {
view.setOnClickListener {
click()
}
}
fun getLeftView(): TextView {
return binding.tvLeftStatus
}
fun addLeftClick(click: (View) -> Unit) {
binding.tvLeftStatus.setOnClickListener(click)
}
fun addRightClick(click: (View) -> Unit) {
binding.tvRightStatus.setOnClickListener(click)
}
// 5分钟
private val TIME_OUT: Long = (5 * 60 * 1000).toLong()
private val mHandler by lazy { Handler(Looper.getMainLooper()) }
private val mTimeoutRunnable = Runnable {
if (this is HomeActivity) {
this.switchLight(false)
}
}
override fun onUserInteraction() {
super.onUserInteraction()
// 重置定时器
mHandler.removeCallbacks(mTimeoutRunnable)
mHandler.postDelayed(mTimeoutRunnable, TIME_OUT)
}
override fun onResume() {
super.onResume()
// 启动定时器
mHandler.postDelayed(mTimeoutRunnable, TIME_OUT)
}
override fun onPause() {
super.onPause()
// 取消定时器
mHandler.removeCallbacks(mTimeoutRunnable)
}
fun timeOutOperation() {
}
} }
@@ -6,3 +6,5 @@ data class SendWeightEvent(
) )
data class WeightEvent(var weight: Int) data class WeightEvent(var weight: Int)
data class ClearShelfEvent(var shelfNo: Int)
@@ -1,7 +1,7 @@
package com.shuwei.intelligent.shelves.model package com.shuwei.intelligent.shelves.model
data class ShelfResult( data class ShelfResult(
val canteenId: String = "", val placeId: String = "",
val canteenName: String = "", val canteenName: String = "",
val containerGoodsList: List<ShelfModel>? = null val containerGoodsList: List<ShelfModel>? = null
) )
@@ -2,6 +2,7 @@ package com.shuwei.intelligent.shelves.net
import com.shuwei.intelligent.shelves.App import com.shuwei.intelligent.shelves.App
import com.shuwei.intelligent.shelves.model.DeviceConfigInfo import com.shuwei.intelligent.shelves.model.DeviceConfigInfo
import com.shuwei.intelligent.shelves.model.GoodsModel
import com.shuwei.intelligent.shelves.model.GoodsRecord import com.shuwei.intelligent.shelves.model.GoodsRecord
import com.shuwei.intelligent.shelves.model.ShelfBody import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.model.ShelfResult import com.shuwei.intelligent.shelves.model.ShelfResult
@@ -43,7 +44,8 @@ interface ApiService {
suspend fun getShelfList( suspend fun getShelfList(
@Url url: String = UrlConfig.GET_SHELF_LIST, @Url url: String = UrlConfig.GET_SHELF_LIST,
@Query("deviceId") deviceId: String, @Query("deviceId") deviceId: String,
@Query("x-access-token") token: String = App.accessToken @Query("x-access-token") token: String = App.accessToken,
@Header("authorization") authorization: String = "57ee87183f2a4fa59683ec9ef41c8f5d"
): RespData<ShelfResult> ): RespData<ShelfResult>
@GET @GET
@@ -53,14 +55,16 @@ interface ApiService {
@Query("goodsName") goodsName: String? = null, @Query("goodsName") goodsName: String? = null,
@Query("pageNo") pageNo: Int = 1, @Query("pageNo") pageNo: Int = 1,
@Query("pageSize") pageSize: Int = 50, @Query("pageSize") pageSize: Int = 50,
@Query("x-access-token") token: String = App.accessToken @Query("x-access-token") token: String = App.accessToken,
): RespData<GoodsRecord> @Header("authorization") authorization: String = "57ee87183f2a4fa59683ec9ef41c8f5d"
): RespData<MutableList<GoodsModel>?>
@POST @POST
suspend fun saveShelfGoodsList( suspend fun saveShelfGoodsList(
@Url url: String = UrlConfig.SAVE_SHELF_GOODS_LIST, @Url url: String = UrlConfig.SAVE_SHELF_GOODS_LIST,
@Body body: ShelfBody, @Body body: ShelfBody,
@Query("x-access-token") token: String = App.accessToken @Query("x-access-token") token: String = App.accessToken,
@Header("authorization") authorization: String = "57ee87183f2a4fa59683ec9ef41c8f5d"
): RespData<Any?> ): RespData<Any?>
} }
@@ -44,10 +44,10 @@ class NetViewModel : ViewModel() {
_getDeviceTokenUiState.value = UiState.Loading _getDeviceTokenUiState.value = UiState.Loading
runCatching { runCatching {
val response = apiService.getDeviceToken(qrcodeId = deviceId) val response = apiService.getDeviceToken(qrcodeId = deviceId)
if (response.success) { if (response.code == 0) {
_getDeviceTokenUiState.value = UiState.Success(response) _getDeviceTokenUiState.value = UiState.Success(response)
} else { } else {
_getDeviceTokenUiState.value = UiState.Error(response.message ?: "请求失败") _getDeviceTokenUiState.value = UiState.Error(response.msg ?: "请求失败")
} }
}.onFailure { }.onFailure {
_getDeviceTokenUiState.value = UiState.Error(it.message ?: "请求异常") _getDeviceTokenUiState.value = UiState.Error(it.message ?: "请求异常")
@@ -59,11 +59,12 @@ class NetViewModel : ViewModel() {
viewModelScope.launch { viewModelScope.launch {
_getDeviceTokenUiState.value = UiState.Loading _getDeviceTokenUiState.value = UiState.Loading
runCatching { runCatching {
val response = apiService.getDeviceInfo(equipmentCode = deviceId, token = deviceToken) val response =
if (response.success) { apiService.getDeviceInfo(equipmentCode = deviceId, token = deviceToken)
if (response.code == 0) {
_getDeviceTokenUiState.value = UiState.Success(response) _getDeviceTokenUiState.value = UiState.Success(response)
} else { } else {
_getDeviceTokenUiState.value = UiState.Error(response.message ?: "请求失败") _getDeviceTokenUiState.value = UiState.Error(response.msg ?: "请求失败")
} }
}.onFailure { }.onFailure {
_getDeviceTokenUiState.value = UiState.Error(it.message ?: "请求异常") _getDeviceTokenUiState.value = UiState.Error(it.message ?: "请求异常")
@@ -76,10 +77,10 @@ class NetViewModel : ViewModel() {
_getAccessTokenUiState.value = UiState.Loading _getAccessTokenUiState.value = UiState.Loading
runCatching { runCatching {
val response = apiService.getAccessToken(qrcodeId = deviceId) val response = apiService.getAccessToken(qrcodeId = deviceId)
if (response.success) { if (response.code == 0) {
_getAccessTokenUiState.value = UiState.Success(response) _getAccessTokenUiState.value = UiState.Success(response)
} else { } else {
_getAccessTokenUiState.value = UiState.Error(response.message ?: "请求失败") _getAccessTokenUiState.value = UiState.Error(response.msg ?: "请求失败")
} }
}.onFailure { }.onFailure {
_getAccessTokenUiState.value = UiState.Error(it.message ?: "请求异常") _getAccessTokenUiState.value = UiState.Error(it.message ?: "请求异常")
@@ -92,10 +93,10 @@ class NetViewModel : ViewModel() {
_getShelfListUiState.value = UiState.Loading _getShelfListUiState.value = UiState.Loading
runCatching { runCatching {
val response = apiService.getShelfList(deviceId = deviceId) val response = apiService.getShelfList(deviceId = deviceId)
if (response.success) { if (response.code == 0) {
_getShelfListUiState.value = UiState.Success(response) _getShelfListUiState.value = UiState.Success(response)
} else { } else {
_getShelfListUiState.value = UiState.Error(response.message ?: "请求失败") _getShelfListUiState.value = UiState.Error(response.msg ?: "请求失败")
} }
}.onFailure { }.onFailure {
_getShelfListUiState.value = UiState.Error(it.message ?: "请求异常") _getShelfListUiState.value = UiState.Error(it.message ?: "请求异常")
@@ -134,10 +135,10 @@ class NetViewModel : ViewModel() {
pageNo = pageNo, pageNo = pageNo,
pageSize = pageSize pageSize = pageSize
) )
if (response.success) { if (response.code == 0) {
_getGoodsListUiState.value = UiState.Success(response) _getGoodsListUiState.value = UiState.Success(response)
} else { } else {
_getGoodsListUiState.value = UiState.Error(response.message ?: "请求失败") _getGoodsListUiState.value = UiState.Error(response.msg ?: "请求失败")
} }
}.onFailure { }.onFailure {
_getGoodsListUiState.value = UiState.Error(it.message ?: "请求异常") _getGoodsListUiState.value = UiState.Error(it.message ?: "请求异常")
@@ -1,8 +1,9 @@
package com.shuwei.intelligent.shelves.net package com.shuwei.intelligent.shelves.net
data class RespData<T>( data class RespData<T>(
val success: Boolean = false, // val success: Boolean = false,
val message: String? = null, val msg: String? = null,
val code: Int = 0, val code: Int = 0,
val result: T? = null val data: T? = null,
val total: Int
) )
@@ -13,12 +13,17 @@ object UrlConfig {
// */ // */
// const val DEVICE_CONFIG = "${DEVICE_BASE_URL}/equipment/stEquipment/queryByEquipmentCode" // const val DEVICE_CONFIG = "${DEVICE_BASE_URL}/equipment/stEquipment/queryByEquipmentCode"
// const val BASE_URL = "http://192.168.1.3:9002" const val BASE_URL = "http://dev.yixiong-tech.com:8081"
const val BASE_URL = "https://yyjk.shuziweidao.com/gateway" // const val BASE_URL = "https://yyjk.shuziweidao.com/gateway"
// const val BASE_URL = "http://192.168.1.201:14801"
var GET_ACCESS_TOKEN = "${App.configUrl}/restaurant/equipment/stEquipment/getEquipmentToken" var GET_ACCESS_TOKEN = "${App.configUrl}/restaurant/equipment/stEquipment/getEquipmentToken"
var GET_SHELF_LIST = "${App.configUrl}/inventory/smartShelves/app/getShelvesListByDeviceId" var GET_SHELF_LIST =
var GET_GOODS_LIST = "${App.configUrl}/inventory/smartShelves/app/getGoodsPageList" "${App.configUrl}/terminal/neglect/smartShelves/app/smartShelves/app/getShelvesListByDeviceId"
var SAVE_SHELF_GOODS_LIST = "${App.configUrl}/inventory/smartShelves/app/saveShelvesGoodsList" var GET_GOODS_LIST =
"${App.configUrl}/terminal/neglect/smartShelves/app/smartShelves/app/getGoodsPageList"
var SAVE_SHELF_GOODS_LIST =
"${App.configUrl}/terminal/neglect/smartShelves/app/smartShelves/app/saveShelvesGoodsList"
} }
@@ -7,6 +7,7 @@ import io.github.jeadyx.jserialport.AndroidSerialPort
import io.github.jeadyx.jserialport.SerialPort import io.github.jeadyx.jserialport.SerialPort
import io.github.jeadyx.jserialport.SerialPortFactory import io.github.jeadyx.jserialport.SerialPortFactory
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collectLatest
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.Locale import java.util.Locale
@@ -53,10 +54,15 @@ object SerialPortManager {
fun startReceive(callback: (String) -> Unit) { fun startReceive(callback: (String) -> Unit) {
scope.launch { scope.launch {
while (isActive) { while (isActive) {
serialPort?.read()?.collect { buffer -> try {
val flow = serialPort?.read()
flow?.collect { buffer ->
val data = buffer.toHexString2().toUpperCase() val data = buffer.toHexString2().toUpperCase()
callback(data) callback(data)
} }
} catch (e: Exception) {
e.printStackTrace()
}
delay(50) delay(50)
} }
} }
@@ -38,10 +38,10 @@ class SyncTask(appContext: Context, workerParams: WorkerParameters) :
val list = HomeActivity.list val list = HomeActivity.list
Log.d(TAG, "performSync: list:${list.toJsonString()}") Log.d(TAG, "performSync: list:${list.toJsonString()}")
val submitList = list.sortedBy { it.deviceNo } val submitList = list.sortedBy { it.deviceNo }
submitList.forEach { // submitList.forEach {
it.temperature = HomeActivity.showTemperatureC // it.temperature = HomeActivity.showTemperatureC
it.humidity = HomeActivity.showHumidity // it.humidity = HomeActivity.showHumidity
} // }
val body = ShelfBody().also { val body = ShelfBody().also {
it.deviceId = App.deviceId ?: "" it.deviceId = App.deviceId ?: ""
it.canteenId = App.canteenId it.canteenId = App.canteenId
@@ -49,8 +49,8 @@ class SyncTask(appContext: Context, workerParams: WorkerParameters) :
it.humidity = HomeActivity.showHumidity it.humidity = HomeActivity.showHumidity
it.goodsList = submitList it.goodsList = submitList
} }
val resp = apiService.saveShelfGoodsList(body = body)
Log.d(TAG, "performSync: body:${body.toJsonString()}") Log.d(TAG, "performSync: body:${body.toJsonString()}")
val resp = apiService.saveShelfGoodsList(body = body)
Log.d(TAG, "performSync: resp:${resp.toJsonString()}") Log.d(TAG, "performSync: resp:${resp.toJsonString()}")
} }
} }
@@ -12,7 +12,7 @@ object TaskManager {
fun startTask() { fun startTask() {
val nextRequest = OneTimeWorkRequestBuilder<SyncTask>() val nextRequest = OneTimeWorkRequestBuilder<SyncTask>()
.setInitialDelay(3, TimeUnit.MINUTES) .setInitialDelay(2, TimeUnit.MINUTES)
// .setInitialDelay(30, TimeUnit.SECONDS) // .setInitialDelay(30, TimeUnit.SECONDS)
// .setInputData(inputData) // .setInputData(inputData)
.build() .build()
@@ -44,7 +44,7 @@ object TaskManager {
fun startDeviceTask() { fun startDeviceTask() {
val nextRequest = OneTimeWorkRequestBuilder<SyncDeviceTask>() val nextRequest = OneTimeWorkRequestBuilder<SyncDeviceTask>()
.setInitialDelay(3, TimeUnit.SECONDS) .setInitialDelay(2, TimeUnit.MINUTES)
.build() .build()
WorkManager.getInstance(App.getInstance()) WorkManager.getInstance(App.getInstance())
.enqueueUniqueWork(DEVICE_TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest) .enqueueUniqueWork(DEVICE_TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
@@ -406,46 +406,44 @@ public class AppUtil {
*/ */
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
public static String getUDID(Context context) { public static String getUDID(Context context) {
return "test111";
// String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); // String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
// L.e("androidID===" + androidID); // if (!androidID.equals("")) {
// try {
// if (!"9774d56d682e549c".equals(androidID)) {
// androidID = UUID.nameUUIDFromBytes(androidID.getBytes("utf8")).toString();
// } else {
// @SuppressLint("MissingPermission") final String deviceId = ((TelephonyManager) context.getSystemService(TELEPHONY_SERVICE)).getDeviceId();
// androidID = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")).toString() : UUID.randomUUID().toString();
// }
// } catch (UnsupportedEncodingException e) {
// throw new RuntimeException(e);
// }
// return androidID; // return androidID;
String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); // }
if (!androidID.equals("")) { //
try { // //需要权限 android.permission.READ_PHONE_STATE
if (!"9774d56d682e549c".equals(androidID)) { // TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
androidID = UUID.nameUUIDFromBytes(androidID.getBytes("utf8")).toString(); // String szImei = TelephonyMgr.getDeviceId();
} else { // if (!szImei.equals("")) {
@SuppressLint("MissingPermission") final String deviceId = ((TelephonyManager) context.getSystemService(TELEPHONY_SERVICE)).getDeviceId(); // return szImei;
androidID = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")).toString() : UUID.randomUUID().toString(); // }
} //
} catch (UnsupportedEncodingException e) { // //需要权限 android.permission.ACCESS_WIFI_STATE
throw new RuntimeException(e); // WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
} // String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
return androidID; // if (!m_szWLANMAC.equals("")) {
} // return m_szWLANMAC;
// }
//需要权限 android.permission.READ_PHONE_STATE //
TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); // //需要权限 android.permission.BLUETOOTH
String szImei = TelephonyMgr.getDeviceId(); // BluetoothAdapter m_BluetoothAdapter = null;
if (!szImei.equals("")) { // m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
return szImei; // String m_szBTMAC = m_BluetoothAdapter.getAddress();
} // if (!m_szBTMAC.equals("")) {
// return m_szBTMAC;
//需要权限 android.permission.ACCESS_WIFI_STATE // }
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); // return getUniquePsuedoID();
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
if (!m_szWLANMAC.equals("")) {
return m_szWLANMAC;
}
//需要权限 android.permission.BLUETOOTH
BluetoothAdapter m_BluetoothAdapter = null;
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();
if (!m_szBTMAC.equals("")) {
return m_szBTMAC;
}
return getUniquePsuedoID();
} }
//获得 Psuedo ID //获得 Psuedo ID
@@ -13,5 +13,9 @@ object KeyboardUtil {
view.clearFocus() // 清除焦点避免键盘再次弹出 view.clearFocus() // 清除焦点避免键盘再次弹出
} }
fun hideKeyboard(view: View) {
val imm = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
view.clearFocus() // 清除焦点避免键盘再次弹出
}
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

+10 -6
View File
@@ -11,29 +11,33 @@
<FrameLayout <FrameLayout
android:id="@+id/flStatusBar" android:id="@+id/flStatusBar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="30dp" android:layout_height="30dp">
android:paddingStart="12dp" <!-- android:paddingTop="9dp"-->
android:paddingEnd="12dp"
android:paddingTop="9dp">
<TextView <TextView
android:id="@+id/tv_left_status" android:id="@+id/tv_left_status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:gravity="center_vertical"
android:textColor="@color/white" android:textColor="@color/white"
android:layout_gravity="start" android:layout_gravity="start"
android:textSize="12sp" android:textSize="12sp"
android:paddingStart="12dp"
android:paddingEnd="0dp"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
tools:text="1-1冷藏柜 -2°C / 87%" /> tools:text="1-1冷藏柜 -2°C / 87%" />
<TextView <TextView
android:id="@+id/tv_right_status" android:id="@+id/tv_right_status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:gravity="center_vertical"
android:textColor="@color/white" android:textColor="@color/white"
android:layout_gravity="end" android:layout_gravity="end"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:textSize="12sp" android:textSize="12sp"
android:paddingStart="0dp"
android:paddingEnd="12dp"
tools:text="6月22日 星期日 15:26:33" /> tools:text="6月22日 星期日 15:26:33" />
</FrameLayout> </FrameLayout>
@@ -25,4 +25,11 @@
layout="@layout/layout_empty_view" layout="@layout/layout_empty_view"
android:visibility="gone"/> android:visibility="gone"/>
<!-- <include-->
<!-- android:id="@+id/includeLight"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- layout="@layout/layout_light_switch"-->
<!-- android:visibility="gone"/>-->
</FrameLayout> </FrameLayout>
+16 -1
View File
@@ -93,7 +93,7 @@
android:insetTop="0dp" android:insetTop="0dp"
android:insetBottom="0dp" android:insetBottom="0dp"
android:maxLines="1" android:maxLines="1"
android:text="清零" android:text="清零00"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp" android:textSize="15sp"
app:cornerRadius="6dp" app:cornerRadius="6dp"
@@ -110,6 +110,21 @@
android:src="@drawable/ic_back_512" android:src="@drawable/ic_back_512"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView
android:id="@+id/btnClearEmpty"
android:layout_width="65dp"
android:layout_height="30dp"
android:layout_gravity="bottom|end"
android:layout_marginBottom="22dp"
android:layout_marginEnd="12dp"
android:maxLines="1"
android:text="清空"
android:textStyle="bold"
android:gravity="center"
android:textColor="@color/food_name_black"
android:textSize="15sp"
tools:ignore="HardcodedText" />
</FrameLayout> </FrameLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#DDFFFFFF">
<ImageView
android:id="@+id/ivLightHide"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="end|center_vertical"
android:src="@drawable/close"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="继电器1"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/btnLightOpen"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="开"
android:gravity="center"
android:background="@drawable/bg_init_button"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/btnLightClose"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="关"
android:gravity="center"
android:background="@drawable/bg_init_button"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="继电器2"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/btnLightOpen2"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="开"
android:gravity="center"
android:background="@drawable/bg_init_button"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/btnLightClose2"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="关"
android:gravity="center"
android:background="@drawable/bg_init_button"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="继电器3"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/btnLightOpen3"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="开"
android:gravity="center"
android:background="@drawable/bg_init_button"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/btnLightClose3"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="关"
android:gravity="center"
android:background="@drawable/bg_init_button"
android:layout_marginStart="50dp"
android:textColor="@color/black"/>
</LinearLayout>
</LinearLayout>