javascript 使用 chrome.bluetooth API 连接到设备

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21940200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 22:03:40  来源:igfitidea点击:

Connecting to a device using the chrome.bluetooth API

javascriptbluetoothbluetooth-lowenergygoogle-chrome-app

提问by Kev K

I have been trying to create a Chrome App that uses the chrome.bluetooth APIto connect to and communicate with the Texas Instruments CC2541 SensorTag device.

我一直在尝试创建一个 Chrome 应用程序,它使用chrome.bluetooth API连接到 Texas Instruments CC2541 SensorTag 设备并与之通信。

The code here detects the SensorTag and gets the device information, but the 'getProfiles' and 'getServices' methods called on the device both return empty, and the 'connect' method gives the error 'Profile not found: invalid uuid'.

这里的代码检测 SensorTag 并获取设备信息,但在设备上调用的 'getProfiles' 和 'getServices' 方法都返回空,并且 'connect' 方法给出错误'Profile not found: invalid uuid'。

I have tried multiple variations of UUIDs taken from the example SensorTag Android app(as can be seen in the code), but all give the same 'invalid uuid' error.

我尝试了从示例 SensorTag Android 应用程序中获取的 UUID 的多种变体(如代码中所示),但都给出了相同的“无效 uuid”错误。

Even if you can't fix this particular problem it would be good to hear from anyone who has had any joy using the chrome.bluetooth API at all. My experience so far is that it is too much of a moving target to really use (yes, I do know it is 'Dev' only...), but I'd really like to get it working if possible.

即使您无法解决这个特定问题,也很高兴听到任何对使用 chrome.bluetooth API 感到高兴的人的意见。到目前为止,我的经验是,真正使用它的移动目标太多了(是的,我确实知道它只是“开发”......),但如果可能的话,我真的很想让它工作。

Thanks for looking - any help or ideas much appreciated!

感谢您的关注 - 非常感谢您的任何帮助或想法!

EDIT : Additional platform information
I first tried running this on Windows 7 with a CSR 4.0 Bluetooth dongle but this turns out to be completely futile: with the generic Windows 7 BT Driver Chrome can see the adapter and detect BT devices, but the driver doesn't support Low Energy so can't detect the device I want it to. Using the CSR Driver, which does support LE and which I can use in Windows "Bluetooth Devices" to connect to LE devices, Chrome.bluetooth cannot detect the Bluetooth adapter at all.

编辑:其他平台信息
我第一次尝试在带有 CSR 4.0 蓝牙加密狗的 Windows 7 上运行它,但结果证明这是完全徒劳的:使用通用的 Windows 7 BT 驱动程序 Chrome 可以看到适配器并检测 BT 设备,但驱动程序没有t 支持 Low Energy,因此无法检测到我想要的设备。使用支持 LE 的 CSR 驱动程序,我可以在 Windows“蓝牙设备”中使用它来连接到 LE 设备,Chrome.bluetooth 根本无法检测到蓝牙适配器。

So now I'm working with an Acer C720 Chromebook, which looks like it should work, but I just get the "Invalid UUID" message whatever I try.

所以现在我正在使用 Acer C720 Chromebook,它看起来应该可以工作,但无论我尝试什么,我都会收到“无效的 UUID”消息。

(Although the Chrome OS and Win/Mac/Linux 'Dev' versions of Chrome are out of step with updates - Chrome OS was behind the others for a while but has now caught up - so for a time required different format 'manifest.json' files to launch the app on the different platforms.)

(尽管 Chrome 操作系统和 Win/Mac/Linux 'Dev' 版本的 Chrome 与更新不同步 - Chrome 操作系统落后于其他操作系统一段时间,但现在已经赶上 - 所以有一段时间需要不同的格式 'manifest.json ' 文件以在不同平台上启动应用程序。)

main.js

主文件

