このページの本文へ

クルマとスマホをつなげるSDLアプリを作ろう! 第2回

ステップ・バイ・ステップでSDLプログラミングの初歩を解説

SDLデバイスシミュレーター「Manticore」でSDLアプリを動かそう!

2020年07月15日 09時00分更新

文● 田中 雅也 編集●藤井 創

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

 前回までで「Smart Device Link(以下、SDL)」はどんなものなのかを紹介しました。ではここから、実際の開発に入っていきましょう。

SDLアプリ開発は簡単って本当?  

 ではさっそく、SDLのアプリ開発に入っていきましょう。ところで、SDLのアプリ開発は簡単と言われているのですが、本当なのでしょうか。こういうのは、動かすまでがかなり大変なのでは…と思っている方。本当にそうだと思います。だからこそ、動作するサンプルアプリを実際に動かしながら進めていけば、開発方法や仕組みも理解しやすいと思います。

 今回説明する内容はこちら。

• SDLデバイスシミュレーターと連携させる
• 画面を表示させる(テンプレート表示)
• 画面を操作する
• 車輌情報を取得する

 最後までできれば、基礎は完璧なはずです! それではさっそく取り掛かりましょう。

事前準備はこちらから  

 まず、始める前に必要なものはこちらです。

 • Android Studio
 • サンプルコード
 • Chromeブラウザ  

 とくに、Android Studioとサンプルコードは、必ず準備してください。今回用意したサンプルコードは「Android Stduio 3.6.3」で動作確認しています。自身の環境でうまく動作しない場合は、最新バージョンにアップデートしてから、ご確認ください。 
 
 後ほど出てくる「SDLデバイスシミュレーター」はブラウザ上で動作しますが、説明はすべてChromeを使って解説しています。もし自身のブラウザで動作しない場合は、Chromeブラウザでお試しください。

サンプルコードを読み込む  

 さっそくサンプルコードを動かしていきます。上記のURLからソースコードを取得したら、Android Studioでプロジェクトを読み込んでください。読み込みが完了すると、以下のファイルが表示されます。

Android Studioにサンプルコードを読み込ませるとこのようなファイルが表示される


 カーナビのモニターに表示する処理は、すべてSdlService.javaに記載されています。今回の説明はすべてこのファイルの中にあるコードです。SDLが公開しているサンプルコードは、ライブラリのソースコードを直接指定していますが、今回のサンプルは、build.gradle(Mpdule: app)の中に依存関係を設定しています。

build.gradle

dependencies {

  implementation 'com.smartdevicelink:sdl_android:4.+'

} 

Manticore(SDLデバイスシミュレーター)に接続  

 Manticoreは、SmartDviceKinkが提供するクラウド型のSDLデバイスシミュレーターです。簡単に利用でき、車輌のシミュレーションもできるので、とても便利です。読み込んだAndroid Studioのプロジェクトと、Manticoreを接続しましょう。

 まずはManticoreのページにアクセスします。利用するには、ユーザー登録が必要となりますので、まだの方は、まずはユーザー登録をしてください。ログイン状態でアクセスすると、次のような画面が表示されます。  

 ここで『LAUNCH MANTICORE』をクリックすると、SDLのデバイスシミュレーターが起動します。

【注意】 Manticoreは同時に利用できる人数に制限があります。世界中からアクセスがあるため、タイミング次第では順番待ちが発生します。順番待ちが発生した場合は、気長にお待ちください。  


これは一人待ちの状態

 起動すると、次のような画面が表示されます。



画面の構成を簡単に説明します。

1. カーナビのモニター部分
ここに作成した画面が表示されます。

2. 車の動作をシミュレートするコントローラ
速度や、シフトレバーの状態な車の動作設定、変更できます。

3. シミュレーターのログ
SDLシミュレーターへのRPC通信のログが表示されます。まだアプリを動かしていないので、画面には何も表示されていません。

 次に先ほどAndroid Studioに読み込んだサンプルのSDLアプリと、Manticoreを接続します。

