At my work, we constantly think about ways to improve the user’s experience. One of the things I am working on is enabling our mobile app to aware of the user’s presence when the user come within proximity of certain rooms at our premise and automatically check the user in. For this check-in feature, I found a NativeScript plugin to detect iBeacons using my android phone. In this post, I am going to show you some codes in a sample NativeScript-Angular app to scan for iBeacons.
在我的工作中,我们一直在思考改善用户体验的方法。 我正在做的一件事情是让我们的移动应用程序能够在用户进入我们房屋内某些房间的附近时意识到用户的存在,并自动将用户签入。对于此签入功能,我找到了NativeScript插件使用我的Android手机检测iBeacons。 在这篇文章中,我将向您展示示例NativeScript-Angular应用中的一些代码,以扫描iBeacons。
什么是蓝牙低功耗(BLE)信标? (What is a Bluetooth Low Energy (BLE) beacon?)
Prior to Bluetooth 4.0, communications via Bluetooth had always been two ways, which means a device can both emit and receive bluetooth signals. For instance, in our daily lives, we use Bluetooth when we stream music wirelessly from smartphones to Bluetooth headsets, or connect the phones to cars’ stereo systems. In 2010, Bluetooth 4.0 came out and with it, one way communication using low energy is possible and open up innovative use cases such as proximity detection, asset tracking, and indoor wayfinding.
在蓝牙4.0之前,通过蓝牙进行通信一直是两种方式,这意味着设备既可以发射也可以接收蓝牙信号。 例如,在我们的日常生活中,当我们从智能手机无线传输音乐到蓝牙耳机或将电话连接到汽车的立体声系统时,我们会使用蓝牙。 在2010年,蓝牙4.0出现了,并实现了低能耗的单向通信,并开辟了创新的用例,例如接近检测,资产跟踪和室内寻路。
A BLE beacon is a little device that constantly emit signals using Bluetooth Low Energy (BLE). You may find them in a variety of form factors, in large retail stores, and embedded in other devices such as WIFI access points and inside smartphones. A battery-powered beacon may last several years, depending on different factors such as configuration, battery type, and manufacture. For instance, I got a development kit of beacons from Estimote two years ago, and as of today, each of those beacons still have 70% of juice left . The more frequent the advertising interval and/or the stronger the signal strength, the more energy the beacon consumes.
BLE信标是一种小型设备,可使用低功耗蓝牙(BLE)不断发出信号。 您可能会在大型零售店中以各种形式找到它们,并且将它们嵌入到其他设备中,例如WIFI接入点和智能手机内部。 电池供电的信标可能会持续数年,具体取决于不同的因素,例如配置,电池类型和制造。 例如,两年前,我从Estimote那里获得了信标开发套件,而到今天,每个信标仍剩70%的果汁。 广告间隔越频繁和/或信号强度越强,信标消耗的能量越多。
什么是iBeacon? (What is iBeacon?)
Packets of data from BLE beacons along are not helpful if we don’t understand what the data mean. However, it would be hard for developers if manufacturers come up with their own ways of encoding data into BLE beacons. It just makes sense that Apple came up with a standard way to allow a beacon to provide contextual information by assigning the beacon with hierarchy ids which are uuid, major, mior and tx power.
如果我们不了解数据的含义,那么来自BLE信标的数据包将无济于事。 但是,如果制造商想出自己的将数据编码到BLE信标中的方式,对开发人员来说将很困难。 苹果提出了一种标准方法,允许信标通过为信标分配uuid,major,mior和tx power的层次结构ID来提供上下文信息,这是有道理的。
UUID: 16-bytes string for identifying a set of beacons that belong to a large group.
UUID :16字节的字符串,用于标识属于大型组的一组信标。
Major: 2-byte string for identifying a set of beacons that belong to a subset of beacons within the large group which is identifiable by the UUID.
Major :2字节的字符串,用于标识属于大组中的信标子集的信标集,UUID可以识别该信标。
Minor: 2-byte string for identifying an individual beacon beacon within a group identifiable by the major id.
次要的 :2字节的字符串,用于标识由主要ID标识的组中的单个信标信标。
Tx power: The signal strength emitting from a beacon 1 meter away from its location.
发射功率 :从距离其位置1米的信标发射的信号强度。
iBeacon has become a protocol which both Android and iOS support. As a side note, Eddystone is another protocol developed by Google for communicating using BLE. An Eddystone compatible beacon transmits data in a different format than iBeacon. However, in this post, we are not going to discuss about Eddystone.
iBeacon已成为Android和iOS支持的协议。 附带说明一下,Eddystone是Google为使用BLE进行通信而开发的另一种协议。 与Eddystone兼容的信标以不同于iBeacon的格式传输数据。 但是,在本文中,我们将不讨论Eddystone。
在带有角度的NativeScript应用程序中检测iBeacon。 (Detect iBeacon in a NativeScript-with-angular app.)
Both iOS and Android SDKs natively support scanning for iBeacons. For NativeScript, you can use a plugin or write your own. Fortunately, I found an existing plugin, the iBeacon plugin by demetrio812 which works and that is what I’m using.
iOS和Android SDK本身都支持扫描iBeacons。 对于NativeScript,您可以使用插件或编写自己的插件。 幸运的是,我找到了一个现有的插件,即demetrio812的iBeacon插件,它可以正常工作,而这正是我正在使用的插件 。

If you head to the web page of the plugin, you can see instructions for installing and using it in your NativeScript application. For the most part, the document provides good enough info to get started. I was able to quickly prototype a sample NativeScript-Angular project and use the plugin to scan for iBeacons. Below I show the sample codes I have in my app.component:
如果您转到插件的网页,则可以在NativeScript应用程序中看到有关安装和使用它的说明。 在大多数情况下,该文档提供了足够的入门信息。 我能够快速创建一个示例NativeScript-Angular项目的原型,并使用该插件扫描iBeacons。 下面显示了我在app.component中的示例代码:
import { Component, OnInit, OnDestroy } from "@angular/core";
import { NativescriptIbeacon } from 'nativescript-ibeacon';
import { BeaconLocationOptions, BeaconLocationOptionsIOSAuthType,
BeaconLocationOptionsAndroidAuthType, BeaconRegion, Beacon } from 'nativescript-ibeacon/nativescript-ibeacon.common';
@Component({
selector: "ns-app",
templateUrl: "./app.component.html"
})
export class AppComponent implements OnInit, OnDestroy {
private _nativescriptIbeacon;
private _region;
constructor () {
var myIbeacon = {
id: "My iBeacon in conference room of Office A ",
proximityUUID: "B9407F30-F5F8-466E-AFF9-25556B57FE6D",
major: 17744,
minor: 28116
}
this._region = new BeaconRegion(myIbeacon.id, myIbeacon.proximityUUID, myIbeacon.major, myIbeacon.minor);
let options: BeaconLocationOptions = {
iOSAuthorisationType: BeaconLocationOptionsIOSAuthType.Always,
androidAuthorisationType: BeaconLocationOptionsAndroidAuthType.Fine,
androidAuthorisationDescription: "Location permission needed"
};
this._nativescriptIbeacon = new NativescriptIbeacon(this.beaconCallback(), options);
if (!this._nativescriptIbeacon.isAuthorised()) {
console.log("NOT Authorised");
this._nativescriptIbeacon.requestAuthorization()
.then(() => {
console.log("Authorised by the user");
this._nativescriptIbeacon.bind();
}, (e) => {
console.log("Authorisation denied by the user");
})
} else {
console.log("Already authorised");
this._nativescriptIbeacon.bind();
}
}
ngOnDestroy(): void {
if (this._nativescriptIbeacon) {
this._nativescriptIbeacon.unbind();
}
}
beaconCallback() {
var self = this;
return {
onBeaconManagerReady(): void {
// start ranging and/or monitoring only when the beacon manager is ready
self._nativescriptIbeacon.startRanging(self._region);
self._nativescriptIbeacon.startMonitoring(self._region);
},
didRangeBeaconsInRegion: function(region: BeaconRegion, beacons: Beacon[]) {
console.log(JSON.stringify(beacons));
},
didFailRangingBeaconsInRegion: function(region: BeaconRegion, errorCode: number, errorDescription: string) {
console.error(`Failed to find beacons with errorCode: ${errorCode} and description:
${errorDescription}`);
},
didEnterRegion: function(region: BeaconRegion) {
console.log("Did enter region called");
},
didExitRegion: function(region: BeaconRegion) {
console.log("Did exit region called.");
}
}
}
ngOnInit(): void {
}
}
For the most part, the codes are straightforward and based on the plugin’s documentation. However, a few things you may want to pay attention:
在大多数情况下,代码是简单明了的,并且基于插件的文档。 但是,您可能需要注意以下几点:
BeaconRegion
encapsulates metadata you define for scanning beacons. You can scan for all the beacons having a same uuid. You can also narrow the scan to a specific group by supplying the major id, and further to a specific beacon by supplying the minor id.BeaconRegion
封装了您定义的用于扫描信标的元数据。 您可以扫描所有具有相同uuid的信标。 您还可以通过提供主要ID将扫描范围缩小到特定的组,并通过提供次要ID将扫描范围缩小到特定的信标。On the android device, be sure to gain your apps access to Location. You can do so by going to Settings -> Apps -> {your app} -> Permissions and enable Location.
在android设备上,请确保您的应用访问“位置”。 为此,您可以转到设置->应用-> {您的应用}->权限并启用位置 。
In
beaconCallback()
method, I use closure to capture the reference to my app component. That is because the method is a callback, which means the object which invokes it at a later time is not my app component, but rather some objects in the plugin. Therefore, had I use this keyword to access the objects defined in my app component, I would get errors because of accessing properties on an undefined object. This is just JavaScript.在
beaconCallback()
方法中,我使用闭包捕获对我的应用程序组件的引用。 那是因为该方法是一个回调,这意味着稍后调用它的对象不是我的应用程序组件,而是插件中的某些对象。 因此,如果我使用此关键字来访问在我的应用程序组件中定义的对象,则由于访问未定义对象上的属性而会出错。 这只是JavaScript。
This is what I get in the console, which let me know things work when I run the app on my android device:
这是我在控制台中获得的信息,当我在android设备上运行该应用程序时,它可以让我知道一切正常:
onBeaconServiceConnect JS: startRanging JS: startRangingBeaconsInRegion JS: startMonitoring JS: didDetermineStateForRegion JS: 1 JS: id1: b9407f30-f5f8-466e-aff9-25556b57fe6d id2: 17744 id3: 28116 JS: [{"proximityUUID":"b9407f30-f5f8-466e-aff9-25556b57fe6d","major":17744,"minor":28116,"distance_proximity":0.13055123127828835,"rssi":-60,"txPower_accuracy":-76}]
That’s it. Thanks for reading and happy coding.
而已。 感谢您的阅读和愉快的编码。
Originally published at https://www.taithienbo.com on May 4, 2020.
最初于 2020年5月4日 在 https://www.taithienbo.com 上 发布 。