LIFFアプリを完成させる

LINE Thingsで利用するLIFFアプリに、サービス探索用service UUIDを指定してください。サービス探索用service UUIDは、トライアルプロダクト情報を作成すると発行されます。詳しくは、『LINE Things APIリファレンス』の「トライアルプロダクト情報を作成する」を参照してください。

スターターLIFFアプリの場合は、自分のGitHubアカウントにフォークしたline-things-starter/liff-app/liff.jsのUSER_SERVICE_UUIDに、サービス探索用service UUIDを指定します。USER_SERVICE_UUIDの書き換えについて詳しくは、「デバイスのGATTサーバーに接続する」を参照してください。

ここでは、デバイスを操作するLIFFアプリの作成方法を、LINE ThingsのスターターLIFFアプリのソースコードを使って説明します。

LIFFアプリを初期化する

liff.init()メソッドを実行すると、LIFF SDKの他のメソッドを実行できるようになります。

function initializeApp() {
    liff.init(() => initializeLiff(), error => uiStatusError(makeErrorMsg(error), false));
}

Bluetoothプラグインを有効化する {#enable-bluetooth-plugin}

liff.initPlugins()を使用して、Bluetoothプラグインを有効化すると、Bluetoothプラグインが提供するクライアントAPI(liff.bluetooth.*)が使用できます。

function initializeLiff() {
    liff.initPlugins(['bluetooth']).then(() => {
        liffCheckAvailablityAndDo(() => liffRequestDevice());
    }).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });
}

Bluetoothプラグインが利用できることを確認する

Bluetoothプラグインが利用できるかどうかを確認します。liff.bluetooth.getAvailability()を使用すると、以下の内容が確認されます。

  • チャネルに追加したLIFFアプリのBluetoothサポートの有無

    注:チャネルに追加したLIFFアプリのBluetooth® Low Energy対応機能を有効にしていないと、Bluetoothプラグインは有効化できません。

  • スマートフォンのBluetooth設定

  • ユーザーがLINE Thingsの利用規約に同意していること

  • ユーザーがLINEをAndroidで使用している場合は、位置情報の取得権限

function liffCheckAvailablityAndDo(callbackIfAvailable) {
    // Check Bluetooth availability
    liff.bluetooth.getAvailability().then(isAvailable => {
        if (isAvailable) {
            uiToggleDeviceConnected(false);
            callbackIfAvailable();
        } else {
            uiStatusError("Bluetooth not available", true);
            setTimeout(() => liffCheckAvailablityAndDo(callbackIfAvailable), 10000);
        }
    }).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });;
}

デバイスを探索する

liff.bluetooth.requestDevice()を使用して、デバイスを探索し、Bluetoothオブジェクトを取得します。

function liffRequestDevice() {
    liff.bluetooth.requestDevice().then(device => {
        liffConnectToDevice(device);
    }).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });
}

注:requestDevice()で探索できるのは、エンドユーザーがLINEで友だち追加したLINE公式アカウント(Messaging APIのチャネル)に関連付けられているプロダクトのデバイスのみです。あらかじめ、LINE DevelopersコンソールのMessaging APIのチャネルの[チャネル基本設定]ページにあるQRコードを読み取って、LINEでLINE公式アカウントを友だち追加してください。

注:liff.bluetooth.requestDevice()を短い間隔で実行すると、スマートフォンが停止する場合があります。

デバイスのGATTサーバーに接続する

探索できたデバイスのGATT(Generic Attribute Profile)サーバーに接続し、サービス探索用service UUIDを指定して、プライマリサービスとcharacteristicを取得します。なお、GATTサーバーは、Bluetooth® Low Energy対応デバイスで利用されているデータの格納方法に従って動作するサービスです。

USER_SERVICE_UUIDには、サービス探索用service UUIDを指定します。サービス探索用service UUIDは、トライアルプロダクト情報を作成すると発行されます。詳しくは、『LINE Things APIリファレンス』の「トライアルプロダクト情報を作成する」を参照してください。

// User service UUID: Change this to your generated service UUID
const USER_SERVICE_UUID         = '91E4E176-D0B9-464D-9FE4-52EE3E9F1552'; // LED, Button
// User service characteristics
const LED_CHARACTERISTIC_UUID   = 'E9062E71-9E62-4BC6-B0D3-35CDCD9B027B';
const BTN_CHARACTERISTIC_UUID   = '62FBD229-6EDD-4D1A-B554-5C4E1BB29169';

