SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事(AD)

ソフトとハードのつくり手が自由につながるIoTプラットフォーム「Linking」の概要と使い方

  • このエントリーをはてなブックマークに追加

 近年、スマートウォッチや活動量計など、スマートフォンアプリと連携できるデバイスが登場し、IoTが身近になってきました。みなさんの中にも、すでに大手メーカーから発売されているものをチェックしたり、クラウドファウンディングサイトでプロジェクトを支援したりすることで、このようなデバイスを手に入れた方も多いのではないでしょうか。しかし、これらデバイスのプラットフォームには、デバイスに対して専用アプリのみでしか連携ができないという課題があります。今回ご紹介する「Linking」は、誰でも無料で使用することができ、スマートフォンとデバイスを自由につなぐことができるIoTプラットフォームです。

  • このエントリーをはてなブックマークに追加

はじめに

 Linkingとは、NTTドコモ等の複数の国内企業が連携して発表した、スマートフォン内のアプリケーションとスマートフォン外部の周辺デバイスとを連携させるためのプラットフォームです。

 Linkingに対応したアプリケーションとデバイスであれば自由に組み合わせて利用することができるため、さまざまなサービスとデバイスの連携が容易になり、ウェアラブルやIoTをより手軽に体験することができます。

図1 Linking(開発者サイトより引用)
図1 Linking(開発者サイトより引用)

 具体的には周辺デバイスとアプリケーション間のBluetooth Low Energy(以降、BLE)による通信を「Linking」が仲介します。それによって、アプリケーションは周辺デバイス毎にプロファイルを意識することなく、Linkingを介して周辺デバイスから必要なデータの取得や送信を行うことが可能になり、容易に周辺デバイスとのBLE通信を実現することができます。

図2 Linkingを利用したBLE通信
図2 Linkingを利用したBLE通信

 本記事では、「Linking」の概要と使用方法について、サンプルコードを交えながら紹介していきます。

備考

 LinkingはiOSとAndroid両方に対応していますが、本記事ではAndroidに絞って解説を行います。

対象読者

  • BLEデバイスとスマートフォンを連携したサービスを考えている方
  • Androidアプリ開発者の方

必要な環境

  • Androidアプリの開発環境
  • Linking対応デバイス

 本記事ではAndroid Studioにて説明を行います。Android SDKおよびAndroid Studioは、Android Developersサイトを参考にして環境を整えておいてください。

図3 Android Studio/SDKのダウンロード
図3 Android Studio/SDKのダウンロード

Linking対応デバイス

 現在Linkingに対応しているデバイスは以下のものがあります。

Tomoru

 Tomoruは、光ることと、スマートフォンからの距離が分かることの2つの機能を持つシンプルなデバイスです。クラウドファンディングサイトMakuakeにて支援を募っていた際には、一個1500円という安価な価格で手に入れることができました(Makuakeでの支援は終了しています)。

 大きさも縦横38mm程度で、少し大きめのキーホルダー程度です。とても軽量で、ボタン電池1個分程度の重さしかありません。

図4 鍵に装着(点灯状態)
図4 鍵に装着(点灯状態)

 機能はシンプルですが、アプリ開発者の発想次第でさまざまなサービスを作り出すことができます。

 例えば、Tomoruはスマートフォンからの距離が変更されたときに通知を送ることができるので、鍵などの大事なモノにつけておくことで忘れ物があったことを知らせてくれます。

 また、お子様の持ち物に取り着けておくことで、お子様がご自身から離れてしまった場合にも知らせてくれます。

 さらに、傘に取りつけておけば、天気予報APIを利用して雨の日だけTomoruが光り、傘を持っていくことを知らせてくれるようにすることも可能です。

 これまで紹介したアプリは以下からダウンロード可能です。

 自由にカスタマイズを行えるのはアプリケーション側だけではありません。Linkingでは、デバイス開発者向けにAPI仕様書を公開しています。

 デバイス側の仕様書は、下記のLinkingの開発者向けサイトからダウンロードが可能です。

 デバイスをLinkingに対応させることで、デバイスに搭載されている各種センサーなどの情報を取得することができます。

 例えば図5のLinking対応の開発用ボードは、バイブレータ、ボタン操作、LED、方位センサー、ジャイロセンサー、加速度センサーなどの機能が搭載されています(Makuakeでの支援は終了しています)。