Manticoreに接続するためのコードを修正  

 Manticoreに接続するために、アプリ側の接続情報を修正します。Manticoreの画面に表示されているCONNECT APPの情報をサンプルコードに反映します。

• 「TPC_PORT」にポート番号
• 「DEV_MACHINE_IP_ADDRESS」にURL

を設定してください。

SdlService.java Line.66

//Manticoreで指定されるポート番号を設定します

private static final int TCP_PORT = 16060;

private static final String DEV_MACHINE_IP_ADDRESS ="m.sdl.tools"; 

Build VariantsをWi-Fi通信用に変更する  

 SDLは、USBやBluetooth、Wi-Fiなどを通して、車載器と接続します。今回はクラウドシミュレーターと接続するため、TCPで接続します。TCPで接続するには、BuildVariantsからTcpDebugを選択します。


 ここまで準備ができれば、ビルドして実行してみましょう! 今回はエミュレーターを使っているので、Manticoreのモニター部分にアイコンが表示されれば、成功です。

画面を表示してみよう  

 それでは、画面上の「Hello Sdl」アイコンをクリックしましょう。猫の画面が表示されれば、成功です。

テンプレートを指定する

 猫ちゃんの画面を構成している部分について説明します。ここがメインなのでじっくり読んでください。SDLの画面表示は、Android Autoなどと異なり、基本的にはテンプレートを利用することを想定しています。あらかじめ決まった画面構成(画像や、ボタンなど)に対して、情報を設定し動作させるイメージです。開発者側は、SDL車載器のデザインを気にすることなく、統一感のあるデザインで機能を提供できます。

 テンプレートを指定するときは、SetDisplayLayoutsetDisplayLayoutで、使用したいテンプレート名を設定します。今回はNON_MEDIAを使用します。他にどんなテンプレートがあるかはこちらでご確認ください。

SdlService.java Line.248

SetDisplayLayout setDisplayLayout = new SetDisplayLayout();
//テンプレートの種類を「NON_MEDIA」に設定する

etDisplayLayout.setDisplayLayout(PredefinedLayout.NON_MEDIA.toString());


//テンプレートを登録する 
sdlManager.sendRPC(setDisplayLayout); 

画面の構成を設定する

 テンプレートが設定できたら、画面を構成するパーツを設定してきます。ScreenManagerのbeginTransaction〜commit間で、テキストや画像を設定します。表示可能なテキストや画像の位置、サイズなどは、テンプレートに依存するため指定することはできません。

 テキストは、ScreenManagerのsetTextFieldで設定します。setTextFieldは、1~4まであるので、テンプレートに合わせて使用してください。

 画像は、SdlArtworkで使用する画像を指定し、ScreenManagerのsetPrimaryGraphicで設定します。

SdlService.java Line.274

sdlManager.getScreenManager().beginTransaction(); 

sdlManager.getScreenManager().setTextField1("Speed");

SdlArtwork artwork = new SdlArtwork("artwork01.png",FileType.GRAPHIC_PNG, R.drawable.artwork01, true); 
sdlManager.getScreenManager().setPrimaryGraphic(artwork); 

sdlManager.getScreenManager().commit() 

 ボタンは、SoftButtonStateでボタンの見た目、SoftButtonObjectで動作を設定します。ボタンの見た目は、「テキストのみ」「画像のみ」「画像とテキスト」から選べ、setHighlightedを指定することでトグルボタンのような表現も可能です。
 
 ScreenManagerのsetSoftButtonObjectsで、作成したSoftButtonObjectを設定します。今回は、2つのボタンを設定していますが、使用しているNON_MEDIAテンプレートは、最大4つのボタンに対応しています。

SdlService.java Line.296

//一つ目のボタン(テキストだけのボタンを設定) 
SoftButtonState textState = new SoftButtonState("text_button", "TEXT BUTTON", null);

