蓝牙app开发(蓝牙app开发重点难点)

小程序开发 47 0

本篇文章给大家谈谈蓝牙app开发,以及蓝牙app开发重点难点对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

如何开发简单的调试蓝牙app

分两种情况:

你懂技术,安卓JAVA或苹果OC。有一定的技术基础,并且愿意去学习和尝试,简单的蓝牙app其实真的简单,就是通过蓝牙协议进行软硬件联调,指令也就那几条,只要调通就好了。

不懂技术。那就百度一家app技术公司去咨询,然后把项目外包给他们,当然一定要货比三家。

app软件开发哪里有

app软件开发如下:

1、《开发者头条》是一款软件开发类型的社区类软件,在这款APP中你可以结交到各种互联网的技术人员,并且可以和他们一起取经,获得各种软件开发的知识和技能,用户可以学习到关于APP开发的各种知识。

对于从事相关行业的人来说,这款软件是非常有用的,在这里,你可以通过这款软件在这款软件中,用户可以学习到数以千计的编程教程,学习之余还可以通过内置的模块进行在线练习,练习模块还有自动纠错功能,对于初学者来说可以少走不少弯路。

2、《小肆开发》是一款个性的应用无代码制作平台,对于那些刚接触编程但还不是很熟练的用户来说,这款软件对于这些人群来说是非常友好的,大家可以在这款软件中制作出自己想要的应用。

这款可以在手机上运行C语言的C语言的编程软件,在平台上用户可以查看各种原创教程,开始轻松的C语言学习模式,还有客服在线,随时为用户解决问题,让C语言学习模式成为用户最喜欢的模式。

3、《BLE开发帮手》它是一款基于蓝牙开发的APP,支持多个蓝牙设备同时连接,能够极大的提高工作效率,并且界面简洁清晰,对于新手来说非常的友好。

用户可以通过内置的库来完成一系列的操作,当然也可以自己去安装一些常用的库,希望大家可以把自己的产品早日开发出来。

混合APP低功耗蓝牙项目解析数据可能用到的一些小方法---ble

可用于第三方蓝牙设备交互,必须要支持蓝牙 4.0。

iOS上:硬件至少是 iphone4s,系统至少是 iOS6。

android上:系统版本至少是 android4.3。

蓝牙 4.0 以低功耗著称,一般也叫 BLE(BluetoothLowEnergy)。目前应用比较多的案例:运动手坏、嵌入式设备、智能家居

在蓝牙通讯中有两个主要的部分,Central 和 Peripheral,有一点类似Client Server。Peripheral 作为周边设备是服务器。Central 作为中心设备是客户端。所有可用的蓝牙设备可以作为周边(Peripheral)也可以作为中央(Central),但不可以同时既是周边也是中央。

一般手机是客户端, 设备(比如手环)是服务器,因为是手机去连接手环这个服务器。周边(Peripheral)是生成或者保存了数据的设备,中央(Central)是使用这些数据的设备。你可以认为周边是一个广播数据的设备,他广播到外部世界说他这儿有数据,并且也说明了能提供的服务。另一边,中央开始扫描附近有没有服务,如果中央发现了想要的服务,然后中央就会请求连接周边,一旦连接建立成功,两个设备之间就开始交换传输数据了。

除了中央和周边,我们还要考虑他俩交换的数据结构。这些数据在服务中被结构化,每个服务由不同的特征(Characteristics)组成,特征是包含一个单一逻辑值的属性类型。

上文中提到了特征(Characteristics),这里简单说明下什么是特征。

特征是与外界交互的最小单位。蓝牙4.0设备通过服务(Service)、特征(Characteristics)和描述符(Descriptor)来形容自己,同一台设备可能包含一个或多个服务,每个服务下面又包含若干个特征,每个特征下面有包含若干个描述符(Descriptor)。比如某台蓝牙4.0设备,用特征A来描述设备信息、用特征B和描述符b来收发数据等。而每个服务、特征和描述符都是用 UUID 来区分和标识的。

source == 字符串

count == 切割的位数

转换接收的ios数据

初始化蓝牙4.0管理器 = initManager

搜索蓝牙4.0设备,模块内部会不断的扫描更新附近的蓝牙4.0设备信息 = scan