図5 Makuakeにて販売されていた開発ボード(引用:Makuake)
図5 Makuakeにて販売されていた開発ボード(引用:Makuake

 Linkingを利用する開発者とユーザーは、従来のデバイスのプラットフォームに比べ、より多くのアプリケーションとデバイスを組み合わせてさまざまなサービスを利用することができます。開発者とユーザーの自由な発想により、もっと身近で、多彩なIoTを体験することができるのはLinkingならではの特徴です。

ダウンロード

 Linkingの開発にあたり、まずはAPI仕様書/SDKのダウンロードを行います。

 デバイスおよびアプリケーションのAPI仕様書/SDKは、Linkingの開発者サイトからダウンロードが可能です。

SDK/API仕様書のダウンロード

 開発者サイトに移動したら、まず利用規約をよく読み、同意してからダウンロードを行います。

図6 Linking開発者サイト

図6 Linking開発者サイト

 「利用規約に同意する」をチェックすると、デバイス開発者向けのAPI仕様書、Android/iOSアプリケーションのAPI仕様書/SDKのダウンロードが可能になります。

 本記事ではAndroid版のAPI仕様書/SDKをダウンロードします。すると、アンケート画面に移動しますので、アンケートの内容を記載します。

図7 Linkingアンケート
図7 Linkingアンケート

 アンケートが完了すると、ダウンロード画面に移動するので、後はダウンロードすることでAPI仕様書/SDKを入手することができます。

図8 Linkingダウンロード
図8 Linkingダウンロード

SDKの反映方法

 利用したいプロジェクトにダウンロードしてきた「sdaiflib.jar」をコピーし、プロジェクトの「libs」直下に配置します。

図9 SDKの配置
図9 SDKの配置

 そして、プロジェクトの「build.gradle」に以下の一文を追加します。

build.gradle
dependencies {
  ~中略~
   compile files('libs/sdaiflib.jar')
}

 これで周辺デバイスとアプリの連携機能が利用できるようになりました。

図10 SDKの反映確認
図10 SDKの反映確認

Linkingでできること

構成

 AndroidでのLinkingは、「周辺デバイス」「Linkingアプリ」「サービスアプリ」の3つの要素で構成されています。Linkingアプリは、周辺デバイスとサービスアプリとの連携を管理する機能を持ち、連携インターフェース(以降、連携IF)を提供します。

図11 Linkingの構成図
図11 Linkingの構成図

Linkingアプリ

 周辺デバイスとサービスアプリの接続状態の確認や、連携内容について設定・管理します。

連携IF

 連携IFには周辺デバイス向けとサービスアプリ向けの2種類が存在します。

 周辺デバイス向けの連携IFでは、周辺デバイスと通信するためのBluetoothプロファイルを規定します。LinkingアプリはOS提供のBLEを操作するAPIと定義されたプロファイルを利用して、周辺デバイスと連携します。

 サービスアプリ向け連携IFは、主にAndroidのブロードキャストインテントを利用して、Linkingアプリとの連携を行うためのAPIです。実行したい機能ごとに定義されたブロードキャストインテントを送信し、Linkingアプリに周辺デバイスとの連携依頼をします。

 この2つの連携IFがつながることで「周辺デバイスとサービスアプリの連携」を実現しています。

 例えば、サービスアプリから周辺デバイスのデータを取得する場合、以下のような動作となります。

  1. サービスアプリからLinkingアプリへブロードキャストにてデータ取得要求を行う
  2. Linkingアプリはブロードキャストを受けて、周辺デバイスとの通信を行う
  3. Linkingアプリは周辺デバイスからの応答を受け、取得した情報をブロードキャストにてサービスアプリに渡す

 このような構成にすることで、複数のアプリが周辺デバイスからの通知を受信することが可能になります。結果、開発者および利用者は特定のデバイスと専用アプリケーションに縛られることなく、アプリケーションと周辺デバイスの組み合わせを自由に行うことができます。

図12 ブロードキャストの構成図

図12 ブロードキャストの構成図

機能一覧

 Linkingで利用できる機能の概要は以下の通りです。

表 Linkingで利用できる機能の概要
機能 内容
Notification AndroidのNotificationに相当する内容(タイトル、本文)を周辺デバイスへ通知します。
メール通知 メールに関する内容を周辺デバイスへ通知します。
スケジュール通知 スケジュールに関する内容を周辺デバイスへ通知します。
その他通知 Notification・メール通知・スケジュール通知に当てはまらない、その他の情報を周辺デバイスに通知するときに使用します。
※Notificationではタイトル、本文、アイコンを通知できるのに対し、複数のデータファイル、 画像、メディアを通知することができます。
接続デバイス情報の取得 Linkingアプリで保持しているデバイスの情報を取得します。
センサーデータの取得開始/停止 周辺デバイスへセンサーデータの取得開始/停止依頼を行います。
ビーコンのスキャン開始/停止 ビーコンの定期的なスキャン開始/停止を行います。
ビーコンのスキャン結果/状態通知 ビーコンスキャン結果/状態を通知します。
サービスアプリへの通知を受信 周辺デバイスからサービスアプリへ通知を受信します。
距離変更通知 Linkingアプリと周辺デバイスとの距離が変更したことを通知します。
周辺デバイス接続/切断通知を受信 Linkingアプリと周辺デバイスとの接続/切断通知を受信します。
※その周辺デバイスの情報が渡されます。

Linkingアプリと周辺デバイスの接続

 Linkingアプリと周辺デバイスとの接続方法について説明します。Linkingアプリでは、デバイスとの接続状態を確認することができます。

 周辺デバイスとLinkingアプリを連携するには、まずダウンロードしたLinkingアプリを起動します。初回起動時には利用規約画面が表示されます。内容をよく確認してから同意し、次に進んでください。

 Linkingアプリを起動すると以下のような画面が表示されます。

 Linking対応デバイスと接続するには、「接続デバイスの検索」をタップして、デバイスを検索します。Bluetoothの設定がOFFだった場合には、ONに設定するダイアログが表示されます。

図13 起動画面
図13 起動画面

 見つかったデバイスを選択して、注意事項をよく読んで接続を開始します。

図14 デバイス検索結果(左)、接続確認画面(右)
図14 デバイス検索結果(左)、接続確認画面(右)

 これで周辺デバイスとの接続は完了しました。次回から、Linkingアプリを起動する場合は図15のように表示されます。

 ON/OFFのトグルスイッチを切り替えることで、接続のON/OFFを切り替えることができます。

図15 接続中(左)、切断状態(右)
図15 接続中(左)、切断状態(右)

 ビーコンの連携も同様にトグルのON/OFFで切り替えることができます。ビーコンとの連携は、周辺デバイスと接続していなくても利用可能です。

図16 ビーコン機能有効確認(左)、ビーコン機能有効状態(右)
図16 ビーコン機能有効確認(左)、ビーコン機能有効状態(右)

 「ビーコンデバイス」をタップすることで、ビーコンデバイス機能を利用できるアプリを確認することができます。

図17 ビーコンデバイス利用アプリの確認
図17 ビーコンデバイス利用アプリの確認

 次に、接続したデバイスからの通知を許可するアプリを設定します。

 接続したデバイスをタップすると、図18の設定画面に移動します。この画面で、通知を許可したいアプリのトグルスイッチをONにすることで、デバイスからの通知を受信することができるようになります。

図18 通知状態の設定
図18 通知状態の設定

 Linkingアプリからの通知を受けるには、サービスアプリのマニフェストファイルに以下のように周辺機器通知対応の宣言を記載しておく必要があります。

AndroidManifest.xml
<application
   ~中略~
   <meta-data
     android:name="com.nttdocomo.android.smartdeviceagent.feature.support"
     android:value="true" />
   ~中略~
</application>

 以上で、デバイスとLinkingの接続は完了しました。

 また、アプリケーションから起動する場合は以下の通りです。Define#SDA_PACKAGEにLinkingのパッケージ名が定義されていますので、指定する場合はそちらを使用して起動させます。

使用例
import com.nttdocomo.android.sdaiflib.Define;

PackageManager pm = getPackageManager();
Intent i = pm.getLaunchIntentForPackage(Define.SDA_PACKAGE);
if (i != null) {
    startActivity(i);
} else {
    Toast.makeText(this, "Linkingアプリがインストールされていません。", Toast.LENGTH_LONG).show();
}

Linkingアプリ接続/切断検知方法

 次に、Linkingアプリと周辺デバイスの接続/切断を検知する方法について説明します。

 NotifyConnectクラスにobserver(NotifyConnect.ConnectInterface)を設定することで接続/切断通知を受けることが可能になります。

 そして、通知を受けた時の情報は、以下の名称でローカルデータとしてSharedPreferencesに格納されます。

  • 接続情報:DeviceConnectInformation
  • 切断情報:DeviceDisconnectInformation

 今回はLinkingServiceを実装することで、バックグラウンドでも周辺デバイスに対する接続/切断を検知しNotificationを表示できるようにします。

LinkingService.java
import com.nttdocomo.android.sdaiflib.Define;
import com.nttdocomo.android.sdaiflib.NotifyConnect;

public class LinkingService extends Service {
    private NotifyConnect mNotifyConnect;
    private MyConnectInterface mMyConnectInterface;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mMyConnectInterface = new MyConnectInterface();
        mNotifyConnect = new NotifyConnect(this, mMyConnectInterface);
    }

   @Override
   protected void onDestroy() {
       super.onDestroy();
       mNotifyConnect.release();
   }

    private void sendNotification(String title, String text){
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this)
                        .setSmallIcon(android.R.drawable.sym_def_app_icon)
                        .setContentTitle(title)
                        .setContentText(text);


        NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(this);
        notificationManager.notify(0, notificationBuilder.build());
    }

    // 接続と切断の通知を受信する
    class MyConnectInterface implements NotifyConnect.ConnectInterface {
        @Override
        public void onConnect() {
            // 接続通知
            SharedPreferences preference = getSharedPreferences(Define.ConnectInfo, Context.MODE_PRIVATE);
            String deviceName = preference.getString("DEVICE_NAME", "");
            sendNotification("接続通知", "デバイス[" + deviceName +"]が接続されました");
        }

        @Override
        public void onDisconnect() {
            // 切断通知
            SharedPreferences preference = getSharedPreferences(Define.DisconnectInfo, Context.MODE_PRIVATE);
            String deviceName = preference.getString("DEVICE_NAME", "");
            sendNotification("切断通知", "デバイス[" + deviceName +"]切断されました");
        }
    }
}

ビーコンからデータを受信

 次に、ビーコンからデータを受信する方法について説明します。

 BeaconScannerクラスを利用することで、ビーコンのスキャン開始/停止依頼を行うことができます。スキャンは定期的に実行され、ビーコンが検出された場合にはビーコンの情報を取得することができます。

 マニフェストファイルには、ビーコン機器通知対応の宣言を記載してください。また受信するレシーバークラスには、IntentFilterの設定が必要です。

AndroidManifest.xml
<application>
   ~中略~
   <meta-data
     android:name="com.nttdocomo.android.smartdeviceagent.feature.beacon" android:value="true" />
   ~中略~

    <receiver
        android:name=".MainActivity$MyBeaconReceiverBase"
        android:exported="true" >
        <intent-filter>
            <action android:name="com.nttdocomo.android.smartdeviceagent.action.BEACON_SCAN_RESULT" />
            <action android:name="com.nttdocomo.android.smartdeviceagent.action.BEACON_SCAN_STATE" />
        </intent-filter>
    </receiver>
</application>
MainActivity.java
import com.nttdocomo.android.sdaiflib.BeaconData;
import com.nttdocomo.android.sdaiflib.BeaconReceiverBase;
import com.nttdocomo.android.sdaiflib.BeaconScanner;

public class MainActivity extends Activity {