// PSDI Service UUID: Fixed value for Developer Trial
const PSDI_SERVICE_UUID         = 'E625601E-9E55-4597-A598-76018A0D293D'; // Device ID

(Omitted)

function liffConnectToDevice(device) {
    device.gatt.connect().then(() => {
        document.getElementById("device-name").innerText = device.name;
        document.getElementById("device-id").innerText = device.id;

        // Show status connected
        uiToggleDeviceConnected(true);

        // Get service
        device.gatt.getPrimaryService(USER_SERVICE_UUID).then(service => {
            liffGetUserService(service);
        }).catch(error => {
            uiStatusError(makeErrorMsg(error), false);
        });
        device.gatt.getPrimaryService(PSDI_SERVICE_UUID).then(service => {
            liffGetPSDIService(service);
        }).catch(error => {
            uiStatusError(makeErrorMsg(error), false);
        });

        // Device disconnect callback
        const disconnectCallback = () => {
            // Show status disconnected
            uiToggleDeviceConnected(false);

            // Remove disconnect callback
            device.removeEventListener('gattserverdisconnected', disconnectCallback);

            // Reset LED state
            ledState = false;
            // Reset UI elements
            uiToggleLedButton(false);
            uiToggleStateButton(false);

            // Try to reconnect
            initializeLiff();
        };

        device.addEventListener('gattserverdisconnected', disconnectCallback);
    }).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });
}

デバイスから情報を読み込む

GATTサーバーに接続できたら、デバイスがcharacteristicに保持している値を読み込めます。

注:service UUIDとcharacteristic UUIDは、デバイスや、デバイスから読み込む情報によって異なります。

以下は、ボタンの状態を読み込む場合の例です。

// User service UUID: Change this to your generated service UUID
const USER_SERVICE_UUID         = '91E4E176-D0B9-464D-9FE4-52EE3E9F1552'; // LED, Button
// User service characteristics
const LED_CHARACTERISTIC_UUID   = 'E9062E71-9E62-4BC6-B0D3-35CDCD9B027B';
const BTN_CHARACTERISTIC_UUID   = '62FBD229-6EDD-4D1A-B554-5C4E1BB29169';

(Omitted)

        // Get service
        device.gatt.getPrimaryService(USER_SERVICE_UUID).then(service => {
            liffGetUserService(service);
        }).catch(error => {
            uiStatusError(makeErrorMsg(error), false);
        });

(Omitted)

function liffGetUserService(service) {
    // Button pressed state
    service.getCharacteristic(BTN_CHARACTERISTIC_UUID).then(characteristic => {
        liffGetButtonStateCharacteristic(characteristic);
    }).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });

    (Omitted)
}

デバイスに情報を書き込む

読み込みと同様、GATTサーバーに接続できたら、characteristicに値を書き込めます。

function liffToggleDeviceLedState(state) {
    // on: 0x01
    // off: 0x00
    window.ledCharacteristic.writeValue(
        state ? new Uint8Array([0x01]) : new Uint8Array([0x00])
    ).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });
}

デバイスに通知を依頼する

GATTサーバーに接続できたら、デバイスからの通知を受け取ることもできます。

function liffGetButtonStateCharacteristic(characteristic) {
    // Add notification hook for button state
    // (Get notified when button state changes)
    characteristic.startNotifications().then(() => {
        characteristic.addEventListener('characteristicvaluechanged', e => {
            const val = (new Uint8Array(e.target.value.buffer))[0];
            if (val > 0) {
                // press
                uiToggleStateButton(true);
            } else {
                // release
                uiToggleStateButton(false);
                uiCountPressButton();
            }
        });
    }).catch(error => {
        uiStatusError(makeErrorMsg(error), false);
    });
}

デバイスからの通知を停止する

通知する必要がなくなったら、デバイスからの通知を停止します。

// Remove disconnect callback
device.removeEventListener('gattserverdisconnected', disconnectCallback);

{{ $t("form.question.helpful") }}

{{ $t("form.question.detail") }}

{{ $t("form.question.improve") }}

{{ $t("form.info.start") }}{{ $t("form.info.link") }}{{ $t("form.info.end") }}


{{ $t("form.result.success") }}
{{ $t("form.result.error") }}
{{ $t("form.result.errorLink") }}