蓝牙秤无法将重量数据正确发送到android应用程序

sqxo8psd  于 2021-06-30  发布在  Java
关注(0)|答案(0)|浏览(301)

我有一个urovo i6310设备和urovo蓝牙秤,我正在kotlin构建一个测试android应用程序,它将通过蓝牙接收秤的重量,并将其写在编辑文本字段中。问题是,我的体重秤工作正常,但我无法在编辑字段中写入大多数重量值。例如,如果权重低于0.5,则“我的txt”字段中将显示nan。如果权重为0,5、0,7或0,9,则正确显示值。如果是1千克,则显示无穷大。0,6和0,8也是nan。对于较大的值也是一样的,有些会显示出来,但大多数情况下我会得到nan。问题是在我的代码,规模是工作良好。如果有人知道我做错了什么,请帮忙。我将在下面发布scalesdk中的weightscale类,以及我活动中使用它的部分。
重量秤

import android.bluetooth.*
import android.bluetooth.BluetoothAdapter.LeScanCallback
import android.content.Context
import android.os.Build
import android.os.Handler
import androidx.annotation.RequiresApi
import java.util.*
import kotlin.experimental.and

@Suppress("DEPRECATION")
class WeightScale(private val context: Context) {
    var connectState = 0
    private val handler = Handler()
    var mScaleDevice: ArrayList<ScaleDevice>? = null
    var mScanaddr: List<String>? = null
    private val bluetoothAdapter: BluetoothAdapter?
    private var device: BluetoothDevice? = null
    private var bluetoothGatt: BluetoothGatt? = null
    private val outCharacteristic: BluetoothGattCharacteristic? = null
    private var ltimes: MutableList<Long?>? = null
    private var scalevalue = 0f
    private var scalesumvalue = 0f
    private var senddate: Byte = 0x00
    private var isBLEWriteWithResponse = false
    private var utime: Long? = null
    var mScanning = false
    private val scanDevice: ScanDevice = ScanDevice()
    private var scanupdate = false
    var ble_item = BLE_item()

    enum class BTN_TYPE {
        BTN_ZERO, BTN_CALIIB
    }

    private val task: Runnable = object : Runnable {
        override fun run() {
            handler.postDelayed(this, 100)
            if (scanupdate == true) {
                if (scanDevice.scanRecord?.let { bytestoAnalysis(it) } == true) {
                    val scaleDevice = ScaleDevice()
                    scaleDevice.devicename = scanDevice.devicename
                    scaleDevice.deviceaddr = scanDevice.deviceaddr
                    if (scaleDevice.devicename == null) {
                        scaleDevice.devicename =
                            "(" + scaleDevice.deviceaddr?.substring(12, 14) + scaleDevice.deviceaddr?.substring(15, 17).toString() + ")"
                    }
                    scaleDevice.scalevalue = scalevalue
                    scaleDevice.sumvalue = scalesumvalue
                    if (mScaleDevice?.isEmpty() != true) {
                        for (i in mScaleDevice?.indices!!) {
                            if (mScaleDevice!![i]?.deviceaddr.equals(scanDevice.deviceaddr) === true) {
                                mScaleDevice!![i] = scaleDevice
                                ltimes?.set(i, utime)
                                break
                            }
                            if (i == mScaleDevice!!.size - 1) {
                                mScaleDevice!!.add(scaleDevice)
                                ltimes?.add(utime)
                            }
                        }
                    } else {
                        mScaleDevice!!.add(scaleDevice)
                        ltimes?.add(utime)
                    }
                }
                scanupdate = false
            }
        }
    }

    fun bluetoothIsEnabled(): Boolean {
        if (bluetoothAdapter == null) return false
        return if (!bluetoothAdapter.isEnabled) false else true
    }

    fun m_ScaleDevice(): ArrayList<ScaleDevice>? {
        return mScaleDevice
    }

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun scanDevice(enable: Boolean) {
        if (connectState == 0) {
            if (Build.VERSION.RELEASE === "4.3") {
                scan_PERIOD = 200
            }
            if (enable) {
                Handler().postDelayed({
                    mScanning = false
                    bluetoothAdapter!!.stopLeScan(mLeScanCallback)
                }, scan_PERIOD)
                mScanning = true
                bluetoothAdapter!!.startLeScan(mLeScanCallback)
            } else {
                mScanning = false
                bluetoothAdapter!!.stopLeScan(mLeScanCallback)
            }
        }
    }

    fun updataDevicelist() {
        if (mScaleDevice?.isEmpty() == false && connectState == 0) {
            for (i in mScaleDevice?.indices!!) {
                if (System.currentTimeMillis() - ltimes?.get(i)!! > 3000) {
                    mScaleDevice!!.removeAt(i)
                    ltimes!!.removeAt(i)
                }
            }
        }
    }

    private val mLeScanCallback = LeScanCallback { device, rssi, scanRecord ->
        for (i in scanRecord.indices) {
            if (scanRecord[i] == 15.toByte()) {
                if (i + 5 < scanRecord.size) {
                    if (scanRecord[i + 1] == 22.toByte()) {
                        if (scanRecord[i + 2] == 29.toByte() && scanRecord[i + 3] == 24.toByte()) {
                            if (scanRecord[i + 4] == (-6).toByte() && scanRecord[i + 5] == (-5).toByte()) {
                                scanDevice.deviceaddr = device.address
                                scanDevice.devicename = device.name
                                scanDevice.scanRecord = scanRecord
                                utime = System.currentTimeMillis()
                                scanupdate = true
                            }
                        }
                    }
                }
            }
        }
    }

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun connectDevice(scaledevice: ScaleDevice, type: BTN_TYPE): Boolean {
        if (connectState == 0) {
            connectState = 1
            bluetoothAdapter!!.stopLeScan(null)
            device = bluetoothAdapter.getRemoteDevice(scaledevice.deviceaddr)
            bluetoothGatt = device!!.connectGatt(context, false, mGattCallback)
            if (bluetoothGatt == null) {
                connectState = 0
                return false
            }
            for (i in 0..799) {
                if (connectState == 2) break
                if (connectState == 0) break
                try {
                    Thread.sleep(10)
                } catch (e: InterruptedException) {
                }
            }
            if (connectState != 2) {
                close()
                connectState = 0
                return false
            }
            if (type == BTN_TYPE.BTN_ZERO) senddate = 0xc0.toByte()
            if (type == BTN_TYPE.BTN_CALIIB) senddate = 0xEC.toByte()
            for (i in 0..99) {
                if (ble_item.write_characteristic != null) break
                try {
                    Thread.sleep(10)
                } catch (e: InterruptedException) {
                }
            }
            try {
                Thread.sleep(500)
            } catch (e: InterruptedException) {
            }
            isBLEWriteWithResponse = false
            if (write(byteArrayOf(senddate)) == 0) {
                connectState = 0
                close()
                return false
            }
            connectState = 0
            close()
            return true
        }
        return false
    }

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun close() {
        if (bluetoothGatt == null) {
            return
        }
        try {
            Thread.sleep(100)
        } catch (e: InterruptedException) {
        }
        ble_item.write_characteristic = null
        bluetoothGatt!!.disconnect()
        try {
            Thread.sleep(100)
        } catch (e: InterruptedException) {
        }
        bluetoothGatt!!.close()
    }

    private val mGattCallback: BluetoothGattCallback = @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    object : BluetoothGattCallback() {
        //¼ì²âÁ¬½Ó״̬±ä»¯
        @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
        override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                gatt.discoverServices()
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                connectState = 0
            }
        }

        override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                setServiceUUID(supportedGattServices)
                connectState = 2
            }
        }

        //¼ì²âÓû§ÏòÀ¶ÑÀдÊý¾ÝµÄ״̬
        override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
            isBLEWriteWithResponse = true
        }
    }

    val supportedGattServices: List<BluetoothGattService>?
        @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2) get() = if (bluetoothGatt == null) null else bluetoothGatt!!.services

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun setServiceUUID(services: List<BluetoothGattService>?) {
        for (service in services!!) {
            ble_item.addService(service)
        }
        for (service in services) {
            for (characteristic in service.characteristics) {
                val charaProp = characteristic.properties
                if (charaProp or BluetoothGattCharacteristic.PROPERTY_READ > 0) {
                }
                if (charaProp or BluetoothGattCharacteristic.PROPERTY_NOTIFY > 0) {
                    setCharacteristicNotification(characteristic, true)
                }
                if (charaProp or BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE > 0) {
                    if (ble_item.write_characteristic_NoRe == null) {
                        ble_item.write_characteristic_NoRe = characteristic
                    }
                }
                if (charaProp or BluetoothGattCharacteristic.PROPERTY_WRITE > 0) {
                    if (ble_item.write_characteristic == null) {
                        ble_item.write_characteristic = characteristic
                    }
                }
            }
        }
    }

    inner class BLE_item {
        var arr_serviceUUID = ArrayList<String>()
        var arr_services = ArrayList<BluetoothGattService>()
        var write_characteristic: BluetoothGattCharacteristic? = null
        var write_characteristic_NoRe: BluetoothGattCharacteristic? = null
        @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
        fun addService(service: BluetoothGattService) {
            service.characteristics
            arr_services.add(service)
            val str_uuid = service.uuid.toString()
            arr_serviceUUID.add(str_uuid.substring(4, 8))
            val list: ArrayList<Any?> = ArrayList<Any?>()
            for (characteristic in service.characteristics) {
                var str_c_uuid = characteristic.uuid.toString()
                str_c_uuid = str_c_uuid.substring(4, 8)
                list.add(str_c_uuid)
                if (str_c_uuid.toLowerCase().contains("fff1")) {
                    setCharacteristicNotification(characteristic, true)
                }
                if (str_c_uuid.toLowerCase().contains("fff2")) {
                    write_characteristic = characteristic
                }
            }
        }
    }

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun setCharacteristicNotification(
        characteristic: BluetoothGattCharacteristic, enabled: Boolean
    ) {
        if (bluetoothAdapter == null || bluetoothGatt == null) {
            return
        }
        bluetoothGatt!!.setCharacteristicNotification(characteristic, enabled)
        val descriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
        )
        if (descriptor != null) {
            descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
            bluetoothGatt!!.writeDescriptor(descriptor)
        }
    }

    fun write(b: ByteArray?): Int {
        if (ble_item.write_characteristic == null) return 0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            ble_item.write_characteristic!!.value = b
            return if (writeCharacteristic(ble_item.write_characteristic)) 1 else 0
        }
        return 0
    }

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun writeCharacteristic(characteristic: BluetoothGattCharacteristic?): Boolean {
        return if (bluetoothAdapter == null || bluetoothGatt == null) {
            false
        } else bluetoothGatt!!.writeCharacteristic(characteristic)
    }

    private fun bytestoAnalysis(bytes: ByteArray): Boolean {
        val AnChars = ByteArray(12)
        var i = 0
        while (i < bytes.size) {
            if (bytes[i] == (-6).toByte()) {
                if (bytes.size - i >= 9 && bytes[i + 1] == (-5).toByte()) {
                    for (j in 0..11) AnChars[j] = bytes[i + j]
                    i = bytes.size - 1
                    break
                }
            }
            if (i == bytes.size - 1) return false
            i++
        }
        val xor8: Byte
        xor8 = AnChars[11]
        if (sum8xor(AnChars, 11) == xor8) {
            scalevalue = ArryToFloat(AnChars, 3)
            scalesumvalue = ArryToFloat(AnChars, 7)
        } else return false
        return true
    }

    private fun sum8xor(data: ByteArray, len: Int): Byte {
        var fcs = 0
        var sc: Int
        for (i in 0 until len) {
            sc = (data[i] and 0xff.toByte()).toInt()
            fcs += sc
        }
        fcs = fcs xor 0xFF
        return fcs.toByte()
    }

    companion object {
        private var scan_PERIOD: Long = 10000
        fun ArryToFloat(Array: ByteArray, Pos: Int): Float {
            var accum = 0
            accum = (Array[Pos + 0] and 0xFF.toByte()).toInt()
            accum = accum or ((Array[Pos + 1] and 0xFF.toByte()).toLong() shl 8).toInt()
            accum = accum or ((Array[Pos + 2] and 0xFF.toByte()).toLong() shl 16).toInt()
            accum = accum or ((Array[Pos + 3] and 0xFF.toByte()).toLong() shl 24).toInt()
            return java.lang.Float.intBitsToFloat(accum)
        }
    }

    init {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        mScaleDevice = ArrayList()
        ltimes = ArrayList()
        utime = System.currentTimeMillis()
        handler.post(task)
    }

    fun stopHandler(){
        handler.removeCallbacks(task)
    }
}

我的活动

private val task: Runnable = object : Runnable {
        @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
        override fun run() {
            handler.postDelayed(this, 150)
            if (!scale!!.bleIsEnabled()) {
                return
            }
            scale!!.Scan(true)
            if (scale!!.getState() === 0) {
                txtScale.text = "Idle"
            } else if (scale!!.getState() !== 0) {
                txtScale.text = "Busy"
            }
            scale!!.updatelist()
            if (scale!!.getDevicelist()!!.isEmpty() !== true) {
                listData.clear()
                for (i in 0 until scale!!.getDevicelist()!!.size) {
                    val map: MutableMap<String, String?> = HashMap()
                    map["devicename"] = scale!!.getDevicelist()!![i].devicename
                    map["value"] = java.lang.String.format(
                        "%4.1f" + "kg" + "     " + "SUM:%4.1f" + "kg", scale!!.getDevicelist()!![i].scalevalue, scale!!.getDevicelist()!![i].sumvalue
                    )
                    eMass?.setText(
                        java.lang.String.format(
                            "%4.1f", scale!!.getDevicelist()!![i].scalevalue
                        )
                    )
                    listData.add(map)
                }
            } else {
                listData.clear()
            }
            if (listData == listlastData == false) adapter?.notifyDataSetChanged()
            listlastData?.clear()
            for (j in listData.indices) listlastData?.add(listData[j])
        }
    }

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题