初心者でもできるSDLアプリの作り方、初級編その2
ギアやシフトレバーの情報など、車のデータを取得してみよう!
2019年10月17日 09時00分更新
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()」で指定しているポート番号が正しいか確認しましょう。
カーナビ側のボタンをタップすると、Androidアプリ側のログに次のようなメッセージが表示されます。
車のデータを取得する
SDLでは、カーナビを通じて車のデータを取得することができます。どのようなデータが取得できるかは車のメーカーによって決められているため、製品としてアプリを開発する場合は権限があるか確認しましょう。Manticoreではサポートされているすべてのデータが取得できます。
データの取得方法は次の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アプリ側のログにシフトレバーの状態が表示されます。
データの変更通知を受け取る
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アプリ側のログに表示されます。
まとめ
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コンソーシアム)
この連載の記事
-
第9回
sponsored
スマホが当たり前になった時代のクルマはすべてこうなる! -
第8回
sponsored
函館高専もSOMPOも、実はごく短期間で一気に制作! -
第7回
sponsored
Smart Device Link対応スマホアプリを、Web系技術でつくってみた -
第6回
sponsored
後部座席の子どもの様子がわかる「こどもカメラ」はただのカメラじゃない! -
第4回
sponsored
まずはSDLの車載機シミュレーター上に画面を出してみよう -
第3回
sponsored
賞金50万円を受賞したグランプリ作品「Instaride」はどう企画されたのか? -
第2回
sponsored
SDLアプリの開発には何が必要なのか? -
第1回
sponsored
スマホと車・バイクを「便利なまま」つなげるSDLって知ってる? -
sponsored
スマホと車・バイクを連携させる新規格SDLのすべて - この連載の一覧へ