注: 参数(params):single 类型:布尔 true 为单例模式,false为非单例模式;默认为false; 描述:(可选项)则扫描附近的所有支持蓝牙4.0的设备类型:parmas:布尔 true 为单例模式,false为非单例模式;默认为false; 非单例模式为仅在本页面生效连接,单例模式为在连接成功后整个app全局生效

获取当前扫描到的所有外围设备信息 = getPeripheral

连接指定外围设备。iOS端无超时判断,android端默认有30秒超时判断 = connect

根据指定的外围设备 UUID 获取该外围设备的所有服务 = discoverService

根据指定的外围设备 UUID 及其服务 UUID 获取该外围设备的所有特征(Characteristic)= discoverCharacteristics

根据指定的外围设备 UUID 及其服务 UUID 和特征 UUID 监听数据回发 =setNotify

根据指定的外围设备 UUID 及其服务 UUID 和特征 UUID 写数据 = writeValueForCharacteristic

剩余方法根据需求酌情使用

此次开发需求 传递字节以及ASCII码,apicloud中ble模块仅仅满足于传递字节,并且初始低功耗蓝牙仅仅满足于传递20字节以下数据,需设置MTU进行大数据传输,此次流控为蓝牙的特征FF03监听来进行数据流控, 蓝牙模块使用百瑞互联,如需定制开发模块或SDK可联系!

微信小程序蓝牙模块开发

//index.js

//获取应用实例

const app = getApp()

const util = require('../../utils/util.js')

const bletool = require('../../utils/bletool.js')