//ボタンを作成する 
SoftButtonObject textButtonObject = new SoftButtonObject(textState.getName(), textState, "ボタンのイベント");

//ボタンを登録する 
List buttons = Arrays.asList(textButtonObject, iconButtonObject); sdlManager.getScreenManager().setSoftButtonObjects(buttons); 

ボタンを操作してみよう  

 TEXT BUTTONをクリックしてみてください。クリックすると、猫の画像が切り替わります。スピーカーアイコンのボタンをクリックすると、音声が再生されます。

ボタンのイベントを設定する  

 ボタンのイベントは、SoftButtonObjectの引数で指定します。ボタンが押されたときは、SoftButtonObject.OnEventListeneronPressが呼び出されます。猫の画像の切り替えは、画面の構成を作るときと同じで、setPrimaryGraphicでSdlArtworkを設定し、commitするだけです

SdlService.java Line.296

//一つ目のボタン(テキストだけのボタンを設定)
SoftButtonObject textButtonObject = new SoftButtonObject(textState.getName(), textState, new SoftButtonObject.OnEventListener() {

     @Override
     public void onPress(SoftButtonObject softButtonObject, OnButtonPress onButtonPress) {


         //画像を変更する
         sdlManager.getScreenManager().beginTransaction();


         SdlArtwork artwork = null;
                if(sdlManager.getScreenManager().getPrimaryGraphic().getResourceId() == R.drawable.artwork01) {
                         artwork = new SdlArtwork("artwork02.png", FileType.GRAPHIC_PNG, R.drawable.artwork02, true);
                }
                 else{
                         artwork = new SdlArtwork("artwork01.png", FileType.GRAPHIC_PNG, R.drawable.artwork01, true);
                 } 
                 sdlManager.getScreenManager().setPrimaryGraphic(artwork);
                 sdlManager.getScreenManager().commit(..略..); 
          }
          @Override
      public void onEvent(SoftButtonObject softButtonObject, OnButtonEvent onButtonEvent) {}
}); 

車輌情報を操作する  

 車の状態を変更してみましょう。Manticoreの右側にあるコントロールパネルより、Speedを選択します。これは車の速度をシミュレーションするための項目です。バーを左右に移動させることで、速度が変更されます。今回のサンプルでは、速度が変更されるとタイトルの下にあるサブラベルの速度が自動的に更新されます。

 車輌情報の取得には2つの方法が存在しています。1つは指定した項目のデータを取得する方法、もう1つは、指定した項目のデータに変化があったときに取得する方法です。

 今回のサンプルではどちらの方法も使用しており、起動時に車輌の速度情報を取得し、以降はデータに変化があった場合に、速度表示を変更しています。デモ画面で、最初に表示されている速度と、シミュレーションバー変更時に更新される速度がそれにあたります。ここが楽しいところなので、じっくり触ってみてください!
 
 特定の車輌情報を取得したい場合は、GetVehicleDataを使用します。  vdRequest.setSpeed(true) のように取得したい車輌情報を設定し、実行します。今回は速度だけですが、項目が複数になっても問題ありません。実行すれば設定された項目の情報がすべて取得できます。

SdlService.java Line.380

GetVehicleData vdRequest = new GetVehicleData(); 

//データを取得したい項目を設定します。
vdRequest.setSpeed(true); 

//速度 //データの取得を行います。
vdRequest.setOnRPCResponseListener(new OnRPCResponseListener() {  
        @Override 
        public void onResponse(int correlationId, RPCResponse response) {

                if(response.getSuccess()) { 
                        GetVehicleDataResponse getVehicleData = (GetVehicleDataResponse) response; 

                        sdlManager.getScreenManager().beginTransaction(); 
                        String speed = String.format("%.02f km/h", getVehicleData.getSpeed()); sdlManager.getScreenManager().setTextField2(speed); 

                        //画面の設定を完了する 
                        sdlManager.getScreenManager().commit(..略..)} 
                } 
    } 
});
sdlManager.sendRPC(vdRequest); 


 次に、データが更新された場合に、そのデータを取得する方法です。更新時に車両情報を取得したい場合は、SubscribeVehicleDataを使用します。subscribeRequest.setSpeed(true)のように、取得したい車輌情報を設定し、実行します。

