リストバンド端末をAndroidアプリからBluetoothで振動させる

# リストバンド型デバイスを制御するAndroidアプリを開発する
振動するリストバンド型デバイス、[Furueru](https://linkingiot.com/developer/devices.html)をAndroidアプリから制御します。
Furueruは1個千数百円で買えます。[Project Linking](https://linkingiot.com/)は、こういった端末を低価格で販売して、制御ライブラリを無償で提供してくれるプロジェクトで、ほかにもユニークな端末が準備されています。

[今回開発したソースコードはこちら（GitHub）](https://github.com/miltood/CallLinkingDevices)

![IMG_20190515_181043.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/cd723e91-c772-8c79-2d4f-1d1d3a1db563.jpeg)
## 開発環境
開発環境：Windows10 64bit
IDE：Androidstudioバージョン3.4
使用言語：Java
Android端末：Lenovo TB-X304Fタブレット　Androidバージョン7.1.1　Bluetooth 4.0
## 開発手順
### LinkingデバイスとAndroid端末の連携
Linkingデバイスの取扱説明書に従い、Bluetooth設定を行います。
Android端末にGooglePlayから[NTT DOCOMO製のLinkingアプリ](https://play.google.com/store/apps/details?id=com.nttdocomo.android.smartdeviceagent)をインストールします。
Linkingアプリを起動し、Linkingデバイスを検索してペアリングを行います。

以下の記事が参考になります。
[Linkingの端末をもらったのでデモアプリを試してみた](https://qiita.com/kojira/items/a8cdf4b499efb06887ea)
### Androidアプリの開発
AndroidアプリからLinkingデバイスを制御するためのライブラリとして[Linking SDKが無償で提供](https://linkingiot.com/developer/api.html)されています。
今回はアプリのボタンを押したらFurueruが振動する内容を開発します。
Androidstudioを起動し、Empty Activityを選択して、新しいプロジェクトを作成します。
言語はJavaを選択し、APIバージョンは99.6%の端末をカバーできる4.1 JellyBean（APIレベル16）にします。
![fu1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/8662fcc9-1993-ff98-f6be-5caf50192cdf.png)
画面左側のプロジェクトビューの表示をProjectにして、アプリケーションのapp/libs/の下にsdaiflib.jar（Linking SDKライブラリ）を貼り付けます。
![fu2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/804a04af-a207-18c0-3ffa-2598881f439d.png)
Linking API 仕様書に従い、app/build.gradleのdependenciesに、以下の一文を追加します。

```build.gradle
compile files('libs/sdaiflib.jar')
```
![fu3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/534a43f7-e976-4ab2-4e69-4dcd95e9cce4.png)
追加したらウィンドウ右上のSync Nowをクリックして同期を行います。
compileは古い言葉なので非推奨ですよ、と怒られました。このままでもビルドは通りますが、きちんとしたい人は以下のように書き替えて直しましょう。

```build.gradle
implementation fileTree(dir: 'libs/sdaiflib.jar')
```

画面にボタンを設置し、SDK付属のサンプルソースを参考にして、タップしたら特定の振動情報をFurueruへ送信できるように開発します。以下、javaソースとレイアウトxmlの全文です。

```MainActivity.java
package com.furueru.systems.tood.furueruapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.nttdocomo.android.sdaiflib.DeviceInfo;
import com.nttdocomo.android.sdaiflib.GetDeviceInformation;
import com.nttdocomo.android.sdaiflib.SendOther;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 画面を描画する。
        setView();
    }

    private void setView() {
        // リニアレイアウトを描画する。
        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        setContentView(linearLayout);
        // ボタンを描画する。
        Button sendButton = new Button(this);
        sendButton.setText("送信");
        linearLayout.addView(sendButton, new LinearLayout.LayoutParams(100, 100));
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 信号を送信する。
                sendMessage();
            }
        });
    }

    static final byte LINKING_IF_VIB_PATTERN_ID = 0x10;
    static final byte LINKING_IF_DURATION_ID = 0x10;

    private void sendMessage() {
        // Linkingデバイス情報を取得する。
        GetDeviceInformation deviceInformation = new GetDeviceInformation(this);
        List<DeviceInfo> deviceInfos = deviceInformation.getInformation();
        if (deviceInfos.size() == 0) {
            Toast.makeText(this, "ペアリングされたデバイスがありません", Toast.LENGTH_SHORT).show();
        }
        for (DeviceInfo deviceInfo : deviceInfos) {
            // 送信情報を設定する。
            SendOther sendOther = new SendOther(this);
            // 送信先デバイスIDを設定する。
            sendOther.setDeviceID(deviceInfo.getModelId());
            // 振動パターンを設定する。（振動PATTERN2＝35）
            sendOther.setVibration(new byte[]{LINKING_IF_VIB_PATTERN_ID, 35});
            // 動作時間を設定する。（振動時間5秒＝33）
            sendOther.setDuration(new byte[]{LINKING_IF_DURATION_ID, 33});
            sendOther.send();
        }
    }
}
```
振動PATTERNと動作時間は、SDK付属のデモアプリで動かしてみて、目的に合ったものを選ぶと良いでしょう。

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>
```
## 動作確認
Furueruの電源をONします。
Linkingアプリを起動し、デバイス（この場合、Furueru0098598）の利用設定をONにします。
デバイス設定で、連携するアプリ（この場合、FurueruApplication）をONにします。
![app1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/8fcb3634-1adc-d217-91d6-583c7dd8eb84.png)
開発したアプリを起動してみましょう。
![app2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/594b9cf3-c87b-63d6-02c3-58b808cc3918.png)
画面上のボタンをタップすると振動命令が送信されます。タップから3秒内外で、Furueruが振動を始めます。
## 所感
予想したよりも振動が激しくて、電池も長持ちします。
開発したアプリは、Linkingアプリを経由してFurueruとBluethoothで通信します。そのため、Android端末（Bluetooth親機）とFurueru（子機）の距離が離れると、Bluetoothが切断され、Linkingアプリ上で再度接続設定を行う必要があります。
直線距離では10m程度離れても切断されませんが、壁を挟むと切れてしまいました。ただ、うっかりAndroid端末と離れてしまっても、切断時に振動が起こるので、利用者は気付くことができます。切断されたまま気付かないことはなさそうで、ありがたいです。
いろいろな運用が想像できて楽しいデバイスです。