LoginSignup
5
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-12-22

自由に画面を作成できるプロジェクションモードの説明をしたいと思います。
※ただ、残念ながらこのモードは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」が、対応してないだけの可能性があります。

最後に

プロジェクションモードが人気だと言う事で、先にプロジェクションモードの説明を行いました。
次回は、車のデータを取得してみたいと思います。

5
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4