スマートウォッチ(Wear OS by Google 2.x)からiBeacon(Bluetooth Low Energy)を発信してみた

# はじめに

スマートウォッチ単独でiBeaconを受信できたので、今度は送信してみよう！ってことでやってみました。

## できたこと

今回できたことは、以下となります。

* Casio Pro Trek smart WSD-F30 で動作
* iBeaconとして発信

## 課題(これからやること)

時間の関係上、ちょっとできなかったのは以下となります。
近いうちに作成して、GitHubに投稿しようかと思ってます。

* onPauseになると受信停止してしまう(サービス化予定)
* 発信データの画面表示・変更

# AltBeacon準備

受信にAltBeaconを利用しました。app.gradleに以下を追加します。

```gradle
...
    implementation 'org.altbeacon:android-beacon-library:2.16.2'
...
```

全体は以下となります。

```gradle:app.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.transmittingbeacon"
        minSdkVersion 26
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.android.support:wearable:2.4.0'
    implementation 'com.google.android.gms:play-services-wearable:17.0.0'
    implementation 'androidx.percentlayout:percentlayout:1.0.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.android.support:wear:28.0.0'

    implementation 'org.altbeacon:android-beacon-library:2.16.2'

    compileOnly 'com.google.android.wearable:wearable:2.4.0'
}
```

# Beacon発信

とりあえず、発信してみました。
確認はAndroid側でiBeaconを受信するアプリで実施しています。
パーミッションの設定も含めて以下のようにするとできました。

```java:MainActivity.java
package com.example.transmittingbeacon;

import android.Manifest;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseSettings;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.BeaconTransmitter;

import java.util.Arrays;

public class MainActivity extends WearableActivity {

    private TextView mTextView;

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

        mTextView = (TextView) findViewById(R.id.text);

        // Enables Always-on
        setAmbientEnabled();

        checkPermissions();
    }

    private void checkPermissions() {

        int isPermittedBluetooth = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH);
        int isPermittedBluetoothAdmin = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN);
        int isPermittedCoarseLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);

        if (isPermittedBluetooth != PackageManager.PERMISSION_GRANTED ||
                isPermittedBluetoothAdmin != PackageManager.PERMISSION_GRANTED ||
                isPermittedCoarseLocation != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(
                    new String[]{
                            Manifest.permission.BLUETOOTH,
                            Manifest.permission.BLUETOOTH_ADMIN,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                    },
                    0
            );
        } else {
            initializeBeaconTransmittion();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        initializeBeaconTransmittion();
    }

    private void initializeBeaconTransmittion() {
        Beacon beacon = new Beacon.Builder()
                .setId1("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6")
                .setId2("1")
                .setId3("2")
                .setManufacturer(0x004C)
                .setTxPower(-59)
                .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);
    }
}
```


# 参考

* [AltBeacon - Smaple Code](https://altbeacon.github.io/android-beacon-library/samples.html)