SdlService.java Line.421

          //定期受信用のデータを設定する
                    SubscribeVehicleData subscribeRequest = new SubscribeVehicleData();
    
                    //定期的にデータを取得したい項目を設定します。
                    subscribeRequest.setSpeed(true);                //エンジン回転数
    
                    //定期受信の登録を行います
                    subscribeRequest.setOnRPCResponseListener(..略..);
                    sdlManager.sendRPC(subscribeRequest);

 
 更新された車輌データは、SdlManagerOnRPCNotificationListenerとして呼び出されます。GetVehicleDataと違う点は、更新された情報のみ取得できるという点です。複数データを取得する場合、データが存在しない項目もあります。取得時は忘れずNULLチェックを実施してください。

SdlService.java Line.179

sdlManager.addOnRPCNotificationListener(FunctionID.ON_VEHICLE_DATA, new OnRPCNotificationListener() {
        @Override
        public void onNotified(RPCNotification notification) {
            OnVehicleData vehicleData = (OnVehicleData) notification;
    
            Double vehicleData_speed = vehicleData.getSpeed();
            if(vehicleData_speed != null){
                sdlManager.getScreenManager().beginTransaction();
                String speed = String.format("%.02f km/h", vehicleData_speed);
                sdlManager.getScreenManager().setTextField2(speed);
    
                //画面の設定を完了する
                sdlManager.getScreenManager().commit(new CompletionListener() {
                    @Override
                    public void onComplete(boolean success) {
                        Log.i(TAG, "ScreenManager update complete: " + success);
                    }
                });
    
           }
       }
 });

ここまでできれば基本は完璧

 駆け足ではありましたが、みなさんSDLアプリを体験できたでしょうか。SDLデバイスシミュレーターを用いて、テンプレートを利用した画面の表示、ボタンの操作、車輌データの取得など、基本的な仕組みをすべて説明しました。あとは、今回のサンプルをいろいろ変更したり、追加したりして知識を深めてもらえるとうれしいです。  

 最後に、1点だけ注意してもらいたいことがあります。今回のサンプルは、シンプルにするため、必要なチェックをしておりません。実際には使用する車載器に応じて、利用可能なテンプレートや、車輌情報は異なります。本格的な開発をする際は、対応されているかどうかを、まずはチェックする必要があることも覚えておいてください。
 

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

主催:SDLアプリコンテスト実行委員会(事務局:角川アスキー総合研究所)
協力:SDLコンソーシアム日本分科会
応募締切:2020年11月4日(水)24:00
募集内容:エミュレーターか開発キット上で開発したSDL対応アプリ(既存アプリのSDL対応、新規開発)
募集対象:年齢、性別、国籍等不問。個人・チームどちらでも応募可
応募方法:プレゼンシートと動作解説動画をWebフォームで応募
審査:審査員が新規性、UX・デザイン、実装の巧みさ等で評価
最終審査会:2020年12月上旬、東京都内で開催予定
グランプリ:賞金50万円+副賞
特別賞(最大5作品):賞金各10万円
公式サイト:http://sdl-contest.com/

8月1日・2日にオンラインハッカソン、および事前ハンズオンを実施!!

本コンテストへの応募をサポートするために、8月1日・2日にSDLアプリ開発のオンラインハッカソンを開催!

 さらに、連動した事前ハンズオンを7月21日・28日に実施します。詳細は、「スマホとクルマをつなぐSDL対応アプリを作る(オンラインハッカソン)」をご覧ください。ぜひふるってご応募を!

■関連サイト

 

(提供:SDLコンソーシアム 日本分科会)

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

最新記事

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

ピックアップ

ASCII.jp RSS2.0 配信中

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