Page({

data: {

// lists: [{ 'order_no': '1111', 'car_no': '321', 'car_type': '尚好捷', 'order_date': '2018-01-02 08:00', 'order_money': '16.00', 'order_time': '4' }],

car_no: '',

order_no: '',

lists: [],

bleList: [], //蓝牙设备数组

serviceId: '',//592B3370-3900-9A71-4535-35D4212D2837

serviceMac: '',//C9:9B:4C:E7:DE:10

service_psd: '',//855525B837253705595800000329

service_uuid: '',

deviceId:'',

characteristics:[] //特征值

},

onLoad: function (options) {

this.initBle();

},

onReady: function () {

// 页面渲染完成

},

onShow: function () {

if (app.globalData.car_no.length0){

this.getDeviceInfo();

}

},

onHide: function () {

// 页面隐藏

},

onUnload: function () {

// 页面关闭

app.globalData.car_no=''

},

//蓝牙相关

//初始化蓝牙

initBle: function () {

var that = this;

wx.onBluetoothAdapterStateChange(function (res) {

console.log('adapterState changed, now is', res)

app.globalData.ble_state = res.available;

if (res.available) {

that.initBle();

} else {

util.showToast('手机蓝牙已关闭');

app.globalData.ble_isonnectting = false;

}

})

//打开蓝牙适配器

wx.openBluetoothAdapter({

success: function (res) {

console.log('打开蓝牙适配器成功');

that.getBluetoothAdapterState();

app.globalData.ble_state = true;

that.onBluetoothDeviceFound();

},

fail: function (res) {

// fail

console.log(res)

util.showToast('请打开手机蓝牙');

},

complete: function (res) {

// complete

}

})

},

onBluetoothDeviceFound:function(){

var that = this;

//监听扫描

wx.onBluetoothDeviceFound(function (res) {

// res电脑模拟器返回的为数组;手机返回的为蓝牙设备对象

console.log('监听搜索新设备:', res);

that.updateBleList([res])

})

},

getBluetoothAdapterState: function () {

var that = this;

wx.getBluetoothAdapterState({

success: function (res) {

var available = res.available;

var discovering = res.discovering;

if (!available) {

util.showToast('蓝牙不可用');

} else {

if (!discovering) {

// that.startBluetoothDevicesDiscovery();

}

}

}

})

},

startBluetoothDevicesDiscovery: function () {

var that = this;

var services = [];

services.push(this.data.serviceId);

wx.showLoading({

title: '设备搜索中'

});

setTimeout(function () {

wx.hideLoading();

if (app.globalData.deviceId.length==0){

util.showModal('设备搜索失败,请重试');

}

}, 10000)

if(bletool.isIOS()){

wx.startBluetoothDevicesDiscovery({

services: services,

allowDuplicatesKey: true,

success: function (res) {

console.log('ios搜索成功');

console.log(res);

},

fail: function (err) {

console.log(err);

}

});

}else{

wx.startBluetoothDevicesDiscovery({

// services: services,

allowDuplicatesKey: true,

success: function (res) {

console.log('Android搜索成功');

console.log(res);

},

fail: function (err) {

console.log(err);

wx.hideLoading();

that.startBluetoothDevicesDiscovery();

// that.getBluetoothAdapterState();

util.showToast('搜索失败');

}

});

}

},

startConnectDevices: function (ltype, array) {

var that = this;

clearTimeout(that.getConnectedTimer);

that.getConnectedTimer = null;

wx.stopBluetoothDevicesDiscovery({

success: function (res) {

// success

}

})

app.globalData.ble_isonnectting = true;

console.log('连接前:'+that.deviceId);

wx.createBLEConnection({

deviceId: that.deviceId,

success: function (res) {

if (res.errCode == 0) {

console.log('连接成功:');

that.getService(that.deviceId);

}

},

fail: function (err) {

console.log('连接失败:', err);

wx.hideLoading();

util.showModal('设备连接失败,请重试');

// if (ltype == 'loop') {

// that.connectDeviceIndex += 1;

// that.loopConnect(array);

// } else {

// that.startBluetoothDevicesDiscovery();

// that.getConnectedBluetoothDevices();

// }

app.globalData.ble_isonnectting = false;

},

complete: function () {

}

});

},

getService: function (deviceId) {

var that = this;

// 监听蓝牙连接

wx.onBLEConnectionStateChange(function (res) {

console.log(res);

app.globalData.ble_isonnectting = res.connected

if (!res.connected) {

util.showToast('连接断开');

}

});

// 获取蓝牙设备service值

wx.getBLEDeviceServices({

deviceId: deviceId,

success: function (res) {

console.log('获取蓝牙设备service值');

console.log(res);

that.getCharacter(deviceId, res.services);

}

})

},

getCharacter: function (deviceId, services) {

var that = this;

services.forEach(function (value, index, array) {

if (value.isPrimary) {

that.setData({

service_uuid: value.uuid,

deviceId: deviceId

})

app.globalData.service_uuid= value.uuid;

app.globalData.deviceId=deviceId;

}

});

//监听通知

wx.onBLECharacteristicValueChange(function (res) {

// callback

console.log('value change', res)

const hex = bletool.buf2char(res.value)

console.log('返回的数据:', hex)

//配对密码

if (hex.indexOf('855800000106') != -1) {

wx.hideLoading();

var charact_write = that.data.characteristics[1]

bletool.writeDataToDevice(that.data.deviceId, that.data.service_uuid, charact_write, that.data.service_psd);

wx.showToast({

title: '设备已连接',

icon: 'success',

duration: 3000

})

setTimeout(function () {

bletool.writeDataToDevice(that.data.deviceId, that.data.service_uuid, charact_write, '235525B837253705590400000273');

}, 2000)

} else if (hex.indexOf('23040000') != -1) {

//启动成功

that.starRenting();

}

})

wx.getBLEDeviceCharacteristics({

deviceId: deviceId,

serviceId: that.getServiceUUID(),

success: function (res) {

wx.getBLEDeviceCharacteristics({

deviceId: deviceId,

serviceId: that.getServiceUUID(),

success: function (res) {

console.log('特征', res)

that.setData({

characteristics:res.characteristics

})

app.globalData.characteristics = res.characteristics;

var charact_read = res.characteristics[0]

},

loopConnect: function (devicesId) {

var that = this;

var listLen = devicesId.length;

if (devicesId[this.connectDeviceIndex]) {

this.deviceId = devicesId[this.connectDeviceIndex];

this.startConnectDevices('loop', devicesId);

} else {

console.log('已配对的设备小程序蓝牙连接失败');

that.startBluetoothDevicesDiscovery();

that.getConnectedBluetoothDevices();

}

},

//更新数据 devices为数组类型

updateBleList: function (devices) {

console.log('设备数据:',devices);

var newData = this.data.bleList

var that = this

var tempDevice = null;

for (var i = 0; i devices.length; i++) {

//ios设备

if (devices[i].devices != null) {

if (devices[i].devices.length 0) {

tempDevice = devices[i].devices[0];

}

else {

continue

}

}

//安卓

else {

tempDevice = devices[i];

}

if (!this.isExist(tempDevice)) {

newData.push(tempDevice)

}

}

console.log('数据:');

console.log(newData)

this.setData({

bleList: newData

})

if (!app.globalData.ble_isonnectting) {

var that = this;

this.data.bleList.forEach(function (value, index, array) {

//找到对应id的设备,ios判断服务id安卓判断mac地址

var deviceId = value['deviceId'];

if(bletool.isIOS()){

let advertisServiceUUID = value['advertisServiceUUIDs'][0];

if (advertisServiceUUID == that.data.serviceId.toUpperCase()){

that.deviceId = deviceId;

console.log(that.deviceId);

that.startConnectDevices();

}

}else{

if (deviceId == that.data.serviceMac) {

that.deviceId = deviceId;

console.log(that.deviceId);

that.startConnectDevices();

}

}

});

}

},

//是否已存在 存在返回true 否则false

isExist: function (device) {

var tempData = this.data.bleList

for (var i = 0; i tempData.length; i++) {

if (tempData[i].deviceId == device.deviceId) {

return true

}

}

return false

},

//服务uuid

getServiceUUID: function () {

return bletool.stringTransition(this.data.service_uuid);

},

getDeviceInfo: function () {

let car_no = app.globalData.car_no;

var that = this;

wx.request({

url: app.globalData.serverURL + '?c=cara=getDeviceInfoopen_id=' + app.globalData.open_id + 'car_no=' + car_no,

method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT

header: { 'content-type': 'application/json' }, // 设置请求的 header

success: function (res) {

// success

var data = res.data;

console.log(data);

if (data.result == 1) {

app.globalData.serviceId = data.data.service_id;

app.globalData.serviceMac = data.data.service_mac,

app.globalData.service_psd = '85' + data.data.service_psd + '5800000329';

that.setData({

serviceId: data.data.service_id,

serviceMac: data.data.service_mac,

service_psd: '85' + data.data.service_psd+'5800000329',

})

app.startBluetoothDevicesDiscovery();

// that.onBLECharacteristicValueChange();

} else {

util.showModal(data.msg);

}

},

fail: function () {

},

complete: function () {

// complete

}

});

},

})

蓝牙耳机APP开发都有哪些功能

App开发广州品向科技认为:蓝牙耳机app开发需要的功能有:

连接功能:与设备进行配对连接

音效调节功能:调节音乐音效

通话功能:当电话接入、微信电话接入等切换通话模式

电量显示:APP中显示蓝牙耳机剩余电量

iOS蓝牙开发相关知识点和注意事项

总结一下蓝牙开发相关的知识点和注意事项,做个笔记,也希望你们能少踩坑

(公司部分蓝牙项目为混编项目,蓝牙相关处理均采用了Objective-C,故本文🌰均采用OC,Swift处理相同)

蓝牙4.0包含两个蓝牙标准,它是一个是 双模 的标准,它包含 传统蓝牙部分(也称经典蓝牙) 和 低功耗蓝牙部分(BLE) , 二者适用于不同的应用场景和应用条件。他们的特点如下

所以蓝牙4.0是集成了传统蓝牙和低功耗蓝牙两个标准的,并不只是低功耗蓝牙

蓝牙4.0支持两种部署方式: 双模式 和 单模式 ,双模同时支持经典蓝牙和低功耗蓝牙,而单模则只支持其中一种。

二者更多细节详见: 传统蓝牙和低功耗蓝牙的区别

iOS中蓝牙相关功能都封装进了 CoreBluetooth 类中,其中有几个常见的参数和概念

具体API参考 CoreBluetooth蓝牙开发

保存到数组中的设备可通过 UUID 来进行区分。从 iOS7之后苹果不提供外设的mac地址,外设的唯一标识换成了由mac封装加密后的UUID,需要注意的是不同的手机获取同一个外设的UUID是不同的,所以在不同手机之间UUID不是唯一的,但在本机上可以作为唯一标识(特殊情况手机刷机后也会改变UUID)。

如何获取Mac地址

一般使用场景是根据Mac地址区分某个外设

注意点:

写入数据时可能会遇到需要分包发送的情况,我们可以通过下面的API或许当前特征支持的最大的单条写入长度

maxLength 一般取决于蓝牙模块内部接收 缓冲区 的大小,很多硬件设备这个缓冲区的大小是 20 字节, 这个大小也和特征的写入权限有关,像具有写入权限 withResponse 类的特征其大小一般为 512 字节,当然这些都是取决于设备测的设置;

当我们单次发送的数据字节长度大于 maxLength 时,我们就需要采用分包的方式来发送数据了,

分包发送的逻辑类似于下面

这边延时主要是设备侧的接收模块接收数据以及处理能力有限

外围设备测和中心设备(大部分情况下是手机)保持蓝牙连接的状态下,如果长时间不产生交互,蓝牙就会断开,所以为了保持两者持续的连接状态,需要做保活处理,也就是需要持续的发送心跳包(watchdog)。相应的处理是使用一个定时器定时向设备侧发送符合设备协议格式的心跳包。

断开连接很简单,只需要调用 [self.centralManager cancelPeripheralConnection:peripheral] 传入需要断开连接的设备对象就行了。断开连接时会自动调用 centralManager:didDisconnectPeripheral:error: 代理方法。

按照之前的惯例,当error为nil时表示断开成功,error不为nil时断开失败。这种理解是错误的。

当你调用 cancelPeripheralConnection: 方法(主动断开)断开连接时error为nil ; 没有调用这个方法(异常断开)而断开时error返回的是异常断开的原因。也可以理解为主动调用断开连接方法一定会断开

接下来就是断开重连的问题了,对蓝牙功能进行封装时肯定少不了断开重连。首先断开时可通过上面的代理方法的error是否为nil判断是否是异常断开,一般情况下异常断开时是需要重连的

原因就是当设备断开连接后 peripheral.services 为nil了,当然 service.characteristics 也是nil,所以需要在断开连接时把保存这个设备对应的服务和特征全部清除,然后在连接成功时重新过一遍发现服务和发现特征的流程就好了。

iOS7 开始,Apple加入了Beacon围栏检测的API, ( iBeacon-维基百科 ), 其工作方式是,配备有低功耗蓝牙(BLE)通信功能的设备使用 BLE 技术向周围发送自己特有的 ID,接收到该 ID 的应用软件会根据该 ID 采取一些行动。比如,在店铺里设置 iBeacon 通信模块的话,便可让 iPhone 和 iPad 上运行一资讯告知服务器,或者由服务器向顾客发送折扣券及进店积分, 或者公司的手机打卡,只要手机靠近打卡器一定范围,手机测就向打开器发送打卡信息,从而自动打卡。这种场景还有很多。 其中一个最重要的功能就是App的唤醒功能(杀死后也能唤醒)

举一个我们的例子,我们的产品业务场景就是在进入车辆以后,需要使用蓝牙连接我们的后装车载设备以采集车辆信息和驾驶行为行程等,这里有一个问题就是在App被杀死的情况下如何唤醒App, 因为不可能要求用户每次都主动去打开App,这样体验太差。我们的做法是通过iBeacon,当我们的车辆点火以后,设备测通电,发出 iBeacon广播 ,App实现监听iBeacon相关功能后就可以唤醒我们App,然后在相应的回调的处理一些事情,比如通过蓝牙连接设备。这里的前提条件是我们的硬件设备测包含iBeacon模块,具有iBeacon功能,而且对iBeacon的广播频率也有一定的要求,长了可能唤醒的功能会不稳定,官方建议的好像是100ms,频率超高越耗电,但可以让手机或其它监听设备越快地发现iBeacon。标准的BLE广播距离是100m,这使Beacon在室内位置跟踪场景下的效果更理想。

关于iBeacon更多的使用及介绍请参考

苹果核 - iOS端近场围栏检测(一) ——iBeacon

iBeacon技术初探

关于蓝牙app开发和蓝牙app开发重点难点的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

扫码二维码