Edited at

【Smart Device Link】プロジェクションモードを試してみる

自由に画面を作成できるプロジェクションモードの説明をしたいと思います。

※ただ、残念ながらこのモードはSDLの趣旨から外れているようですが・・。


プロジェクションモードって?

簡単に言うとテンプレートのようにSDL側で画面を生成するのではなく、

Android側の画面をストリーミングで配信して表示する方法です。

そのためAndroidの開発と同じ方法で、画面を設計する事ができます。

SDL単体では難しい動画の再生なども可能になります。

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

注意:プロジェクションモードは、MantiCoreエミュレータでは動作しません。

   動きを見るには、SDLアプリ開発キット「SDL DEVELOPMENT TOOLS」が必要です。


画面を作る


画面のデザインを作る

特殊な作業はありません。

Android StudioのLayout Editorで画面を作成します。

利用可能なコントロールに制限がある可能性もありますが、

VideoViewTextureViewWebViewなども動いているようです。

注意:ImageViewで画像を設定する場合、app:srcCompatを使用すると

正しく表示されないようです。srcで画像を設定してください。


画面を作る

表示する画面は、SdlRemoteDisplayを継承させて作ります。

setContentView(R.layout.remote_display)で作った画面レイアウトを設定するだけです。


SdlService.java

public static class RemoteDisplay extends SdlRemoteDisplay {

public RemoteDisplay(Context context, Display display) {
super(context, display);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_display);
}
}



ボタンのイベントを作る

各種コントロールの制御方法は、通常のAndroid開発と同じですので、

ここでは説明しません。

注意が必要なのは、ボタン操作においてOnClickListenerイベントは発生しません。

基本的には、OnTouchListenerが有効のようです。


SdlService.java


final TextView textView = (TextView)this.findViewById(R.id.textView);

Button button01 = (Button)this.findViewById(R.id.button01);
button01.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//このToastは、SDL側ではなくスマホ側で表示されます。
Toast.makeText(view.getContext(),"Touch event received: " + motionEvent.getX(),Toast.LENGTH_SHORT).show();
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
textView.setText("Hello SDL");
break;
}
return true;
}
});



AppHMITypeを設定する

AppHMITypeをNAVIGATIONに設定してください。

MEDIAのままだと正しく出力されません。


SdlService.java

Vector<AppHMIType> appType = new Vector<>();

appType.add(AppHMIType.NAVIGATION);


プロジェクションモードを開始する

startRemoteDisplayStreamを行う事で、SDL端末に画面が転送されます。

開始処理は、必ずSdlManager.startが成功した後に呼び出してください。

注意:

startRemoteDisplayStreamの第三引数のparameterは、画面サイズなどを指定します。

nullの場合、自動的に最適な値が設定されます。

実際に表示されせるとこんな感じになります。

開発ツールの画面

よく見ると、縦長に見えませんか?

SDLアプリ開発キット「SDL DEVELOPMENT TOOLS」のカタログスペックでは、幅800px、縦480pxなのですが、幅800px、縦350pxの値が設定されるようで、なぜか縦長に表示されます。

正しく出力させるために、強制的に正しい値を設定します。


SdlService.java


VideoStreamingParameters parameters = new VideoStreamingParameters();
parameters.getResolution().setResolutionWidth(800);
parameters.getResolution().setResolutionHeight(480);

sdlManager.getVideoStreamManager().startRemoteDisplayStream(getApplicationContext(), RemoteDisplay.class, parameters, false);


この設定だと、このように正しいアスペクト比で表示されます。

開発ツールの画面

ただし、タッチの位置までは対応しきれないようで、縦のタッチ位置がずれます。

いろいろ試しましたが、解決方法が見つかっていません。。

また、何か分かりましたら追記します。


プロジェクションモードを終了する

SDL終了時には、必ずstopStreamingを行います。


SdlService.java

sdlManager.getVideoStreamManager().stopStreaming();



実際に動かしてみる

テキストや、画像が切り替わる簡単なデモです。

ストリーミングなため、反応は遅めです。

動作画面

参考:VideoStreaming


補足


テンプレートとプロジェクションモードの切り替えはできるのか??

簡単ではありますが、検証してみました。

※推測の部分がありますのでご注意ください。

テンプレートだけの場合、テンプレートの切り替えは可能でしたが、

現時点でテンプレートとプロジェクションモードは、切り替えできていません。

プロジェクションを構成するSdlRemoteDisplayは、Dialogベースで作成されています。

Dialogを閉じるdismissdismissPresentationまたは、stopで呼び出していますが

SDLアプリ開発キット「SDL DEVELOPMENT TOOLS」では、閉じる事はできませんでした。

ちなみに、プロジェクション表示中にテンプレートを呼び出す事は可能でした。

補足:

正確には、SDLレベルでは切り替えは対応してるとのことでした。

使用したSDLアプリ開発キット「SDL DEVELOPMENT TOOLS」が、対応してないだけの可能性があります。


最後に

プロジェクションモードが人気だと言う事で、先にプロジェクションモードの説明を行いました。

次回は、車のデータを取得してみたいと思います。