<!DOCTYPE HTML>
|
<html>
|
<head>
|
<meta charset="utf-8"/>
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
<meta name="HandheldFriendly" content="true"/>
|
<meta name="MobileOptimized" content="320"/>
|
<title>Hello H5+</title>
|
<script type="text/javascript" src="../js/common.js"></script>
|
<script type="text/javascript">
|
var bds = []; // 可连接设备列表
|
var deviceId = null, bconnect = false;
|
var bss = []; // 连接设备服务列表
|
var serviceId = null;
|
var bscs = []; // 连接设备服务对应的特征值列表
|
var characteristicId = null;
|
var bscws = []; // 可写特征值列表
|
var wcharacteristicId = null;
|
// 重设数据
|
function resetDevices(d,s){
|
d||(bds=[],deviceId=null,document.getElementById('deivce').value='');
|
s||(bss=[],serviceId=null,document.getElementById('service').value='');
|
bscs=[],bscws=[],characteristicId=null,wcharacteristicId=null,document.getElementById('characteristic').value='',document.getElementById('wcharacteristic').value='';
|
}
|
|
// 页面初始化操作
|
document.addEventListener('plusready', function(e){
|
// 监听蓝牙适配器状态变化
|
plus.bluetooth.onBluetoothAdapterStateChange(function(e){
|
outLine('onBluetoothAdapterStateChange: '+JSON.stringify(e));
|
});
|
// 监听搜索到新设备
|
plus.bluetooth.onBluetoothDeviceFound(function(e){
|
var devices = e.devices;
|
outLine('onBluetoothDeviceFound: '+devices.length);
|
for(var i in devices){
|
outLine(JSON.stringify(devices[i]));
|
var device = devices[i];
|
if(device.deviceId/*&&device.name&&device.name.length>0&&device.name!='null'*/){
|
bds.push(device);
|
}
|
}
|
if(!bconnect && bds.length>0){ // 默认选择最后一个
|
var n = bds[bds.length-1].name;
|
if(!n || n.length<=0){
|
n = bds[bds.length-1].deviceId;
|
}
|
document.getElementById('deivce').value = n;
|
deviceId = bds[bds.length-1].deviceId;
|
}
|
});
|
// 监听低功耗蓝牙设备连接状态变化
|
plus.bluetooth.onBLEConnectionStateChange(function(e){
|
outLine('onBLEConnectionStateChange: '+JSON.stringify(e));
|
if(deviceId == e.deviceId){ // 更新连接状态
|
bconnect = e.connected;
|
}
|
});
|
// 监听低功耗蓝牙设备的特征值变化
|
plus.bluetooth.onBLECharacteristicValueChange(function(e){
|
outLine('onBLECharacteristicValueChange: '+JSON.stringify(e));
|
var value = buffer2hex(e.value);
|
outLine('value(hex) = '+value);
|
if(characteristicId == e.characteristicId){
|
// 更新到页面显示
|
document.getElementById('readvalue').value = value;
|
}else if(wcharacteristicId == e.characteristicId){
|
plus.nativeUI.toast(value);
|
}
|
});
|
}, false);
|
|
function buffer2hex(value){
|
var t='';
|
if(value){
|
var v=new Uint8Array(value);
|
for(var i in v){
|
t += '0x'+v[i].toString(16)+' ';
|
}
|
}else{
|
t='无效值';
|
}
|
return t;
|
}
|
|
// 打开蓝牙
|
function openBluetooth(){
|
outSet('打开蓝牙适配器:');
|
plus.bluetooth.openBluetoothAdapter({
|
success: function(e){
|
outLine('打开成功!');
|
},
|
fail: function(e){
|
outLine('打开失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 开始搜索蓝牙设备
|
function startDiscovery(){
|
outSet('开始搜索蓝牙设备:');
|
resetDevices();
|
plus.bluetooth.startBluetoothDevicesDiscovery({
|
success: function(e){
|
outLine('开始搜索成功!');
|
},
|
fail: function(e){
|
outLine('开始搜索失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 停止搜索蓝牙设备
|
function stopDiscovery(){
|
outSet('停止搜索蓝牙设备:');
|
plus.bluetooth.stopBluetoothDevicesDiscovery({
|
success: function(e){
|
outLine('停止搜索成功!');
|
},
|
fail: function(e){
|
outLine('停止搜索失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 选择蓝牙设备
|
function selectDevice(){
|
if(bds.length <= 0){
|
plus.nativeUI.toast('未搜索到有效蓝牙设备!');
|
return;
|
}
|
var bts=[];
|
for(var i in bds){
|
var t = bds[i].name;
|
if(!t || t.length<=0){
|
t = bds[i].deviceId;
|
}
|
bts.push({title:t});
|
}
|
plus.nativeUI.actionSheet({title:"选择蓝牙设备",cancel:"取消",buttons:bts}, function(e){
|
if(e.index>0){
|
document.getElementById('deivce').value = bds[e.index-1].name;
|
deviceId = bds[e.index-1].deviceId;
|
outLine('选择了"'+bds[e.index-1].name+'"');
|
}
|
});
|
}
|
|
// 连接蓝牙设备
|
function connectDevice(){
|
if(!deviceId){
|
plus.nativeUI.toast('未选择设备!');
|
return;
|
}
|
outSet('连接设备: '+deviceId);
|
plus.bluetooth.createBLEConnection({
|
deviceId: deviceId,
|
success: function(e){
|
outLine('连接成功!');
|
},
|
fail: function(e){
|
outLine('连接失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 获取设备服务
|
function getServices(){
|
if(!deviceId){
|
plus.nativeUI.toast('未选择设备!');
|
return;
|
}
|
if(!bconnect){
|
plus.nativeUI.toast('未连接蓝牙设备!');
|
return;
|
}
|
resetDevices(true);
|
outSet('获取蓝牙设备服务:');
|
plus.bluetooth.getBLEDeviceServices({
|
deviceId: deviceId,
|
success: function(e){
|
var services = e.services;
|
outLine('获取服务成功! '+services.length);
|
if(services.length>0){
|
for(var i in services){
|
bss.push(services[i]);
|
outLine(JSON.stringify(services[i]));
|
}
|
if(bss.length>0){ // 默认选择最后一个服务
|
document.getElementById('service').value = serviceId = bss[bss.length-1].uuid;
|
}
|
}else{
|
outLine('获取服务列表为空?');
|
}
|
},
|
fail: function(e){
|
outLine('获取服务失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 选择服务
|
function selectService(){
|
if(bss.length <= 0){
|
plus.nativeUI.toast('未获取到有效蓝牙服务!');
|
return;
|
}
|
var bts=[];
|
for(var i in bss){
|
bts.push({title:bss[i].uuid});
|
}
|
plus.nativeUI.actionSheet({title:"选择服务",cancel:"取消",buttons:bts}, function(e){
|
if(e.index>0){
|
document.getElementById('service').value = serviceId = bss[e.index-1].uuid;
|
outLine('选择了服务: "'+serviceId+'"');
|
}
|
});
|
}
|
|
// 获取服务的特征值
|
function getCharacteristics(){
|
if(!deviceId){
|
plus.nativeUI.toast('未选择设备!');
|
return;
|
}
|
if(!bconnect){
|
plus.nativeUI.toast('未连接蓝牙设备!');
|
return;
|
}
|
if(!serviceId){
|
plus.nativeUI.toast('未选择服务!');
|
return;
|
}
|
resetDevices(true, true);
|
outSet('获取蓝牙设备指定服务的特征值:');
|
plus.bluetooth.getBLEDeviceCharacteristics({
|
deviceId: deviceId,
|
serviceId: serviceId,
|
success: function(e){
|
var characteristics = e.characteristics;
|
outLine('获取特征值成功! '+characteristics.length);
|
if(characteristics.length>0){
|
for(var i in characteristics){
|
var characteristic = characteristics[i];
|
outLine(JSON.stringify(characteristic));
|
if(characteristic.properties){
|
if(characteristic.properties.read){
|
bscs.push(characteristics[i]);
|
}
|
if(characteristic.properties.write){
|
bscws.push(characteristics[i]);
|
if(characteristic.properties.notify||characteristic.properties.indicate){
|
plus.bluetooth.notifyBLECharacteristicValueChange({ //监听数据变化
|
deviceId: deviceId,
|
serviceId: serviceId,
|
characteristicId: characteristic.uuid,
|
success: function(e){
|
outLine('notifyBLECharacteristicValueChange '+characteristic.uuid+' success.');
|
},
|
fail: function(e){
|
outLine('notifyBLECharacteristicValueChange '+characteristic.uuid+' failed! '+JSON.stringify(e));
|
}
|
});
|
}
|
}
|
}
|
}
|
if(bscs.length>0){ // 默认选择最后特征值
|
document.getElementById('characteristic').value = characteristicId = bscs[bscs.length-1].uuid;
|
}
|
if(bscws.length>0){ // 默认选择最后一个可写特征值
|
document.getElementById('wcharacteristic').value = wcharacteristicId = bscws[bscws.length-1].uuid;
|
}
|
}else{
|
outLine('获取特征值列表为空?');
|
}
|
},
|
fail: function(e){
|
outLine('获取特征值失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 选择特征值(读取)
|
function selectCharacteristic(){
|
if(bscs.length <= 0){
|
plus.nativeUI.toast('未获取到有效可读特征值!');
|
return;
|
}
|
var bts=[];
|
for(var i in bscs){
|
bts.push({title:bscs[i].uuid});
|
}
|
plus.nativeUI.actionSheet({title:'选择特征值',cancel:'取消',buttons:bts}, function(e){
|
if(e.index>0){
|
document.getElementById('characteristic').value = characteristicId = bscs[e.index-1].uuid;
|
outLine('选择了特征值: "'+characteristicId+'"');
|
}
|
});
|
}
|
|
// 读取特征值数据
|
function readValue(){
|
if(!deviceId){
|
plus.nativeUI.toast('未选择设备!');
|
return;
|
}
|
if(!bconnect){
|
plus.nativeUI.toast('未连接蓝牙设备!');
|
return;
|
}
|
if(!serviceId){
|
plus.nativeUI.toast('未选择服务!');
|
return;
|
}
|
if(!characteristicId){
|
plus.nativeUI.toast('未选择读取的特征值!');
|
return;
|
}
|
outSet('读取蓝牙设备的特征值数据: ');
|
plus.bluetooth.readBLECharacteristicValue({
|
deviceId: deviceId,
|
serviceId: serviceId,
|
characteristicId: characteristicId,
|
success: function(e){
|
outLine('读取数据成功!');
|
},
|
fail: function(e){
|
outLine('读取数据失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 选择特征值(写入)
|
function selectwCharacteristic(){
|
if(bscws.length <= 0){
|
plus.nativeUI.toast('未获取到有效可写特征值!');
|
return;
|
}
|
var bts=[];
|
for(var i in bscws){
|
bts.push({title:bscws[i].uuid});
|
}
|
plus.nativeUI.actionSheet({title:'选择特征值',cancel:'取消',buttons:bts}, function(e){
|
if(e.index>0){
|
document.getElementById('wcharacteristic').value = wcharacteristicId = bscws[e.index-1].uuid;
|
outLine('选择了特征值: "'+wcharacteristicId+'"');
|
}
|
});
|
}
|
|
// 写入特征值数据
|
function writeValue(){
|
if(!deviceId){
|
plus.nativeUI.toast('未选择设备!');
|
return;
|
}
|
if(!bconnect){
|
plus.nativeUI.toast('未连接蓝牙设备!');
|
return;
|
}
|
if(!serviceId){
|
plus.nativeUI.toast('未选择服务!');
|
return;
|
}
|
if(!wcharacteristicId){
|
plus.nativeUI.toast('未选择写入的特征值!');
|
return;
|
}
|
var value = document.getElementById('writevalue').value;
|
if(!value || value==''){
|
plus.nativeUI.toast('请输入需要写入的数据');
|
document.getElementById('writevalue').focus();
|
return;
|
}
|
// 转换为ArrayBuffer写入蓝牙
|
str2ArrayBuffer(value, function(buffer){
|
outSet('写入蓝牙设备的特征值数据: ');
|
plus.bluetooth.writeBLECharacteristicValue({
|
deviceId: deviceId,
|
serviceId: serviceId,
|
characteristicId: wcharacteristicId,
|
value: buffer,
|
success: function(e){
|
outLine('写入数据成功!');
|
},
|
fail: function(e){
|
outLine('写入数据失败! '+JSON.stringify(e));
|
}
|
});
|
});
|
}
|
|
function str2ArrayBuffer(s,f) {
|
var b = new Blob([s],{type:'text/plain'});
|
var r = new FileReader();
|
r.readAsArrayBuffer(b);
|
r.onload = function(){if(f)f.call(null,r.result)}
|
}
|
|
|
// 断开蓝牙设备
|
function disconnectDevice(){
|
if(!deviceId){
|
plus.nativeUI.toast('未选择设备!');
|
return;
|
}
|
resetDevices(true);
|
outSet('断开蓝牙设备连接:');
|
plus.bluetooth.closeBLEConnection({
|
deviceId: deviceId,
|
success: function(e){
|
outLine('断开连接成功!');
|
},
|
fail: function(e){
|
outLine('断开连接失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
|
// 关闭蓝牙
|
function closeBluetooth(){
|
outSet('关闭蓝牙适配器:');
|
resetDevices();
|
plus.bluetooth.closeBluetoothAdapter({
|
success: function(e){
|
outLine('关闭成功!');
|
bconnect = false;
|
},
|
fail: function(e){
|
outLine('关闭失败! '+JSON.stringify(e));
|
}
|
});
|
}
|
</script>
|
<link rel="stylesheet" href="../css/common.css" type="text/css" charset="utf-8"/>
|
</head>
|
<body>
|
<br/>
|
<div class="button" onclick="openBluetooth()">初始化蓝牙模块</div>
|
<div class="button" onclick="startDiscovery()">开始搜索蓝牙设备</div>
|
<div class="button" onclick="stopDiscovery()">停止搜索蓝牙设备</div>
|
设备:<input id="deivce" type="text" disabled="disabled"></input>
|
<a href="#" onclick="selectDevice()">选择设备</a>
|
<div class="button" onclick="connectDevice()">连接蓝牙设备</div>
|
<div class="button" onclick="getServices()">获取设备服务</div>
|
服务:<input id="service" type="text" disabled="disabled"></input>
|
<a href="#" onclick="selectService()">选择服务</a>
|
<div class="button" onclick="getCharacteristics()">获取服务的特征值</div>
|
读取特征值:<input id="characteristic" type="text" disabled="disabled"></input>
|
<a href="#" onclick="selectCharacteristic()">选择</a>
|
<div class="button" onclick="readValue()">读取特征值数据</div>
|
读取数据:<input id="readvalue" type="text" disabled="disabled" style="width:60%"></input>
|
<hr/>
|
<br/>
|
写入特征值:<input id="wcharacteristic" type="text" disabled="disabled"></input>
|
<a href="#" onclick="selectwCharacteristic()">选择</a>
|
<div class="button" onclick="writeValue()">写入特征值数据</div>
|
写入数据:<input id="writevalue" type="text" style="width:60%;-webkit-user-select:text" value="test"></input>
|
<div class="button" onclick="disconnectDevice()">断开蓝牙设备</div>
|
<div class="button" onclick="closeBluetooth()">关闭蓝牙模块</div>
|
<div id="outpos"/>
|
<div id="output">
|
Bluetooth用于管理蓝牙设备,搜索附近蓝牙设备、连接实现数据通信等。
|
</div>
|
</body>
|
</html>
|