    private BeaconScanner mBeaconScanner;
    private MyBeaconReceiverBase mMyBeaconReceiverBase;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ~中略~
        mBeaconScanner = new BeaconScanner(this);
        mMyBeaconReceiverBase = new MyBeaconReceiverBase();
    }

    public void onStartBeaconScan(View view) {
        // サービスIDを指定
        // すべての検出されたビーコンサービスID/データが含まれるビーコン情報を通知
        mBeaconScanner.startScan(new int[] {0} );
    }

    public void onStopBeaconScan(View view) {
        // スキャン停止依頼
        mBeaconScanner.stopScan();
    }

    // ビーコンスキャンの結果を受信するレシーバー
    public static class MyBeaconReceiverBase extends BeaconReceiverBase {

        public MyBeaconReceiverBase() {
        }

        @Override
        protected void onReceiveScanResult(BeaconData beaconData) {
            Log.d(TAG, "ビーコン検出時間" + beaconData.getTimestamp());
            Log.d(TAG, "距離の種別:" + beaconData.getDistance());
            Log.d(TAG, "バッテリー:" + beaconData.getBatteryPower() + "%");
        }

        @Override
        protected void onReceiveScanState(int scanState, int detail) {
            if (scanState == 0 && detail == 0) {
                Log.d(TAG, "スキャン実行中");
            } else {
                Log.d(TAG, "スキャン要求に失敗しました : " + detail);
            }
        }
    }
}

周辺デバイス情報の取得

 次に、周辺デバイスの情報を取得する方法を紹介します。ここでは下記のような、Linkingアプリへ接続履歴のあるデバイスについての情報と、周辺デバイスのセンサーデータの取得に関する操作について説明します。

  • 接続機器情報の取得
    • 周辺デバイスの情報を取得することができます。
  • センサーデータの取得
    • 周辺デバイスのセンサーデータを取得開始/停止することができます。

接続機器情報の取得

 Linkingアプリで保持しているデバイスの情報の取得方法について紹介します。

 GetDeviceInformationを使用して、接続履歴のあるデバイス情報を取得することができます。

備考

 ContentResolverを利用してデバイス情報を取得するため、GetDeviceInformationのコンストラクタには必ずContextを渡すようにしてください。

使用例
import com.nttdocomo.android.sdaiflib.DeviceInfo;
import com.nttdocomo.android.sdaiflib.GetDeviceInformation;

public void getDeviceInfo() {
    GetDeviceInformation deviceInfo = new GetDeviceInformation(getApplicationContext()
);
    List<DeviceInfo> devices = deviceInfo.getInformation();
    for (DeviceInfo info : devices) {
        Log.d(TAG, "Device name : " + info.getName() + " BD address : " + info.getBdaddress());
    }
}

センサーデータの取得

 周辺機器のセンサーデータの取得方法について説明します。

 ControlSensorDataクラスにobserver(ControlSensorData.SensorDataInterface)を設定することでセンサーデータを取得やセンサーデータの停止通知を受信することができます。

 また、センサーデータの取得を開始依頼の結果は、Activity#onActivityResultの第2引数に結果が返却されます。そのため、Activity内のonActivityResult内に結果毎の処理を実装してください。

import com.nttdocomo.android.sdaiflib.ControlSensorData;
import com.nttdocomo.android.sdaiflib.DeviceInfo;
import com.nttdocomo.android.sdaiflib.ErrorCode;
import com.nttdocomo.android.sdaiflib.GetDeviceInformation;

public class MainActivity extends Activity {

    private ControlSensorData mSensorData;
    private MySensorDataInterface mySensorDataInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ~中略~
        // ControlSensorData
        mySensorDataInterface = new MySensorDataInterface();
        mSensorData = new ControlSensorData(this, mySensorDataInterface);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mSensorData.release();
    }

    // センサーデータの取得開始
    public void onClickStartSensor(View view) {

        GetDeviceInformation getDeviceInformation = new GetDeviceInformation(this);
        List<DeviceInfo> deviceInfos = getDeviceInformation.getInformation();

        if (deviceInfos.isEmpty()) {
            Log.e(TAG, "デバイス情報が取得できませんでした");
            return;
        }

        DeviceInfo info = deviceInfos.get(0);

        // 0 : ジャイロセンサー
        // 1 : 加速度センサー
        // 2 : 方位センサー
        // 3 ~ 255 : 拡張センサー
        mSensorData.setType(0)
        mSensorData.setBDaddress(info.getBdaddress());
        mSensorData.start();
    }

    // センサーデータの停止依頼
    public void onClickStopSensor(View view) {
        mSensorData.stop();
    }

    // センサーデータの受信/センサー停止通知を受信する
    class MySensorDataInterface implements ControlSensorData.SensorDataInterface {
        @Override
        public void onStopSensor(final String bd, int type, int reason) {
            Log.d(TAG, bd + ":センサーが停止しました。");
        }

        @Override
        public void onSensorData(String bd, int type, float x, float y, float z, byte[] originalData, long time) {
            Log.d(TAG, bd + ":センサーデータを受信しました。");
            Log.d(TAG, "xの値:" + x + "yの値 : " + y +"zの値 : " + z);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // センサーデータ取得開始依頼の結果が返る
        int result = mSensorData.onActivityResult(requestCode, requestCode, data);
        if (result != ErrorCode.RESULT_OTHER_ERROR) {
            switch (result) {
                case ErrorCode.RESULT_OK : {
                    Log.d(TAG, "正常に取得開始しました。");
                    break;
                }
                default : {
                    Log.e(TAG, "エラーにより失敗しました : " + result);
                    break;
                }
            }
        }
    }
}

