このページの本文へ

スマホと車・バイクを連携させる新規格SDLのすべて 第5回

初心者でもできるSDLアプリの作り方、初級編その2

ギアやシフトレバーの情報など、車のデータを取得してみよう!

2019年10月17日 09時00分更新

文● 深見浩和 編集●ASCII

  • この記事をはてなブックマークに追加
  • 本文印刷

1行もプログラムを書いたことがない人に、SDL(Smart Device Link)対応アプリの作り方を解説する本連載。前回はSDLを使ってカーナビ側に画面を表示するAndroidアプリを作成しました。今回はより発展的な内容を扱います。

カーナビ側のボタンがタップされた時の処理

 SDLで定義されているUIテンプレートにはボタンを持つものがあります。カーナビの画面にあるボタンがタップされたときの処理を記述してみましょう。

 まず、UIテンプレートをボタンがあるものに変更します。テンプレートの変更は前回説明した「SetDisplayLayout()」を使用します。今回はテキストボタンと画像がある「PredefinedLayout.TEXTBUTTONS_WITH_GRAPHIC」にします。

class MySDLService : Service() {
    ...
    private fun setLayout() {
        val request = SetDisplayLayout()
        request.displayLayout = PredefinedLayout.TEXTBUTTONS_WITH_GRAPHIC.toString()
        request.onRPCResponseListener = object: OnRPCResponseListener() {
            override fun onResponse(correlationId: Int, r: RPCResponse?) {
                val response = r as? SetDisplayLayoutResponse
                if (response == null) {
                    return
                }
                if (response.success) {
                    // レイアウトの変更が成功したので、値をセット
                    showUI()
                } else {
                    Log.v("SetLayout", "onError")
                }
            }
        }
        sdlManager?.sendRPC(request)
    }
}

 次に「showUI()」の中でボタンオブジェクトを作り、配置します。SDLでは、ボタンの状態をあらかじめ定義しておく必要があります。ボタンの状態を定義するには「SoftButtonState」を使用します。

private fun showUI() {
    ...
    val state = SoftButtonState("state1", "ON", null)
    val button = SoftButtonObject("button1", state, object: SoftButtonObject.OnEventListener {
        override fun onEvent(
            softButtonObject: SoftButtonObject?,
            onButtonEvent: OnButtonEvent?
        ) {

        }
        override fun onPress(             softButtonObject: SoftButtonObject?,             onButtonPress: OnButtonPress?         ) {             Log.v("sdl", "ボタンがタップされたよ")         }     }) }

 ボタンの状態を「SoftButtonState」で定義した後、「SoftButtonObject」オブジェクトを作ります。第1引数の「button1」はボタンのIDです。第2引数は先ほど作った「SoftButtonState」を指定します。第3引数でボタンがタップされたときの処理を記述します。ここでは「onPress」の中でAndroidアプリ側でログを表示するようにしています。

 最後に「ScreenManager」の「softButtonObjects」にボタンをセットします。ボタンは画面に複数表示される可能性があるため、「listOf」でリストで渡します。

// UI更新トランザクションの開始
manager.beginTransaction()

manager.textField1 = "Hello SDL world" manager.textField2 = "アプリ作ろう" manager.primaryGraphic = primaryGraphic // ボタンのセット manager.softButtonObjects = listOf(button)

 Androidアプリを実行し、Manticoreで表示を確認してみましょう。Manticore側でアプリが表示されない場合は、「startSdlManager()」で指定しているポート番号が正しいか確認しましょう。

図1 ボタンが表示されている画面

 カーナビ側のボタンをタップすると、Androidアプリ側のログに次のようなメッセージが表示されます。

図2 Androidアプリ側のログ

車のデータを取得する

 SDLでは、カーナビを通じて車のデータを取得することができます。どのようなデータが取得できるかは車のメーカーによって決められているため、製品としてアプリを開発する場合は権限があるか確認しましょう。Manticoreではサポートされているすべてのデータが取得できます。

 データの取得方法は次の2種類があります。

  1. ワンタイムで取得する
  2. データの変更通知を受け取る

ワンタイムで取得する

 データをワンタイムで取得するには「GetVehicleData」を使用します。次のコードはギア/シフトレバーの状態(Prndl / Park,Reverse,Neutral,Drive,Low gear)を取得する例です。

