1. 程式人生 > >Android 雙屏異顯

Android 雙屏異顯

需求分析:

在做一個車載專案時,有一個雙屏顯示的需求,當時一臉蒙逼完全不知如何著手,不過幸好有 demo,在看 demo 過程中,發現了 presentation 關鍵詞,Google 一番,原來實現雙屏異顯完全是這東東起的作用。在此記錄一下學習的筆記,供後續參考。

文件解析:

任何新鮮的 API,第一件事當然是上 Google 官網查閱一番。

A presentation is a special kind of dialog whose purpose is to present content on a secondary display. A Presentation is associated with the target Display at creation time and configures its context and resource configuration according to the display’s metrics.

Notably, the Context of a presentation is different from the context of its containing Activity. It is important to inflate the layout of a presentation and load other resources using the presentation’s own context to ensure that assets of the correct size and density for the target display are loaded.

A presentation is automatically canceled (see cancel()) when the display to which it is attached is removed. An activity should take care of pausing and resuming whatever content is playing within the presentation whenever the activity itself is paused or resumed.

presentation 是一個特殊的 dialog ,主要的目的是在輔助顯示屏上顯示內容,Presentation 在建立的時候需要和特定的 Display 相關聯。
值得注意的是,在建構函式中傳遞的 context 必須是一個 activity 的 context。

輔助顯示屏的內容:

1.您需要擴充套件 Presentation 類,並實現 onCreate() 回撥方法。在 onCreate() 中,呼叫setContentView() 來指定您要在輔助顯示屏上顯示的 UI。
2.作為 Dialog 類的擴充套件,Presentation 類提供了一個區域,在其中,您的應用可以在輔助顯示屏上顯示不同的 UI。

獲取顯示Presentation的輔助顯示屏:

根據官網文件,獲取顯示屏的程式碼如下;

 DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
 Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
 if (presentationDisplays.length > 0) {
     // If there is more than one suitable presentation display, then we could consider
     // giving the user a choice.  For this example, we simply choose the first display
     // which is the one the system recommends as the preferred presentation display.
     Display display = presentationDisplays[0];
     Presentation presentation = new MyPresentation(context, presentationDisplay);
     presentation.show();
 }

demo 示例

1. 設定許可權

<!-- 顯示系統視窗許可權 -->
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 <!-- 在 螢幕最頂部顯示addview-->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

2.自定義類 繼承Presentation

 public class DifferentDislay extends Presentation {

        public DifferentDislay(Context outerContext, Display display) {
            super(outerContext,display);

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

        }
    }

3.程式碼實現:

public class MainActivity extends AppCompatActivity {

    private DifferentDislay mPresentation;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        DisplayManager manager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays = manager.getDisplays();
        // displays[0] 主屏
        // displays[1] 副屏
        DifferentDislay differentDislay = new DifferentDislay(this,displays[1]);
        differentDislay.getWindow().setType(
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        differentDislay.show();
    }

    public class DifferentDislay extends Presentation {

        public DifferentDislay(Context outerContext, Display display) {
            super(outerContext,display);

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

        }
    }
}

整體效果如下:

這裡寫圖片描述

在輔助顯示屏上播放視訊:

public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {

    private static final String TAG = "Bradlley";
    private DifferentDislay mPresentation;
    private MediaPlayer mMediaPlayer;
    private SurfaceView mSurfaceView;

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

        DisplayManager manager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays = manager.getDisplays();
        // displays[0] 主屏
        // displays[1] 副屏
        DifferentDislay differentDislay = new DifferentDislay(this,displays[1]);
        differentDislay.getWindow().setType(
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        differentDislay.show();

        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(this);

        mSurfaceView= differentDislay.getSurfaceView();
        mSurfaceView.getHolder().addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated: ");
        try {
            mMediaPlayer.setDataSource("/sdcard/Movies/mv.wmv");
            mMediaPlayer.setDisplay(mSurfaceView.getHolder());
            mMediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.d(TAG, "onPrepared: ");
        mMediaPlayer.start();
    }
}

DifferentDislay 程式碼片段:

public class DifferentDislay extends Presentation {

    private static final String TAG = "DifferentDislay";
    private SurfaceView mSurfaceView;

    public DifferentDislay(Context outerContext, Display display) {
        super(outerContext,display);

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: ");
        setContentView(R.layout.second_screen);
        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);

    }

    public SurfaceView getSurfaceView(){
        return mSurfaceView;
    }
}

happy a nice day!