周辺デバイスへのデータ送信

 周辺デバイスに対してのデータ送信方法を説明します。送信方法は以下の4種類があります。

  • Notification
    • AndroidのNotificationに相当する内容を周辺デバイスへ通知することができます。
  • メール通知
    • メールに関する内容を周辺デバイスへ通知します。
  • スケジュール通知
    • スケジュールに関する内容を周辺デバイスへ通知します。
  • その他通知
    • 複数のデータファイル、 画像、メディアを通知することができます。

Notification

 SendNotificationクラスを利用することで、AndroidのNotification相当の内容(タイトル、本文)を周辺デバイスに通知することができます。その他、アイコン画像もあわせて通知できます。

使用例
import com.nttdocomo.android.sdaiflib.SendNotification;

public void sendNotify() {
    SendNotification sendNotification = new SendNotification(getApplicationContext());
    sendNotification.setText("本文");
    sendNotification.setTitle("タイトル");
    int resId = R.drawable.ic_notificaion; // アイコン画像のリソースID
    sendNotification.setIcon(resId);
    sendNotification.send();
}

メール通知

 SendMailクラスを利用することで、メールに関する内容を周辺デバイスへ通知します。

 タイトルや本文、送信者名、送信者のアドレスや受信時間を通知することができます。

 マニフェストファイルにはメール通知利用の宣言を記載してください。

AndroidManifest.xml
<application
    ~中略~
    <meta-data
      android:name="com.nttdocomo.android.smartdeviceagent.feature.mail_notification"
      android:value="true" />
    ~中略~
</application>
使用例
import com.nttdocomo.android.sdaiflib.SendMail;

public void sendMail() {
    SendMail sendMail = new SendMail(getApplicationContext());
    sendMail.setTitle("タイトル");
    sendMail.setText("本文");
    sendMail.setSendUser("ユーザー");
    String address = "xxxx@xxx.com";
    sendMail.setAddress(address);
    long receiveTime = Calendar.getInstance().getTimeInMillis(); // 受信日時(UNIXタイム)
    sendMail.setReceiveTime(receiveTime);
    sendMail.send();
}

スケジュール通知

 SendScheduleクラスを利用することで、スケジュール情報を周辺デバイスへ通知します。

 タイトル、本文、開始時間、終了時間、場所、人の情報、詳細、内容(3種類まで送信可能)を通知することができます。

使用例
import com.nttdocomo.android.sdaiflib.SendSchedule;

public void sendSchedule() {
    SendSchedule sendSchedule = new SendSchedule(getApplicationContext());
    long startTime = 1449810987; // 開始時間
    long endTime = 1449813315;   // 終了時間
    sendSchedule.setStartTime(startTime);
    sendSchedule.setEndTime(endTime);
    sendSchedule.setTitle("タイトル");
    sendSchedule.setWhere("場所");
    sendSchedule.setPerson("人の情報");
    sendSchedule.setDescription("詳細");
    sendSchedule.setContent1(new byte[] {}); // 内容
    sendSchedule.send();
}

その他通知

 SendOtherクラスを利用することで、Notification、メール通知、スケジュールに当てはまらない、その他の情報を周辺デバイスに通知するときに使用します。

 Notificationではタイトル、本文、アイコンを通知できるのに対し、その他通知では、複数のデータファイル、 画像、メディアを通知することができます。

import com.nttdocomo.android.sdaiflib.SendOther;

public void sendOther() {
    SendOther sendOther = new SendOther(getApplicationContext());
    int dataNo1 = 1; // contentの番号(1~10まで)
    int dataNo2 = 2;
    byte dataContent[] = new byte[] {};
    sendOther.setContent(dataNo1, dataContent);
    sendOther.setContentUri(dataNo2, "データのURI");
    sendOther.setImageUri("画像のURI");
    sendOther.setImageMime("画像のMIMEタイプ");
    sendOther.setMediaUri("メディアのURI");
    sendOther.setMediaMime("メディアのMIMEタイプ");
    sendOther.send();
}

