自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用 Chrome Web 藍(lán)牙 API 構(gòu)建藍(lán)牙應(yīng)用

系統(tǒng) Linux
盡管藍(lán)牙 API 仍處于測試階段,但我們會(huì)嘗試并制作一個(gè)簡單的網(wǎng)頁,該網(wǎng)頁將與我們的手機(jī)配對(duì)并提供基本詳細(xì)信息,例如電池百分比、設(shè)備名稱以及設(shè)備提供的基本信息制造商。

[[433680]]

如今,瀏覽器不斷發(fā)展,帶來了新的 API 和連接其他設(shè)備的方式,并允許訪問比以往更多的功能。其中一種 API 是 Web 藍(lán)牙 API[1]。

在撰寫本文時(shí),該 API 仍處于測試階段,但一旦向公眾發(fā)布,它將為想要使用藍(lán)牙但不想為每個(gè)平臺(tái)創(chuàng)建原生應(yīng)用程序的開發(fā)人員提供大量機(jī)會(huì)。

盡管藍(lán)牙 API 仍處于測試階段,但我們會(huì)嘗試并制作一個(gè)簡單的網(wǎng)頁,該網(wǎng)頁將與我們的手機(jī)配對(duì)并提供基本詳細(xì)信息,例如電池百分比、設(shè)備名稱以及設(shè)備提供的基本信息制造商。

我們不會(huì)在本教程中使用樣式,因?yàn)槲覀冎恍枰私馊绾问褂?JavaScript 與藍(lán)牙 API 交互。

請(qǐng)記住,并非所有瀏覽器都支持此 API,您將無法在每部手機(jī)上進(jìn)行測試。某些手機(jī)可能不允許獲取設(shè)備信息。在本教程中,我將使用 Apple iPhone 11,它允許我通過瀏覽器上的藍(lán)牙獲取我的設(shè)備信息而不會(huì)出現(xiàn)任何問題。

前提

  • 一個(gè)代碼編輯器;我更喜歡 VS Code
  • 使用 VS Code 時(shí)的實(shí)時(shí)服務(wù)器擴(kuò)展
  • 具有藍(lán)牙功能(或即插即用藍(lán)牙硬件)的筆記本電腦或 PC
  • 有藍(lán)牙功能的移動(dòng)設(shè)備(我用的是iPhone 11,你可以用自己的手機(jī)試試)
  • 對(duì)JavaScript有一定的了解
  • Chrome Beta 安裝在您的 PC 或筆記本電腦上。藍(lán)牙 API 是 Beta 版功能,在 Chrome Beta 版上效果最佳。

請(qǐng)注意,并非所有基于 Chromium 的瀏覽器(例如 Brave)都支持藍(lán)牙 API。我嘗試在 Brave 上使用 API,但發(fā)現(xiàn) Brave 出于安全原因故意禁用了 API。

如果你對(duì)代碼需要任何幫助,這里是[GitHub倉庫](https://github.com/atharvadeosthale/web-bluetooth-phone)。

讓我們開始吧

首先,我們需要?jiǎng)?chuàng)建一個(gè)文件夾,我們將把它作為一個(gè)工作區(qū)。一旦你創(chuàng)建了一個(gè)文件夾,使用以下命令打開VS Code:

code .

我們將在本教程中使用兩個(gè)文件;將它們命名為 index.html 和 script.js。在 index.html 中,我們只需要基本布局(只是一個(gè)按鈕),并將文件鏈接到我們的 JavaScript 文件。

以下是 index.html 的內(nèi)容:

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3.   <head> 
  4.     <meta charset="UTF-8" /> 
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
  7.     <title>Document</title> 
  8.   </head> 
  9.   <body> 
  10.     <button id="getDetails">Get device details</button> 
  11.     <div id="details"></div> 
  12.     <script src="script.js"></script> 
  13.   </body> 
  14. </html> 

添加藍(lán)牙功能

讓我們從功能開始。轉(zhuǎn)到 script.js 并將 UI 元素存儲(chǔ)在變量中,以便我們以后可以訪問它們:

  1. const button = document.getElementById("getDetails"); 
  2. const details = document.getElementById("details"); 

現(xiàn)在,讓我們?yōu)槲覀兊陌粹o創(chuàng)建一個(gè)點(diǎn)擊監(jiān)聽器,這樣我們就可以在用戶點(diǎn)擊按鈕時(shí)執(zhí)行我們的操作:

  1. button.addEventListener("click", async () => { 
  2.   try { 
  3.   } catch(err) { 
  4.     console.error(err); 
  5.     alert("An error occured while fetching device details"); 
  6.   } 
  7. }); 

我們將該函數(shù)設(shè)為異步函數(shù),因?yàn)樗刮覀兊氖虑樽兊酶唵?,而且我們不需要進(jìn)行很多回調(diào),使我們的代碼看起來更有條理。從現(xiàn)在開始,我們所有的代碼都將在 try 塊中。

請(qǐng)求藍(lán)牙設(shè)備

接下來,讓我們通過瀏覽器請(qǐng)求藍(lán)牙設(shè)備:

  1. // 通過瀏覽器請(qǐng)求藍(lán)牙設(shè)備 
  2. const device = await navigator.bluetooth.requestDevice({ 
  3.   optionalServices: ["battery_service""device_information"], 
  4.   acceptAllDevices: true
  5. }); 

在上面的代碼中,我們通過 navigator.bluetooth 使用了藍(lán)牙 API。在連接到設(shè)備之前,我們需要向設(shè)備提供有關(guān)我們將要訪問哪些數(shù)據(jù)的信息。

我們可以使用目標(biāo)藍(lán)牙設(shè)備上存在的各種服務(wù)訪問所需的數(shù)據(jù)。在這種情況下,我們正在與電池和設(shè)備信息進(jìn)行交互,因此我們需要 Battery_service 和 device_information 服務(wù)。

一旦用戶選擇了他想要連接的藍(lán)牙設(shè)備,我們就會(huì)建立到 GATT 服務(wù)器的連接,它為我們提供了對(duì)我們之前請(qǐng)求的服務(wù)的訪問,并將設(shè)備名稱存儲(chǔ)在一個(gè)變量中以供以后使用:

  1. // 連接到 GATT 服務(wù)器 
  2. // 我們還在這里獲得了藍(lán)牙設(shè)備的名稱 
  3. let deviceName = device.gatt.device.name
  4. const server = await device.gatt.connect(); 

現(xiàn)在,我們需要從 GATT 服務(wù)器單獨(dú)獲取服務(wù),以便我們可以單獨(dú)訪問它們:

  1. // 通過 GATT 服務(wù)器獲取我們之前提到的服務(wù) 
  2. const batteryService = await server.getPrimaryService("battery_service"); 
  3. const infoService = await server.getPrimaryService("device_information"); 

從設(shè)備獲取信息

首先,讓我們獲取目標(biāo)設(shè)備的電池電量。

每個(gè)藍(lán)牙設(shè)備都有各種服務(wù)可以互動(dòng)。例如,一個(gè)移動(dòng)設(shè)備可以有一個(gè)電池服務(wù),用于所有電池活動(dòng)。還可以提供幫助撥打和接聽電話的電話服務(wù)。不同的設(shè)備都有不同的藍(lán)牙服務(wù)。

每個(gè)服務(wù)都有特征,每個(gè)特征都有一個(gè)值。這個(gè)值是一個(gè)緩沖區(qū),所以我們需要把它轉(zhuǎn)換成人類可讀的形式。

電池電量是一個(gè)百分比,因此我們將緩沖區(qū)轉(zhuǎn)換為整數(shù):

  1. // 獲取當(dāng)前電池電量 
  2. const batteryLevelCharacteristic = await batteryService.getCharacteristic( 
  3.   "battery_level" 
  4. ); 
  5. // 將收到的緩沖區(qū)轉(zhuǎn)換為數(shù)字 
  6. const batteryLevel = await batteryLevelCharacteristic.readValue(); 
  7. const batteryPercent = await batteryLevel.getUint8(0); 

readValue() 函數(shù)返回一個(gè)緩沖區(qū),我們需要將其轉(zhuǎn)換為人類可讀的形式。

現(xiàn)在,讓我們努力獲取更多設(shè)備信息。如前所述,每項(xiàng)服務(wù)都有一個(gè)或多個(gè)特征。device_information 服務(wù)根據(jù)設(shè)備的不同可能有相當(dāng)多的特征,我們無法提取一個(gè)特定的特征,因?yàn)槊總€(gè)設(shè)備都有不同的配置和不同的唯一 ID 來訪問數(shù)據(jù)。因此,我們只需讀取本例中的所有特征。

下面的代碼就是這樣做的:

  1. // 獲取設(shè)備信息 
  2. // 我們將從 device_information 中獲取所有特征 
  3. const infoCharacteristics = await infoService.getCharacteristics(); 
  4. console.log(infoCharacteristics); 
  5. let infoValues = []; 
  6. const promise = new Promise((resolve, reject) => { 
  7.   infoCharacteristics.forEach(async (characteristic, index, array) => { 
  8.     // Returns a buffer 
  9.     const value = await characteristic.readValue(); 
  10.     console.log(new TextDecoder().decode(value)); 
  11.     // Convert the buffer to string 
  12.     infoValues.push(new TextDecoder().decode(value)); 
  13.     if (index === array.length - 1) resolve(); 
  14.   }); 
  15. }); 

我們將 forEach 包裝在 Promise 下,因?yàn)楦讣?jí)和 forEach 本身是一個(gè)異步函數(shù),因此我們需要在繼續(xù)顯示數(shù)據(jù)之前獲取數(shù)據(jù)。在這里,當(dāng)我們使用 readValue() 獲取值時(shí),我們使用的是 TextDecoder,因?yàn)槲覀冎?device_information 服務(wù)中的大部分?jǐn)?shù)據(jù)是字符串類型而不是整數(shù)。

然后我們將所有數(shù)據(jù)推送到一個(gè)數(shù)組中,以便我們可以在 UI 上呈現(xiàn)它,然后在讀取所有特征后解析 Promise。

現(xiàn)在,我們只需在屏幕上渲染數(shù)據(jù):

  1. promise.then(() => { 
  2.   // 在屏幕上顯示所有信息 
  3.   // 使用innerHTML 
  4.   details.innerHTML = ` 
  5.     Device Name - ${deviceName}<br /> 
  6.     Battery Level - ${batteryPercent}%<br /> 
  7.     Device Information: 
  8.     <ul> 
  9.       ${infoValues.map((value) => `<li>${value}</li>`).join("")} 
  10.     </ul>  
  11.   `; 
  12. }); 

現(xiàn)在,當(dāng)您在 Chrome Beta 上運(yùn)行我們的Web應(yīng)用程序并單擊該按鈕時(shí),您應(yīng)該會(huì)看到一個(gè)連接藍(lán)牙設(shè)備的提示,如下所示:

一旦你選擇了你的手機(jī)(在我的例子中是 Atharva 的 iPhone)并點(diǎn)擊配對(duì),你應(yīng)該會(huì)在幾秒鐘內(nèi)看到屏幕上的信息,就像這樣:

信息是正確的,我截圖的時(shí)候,我的手機(jī)是百分之百開著的。

這里需要注意的一件事是 iPhone 12,1 ,這不是說我有 iPhone12,它是 iPhone 11 的代號(hào),因此,如果您看到一些奇怪的設(shè)備名稱,您應(yīng)該知道它可能是代號(hào)或制造商提供的其他名稱。

你應(yīng)該使用藍(lán)牙API嗎?

這是最重要的問題。此功能在大多數(shù)瀏覽器中處于測試階段,即使向公眾發(fā)布,也可能存在一些問題,例如硬件不支持藍(lán)牙。如果您想為某人創(chuàng)建鏈接其設(shè)備的服務(wù),則應(yīng)牢記這一點(diǎn)。

另一方面,如果你的組織有正確配置了藍(lán)牙的定制系統(tǒng),你肯定可以為組織創(chuàng)建一個(gè)內(nèi)部Web應(yīng)用,可以根據(jù)他們的需要與藍(lán)牙設(shè)備進(jìn)行互動(dòng)。

我認(rèn)為你應(yīng)該在這個(gè)API處于測試階段時(shí)嘗試一下,因?yàn)橐话銇碚f,當(dāng)它向公眾發(fā)布時(shí),你就會(huì)占到先機(jī)。沒有多少人會(huì)知道如何使用這個(gè)API,所以對(duì)它的了解可以幫助你獲得更多的演出機(jī)會(huì)。

在測試階段使用這個(gè)的另一個(gè)原因是為了挑戰(zhàn)自己。當(dāng)API被發(fā)布后,事情可能會(huì)變得更容易。但如果你像我一樣喜歡玩API測試版,你可能會(huì)有一些樂趣,并在這個(gè)過程中學(xué)習(xí)一些新東西。

一旦API向公眾發(fā)布,就會(huì)產(chǎn)生更多的意識(shí),在我看來,越來越多的藍(lán)牙相關(guān)服務(wù)將在Web上而不是在原生應(yīng)用程序中進(jìn)行。這將使這項(xiàng)技術(shù)更容易為Web開發(fā)者所接受。

原文:https://blog.logrocket.com/build-bluetooth-app-chrome-bluetooth-web-api/

作者:Atharva Deosthale

參考資料

[1]Web 藍(lán)牙 API: https://www.chromestatus.com/feature/5264933985976320

 

責(zé)任編輯:武曉燕 來源: 前端全棧開發(fā)者
相關(guān)推薦

2024-04-12 15:52:42

藍(lán)牙

2024-04-10 10:11:14

藍(lán)牙藍(lán)牙網(wǎng)關(guān)

2022-08-02 22:00:30

Chrome谷歌瀏覽器

2012-10-10 09:15:56

藍(lán)牙藍(lán)牙技術(shù)聯(lián)盟

2010-03-29 09:46:54

2011-09-16 14:21:47

Web API

2010-06-13 09:22:37

jQuery

2023-02-17 17:21:17

藍(lán)牙5.0物聯(lián)網(wǎng)

2010-09-08 11:59:38

藍(lán)牙協(xié)議棧

2009-01-03 14:25:10

ibmdwWeb

2024-04-15 14:58:29

藍(lán)牙智能家居

2023-03-08 21:30:33

2009-09-22 12:59:07

ibmdwWeb

2023-12-26 00:58:53

Web應(yīng)用Go語言

2013-05-02 09:19:30

Chrome Web

2022-10-08 00:53:12

HTTP物聯(lián)網(wǎng)應(yīng)用程序

2010-09-10 09:29:29

藍(lán)牙IVT Bluelet協(xié)議棧

2020-11-19 18:14:56

國產(chǎn)

2014-12-10 10:10:00

藍(lán)牙4.2

2023-06-29 07:45:03

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)