private fun readVehicleData() {
    val vdRequest = GetVehicleData()
    // PRNDL(Park,Reverse,Neutral,Drive,Low gear)を取得したいので、trueに。
    vdRequest.prndl = true
    vdRequest.onRPCResponseListener = object : OnRPCResponseListener() {
        override fun onResponse(correlationId: Int, response: RPCResponse?) {
            if (response?.success == true) {
                val prndl = (response as GetVehicleDataResponse).prndl
                Log.i("SdlService", "シフトレバーの状態: $prndl")
            } else {
                Log.i("SdlService", "GetVehicleData was rejected.")
            }
        }
    };
    sdlManager?.sendRPC(vdRequest)
}

 まず、「GetVehicleData」オブジェクトを作成し、取得したい「prndl」に「true」をセットします。次に「OnRPCResponseListener」で取得できた時の処理を記述します。結果は「GetVehicleDataResponse」オブジェクトに入っています。ここではシフトレバーの状態をAndroidアプリ側のログに表示しています。

 最後に「sendRPC()」で取得を開始します。

 実際にデータを取得する場合、次のようにHMIの状態を取得した後に行うのがよいでしょう。

private fun addHmiStatusListener() {
    sdlManager?.addOnRPCNotificationListener(
        FunctionID.ON_HMI_STATUS,
        object : OnRPCNotificationListener() {
            override fun onNotified(notification: RPCNotification?) {
                val status = notification as OnHMIStatus
                if (status.hmiLevel == HMILevel.HMI_FULL && status.firstRun) {
                    setLayout()
                    readVehicleData()
                }
            }
        })
}

 Manticoreで実行すると、次のようにAndroidアプリ側のログにシフトレバーの状態が表示されます。

図3 シフトレバーの状態を表したログ

データの変更通知を受け取る

 SDLでは車のデータに変更があった時点で通知を受け取ることもできます。たとえばシフトレバーがドライブ(DRIVE)に変更された時に画面を更新するといった処理が作れます。

 データの変更通知を受け取るには、「SubscribeVehicleData」を使用します。

private fun subscribeVehicleData() {
    val request = SubscribeVehicleData()
    request.prndl = true
    request.onRPCResponseListener = object : OnRPCResponseListener() {
        override fun onResponse(correlationId: Int, response: RPCResponse?) {
            if (response?.success == true) {
                Log.i("SdlService", "Successfully subscribed to vehicle data.")
            } else {
                Log.i("SdlService", "Request to subscribe to vehicle data was rejected.")
            }
        }
    };
    sdlManager?.sendRPC(request)

    sdlManager?.addOnRPCNotificationListener(         FunctionID.ON_VEHICLE_DATA,         object : OnRPCNotificationListener() {             override fun onNotified(notification: RPCNotification?) {                 val vehicleData = notification as OnVehicleData                 if (vehicleData.prndl != null) {                     Log.i("SdlService", "今のシフトレバーの状態: ${vehicleData.prndl}")                 }             }         }) }

 次に、「SdlManager」の「addOnRPCNotificationListener」で、データの変更があったときの処理を記述します。ここではAndroidアプリ側のログに更新後のシフトレバーの状態を表示しています。

 Manticoreで実行し、右側のVEHICLE DATAでPrndlの値を変更すると、次のように変更後の値がAndroidアプリ側のログに表示されます。

図4 VEHICLE DATA

図5 シフトチェンジ

図6 ログに今のシフトレバーの状態が表示された

まとめ

 SDLでボタンの処理を記述する方法と、車のデータ取得方法を紹介しました。SDLについては、先日、対応カーナビ(車載機)が標準搭載されたトヨタの新型カローラが発表されたばかりです。取得したデータをうまく活用し、車の運転が楽しくなるようなアプリを開発してみましょう。


「クルマとスマホをなかよくする SDLアプリコンテスト2019」

主催:SDLアプリコンテスト実行委員会(事務局:角川アスキー総合研究所)
協力:SDLコンソーシアム日本分科会、株式会社ナビタイムジャパン
後援(予定): 独立行政法人国立高等専門学校機構、一般社団法人コンピュータソフトウェア協会ほか
応募締切:2019年10月31日(木)24:00
募集内容:エミュレーターか開発キット上で開発したSDL対応アプリ(既存アプリの移植、新規開発)
募集対象:年齢、性別、国籍等不問。個人・チームどちらでも応募可
応募方法:プレゼンシートと動作解説動画をWebフォームで応募
審査:審査員が新規性、UX・デザイン、実装の巧みさ等で評価
最終審査会:2019年11月22日(金)
審査員:暦本純一(東京大学情報学環教授)、川田十夢(AR三兄弟長男)ほか
グランプリ:賞金50万円+副賞
特別賞(5作品):賞金各10万円
公式サイト:http://sdl-contest.com/

■関連サイト

(提供:SDLコンソーシアム)

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

最新記事

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン