Monaca Docs
検索…
iBeacon
iBeacon ( アイビーコン ) サービスを組み込んだサンプルアプリです。iBeacon 発信機との距離を検知します。こちらの Monaca アプリでは、Onsen UI を使用して、UI を構築しています。iBeacon 発信機の射程内に携帯端末が入ると、発信機の UUID が画面上に表示されます ( このサンプルでは、アプリが起動中であること、発信機は端末側に登録済みであることが必要です )。
サードパーティー製 Cordova プラグインを確認する場合は、カスタムビルドデバッガー ( Android 版 または iOS 版 ) を作成する必要があります。

デモ

テスト環境
  • Android 11.0
  • iOS 14.3

事前準備

  1. 1.
    iBeacon プラグインを こちら からダウンロードして、Monaca クラウド IDE 上にインポートします。詳細は、ユーザー Cordova プラグインのインポートをご確認ください。
  2. 2.
    対象とする iBeacon 発信機を決めます ( 最低限 1 つ )。
  3. 3.
    専用のユーティリティー ソフトウェアを使用して、iBeacon 発信機側の情報を入手します。ここでは、 MyBeacon Tool を使用します。
  4. 4.
    iBeacon 発信機の UUID のメモを取ります。

ファイル構成

ファイル
説明
index.html
スタート画面のページ ( 接続画面で構成 )
top_page.html
アプリのトップページ
info_page.html
iBeacon 発信機側の情報を表示するページ
js/app.js
アプリの動作を制御する JavaScript のファイル
css/style.css
アプリのスタイルシート

必要な JS/CSS コンポーネント

  • Onsen UI

必要な Cordova プラグイン

HTML の解説

ユーザー インターフェースには、Onsen UI を使用しています。 Onsen UI のタグとそのコンポーネントの詳細は、Onsen UI ドキュメント をご確認ください。
index.html ファイル内の次の記述 ( HTML の <body> 内 ) で、 top-page.html ファイルを起動時に読み込みます。
...
<ons-navigator var="myNavigator" page="top-page.html"></ons-navigator>
...
top-page.html ファイル内の次の記述 ( HTML の <body> 内 ) で、登録済みの iBeacon 発信機の一覧と距離情報を表示します。
<ons-page ng-controller="TopPageCtrl">
<ons-toolbar>
<div class="center">iBeacon Testing</div>
</ons-toolbar>
<ons-list modifier="inset" style="margin: 10px">
<ons-list-item class="list-item-container" ng-repeat="(uuid, beacon) in beacons">
<ons-row>
<ons-col width="70px">
<img ng-src="{{beacon.icon}}" class="top-page-icon">
</ons-col>
<ons-col>
<div class="top-page-name">{{beacon.name}}</div>
<div class="top-page-proximity">{{beacon.proximity}}</div>
<div class="top-page-proximity">{{beacon.rssi}} dBm</div>
</ons-col>
</ons-row>
</ons-list-item>
</ons-list>
</ons-page>
info-page.html ファイル内の次の記述 ( HTML の <body> 内 ) で、最も近接する iBeacon 発信機の情報 ( UUID ) を表示します。
<ons-page ng-controller="InfoPageCtrl">
<ons-toolbar>
<div class="left"><ons-back-button>Back</ons-back-button></div>
<div class="center">{{beacon.name}}</div>
</ons-toolbar>
<ons-list>
<ons-list-item class="list-item-container">
<ons-row>
<ons-col width="110px">
<img src="{{beacon.icon}}" class="info-page-img">
</ons-col>
<ons-col>
<div class="info-page-description">
<p style="text-decoration: underline;">UUID</p>
{{beaconUuid}}
</div>
</ons-col>
</ons-row>
</ons-list-item>
</ons-list>
</ons-page>

JavaScript の解説