// I have tried multiple variations of known UUIDS for device... all give "Profile not found: invalid uuid" 
var profiles = [
             // UUID_IRT_SERV from example Android app
                {uuid : 'f000aa00-0451-4000-b000-000000000000', name : 'SensorTag1-lc'},
                {uuid : 'F000AA00-0451-4000-B000-000000000000', name : 'SensorTag1-uc'},
                {uuid : 'f000aa00', name : 'SensorTag1-shortlc'},
                {uuid : 'F000AA00', name : 'SensorTag1-shortuc'},
             // UUID_IRT_DATA from example Android app
                {uuid : 'f000aa01-0451-4000-b000-000000000000', name : 'SensorTag2-lc'},
                {uuid : 'F000AA01-0451-4000-B000-000000000000', name : 'SensorTag2-uc'},
                {uuid : 'f000aa01', name : 'SensorTag2-shortlc'},
                {uuid : 'F000AA01', name : 'SensorTag2-shortuc'},
             // UUID_IRT_CONF from example Android app
                {uuid : 'f000aa02-0451-4000-b000-000000000000', name : 'SensorTag3-lc'},
                {uuid : 'F000AA02-0451-4000-B000-000000000000', name : 'SensorTag3-uc'},
                {uuid : 'f000aa02', name : 'SensorTag3-shortlc'},
                {uuid : 'F000AA02', name : 'SensorTag3-shortuc'},
             // UUID_IRT_PERI from example Android app
                {uuid : 'f000aa03-0451-4000-b000-000000000000', name : 'SensorTag4-lc'},
                {uuid : 'F000AA03-0451-4000-B000-000000000000', name : 'SensorTag4-uc'},
                {uuid : 'f000aa03', name : 'SensorTag4-shortlc'},
                {uuid : 'F000AA03', name : 'SensorTag4-shortuc'},
             // UUID_KEY_SERV from example Android app
                {uuid : '0000ffe0-0000-1000-8000-00805f9b34fb', name : 'SensorTag5-lc'},
                {uuid : '0000FFE0-0000-1000-8000-00805F9B34FB', name : 'SensorTag5-uc'},
                {uuid : '0000ffe0', name : 'SensorTag5-shortlc'},
                {uuid : '0000FFE0', name : 'SensorTag5-shortuc'},
             // UUID_KEY_DATA from example Android app
                {uuid : '0000ffe1-0000-1000-8000-00805f9b34fb', name : 'SensorTag6-lc'},
                {uuid : '0000FFE1-0000-1000-8000-00805F9B34FB', name : 'SensorTag6-uc'},
                {uuid : '0000ffe1', name : 'SensorTag6-shortlc'},
                {uuid : '0000FFE1', name : 'SensorTag6-shortuc'},
];

// Listener to deal with initial connection
chrome.bluetooth.onConnection.addListener(onConnected);

// onAdapterStateChanged callback - for debug only
chrome.bluetooth.onAdapterStateChanged.addListener(function(newStatus) {
    log('onAdapterStateChanged: ' + JSON.stringify(arguments));
});

// Logs debug messages to app window
function log(msg) {
  var msg_str = (typeof(msg) == 'object') ? JSON.stringify(msg) : msg;
  console.log(msg_str);
  var l = document.getElementById('log');
  if (l) {
    l.innerText += msg_str + '\n';
  }
}

// Function that is called on connection to device
var onConnected = function(socket) {
    log("Success - Connected to SensorTag!");
    log("Socket: " + JSON.stringify(socket));
}

function recordDevice(device) {
    log("Found BT Device: " + JSON.stringify(device));
    if (device.name == "SensorTag") {
        log("Got SensorTag...");
        // Stop discovery and then connect to SensorTag
        chrome.bluetooth.stopDiscovery(connectToSensorTag(device));
    }
}

function connectToSensorTag(device) {
    log("Getting profiles of SensorTag...");
    chrome.bluetooth.getProfiles({device: device}, function(profiles) { 
        log('Got profiles: ' + JSON.stringify(profiles));
    });
    chrome.bluetooth.getServices({deviceAddress: device.address}, function(services) { 
        log('Got services: ' + JSON.stringify(services));
    });
    for (var i = 0; i < profiles.length; i++) {
        chrome.bluetooth.connect({ device: device, profile: profiles[i] }, function() {
            log('Connect called: ' + JSON.stringify(arguments));
            if (chrome.runtime.lastError) {
                  log("Connection error: " + chrome.runtime.lastError.message);
            }
        });
    }
}

function findDevices() {
    log("Finding devices...");
    chrome.bluetooth.startDiscovery({deviceCallback: recordDevice});
}

// App execution begins here.
// Add all profiles to try connection later
for (var i = 0; i < profiles.length; i++) {
    log("Adding profile: " + profiles[i]);
    chrome.bluetooth.addProfile(profiles[i], function() {
        log("SensorTag profile added."));
    });
}

chrome.bluetooth.getAdapterState( function(result) {
      if (result.powered == false || result.available == false ) {
        log("Error: No bluetooth adapter available.");
      } else {
        log("Bluetooth adapter enabled.");
        findDevices();
      }   
});

index.html

索引.html

<html>
<head></head>
<body>
    <div id="log"></div>