周辺デバイスからデータを受信

 周辺デバイスからデータを受信する方法を紹介します。

サービスアプリへの通知

 NotifyNotificationクラスにobserver(NotifyNotification.NotificationInterface)を設定することで周辺デバイスからの通知を受けることができます。

 受信したデータは以下の名称でローカルデータとしてSharedPreferencesに格納されます。

  • 受信データ:NotificationInformation
LinkingService.java
import com.nttdocomo.android.sdaiflib.NotifyNotification;
import com.nttdocomo.android.sdaiflib.Define;

public class LinkingService extends Service {

    private NotifyNotification mNotifyNotification;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mMyNotificationInterface = new MyNotificationInterface();
        mNotifyNotification = new NotifyNotification(this, mMyNotificationInterface);
    }

    public void onDestroy() {
        super.onCreate();
        mNotifyNotification.release();
    }

    private void sendNotification(String title, String text){
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this)
                        .setSmallIcon(android.R.drawable.sym_def_app_icon)
                        .setContentTitle(title)
                        .setContentText(text);

        NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(this);
        notificationManager.notify(0, notificationBuilder.build());
    }

    // 周辺デバイスからの通知を受信する
    class MyNotificationInterface implements NotifyNotification.NotificationInterface {
        @Override
        public void onNotify() {
            SharedPreferences preference = getSharedPreferences(Define.NotificationInfo, Context.MODE_PRIVATE);
            String appName = preference.getString("APP_NAME", "");
            sendNotification("通知", "[" + appName +"]" + “から通知がありました”);
        }
    }
}

距離通知

 NotifyRangeクラスにobserver(NotifyRange.MyRangeInterface)を設定することで距離の変化通知を受けることが可能になります。

 受信したデータは以下の名称でローカルデータとしてSharedPreferencesに格納されます。

  • 受信データ:RangeInformation

 距離通知を受信する場合は、サービスアプリのマニフェストファイルに、距離通知対応の宣言を記載してください。

AndroidManifest.xml
<application
    ~中略~
        <meta-data
            android:name="com.nttdocomo.android.smartdeviceagent.feature.notify_distance"
             android:value="true" />
    ~中略~
</application>
MainActivity.java
import com.nttdocomo.android.sdaiflib.NotifyRange;

public class MainActivity extends AppCompatActivity {

    private NotifyRange mNotifyRange;
    private MyRangeInterface mMyRangeInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ~中略~
        mMyRangeInterface = new MyRangeInterface();
        mNotifyRange = new NotifyRange(this, mMyRangeInterface);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mNotifyRange.release();
    }

    // 距離通知を受信する
    class MyRangeInterface implements NotifyRange.RangeInterface {
        @Override
        public void onRangeChange() {
            SharedPreferences preference = getSharedPreferences(Define.RangeInfo, Context.MODE_PRIVATE);
            int rangeSetting = preference.getInt("RANGE_SETTING", -1);
            String address = preference.getString("BD_ADDRESS", "");

            // 3段階で通知される
            switch (rangeSetting) {
                case 1: {
                    Log.d(TAG, address + " : との距離は" + "近い");
                    break;
                }
                case 2: {
                    Log.d(TAG, address + " : との距離は" + "やや近い");
                    break;
                }
                case 3: {
                    Log.d(TAG, address + " : との距離は" + "遠い");
                    break;
                }
            }
        }
    }
}

さいごに

 本記事ではLinkingの概要と使用方法を紹介しました。いかがでしたでしょうか。

 このようにLinkingアプリを利用することで、周辺デバイスとサービスアプリの連携がより簡単になります。サービスアプリが増えることでユーザーはもっと身近にIoTを体験することができるでしょう。

 また、Linkingでは新しい周辺デバイスやサービスアプリを作っていく仲間を求めています。ハードウェア開発者の方も、ソフトウェア開発者の方も、ユーザーコミュニティ「Project Linking」に参加してみませんか。

 Project Linkingに関心を持たれた方は、以下のサイトの「Contact Us」よりお問い合わせください。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9224 2016/02/17 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング