Przeglądaj źródła

优化部分蓝牙设备读取作业票太快导致作业票异常的问题

bjb 1 miesiąc temu
rodzic
commit
0f3693a172

+ 1 - 0
.idea/gradle.xml

@@ -16,5 +16,6 @@
         </option>
       </GradleProjectSettings>
     </option>
+    <option name="parallelModelFetch" value="true" />
   </component>
 </project>

+ 70 - 47
app/src/main/java/com/iscs/comm/MainActivity.kt

@@ -1,10 +1,13 @@
 package com.iscs.comm
 
+import android.Manifest
 import android.os.Bundle
 import android.util.Log
 import androidx.activity.ComponentActivity
+import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.compose.setContent
 import androidx.activity.enableEdgeToEdge
+import androidx.activity.result.contract.ActivityResultContracts
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
@@ -26,27 +29,27 @@ import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
+import androidx.lifecycle.lifecycleScope
+import com.iscs.comm.entity.BleTicketDataPackage
 import com.iscs.comm.entity.device.Device
 import com.iscs.comm.entity.device.DeviceKeySlot
 import com.iscs.comm.entity.device.status.DeviceStatusKeySlot
 import com.iscs.comm.enums.CommType
-import com.iscs.comm.enums.RunMode
 import com.iscs.comm.extension.BleFrameExt
 import com.iscs.comm.extension.BleFrameExt.buildBLEGetPowerCMD
 import com.iscs.comm.extension.BleFrameExt.buildBLEGetStatusCMD
-import com.iscs.comm.extension.BleFrameExt.buildBLEPowerOffCMD
-import com.iscs.comm.extension.BleFrameExt.buildBLESwitchRunModeCMD
-import com.iscs.comm.extension.BleFrameExt.buildBLETicketDataCMDList
+import com.iscs.comm.extension.BleFrameExt.buildBLEGetTicketInfoCMD
 import com.iscs.comm.extension.BleFrameExt.getPower
 import com.iscs.comm.extension.BleFrameExt.getRunMode
-import com.iscs.comm.extension.BleFrameExt.getSendTicketResult
-import com.iscs.comm.extension.BleFrameExt.getSwitchRunModeResult
+import com.iscs.comm.extension.BleFrameExt.getTicketPackageInfo
 import com.iscs.comm.extension.BleFrameExt.getToken
 import com.iscs.comm.extension.byteArrayToHexString
 import com.iscs.comm.intf.IDeviceListener
 import com.iscs.comm.manager.BleManager
 import com.iscs.comm.ui.theme.CommDemoTheme
 import com.iscs.comm.utils.ISCSLog
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
 
 class MainActivity : ComponentActivity() {
 
@@ -80,7 +83,7 @@ class MainActivity : ComponentActivity() {
                 if (device is DeviceKeySlot) {
                     val slots = (device.deviceStatus as DeviceStatusKeySlot).slotList
                     slots.forEach { slot ->
-                       if(slot.isChanged()) Log.d("xiaoming", "slot -> ${slot.ch} isUsed:${slot.isUsedChanged()} isRfid:${slot.isRfidChanged()}")
+                        if (slot.isChanged()) Log.d("xiaoming", "slot -> ${slot.ch} isUsed:${slot.isUsedChanged()} isRfid:${slot.isRfidChanged()}")
                     }
                 }
             }
@@ -91,23 +94,13 @@ class MainActivity : ComponentActivity() {
             CommManager.addOnDeviceListener(listener)
             // SDK初始化
             CommManager.init(CommConfig().setCommType(CommType.CAN).setPort("can0").setBitrate(1000000))
-            Log.d("xiaoming", testJobJson)
-            // 蓝牙钥匙功能测试
-            // bleKeyTest("CC:BA:97:21:72:C6")
-//            repeat(10) {
-//                ISCSLog.i("xiaoming", "------------ start ------------")
-//                bleKeyTest("CC:BA:97:21:71:E6")
-//                bleKeyTest("CC:BA:97:21:72:0A")
-//                bleKeyTest("CC:BA:97:21:71:CA")
-//                ISCSLog.i("xiaoming", "------------- end -----------")
-//                delay(10000)
-//            }
         }
         DisposableEffect("") {
             // 移除页面监听
             CommManager.removeOnDeviceListener(listener)
             onDispose { }
         }
+        RequestMultiplePermissions()
         LazyVerticalGrid(
             columns = GridCells.Adaptive(minSize = 100.dp),
             contentPadding = PaddingValues(10.dp, pv.calculateTopPadding() + 10.dp),
@@ -131,6 +124,34 @@ class MainActivity : ComponentActivity() {
 
     }
 
+    @Composable
+    fun RequestMultiplePermissions() {
+        // 定义要请求的多个权限
+        val permissions = listOf(
+            Manifest.permission.BLUETOOTH_CONNECT,
+            Manifest.permission.BLUETOOTH_SCAN,
+            Manifest.permission.ACCESS_FINE_LOCATION
+        )
+
+        // 创建权限请求的 launcher
+        val permissionLauncher = rememberLauncherForActivityResult(
+            contract = ActivityResultContracts.RequestMultiplePermissions(),
+            onResult = { permissionsResult ->
+                // 检查所有权限是否都被授予
+                if (permissionsResult.all { it.value }) {
+                    lifecycleScope.launch { bleKeyTest("CC:BA:97:21:72:0A") }
+                } else {
+                    // 有权限被拒绝
+                }
+            }
+        )
+
+        // 请求权限
+        LaunchedEffect(Unit) {
+            permissionLauncher.launch(permissions.toTypedArray())
+        }
+    }
+
     private suspend fun bleKeyTest(mac: String) {
         // 测试蓝牙扫描
         val bm = BleManager(this@MainActivity.application, mac = mac)
@@ -149,36 +170,38 @@ class MainActivity : ComponentActivity() {
 //                val switch = bm.writeByResponse(token.buildBLESwitchRunModeCMD(RunMode.STBY)).getSwitchRunModeResult()
 //                ISCSLog.i("xiaoming $mac", "切换工作模式:$switch")
             // 下发作业票
-            val tickets = token.buildBLETicketDataCMDList(testJobJson)
-            var ticketSendOk = true
-            tickets.forEach {
-                val ticket = bm.writeByResponse(it).getSendTicketResult()
-                ISCSLog.i("xiaoming $mac", "下发作业票:分包${it.data[4].toInt()}发送结果:$ticket")
-                if (ticket != 0) {
-                    ticketSendOk = false
-                    return@forEach
-                }
-            }
-            ISCSLog.i("xiaoming $mac", "下发作业票:$ticketSendOk")
-            // 作业票下发成功,修改设备运行模式为工作模式
-            val switch = bm.writeByResponse(token.buildBLESwitchRunModeCMD(RunMode.WORK)).getSwitchRunModeResult()
-            ISCSLog.i("xiaoming $mac", "切换工作模式:$switch")
-            // 读取作业票信息
-//            val pkgList = ArrayList<BleTicketDataPackage>()
-//            val ticketInfo = bm.writeByResponse(token.buildBLEGetTicketInfoCMD()).getTicketPackageInfo()
-//            pkgList.add(ticketInfo)
-//            ISCSLog.i("xiaoming $mac", "读取作业票:首包信息:$ticketInfo")
-//            // 校验是否有子包,如果有,继续读取子包数据
-//            for (idx in 1 until ticketInfo.pkgTotal) {
-//                val ticketSubPackageInfo = bm.writeByResponse(token.buildBLEGetTicketInfoCMD(idx, ticketInfo.pkgTotal)).getTicketPackageInfo()
-//                pkgList.add(ticketSubPackageInfo)
-//                ISCSLog.i("xiaoming $mac", "读取作业票:子包信息:$ticketSubPackageInfo")
+//            val tickets = token.buildBLETicketDataCMDList(testJobJson)
+//            var ticketSendOk = true
+//            tickets.forEach {
+//                val ticket = bm.writeByResponse(it).getSendTicketResult()
+//                ISCSLog.i("xiaoming $mac", "下发作业票:分包${it.data[4].toInt()}发送结果:$ticket")
+//                if (ticket != 0) {
+//                    ticketSendOk = false
+//                    return@forEach
+//                }
 //            }
-//            var datas = byteArrayOf()
-//            pkgList.forEach { datas += it.pkgData }
-//            ISCSLog.i("xiaoming $mac", "读取作业票:${String(datas)}")
-            val powerOff = bm.writeByResponse(token.buildBLEPowerOffCMD())
-            ISCSLog.i("xiaoming $mac", "设备关机结果:$powerOff")
+//            ISCSLog.i("xiaoming $mac", "下发作业票:$ticketSendOk")
+//            // 作业票下发成功,修改设备运行模式为工作模式
+//            val switch = bm.writeByResponse(token.buildBLESwitchRunModeCMD(RunMode.WORK)).getSwitchRunModeResult()
+//            ISCSLog.i("xiaoming $mac", "切换工作模式:$switch")
+            // 读取作业票信息
+            val pkgList = ArrayList<BleTicketDataPackage>()
+            val ticketInfo = bm.writeByResponse(token.buildBLEGetTicketInfoCMD()).getTicketPackageInfo()
+            pkgList.add(ticketInfo)
+            ISCSLog.i("xiaoming $mac", "读取作业票:首包信息:$ticketInfo")
+            // 校验是否有子包,如果有,继续读取子包数据
+            for (idx in 1 until ticketInfo.pkgTotal) {
+                delay(100)
+                val ticketSubPackageInfo = bm.writeByResponse(token.buildBLEGetTicketInfoCMD(idx, ticketInfo.pkgTotal)).getTicketPackageInfo()
+                pkgList.add(ticketSubPackageInfo)
+                ticketSubPackageInfo.pkgIdx
+                ISCSLog.i("xiaoming $mac", "读取作业票:子包信息:$ticketSubPackageInfo")
+            }
+            var datas = byteArrayOf()
+            pkgList.forEach { datas += it.pkgData }
+            ISCSLog.i("xiaoming $mac", "读取作业票:${String(datas)}")
+//            val powerOff = bm.writeByResponse(token.buildBLEPowerOffCMD())
+//            ISCSLog.i("xiaoming $mac", "设备关机结果:$powerOff")
         } else {
             // 进行重连,这里可以封装尝试次数
             bleKeyTest(mac)

+ 3 - 1
transport/src/main/java/com/iscs/comm/manager/BleManager.kt

@@ -9,6 +9,7 @@ import android.bluetooth.BluetoothGattCharacteristic
 import android.bluetooth.BluetoothGattDescriptor
 import android.bluetooth.BluetoothManager
 import android.bluetooth.BluetoothProfile
+import android.bluetooth.BluetoothStatusCodes
 import android.bluetooth.le.ScanCallback
 import android.bluetooth.le.ScanFilter
 import android.bluetooth.le.ScanResult
@@ -140,6 +141,7 @@ class BleManager(
 
         override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
             super.onCharacteristicWrite(gatt, characteristic, status)
+            if (characteristic.value == null) return
             ISCSLog.w(TAG, "gattCallback ---> ${characteristic.value.byteArrayToHexString(" ")}")
         }
 
@@ -277,7 +279,7 @@ class BleManager(
 
             // 写入desc
             val enable = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-                gatt?.writeDescriptor(descriptor, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)
+                gatt?.writeDescriptor(descriptor, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE) == BluetoothStatusCodes.SUCCESS
             } else {
                 descriptor.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
                 gatt?.writeDescriptor(descriptor)