このサンプルアプリの JavaScript には、AngularJS を使用しています。AngularJS では、連携するページのそれぞれに、コントローラー関数を設置します。このサンプルでは、 TopPageCtrlInfoPageCtrl の 2 つのコントローラー関数を使用しており、それぞれ、 top-page.html ページ、 info-page.html ページに紐付けされています。これらのコントローラー関数間で使用するグローバル変数を作成するため、グローバル変数を格納する service 関数を、次のように、1 つ作成します。
...
app.service('iBeaconService', function() {
this.currentBeaconUuid = null;
this.onDetectCallback = function(){};
var beacons = {
"00000000-EA98-1001-B000-001C4D9C64FA": {icon: 'img/1.jpg', rssi: -63, proximity: PROX_UNKNOWN, name: 'JIBBER', number: '1', id: '000265C9', major: 1, minor: 1},
"F5A10AF9-A670-4F54-B491-8607393F0DDC": {icon: 'img/2.jpg', rssi: -63, proximity: PROX_UNKNOWN, name: 'BUONO', number: '2', id: '0002D08D', major: 1, minor: 1},
"ABE425B2-0000-4409-8035-1668AFC7FCFE": {icon: 'img/3.jpg', rssi: -63, proximity: PROX_UNKNOWN, name: 'LION', number: '3', id: '00029BAA', major: 1, minor: 1},
"BC564E82-0000-43A3-94E7-1D54EC02622D": {icon: 'img/4.jpg', rssi: -63, proximity: PROX_UNKNOWN, name: 'COMA', number: '4', id: '0003F321', major: 1, minor: 1},
"6F29CF85-0000-414A-A7A6-6206A2DA9773": {icon: 'img/5.jpg', rssi: -63, proximity: PROX_UNKNOWN, name: 'GNAR', number: '5', id: '00027EA8', major: 1, minor: 1},
"EEB52632-0000-47E2-8C15-897494E12015": {icon: 'img/6.jpg', rssi: -63, proximity: PROX_UNKNOWN, name: 'TEEMO', number: '6', id: '00032449', major: 1, minor: 1}
};
this.beacons = beacons;
createBeacons = function() {
var result = [];
try {
angular.forEach(beacons, function(value, key) {
result.push(new cordova.plugins.locationManager.BeaconRegion(value.id, key, value.major, value.minor));
});
} catch (e) {
console.log('createBeacon err: ' + e);
}
return result;
};
this.watchBeacons = function(callback){
document.addEventListener("deviceready", function(){
var deviceVersion = window.device ? device.version : '';
var beacons = createBeacons();
try {
var delegate = new cordova.plugins.locationManager.Delegate();
delegate.didDetermineStateForRegion = function (pluginResult) {
console.log('[DOM] didDetermineStateForRegion: ' + JSON.stringify(pluginResult));
cordova.plugins.locationManager.appendToDeviceLog('[DOM] didDetermineStateForRegion: '
+ JSON.stringify(pluginResult));
};
delegate.didStartMonitoringForRegion = function (pluginResult) {
console.log('didStartMonitoringForRegion:', pluginResult);
console.log('didStartMonitoringForRegion:' + JSON.stringify(pluginResult));
};
delegate.didRangeBeaconsInRegion = function (pluginResult) {
var beaconData = pluginResult.beacons[0];
var uuid = pluginResult.region.uuid.toUpperCase();
if (!beaconData || !uuid) {
return;
}
callback(beaconData, uuid);
console.log('[DOM] didRangeBeaconsInRegion: ' + JSON.stringify(pluginResult));
};
cordova.plugins.locationManager.setDelegate(delegate);
// required in iOS 8+
cordova.plugins.locationManager.requestWhenInUseAuthorization();
// or cordova.plugins.locationManager.requestAlwaysAuthorization()
beacons.forEach(function(beacon) {
cordova.plugins.locationManager.startRangingBeaconsInRegion(beacon);
});
} catch (e) {
console.log('Delegate err: ' + e);
}
}, false);
};
});
...
service 関数内で行っていることを、解説します。
  • 登録済み iBeacon 発信機の情報 ( UUID、距離、名称、アイコンファイルなど ) を格納する配列の作成。
  • 近接する iBeacon 発信機の検知、および、最も近接する発信機の UUID の取得を行う関数の作成。
各コントローラーに関して解説します。

TopPageCtrl

TopPageCtrl は、 top-page.html ファイル内の各種処理を行っています。近接する iBeacon 発信機の検知を、主に行っています。登録済みの iBeacon 発信機が検知された場合、その proximity ( 近接度 ) と rssi ( 受信信号の強度指数 / received signal strength indicator ) が更新されます。検知できない場合、その発信機の proximity 値は ProximityUnknown になり、rssi 値は -63 dBm になります。
この関数の JavaScript コードを、次に記します。
...
app.controller('TopPageCtrl', ['$scope', 'iBeaconService', function($scope, iBeaconService) {
$scope.beacons = iBeaconService.beacons;
var callback = function(deviceData, uuid)
{
var beacon = $scope.beacons[uuid];
$scope.$apply(function()
{
beacon.rssi = deviceData.rssi;
switch (deviceData.proximity)
{
case PROX_IMMEDIATE:
beacon.proximity = 'Immediate';
break;
case PROX_NEAR:
beacon.proximity = 'Near';
break;
case PROX_FAR:
beacon.proximity = 'Far';
break;
case PROX_UNKNOWN:
default:
break;
}
if (iBeaconService.currentBeaconUuid === null && beacon.rssi > -45) {
$scope.enterInfoPage(uuid);
}
});
};
iBeaconService.watchBeacons(callback);
$scope.enterInfoPage = function(currentUuid) {
iBeaconService.currentBeaconUuid = currentUuid;
$scope.ons.navigator.pushPage('info-page.html');
$scope.ons.navigator.on("prepop", function() {
iBeaconService.currentBeaconUuid = null;
});
};
}]);
...

InfoPageCtrl

InfoPageCtrl は、 info-page.html ファイル内の各種処理を行っています。このコントローラ関数では、主に、 iBeaconService 経由で渡された UUID 値を使用して、最も近接する iBeacon 発信機の UUID を表示します。この解説で使用している 「 最も近接 」 とは、iBeacon 用語の 「 Immediate 」 ( 3 段階評価の最も近いこと ) を意味します。これ以外の場合には、 info-page.html が表示されません。
この関数の JavaScript コードを、次に記します。
...
app.controller('InfoPageCtrl', ['$scope', 'iBeaconService', function($scope, iBeaconService) {
$scope.beacon = iBeaconService.beacons[iBeaconService.currentBeaconUuid];
$scope.beaconUuid = iBeaconService.currentBeaconUuid;
}]);
...