前回の記事では、Googleマップで検索した地点をカーナビへ送るための、小さなAndroidアプリを作れないか考えた。
前回の記事はこちら。
前回の最後には、
「どこでつまづくかは分からんが、とにかく作ってみよう。」
と書いた。
ということで、実際に作ってみた。
前回考えていた仕組み
前回考えていたのは、次のような仕組みだった。
Googleマップで目的地を検索
↓
共有先から自作アプリを選択
↓
共有されたURLを解析
↓
緯度・経度を取得
↓
NaviConへ地点情報を送信
↓
車の純正ナビへ目的地を設定
Googleマップの検索機能はそのまま使い、自作アプリはGoogleマップとカーナビの間をつなぐだけの「橋渡し役」にする。
専用の検索画面や地図画面は作らず、共有された情報を解析して別のアプリへ渡すだけの、小さなユーティリティを想定していた。
Googleマップの共有先として自作アプリを登録する
まずは、Googleマップの共有先に自作アプリを表示できるようにした。
Androidでは、アプリ側にIntent Filterを設定することで、テキストの共有先として自作アプリを表示できる。
作成したアプリをPixel 9 Pro XLへインストールし、Googleマップで適当な施設を検索して「共有」を押したところ、共有先に自作アプリが表示された。
自作アプリを選択すると、Googleマップから送られた情報を受け取るところまでは、特に問題なく動作した。
このアプリは、アイコンから直接起動して使うものではない。
Googleマップの共有画面から呼び出して使う形になる。
共有されてきたのは座標ではなく短縮URLだった
次に、Googleマップから実際に何が共有されているのか確認した。
前回の記事では、ここを最大の不確定要素としていた。
実際に受け取った共有Intentの主な内容は、次のようなものだった。
・Subject:施設名
・Text:Googleマップの短縮URL
・緯度・経度:直接は含まれていない
Textには、次のようなURLが入っていた。
前回予想していたとおり、Googleマップから緯度と経度がそのまま渡されるわけではなかった。
共有された短縮URLを展開し、そこから必要な情報を探す必要がある。
短縮URLを展開する
Googleマップから受け取った短縮URLへアクセスし、リダイレクト先となる正式なGoogleマップURLを取得する処理を追加した。
HTTP通信にはOkHttpを使用した。
Googleの短縮URLへアクセスすると、別のURLへリダイレクトされる。
OkHttpはリダイレクトを自動で追跡できるため、最終的に到達したGoogleマップURLを取得できる。
この部分については、前回考えていた方法で問題なく実装できた。
Googleマップから短縮URLを受信
↓
短縮URLへアクセス
↓
正式なGoogleマップURLを取得
ここまでは比較的順調だった。
正式なURLを取得すれば座標が取れるとは限らなかった
正式なGoogleマップURLを取得できれば、そこから簡単に緯度と経度を取り出せると思っていた。
しかし、実際にはそれほど単純ではなかった。
いろいろな場所を共有してみると、GoogleマップURLには複数の形式があった。
・URL内に緯度と経度が含まれているもの
・施設名と住所が含まれているもの
・住所だけが含まれているもの
・Google内部の識別子が中心になっているもの
・同じように見えても情報の入り方が異なるもの
つまり、一つの解析方法だけで、すべてのGoogleマップURLから座標を取り出すことはできなかった。
URL内に座標が見つかる場合はよいが、施設名や住所しか取得できない場合もある。
前回は、短縮URLを展開すれば座標が取れる可能性が高いと考えていたが、ここが最初の大きなつまずきだった。
住所を施設名として扱ってしまう問題
URLから地点名らしき文字列を取り出す処理を作ったところ、別の問題も発生した。
施設名が含まれていない地点を共有した場合に、住所を施設名として扱ってしまうことがあった。
本来は、
・施設名:不明
・住所:愛媛県○○市……
と判断すべきところを、
・施設名:愛媛県○○市……
として処理してしまう。
画面に表示するだけなら、それほど大きな問題ではないかもしれない。
しかし、今回はカーナビへ目的地を送るアプリである。
情報がないのに、アプリ側が勝手にそれらしい答えを作ってしまうのはよくない。
座標を最優先し、分からない情報は推測しない
そこで、地点情報を解析する際の優先順位を整理した。
1.URL内に明確な緯度と経度があれば、その座標を使用する
2.座標がなければ、取得できた施設名や住所を利用する
3.住所と施設名をできるだけ区別する
4.判定できない文字列は、無理に施設名として扱わない
5.正しい地点か判断できない場合は、誤った座標を送らない
このアプリでは、何が何でも座標を取得することよりも、間違った場所を目的地として送らないことを優先することにした。
うまく判定できない情報を無理に推測すると、まったく別の場所をカーナビへ設定してしまう可能性がある。
Geocoderで座標を補う
URLから直接座標を取得できない場合に備えて、AndroidのGeocoderも使用することにした。
Geocoderは、施設名や住所などの文字列から、緯度と経度を検索するための機能である。
処理の流れは次のようになった。
URL内に座標がある
↓
その座標を使用する
URL内に座標がない
↓
施設名や住所をGeocoderへ渡す
Geocoderでも座標を取得できない
↓
無理に地点を送信しない
Geocoderだけですべてを解決するのではなく、URL解析だけでは情報が足りない場合の補助手段として使用している。
これにより、Googleマップから施設名や住所しか取得できなかった場合でも、座標を補えるようになった。
本当にやりたかったNaviCon連携は有料だった
地点の解析ができるようになったので、次は取得した座標をカーナビへ送る処理を作ることにした。
当初考えていたのは、自作アプリから地点情報を渡すと、そのままカーナビへ目的地が送信される仕組みだった。
Googleマップで地点を共有
↓
共有先から自作アプリを選択
↓
自作アプリが地点を解析
↓
そのままカーナビへ目的地を送信
これが最初に想像していた完成形だった。
しかし、NaviConについて調べてみると、NaviConの画面を表示せず、裏側でカーナビへ直接地点を送る機能は、有料のセキュアタイプで提供されていた。これが年額15万円(税別)。高い!!
無料のオープンタイプでできる範囲
NaviConには、無料で利用できるオープンタイプも用意されている。
ただし、無料のオープンタイプでは、自作アプリからカーナビへ直接送信されるわけではない。
操作の流れは次のようになる。
Googleマップで地点を共有
↓
共有先から自作アプリを選択
↓
自作アプリが地点を解析
↓
NaviConアプリが起動して目的地を表示
↓
内容を確認して車のアイコンを押す ※直接転送と比較すると、この操作が1つ増える
↓
カーナビへ目的地を送信
一度NaviConの画面を開き、ユーザーが車のアイコンを押す必要はあるが、この方法であれば無料の範囲でも実現できる。
ただし、オープンタイプを利用する場合でも、開発者登録や用途登録を行い、APIキーや用途IDを取得する必要がある。
それならsmart nAVVi Linkで代用できる
ここで気付いたのが、無料のオープンタイプでできる操作なら、すでに使用しているsmart nAVVi Linkでも代用できるということだった。
smart nAVVi Linkには、緯度、経度、地点名などを指定して地点画面を開くための公開URIが用意されている。
これを利用した場合の操作は次のようになる。
Googleマップで地点を共有
↓
共有先から自作アプリを選択
↓
自作アプリが地点を解析
↓
smart nAVVi Linkが起動して目的地を表示
↓
内容を確認してカーナビへ送信
無料のNaviConオープンタイプと、操作の流れはほとんど同じである。
NaviConが起動する代わりに、smart nAVVi Linkが起動するという違いしかない。
smart nAVVi Linkは以前から車との連携に使用しており、公開URIを使えばAPIキーなども必要なかった。
そのため、本当にやりたかった直接転送は有料なので諦め、無料でできる範囲についてはsmart nAVVi Linkで代用することにした。
完成した処理の流れ
最終的な処理は次のようになった。
Googleマップで地点を検索
↓
「共有」から自作アプリを選択
↓
自作アプリが短縮URLを受信
↓
正式なGoogleマップURLへ展開
↓
座標、施設名、住所を解析
↓
必要に応じてGeocoderで座標を補完
↓
smart nAVVi Linkの地点画面を開く
↓
内容を確認してカーナビへ送信
当初考えていたNaviConを使う方式とは少し変わったが、Googleマップで検索した地点をカーナビへ渡すという目的は同じである。
NaviConの無料オープンタイプでも実現できそうだったが、今回は、すでに使用していたsmart nAVVi Linkで同じ役割を代用できたという形になった。
smart nAVVi Linkの公開URIを使う方式へ変更
別の方法がないか調べたところ、smart nAVVi Linkには、地点情報を渡してアプリの地点画面を開くための公開URIが用意されていることが分かった。
そこで、当初予定していたNaviCon API方式をやめて、smart nAVVi Linkの公開URIを使用する方式へ変更した。
完成した流れは次のようになる。
Googleマップで地点を検索
↓
「共有」から自作アプリを選択
↓
自作アプリが短縮URLを受信
↓
正式なGoogleマップURLへ展開
↓
座標、施設名、住所を解析
↓
必要に応じてGeocoderで座標を補完
↓
smart nAVVi Linkの地点画面を開く
当初考えていた連携方法とは少し変わったが、Googleマップで検索した地点をカーナビ側のアプリへ渡すという目的は変わっていない。
アプリはいったん完成
現在は、Googleマップで地点を共有すると、自作アプリが自動でURLを解析し、smart nAVVi Linkの地点画面を開けるようになった。
smart nAVVi Linkと車の連携自体は、以前から何度も利用しているのでテスト不要。
今回確認したかったのは、Googleマップの地点情報をsmart nAVVi Linkまで正しく渡せるかという部分だった。
そこまで正常に動作したため、このアプリについてはいったん完成としてよさそうだ。
実際に使ってみた感想
当初考えていた、Googleマップとカーナビの間をつなぐ小さなアプリは無事に完成した。
ただ、実際に使ってみた感想としては、正直なところ、期待していたほど大きな効果はなかった。
もともとsmart nAVVi Linkでも、店名や住所から目的地を検索できるためである。
Googleマップの方が目的地を見つけやすく、普段どおり検索してそのまま共有できるのは確かに便利だが、操作が劇的に短くなったわけではなく、実際には検索方法の選択肢が一つ増えて少し便利になったくらいだった。
それでも、前回考えていた仕組みを、実際に動くところまで完成させることができた。
Googleマップから座標が直接渡ってくるわけではなく、短縮URLの展開、複数形式のURL解析、住所と施設名の判定、Geocoderによる座標の補完など、作ってみなければ分からなかった問題も多かった。
途中で連携方法も変更することになったが、一つずつ問題を調べ、最終的に使える形まで持っていけた。
期待していたほどの効果ではなかったものの、ちゃんと完成できたので、作ってみてよかったと思う。

コメント