</body>
<script src="main.js"></script>
</html>

manifest.json

清单文件.json

{
  "manifest_version": 2,
  "name": "Connect to SensorTag",
  "description": "Connects to TI SensorTag",
  "version": "1.0",
  "minimum_chrome_version": "30",
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "bluetooth": {}
}

background.js

背景.js

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', {
    id: "window1",
    bounds: {
      width: 640,
      height: 480
    }
  });
});

回答by Jesse S

I ran into this same problem. After a fair bit of digging I was able to pin down two issues with the pattern I was using.

我遇到了同样的问题。经过一番挖掘,我能够确定我使用的模式的两个问题。

The first issue is that it turns out, from what I can tell, an empty "bluetooth" object in the manifest is not actually valid despite the fact that there are examples around that use it and chrome does not complain:

第一个问题是,据我所知,清单中的空“蓝牙”对象实际上并不有效,尽管周围有使用它的示例并且 chrome 没有抱怨:

"bluetooth": {}

Rather your bluetooth manifest entry should look something like this:

相反,您的蓝牙清单条目应如下所示:

"bluetooth":{
"profiles":
    [
        "00001101-0000-1000-8000-00805f9b34fb" // array of uuids
    ]
},

The documentation for this, such that it is, can be found in this chrome commit from two weeks ago: https://codereview.chromium.org/145663004/patch/760001/770016

可以在两周前的 chrome 提交中找到相关文档,例如:https: //codereview.chromium.org/145663004/patch/760001/770016

The other idiosyncrasy of this API that I discovered while tracking this issue down is that it is not only the connect call that can leave errors in "chrome.runtime.lastError", any of these calls may leave messages behind for you. If you check lastError after your addProfile call, you will likely see chrome complain about permissions: "Permission to add profile denied."

我在跟踪这个问题时发现的这个 API 的另一个特性是,不仅连接调用会在“chrome.runtime.lastError”中留下错误,这些调用中的任何一个都可能为你留下消息。如果您在 addProfile 调用后检查 lastError,您可能会看到 chrome 抱怨权限:“添加配置文件的权限被拒绝。”

Going back and reading the chrome.bluetooth api documentation it actually says this in the description near the top (although I missed it just like you did)

回去阅读 chrome.bluetooth api 文档,它实际上在顶部附近的描述中说明了这一点(尽管我和你一样错过了它)

Use the chrome.bluetooth API to connect to a Bluetooth device. All functions report failures via chrome.runtime.lastError.

使用 chrome.bluetooth API 连接到蓝牙设备。所有函数都通过 chrome.runtime.lastError 报告失败。

(emphasis added) http://developer.chrome.com/apps/bluetooth#type-Profile

(强调)http://developer.chrome.com/apps/bluetooth#type-Profile

Hope this helps.

希望这可以帮助。

回答by Scott James Remnant

The CSR tag you're using is a Low Energy device? In that case you'd want to use the chrome.bluetoothLowEnergy API instead: https://developer.chrome.com/apps/bluetoothLowEnergy

您使用的 CSR 标签是低能耗设备?在这种情况下,您需要使用 chrome.bluetoothLowEnergy API:https: //developer.chrome.com/apps/bluetoothLowEnergy

For an example see: https://github.com/armansito/ble-battery-service-demo/blob/master/script.js

有关示例,请参阅:https: //github.com/armansito/ble-battery-service-demo/blob/master/script.js

回答by user4029319

Found another solution seems also good: www.github.com/bcsphere/bluetooth

发现另一个解决方案似乎也不错:www.github.com/bcsphere/bluetooth

It supports iOS/Android Bluetooth JS API. It supports not only BLE/GATT, but also BT2.1 classic (to support Serial port / rfcomm profile for example.)

它支持 iOS/Android 蓝牙 JS API。它不仅支持 BLE/GATT,还支持 BT2.1 经典(例如支持串行端口/rfcomm 配置文件。)

They even implement some service/profiles libraries. https://github.com/bcsphere/bluetooth/tree/master/www

他们甚至实现了一些服务/配置文件库。 https://github.com/bcsphere/bluetooth/tree/master/www

Various kinds of open source examples: https://github.com/bcsphere/apps

各类开源示例:https: //github.com/bcsphere/apps

回答by khankuan

Some update, seems like the manifest format is changed slightly based on: https://developer.chrome.com/apps/app_bluetooth

一些更新,似乎清单格式根据以下内容略有更改:https: //developer.chrome.com/apps/app_bluetooth

"bluetooth": {
    "uuids": [ "1105", "1106" ]
}