【uniapp蓝牙】基于native.js链接ble和非ble蓝牙

news2024/12/25 15:11:41

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙

uniapp不是仅支持低功耗蓝牙(基础蓝牙通讯不支持),有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗,基础蓝牙都支持

/**
 * @author wzj
 * 通用蓝牙模块封装
 * 搜索 ble 和非 ble 蓝牙设备
 */
class Ble {
    constructor() {
        // false 蓝牙关闭, true 蓝牙打开
        this.bluetooth = false
        this.systemPlatform = uni.$uv.os()
        this.context = plus.android.importClass('android.content.Context')
        this.locationManager = plus.android.importClass('android.location.LocationManager')
        this.main = plus.android.runtimeMainActivity()
        this.mainSvr = this.main.getSystemService(this.context.LOCATION_SERVICE)
        this.Intent = plus.android.importClass('android.content.Intent')
        this.Settings = plus.android.importClass('android.provider.Settings')
        this.IntentFilter = plus.android.importClass('android.content.IntentFilter')
        this.BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter')
        this.BluetoothDevice = plus.android.importClass('android.bluetooth.BluetoothDevice')
        this.UUID = plus.android.importClass('java.util.UUID')
        // 未配对蓝牙设备列表
        this.unpairedList = []
        // 已配对蓝牙设备列表
        this.pairedList = []
    }

    // 监听蓝牙状态改变
    listenerConnection() {
        plus.bluetooth.onBLEConnectionStateChange(function (e) {
            console.log('connection state changed: ' + JSON.stringify(e))
        })
    }

    // 提示框
    showToast(title, options = {}) {
        uni.showToast({
            title,
            ...options
        })
    }

    // 初始化蓝牙模块
    openBluetoothAdapter() {
        this.getBluetoothState()
        if (!this.bluetooth) {
            this.showToast('请先打开蓝牙!', {
                icon: 'error',
                duration: 2000
            })
            return false
        }

        if (this.systemPlatform !== 'android') {
            this.showToast('蓝牙功能只支持Android系统!', {
                icon: 'error',
                duration: 2000
            })
            return false
        }

        // 定位检测
        this.checkLocation()
    }

    // gps是否开启
    isProviderEnabled() {
        return this.mainSvr.isProviderEnabled(this.locationManager.GPS_PROVIDER)
    }

    // 建立连接
    createBLEConnection(mac_address) {
        const that = this
        var BAdapter = this.BluetoothAdapter.getDefaultAdapter()
        let device = BAdapter.getRemoteDevice(mac_address)
        plus.android.importClass(device)
        let bdevice = new this.BluetoothDevice()
        // 判断是否配对
        const getBondState = device.getBondState() === bdevice.BOND_NONE
        if (!getBondState) {
            console.log('已配对蓝牙设备')
            return true
        }
        // 参数如果跟取得的mac地址一样就配对
        const addressSame = device.getAddress() === mac_address
        if (!addressSame) return false
        // 配对命令
        const createBond = device.createBond()
        if (!createBond) return false
        let cha = setInterval(() => {
            if (device.getBondState() === bdevice.BOND_BONDED) {
                clearInterval(cha)
                // 删除未配对蓝牙,添加到已配对
                that.unpairedList.map((item, i) => {
                    if (item.address === mac_address) {
                        that.pairedList.push(item)
                        that.unpairedList.splice(i, 1)
                    }
                })
            }
        }, 1000)
    }

