[Alexa] 位置情報サービスを使ってスキルからモバイルデバイスの位置情報を取得する

Alexaの位置情報サービス機能を使うと、モバイルデバイスから提供される位置情報をスキルから取得することができます。
2019.02.27

はじめに

Alexaのスキル開発において、位置情報サービスという機能を利用すると、スキルからAlexa搭載デバイス(Alexaアプリを動作させるモバイルデバイスなど)のリアルタイム位置情報を取得することができます。

このエントリでは、位置情報サービスを使って、スキル上でデバイスの位置情報を取得する方法をご紹介します。

位置情報について

ここで言うデバイスの位置情報とは、モバイルデバイスなどが提供する地理座標系(緯度や経度など)の位置情報のことです。

Alexaアプリ上で設定されるデバイスごとの「デバイスの所在地(物理アドレス)」ではありませんので、注意してください。
(なお、「デバイスの所在地」をスキル上で取得したい場合は、以下のエントリが参考になります)

[日本語Alexa] Alexa-SDK Ver2(その6) 所在地情報

位置情報サービスを利用して取得された情報は、スキル上ではcontextオブジェクトのGeolocationセクションに含まれており、具体的には以下のようなデータが取得できます。

{
  "timestamp": "2019-02-26T06:59:25Z",
  "coordinate": {
    "latitudeInDegrees": 35.697319, // 緯度
    "longitudeInDegrees": 139.774724, // 経度
    "accuracyInMeters": 10 // 緯度および経度の不確かさ(m)
  },
  "altitude": {
    "altitudeInMeters": 20.27075958251953, //GPS制限内の海抜距離(m)
    "accuracyInMeters": 10 // 標高の不確かさ(m)
  },
  "heading": {
    "directionInDegrees": 123.08438110351562 // 方角・真北からの角度
  },
  "speed": {
    "speedInMetersPerSecond": 1 // GPS制限内の速度(m/sec)
  }
}

(iOSのAlexaアプリからスキルを起動して位置情報を取得した場合です)

スキルの設定

それでは、実際に位置情報サービスを使ったスキルを作ってみます。
今回は、取得した位置情報を元に、今どちらの方角を向いているのか雑に教えてくれるスキルを作ってみます。

開発者コンソールに適当なスキルを作成し、「アクセス権限」の画面にて「位置情報サービス」を有効にします。

また、ユーザーがスキルを利用する際に「位置情報サービス」のアクセス権を有効にしてもらう必要があります。(後述)

Lambdaの実装

スキルのバックエンドLambdaの実装は以下となります。

  • Node.js 8.10
  • ask-sdk(v2)をnpmやyarnでインストールしておくこと
const Alexa = require('ask-sdk-core');

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const { requestEnvelope, responseBuilder } = handlerInput;

    const isGeoSupported = requestEnvelope.context.System.device.supportedInterfaces.Geolocation;
    if (isGeoSupported) {
      const geoObject = requestEnvelope.context.Geolocation;
      if (!geoObject || !geoObject.coordinate) {
        // スキルorデバイスで位置情報のアクセス権が設定されていない
        const permissions = ['alexa::devices:all:geolocation:read'];
        return responseBuilder
          .speak('このスキルでは、あなたがお使いのデバイスの位置情報を利用します。デバイスの位置情報をAlexaアプリが利用可能になっていることを確認し、位置情報サービスのアクセス権を設定してください。')
          .withAskForPermissionsConsentCard(permissions)
          .getResponse();
      } else {
        // 位置情報サービスが利用可能な場合
        console.log(geoObject); // 地理座標系情報をログに出力

        const directions = ["北", "北北東", "北東", "東北東", "東", "東南東", "南東", "南南東", "南", "南南西", "南西", "西南西", "西", "西北西", "北西", "北北西", "北"];
        const degree = geoObject.heading.directionInDegrees;
        const speechText = 'あなたは今、' + directions[Math.round(degree / 22.5)] + 'の方角を向いています。';
        return responseBuilder
          .speak(speechText)
          .getResponse();
      }
    } else {
      // デバイスが位置情報ベースの機能をサポートしていない(e.g. Amazon Echo)
      return responseBuilder
        .speak('このデバイスでは位置情報サービスを利用することはできません。モバイルデバイスのAlexaアプリなどからお試しください。')
        .getResponse();
    }

  }
};

(長くなるため、スキル起動時のLaunchRequestHandler以外のハンドラは省略しています)

まず、10行目のrequestEnvelope.context.System.device.supportedInterfaces.Geolocationでデバイスが位置情報をサポートしているかを判別しています。
Echoなどの固定デバイスやテストシミュレータでは位置情報は提供されないため、固定デバイスから起動した場合はモバイルデバイスなどからスキルを起動するようにアナウンスします。

次に、12行目のrequestEnvelope.context.Geolocationのデータが取得できているかどうかで、デバイスやアプリ上の位置情報への利用許可が設定されているかどうか判別します。
利用許可が設定されていない場合は、Alexaアプリにカードを表示してアクセスを許可するように促します。

位置情報が取得できる場合、25行目のgeoObject.heading.directionInDegreesで方角(真北からの角度)を取得して方位に置き換えて発話します。

スキルのテスト

スキルを有効にし、モバイル端末にてテストしてみます。

まず、デバイスがAlexaアプリに位置情報の利用を許可していることを確認します。

次に、Alexaアプリで作成したスキルを開きます。
「設定」をクリックし、位置情報のアクセス権を設定します。




Alexaアプリでスキルを起動してみます。

モバイル端末から取得した位置情報から、向いている方角を教えてくれました!

おわりに

Alexaの位置情報サービスを利用して、モバイルデバイスの現在地情報を使ったスキルを作ってみました。
位置情報を活用することで、タクシーの配車スキルや現在地から近いお店を調べるスキルなど、色々と有用なスキルが作れそうです。

移動することが前提なモバイル端末やカーナビなどでAlexaが搭載されている場合、位置情報は必須の機能になるのではと思います。
これから、モバイルなAlexa搭載デバイスがたくさん登場してくれることを期待したいですね!