Posted at

【Smart Device Link】画面とかを作ってみる

今回は、SDLの画面をいろいろ触ってみたいと思います。

似たようなタイミングで、ASCIIさんもSDLの連載をされています。

エミュレータの作成など、かなり詳しく記載されてますので、

こちらもご覧頂けるといろいろ知識が得られるかなと思います。


SDLの画面について

SDLの画面表示は、Android Autoなどとは異なり、

基本的には、テンプレートを利用することを想定しているようです。

あらかじめ決まった画面構成(画像や、ボタンなど)に対して、情報を設定し動作させます。

開発者側は、SDL端末のデザインを気にすることなく、統一感のあるデザインで機能を提供することができます。

※良いように言い過ぎな気もします。。

自由に画面を作成する方法(プロジェクションモード)もありますが、それは別の機会に説明します。

今回は、Github:SDLのサンプルをベースに説明していきます。


画面を作ってみる


テンプレートの設定

何も設定しない場合は、PredefinedLayout.MEDIAが設定されている状態になります。

特定のテンプレートを使用したい場合は、SetDisplayLayout.setDisplayLayoutでテンプレートを指定し、sdlManager.sendRPCで登録します。


SdlService.java

private void setDisplayGraphicWithTextButtons(){

SetDisplayLayout setDisplayLayoutRequest = new SetDisplayLayout();

//GRAPHIC_WITH_TEXT_AND_SOFTBUTTONSのテンプレートを設定
setDisplayLayoutRequest.setDisplayLayout(PredefinedLayout.GRAPHIC_WITH_TEXTBUTTONS.toString());
setDisplayLayoutRequest.setOnRPCResponseListener(new OnRPCResponseListener() {
@Override
public void onResponse(int correlationId, RPCResponse response) {
//テンプレートの設定に成功した場合
if(((SetDisplayLayoutResponse) response).getSuccess()){
Log.i("SdlService", "Display layout set successfully.");
//ここで画面の設定処理などを記載します。
}else{
Log.i("SdlService", "Display layout request rejected.");
}
});

sdlManager.sendRPC(setDisplayLayoutRequest);
}



利用可能なテンプレートは??

テンプレートは、SDL端末に依存するため、テンプレートを利用する前に利用可能かチェックする必要があります。

利用可能なテンプレートは、以下の方法で取得可能です。


SdlService.java

private void checkTemplateType(){

Object result = sdlManager.getSystemCapabilityManager().getCapability(SystemCapabilityType.DISPLAY);
if( result instanceof DisplayCapabilities){
List<String> templates = ((DisplayCapabilities) result).getTemplatesAvailable();
Log.i("Templete", templates.toString());
}
}

ちなみに、Manticoreのエミュレータで利用可能なテンプレートは以下の通りです。

※でも、正しく動かなかったりするものもあったり・・。


[DEFAULT, MEDIA, NON-MEDIA, ONSCREEN_PRESETS, NAV_FULLSCREEN_MAP, NAV_KEYBOARD, GRAPHIC_WITH_TEXT, TEXT_WITH_GRAPHIC, TILES_ONLY, TEXTBUTTONS_ONLY, GRAPHIC_WITH_TILES, TILES_WITH_GRAPHIC, GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS, TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC, GRAPHIC_WITH_TEXTBUTTONS, TEXTBUTTONS_WITH_GRAPHIC, LARGE_GRAPHIC_WITH_SOFTBUTTONS, DOUBLE_GRAPHIC_WITH_SOFTBUTTONS, LARGE_GRAPHIC_ONLY]


参考:DisplayCapabilitiesクラスの説明

参考:デザインについて


画像やテキストを設定してみる

画像や、テキストは、sdlManager.getScreenManager().beginTransactionから

sdlManager.getScreenManager().commitの間で設定します。

表示可能なテキストや、画像の位置や、サイズなどはテンプレートに依存するため指定することはできません。

画像を指定する場合、FileTypeは、画像の種類に合ったものを使用してください。

また、利用可能な画像もSDL端末に依存するため、実際に利用可能かは、テンプレートと同じくチェックする必要があります。

利用可能な画像は、DisplayCapabilities.getGraphicSupportedで確認できます。


SdlService.java


sdlManager.getScreenManager().beginTransaction();
//テキストを登録する場合
//sdlManager.getScreenManager().setTextField1("Hello, this is MainField1.");
//画像を登録する
SdlArtwork artwork = new SdlArtwork("sample01.png", FileType.GRAPHIC_PNG, R.drawable.sample01, true);
sdlManager.getScreenManager().setPrimaryGraphic(artwork);
sdlManager.getScreenManager().commit(new CompletionListener() {
@Override
public void onComplete(boolean success) {
if (success) {
Log.i(TAG, "welcome show successful");
}
}
});


ボタンを設定してみる

ボタンは、SoftButtonObjectをgetScreenManager().setSoftButtonObjectsすることで設定する事ができます。

テンプレートに応じて複数個のボタンも登録可能です。

SoftButtonObjectは、SoftButtonStateを保持しており、複数個設定する事で、

トグルボタンのように表示を切り替えて利用する事ができます。

ボタンの切り替えは、SoftButtonObject.transitionToNextStateで可能です。


SdlService.java

//一つ目のボタンの設定

//一つ目のボタンステート
SoftButtonState softButton01State1 = new SoftButtonState("button01_state1", "button01_state1", null);

//Artworkを設定する事でボタンに画像を貼り付けることも可能
SdlArtwork state_artwork = new SdlArtwork("state2.png", FileType.GRAPHIC_PNG, R.drawable.ic_sdl, true);
SoftButtonState softButton01State2 = new SoftButtonState("button01_state2", "button01_state2", state_artwork);

List<SoftButtonState> softButtonStates = Arrays.asList(softButton01State1, softButton01State2);
SoftButtonObject softButtonObject1 = new SoftButtonObject("softButtonObject01", softButtonStates, softButton01State1.getName(), null);

//二つ目のボタン設定
SoftButtonState softButton02State1 = new SoftButtonState("button02_state1", "button02_state1", null);
SoftButtonObject softButtonObject2 = new SoftButtonObject("softButtonObject02", Collections.singletonList(softButton02State1), softButton02State1.getName(), null);

//二つのボタンを登録する
List<SoftButtonObject> buttons = Arrays.asList(softButtonObject1, softButtonObject2);
sdlManager.getScreenManager().setSoftButtonObjects(buttons);


ボタンのイベントは、SoftButtonObjectの生成時、またはsetOnEventListenerで登録する事ができます。

onPressは、ボタンが押されたとき呼び出されます。

onEventは、各動作毎に呼び出され、OnButtonEvent.getButtonEventModeをチェックする事で、

BUTTONUPまたは、BUTTONDOWNを判断する事ができます。


SdlService.java

softButtonObject1.setOnEventListener(new SoftButtonObject.OnEventListener() {

@Override
public void onPress(SoftButtonObject softButtonObject, OnButtonPress onButtonPress) {
softButtonObject.transitionToNextState();
}

@Override
public void onEvent(SoftButtonObject softButtonObject, OnButtonEvent onButtonEvent) {
}
});


今回のサンプルを実際に動かすとこんな感じになります。

button01_state1を動かすとボタンが切り替わります。

button02_state1を動かすと左の画像が切り替わります。

参考:テキスト、画像とボタンについて


最後に

ざっくりですが、画面の作り方について説明してみました。

本気で作る場合、SDL依存チェック(テンプレートとか、画像フォーマットとかいろいろ・・)がたくさん入り少し面倒な感じです。

ただ、簡単なデモ用のアプリを作る分には、今回の内容がわかればいろいろ作っていけそうな気がします。

SdlManagerListenerなど基本的な部分を飛ばしていたりするところもありますが、

次回は、自動車からの情報取得をやってみたいと思います。