    // 执行蓝牙打印
    blueToothPrint(mac_address, dataToSend) {
        if (!mac_address) {
            this.showToast('请选择蓝牙打印机', {
                icon: 'error',
            })
            return false
        }
        let uuid = this.UUID.fromString('00001101-0000-1000-8000-00805f9b34fb')
        let BAdapter = this.BluetoothAdapter.getDefaultAdapter()
        let device = BAdapter.getRemoteDevice(mac_address)
        plus.android.importClass(device)
        let bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid)
        plus.android.importClass(bluetoothSocket)
        if (bluetoothSocket.isConnected()) {
            let outputStream = bluetoothSocket.getOutputStream()
            plus.android.importClass(outputStream)
            let bytes = plus.android.invoke(dataToSend, 'getBytes', 'gbk')
            console.log('发送数据完成', bytes)
            outputStream.write(bytes)
            outputStream.flush()
            // 这里关键
            device = null
            // 必须关闭蓝牙连接否则意外断开的话打印错误
            bluetoothSocket.close()
        } else {
            console.log('检测到设备未连接,尝试连接....')
            bluetoothSocket.connect()
        }
    }

    // 定位检测
    checkLocation() {
        const GPS_PROVIDER = this.isProviderEnabled()
        if (GPS_PROVIDER) {
            this.searchDevices()
            return true
        }

        uni.showModal({
            title: "提示",
            content: "请打开定位服务功能",
            showCancel: false, // 不显示取消按钮
            success() {
                if (GPS_PROVIDER) {
                    this.showToast('GPS功能已开启!', {
                        icon: 'success',
                    })
                    return true
                }
                const intent = new this.Intent(this.Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                // 打开系统设置GPS服务页面
                this.main.startActivity(intent)
            }
        })
        return false
    }

    // 开始搜寻附近的蓝牙外围设备
    startBluetoothDevicesDiscovery() {
        const that = this
        let main = this.main
        let BluetoothAdapter = this.BluetoothAdapter
        uni.startBluetoothDevicesDiscovery({
            success: (res) => {
                let BAdapter = BluetoothAdapter.getDefaultAdapter()
                const isEnabled = BAdapter !== null && !BAdapter.isEnabled()
                if (isEnabled) {
                    const intent = new this.Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                    main.startActivityForResult(intent, 200)
                }

                uni.showLoading({
                    title: "开始搜索设备",
                })

                let filter = new this.IntentFilter()
                let bdevice = new this.BluetoothDevice()
                let BluetoothDevice = this.BluetoothDevice
                // 开启搜索
                BAdapter.startDiscovery()
                // 获取配得和未配对蓝牙回调
                let receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
                    //实现onReceiver回调函数
                    onReceive: function (context, intent) {
                        // 通过 intent 实例引入 intent 类,方便以后的‘.’操作
                        plus.android.importClass(intent)
                        let BleDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                        // 获取已经配对的蓝牙设备
                        const getBondState = BleDevice.getBondState() !== bdevice.BOND_NONE
                        if (getBondState) {
                            // 已配对蓝牙设备
                            const addressLen = that.unpairedList.filter(item => item.address === BleDevice.getAddress())
                            if (addressLen.length > 0) return
                            that.unpairedList.push({
                                name: BleDevice.getName(),
                                address: BleDevice.getAddress(),
                            })
                        }

                        const action = intent.getAction() === "android.bluetooth.adapter.action.DISCOVERY_FINISHED"
                        if (action) {
                            // 取消监听
                            main.unregisterReceiver(receiver)
                            uni.hideLoading()
                            return false
                        }
                        const isBondState = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE).getBondState() === 10
                        if (isBondState) {

                            const name = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE).getName()
                            const address = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE).getAddress()
                            var y = 0
                            const unpairedListLength = that.unpairedList.length
                            for (let x = 0; x < unpairedListLength; x++) {
                                let isAddress = that.unpairedList[x].address === address
                                if (isAddress) {
                                    y++
                                }
                            }
                            if (y > 0) {
                                return y = 0
                            }
                            if (!name) {
                                return
                            }
                            that.unpairedList.push({
                                name,
                                address,
                            })
                        }
                    }
                })

                filter.addAction(bdevice.ACTION_FOUND)
                filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED)
                filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED)
                filter.addAction(BAdapter.ACTION_STATE_CHANGED)
                main.registerReceiver(receiver, filter)
            },
            fail: (res) => {
                console.log('startBluetoothDevicesDiscovery fail', res)
            },
        })
    }

    // 搜索蓝牙设备
    searchDevices() {
        this.openBluetooth(() => {
            if (!this.bluetooth) {
                return false
            }
            this.startBluetoothDevicesDiscovery()
        })
    }

    // 打开蓝牙模块
    openBluetooth(callBack) {
        const that = this
        uni.openBluetoothAdapter({
            success(res) {
                uni.getBluetoothAdapterState({
                    success(res) {
                        that.bluetooth = res.available
                        callBack && callBack()
                    }
                })
            },
            fail(res) {
                console.log('openBluetoothAdapter fail', res)
            }
        })
    }

    // 获取蓝牙状态
    getBluetoothState() {
        /* 判断是否打开蓝牙 */
        this.openBluetooth()
    }
}

export default Ble

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2264760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataV的安装与使用(Vue3版本)

1、DataV(vue3)地址&#xff1a;DataV Vue3TSVite版 | DataV - Vue3 2、使用 npm install kjgl77/datav-vue3 安装 3、全局引入。 4、此时就可以按需使用了~

隐藏指定文件/文件夹和自动提示功能消失解决方案

一. 隐藏指定文件/文件夹 Idea中隐藏指定文件或指定类型文件 Setting → File Types → Ignored Files and Folders输入要隐藏的文件名&#xff0c;支持*号通配符回车确认添加 二. 自动提示功能消失解决方案 指定SpringBoot配置文件 File → Project Structure → Facets选…

Echarts连接数据库,实时绘制图表详解

文章目录 Echarts连接数据库&#xff0c;实时绘制图表详解一、引言二、步骤一&#xff1a;环境准备与数据库连接1、环境搭建2、数据库连接 三、步骤二&#xff1a;数据获取与处理1、查询数据库2、数据处理 四、步骤三&#xff1a;ECharts图表配置与渲染1、配置ECharts选项2、动…

Springboot应用开发:配置类整理

目录 编写目的 一、线程池 1.1 setCorePoolSize 1.2 setMaxPoolSize 1.3 setQueueCapacity 1.4 setKeepAliveSeconds 1.5 setThreadNamePrefix 1.6 setRejectedExecutionHandler 1.7 示例代码 二、Durid数据库连接池 2.1 ServletRegistrationBean 2.2 FilterRegist…

AI新书推荐:深度学习和大模型原理与实践(清华社)

本书简介 在这个信息爆炸、技术革新日新月异的时代&#xff0c;深度学习作为人工智能领域的重要分支&#xff0c;正引领着新一轮的技术革命。《深度学习和大模型原理与实践》一书&#xff0c;旨在为读者提供深度学习及其大模型技术的全面知识和实践应用的指南。 本书特色在于…

java如何使用poi-tl在word模板里渲染多张图片

1、poi-tl官网地址 http://deepoove.com/poi-tl/ 2、引入poi-tl的依赖 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version></dependency>3、定义word模板 释义&#xf…

电力通信规约-104实战

电力通信规约-104实战 概述 104规约在广泛应用于电力系统远动过程中&#xff0c;主要用来进行数据传输和转发&#xff0c;本文将结合实际开发实例来讲解104规约的真实使用情况。 实例讲解 因为个人技术栈是Java&#xff0c;所以本篇将采用Java实例来进行讲解。首先我们搭建一…

linux socket编程之udp_dict_serve服务端--引入配置文件

注意&#xff1a;本篇博客只是对上一篇博客功能的增加 1.创建配置文件(翻译) Dict.txt apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 happy: 快乐的 sad: 悲伤的 run: 跑 jump: 跳 teacher: 老师 student: 学生 car: 汽车 bus: 公交车 love: 爱 hate: 恨 hell…

stm32定时器输出比较----驱动步进电机

定时器输出比较理论 OC(Output Compare)输出比较输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形每个高级定时器和通用定时器都拥有4个输出比较通道高级定时器的前3个通道额外拥有死区生成和互补输出…

ArrayList 类 (顺序表)

目录 一. ArrayList 基本介绍 二. ArrayList 中的法及其应用 1. 添加元素 (1) add() (2) addAll() 2. 删除元素 (1) remove() (2) removeAll() 3. 遍历元素 (1) for 循环遍历 (2) for - each 遍历 (3) 迭代器遍历 (4) 列表迭代器遍历 4. 判断 (1) cotains() (2…

ubuntu22.04安装PaddleX3

PaddleOCR 安装过程可以参考PaddleX本地安装教程 我的电脑环境配置&#xff1a; ubuntu22.04 cuda11.8&#xff08;之前安装的是12.4没有匹配的paddle-gpu;这里改成11.8&#xff09; 一、安装基础环境 1、 conda create -n ppx1 python3.10 2、 conda activate ppx1 3、…

圣诞快乐(h5 css js(圣诞树))

一&#xff0c;整体设计思路 圣诞树h5&#xff08;简易&#xff09; 1.页面布局与样式&#xff1a; 页面使用了全屏的黑色背景&#xff0c;中央显示圣诞树&#xff0c;树形由三层绿色的三角形组成&#xff0c;每一层的大小逐渐变小。树干是一个棕色的矩形&#xff0c;位于三角…

行业观察|西门子收购Altair:从多学科仿真到工业元宇宙

在当今数字化时代&#xff0c;工业领域正经历着深刻的变革。而CAE软件作为工业领域关键工具&#xff0c;在产品设计、验证和优化等环节发挥着越来越重要的作用。 11月&#xff0c;西门子宣布收购Altair的新闻屠版了整个朋友圈&#xff0c;无疑验证了CAE在制造业的核心地位。对A…

【Verilog】UDP用户原语

User-defined primitives 概述基本语法组合逻辑的UDP时序逻辑的UDPUDP 符号表 Verilog HDL&#xff08;简称 Verilog &#xff09;是一种硬件描述语言&#xff0c;用于数字电路的系统设计。可对算法级、门级、开关级等多种抽象设计层次进行建模。 Verilog 不仅定义了语法&…

计算机网络压缩版

计算机网络到现在零零散散也算过了三遍&#xff0c;一些协议大概了解&#xff0c;但总是模模糊糊的印象&#xff0c;现在把自己的整体认识总结一下&#xff0c;&#xff08;本来想去起名叫《看这一篇就够了》&#xff0c;但是发现网上好的文章太多了&#xff0c;还是看这篇吧&a…

单元测试使用记录

什么是单元测试 简单来说就是对一个类中的方法进行测试&#xff0c;对输出的结果检查判断是否符合预期结果 但是在多年的工作中&#xff0c;从来没有哪个项目中真正系统的用到了单元测试&#xff0c;因此对它还是很陌生的&#xff0c;也就造成更加不会在项目中区使用它。 如何…

bridge between Lua world and the .NET

一、新建项目&#xff1a;luademo 安装包&#xff1a;<PackageReference Include"NLua" Version"1.7.3" /> using NLua; using System;namespace luademo {internal class Program{static void Main(string[] args){Lua state new Lua();for (int …

路径规划之启发式算法之二十三:免疫算法(Immune Algorithm,IA)

免疫算法(Immune Algorithm,IA)是基于人工免疫系统的理论,受生物免疫系统的启发而推出的一种新型的智能搜索算法。通过模拟生物免疫系统的工作原理来解决优化问题。 一、定义与原理 免疫算法是以人工免疫系统的理论为基础,实现了类似于生物免疫系统的抗原识别、细胞分化、…

2.5.1 文件管理基本概念

文章目录 文件文件系统文件分类 文件 文件&#xff1a;具有符号名&#xff0c;逻辑上有完整意义的一组相关信息的集合。 文件包含文件体、文件说明两部分。文件体存储文件的真实内容&#xff0c;文件说明存放操作系统管理文件所用的信息。 文件说明包含文件名、内部标识、类型、…

C#调用WebService的方法

一、前言 在日常工作中&#xff0c;如果涉及到与第三方进行接口对接&#xff0c;有的会使用WebService的方式&#xff0c;这篇文章主要讲解在.NET Framework中如何调用WebService。 1.创建WebService &#xff08;1&#xff09;新建项目——模板选择ASP.NET Web 应用程序 &a…