LoginSignup
36
47

More than 5 years have passed since last update.

AndroidでiBeaconの受信、送信をやってみる (AltBeacon)

Posted at

AltBeaconというライブラリを使って、iBeaconの受信と送信のやり方みたいなものを書きます。
※AltBeaconのバージョンは、2.9です。

AltBeaconを使わなくても、頑張れば実装できるのですが...
AndroidのBLE周りは、まあ...うん...アレなので、自力でやるとヤバイことになると思う...
この辺はAndroid BLE ひどいとかで検索すると大量に出てくるので、興味がある人はググってください(笑)

AltBeaconの導入

build.gradleに以下を加えます。

repositories {
    jcenter()
}
dependencies {
    compile 'org.altbeacon:android-beacon-library:2+'
}

AndroidManifestには以下を加えます。

AndroidManifest.xml
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <!--対応していない機種にインストールされないようにuser-futureを設定する-->
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
    <!--Android 6.0でBLEを使うのに位置情報のパーミッションが必要-->
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>

iBeacon受信

受信

ただ受信するだけなら、これだけで大丈夫です。

※2.9からsetMonitorNotifierがDeprecatedになり、addMonitorNotifierを使用するようになっています。

MainActivity.java
public class MainActivity extends AppCompatActivity implements BeaconConsumer {

    private static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
    private static final String UUID = "74A23A96-A479-4330-AEFF-2421B6CF443C";

    private BeaconManager beaconManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_FORMAT));

    }

    @Override
    protected void onResume() {
        super.onResume();
        // サービスの開始
        beaconManager.bind(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // サービスの停止
        beaconManager.unbind(this);
    }

    @Override
    public void onBeaconServiceConnect() {
        Identifier uuid = Identifier.parse(UUID);
        Region mRegion = new Region("ibeacon", uuid, null, null);

        beaconManager.addMonitorNotifier(new MonitorNotifier() {
            @Override
            public void didEnterRegion(Region region) {
                 // 領域侵入
            }

            @Override
            public void didExitRegion(Region region) {
                 // 領域退出
            }

            @Override
            public void didDetermineStateForRegion(int i, Region region) {
                 // 領域に対する状態が変化
            }
        });

        try {
            beaconManager.startMonitoringBeaconsInRegion(mRegion);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}

AltBeaconのデフォルト設定ではiBeaconを対象としていないので、こんな感じにBeaconParserの設定が必要です。

beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

Regionと呼ばれる監視領域を設定することで、iBeaconを検知できるようになります。
startMonitoringBeaconsInRegionで、その監視領域の設定をします。

beaconManager.startMonitoringBeaconsInRegion(new Region("ibeacon", null, null, null));

Regionの引数は、このようになっているようです。

Identifier uuid = Identifier.parse("DCE285F8-27B9-4D0E-981E-CF9C675972ED");
Identifier major = Identifier.parse("3");
Identifier minor = Identifier.parse("5");
new Region("任意のユニークID", uuid, major, minor);

iBeaconの情報を取得

iBeaconの情報を取得するにはBeaconManagerからレンジングを行う必要があります。

@Override
public void didEnterRegion(Region region) {
     //レンジングの開始
     beaconManager.startRangingBeaconsInRegion(mRegion);
}

@Override
public void didExitRegion(Region region) {
    //レンジングの停止
    beaconManager.stopRangingBeaconsInRegion(mRegion);
}

beaconManager.addRangeNotifier(new RangeNotifier() {
   @Override
   public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        // 検出したビーコンの情報
  }
});

startRangingBeaconsInRegionでレンジング開始です。
stopRangingBeaconsInRegionでレンジング停止。

今回は、didEnterRegionで開始して、didExitRegionで停止してます。

iBeaconの情報はdidRangeBeaconsInRegionで、以下のような感じで取得できます。

  • UUID: beacon.getId1()
  • major: beacon.getId2()
  • minor: beacon.getId3()
  • Distance: beacon.getDistance()
  • RSSI: beacon.getRssi()
  • Name: beacon.getBluetoothName()

iBeacon送信

iBeaconの送信ですが、こちらは制限があります。
Android5.0以上かつmultiple advertisementのHCIコマンドに対応している端末でのみ、送信可能のようです。
送信できる端末はこちらを参考にしてください。

まず始めに、Beaconの設定をします。
Id1はuuid, Id2はmajor, Id3はminorです。

Beacon beacon = new Beacon.Builder()
                .setId1(UUID)
                .setId2("1")
                .setId3("80")
                .setManufacturer(0x004C)
                .build();
BeaconParser beaconParser = new BeaconParser()
                .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
BeaconTransmitter beaconTransmitter = new BeaconTransmitter(getApplicationContext(), beaconParser);

//送信開始
beaconTransmitter.startAdvertising(beacon);

startAdvertisingで送信開始します。
AdvertiseCallbackで、送信成功か失敗かの通知を受け取ることが出来ます。

 beaconTransmitter.startAdvertising(beacon, new AdvertiseCallback() {
                @Override
                public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                    super.onStartSuccess(settingsInEffect);
                    //成功
                }

                @Override
                public void onStartFailure(int errorCode) {
                    //失敗
                }
            });

送信停止はstopAdvertisingです。

 beaconTransmitter.stopAdvertising();

isStartedで、送信しているかどうか分かります。

beaconTransmitter.isStarted()

まとめ

AltBeaconを使うと、Androidでも簡単にiBeaconを扱えます。
あ!Android6.0以上はACCESS_COARSE_LOCATIONの許可を取るのを忘れないでください。

参考サイト

36
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
47