How to show Presentation on android Virtual Display

来源:互联网 发布:人工智能李开复读后感 编辑:程序博客网 时间:2024/06/02 02:37

from http://andronblog.com/how-to-show-presentation-on-android-virtual-display/


In this post you will see how to show Presentation on android virtual display. Two use-cases will be demonstrated in one simple android application:

How to create a virtual display rendering the content to a Surface
How to show a Presentation on this virtual display
To get the repository of Android Studio project:

git clone https://github.com/andronmobi/PresentationOnVirtualDisplay.git -b l01_virtualdisplay

Creating Virtual Display

A virtual display is created by createVirtualDisplay method of DisplayManager. In this method (among other parameters) we have to pass a surface to which the content of the virtual display will be rendered and flags varying the behaviour of the virtual display:

mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION |     DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay("MyVirtualDisplay",    WIDTH, HEIGHT, DENSITY_DPI, surface, flags);

But the code snippet presented above wont work if your application is not system and doesn’t have some permissions (like CAPTURE_VIDEO_OUTPUT or CAPTURE_SECURE_VIDEO_OUTPUT) required for certain flags. That’s why we have to use MediaProjectionManager to ask a permission to user to “cast a screen” (to obtain MediaProjection which creates a virtual display):

mProjectionManager = (MediaProjectionManager) getSystemService(    Context.MEDIA_PROJECTION_SERVICE);startActivityForResult(mProjectionManager.createScreenCaptureIntent(),     PERMISSION_CODE);In case if a user accepts the permission to cast a screencast-screen-permissionit will be possible to obtain an instance of MediaProjection and to create a virtual display:@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {    mResultCode = resultCode;    mResultData = data;    if (requestCode != PERMISSION_CODE) {        Toast.makeText(this, "Unknown request code: " + requestCode,            Toast.LENGTH_SHORT).show();        return;    }    if (resultCode != RESULT_OK) {        Toast.makeText(this, "Screen Cast Permission Denied",            Toast.LENGTH_SHORT).show();        return;    }    Log.i(TAG, "Get media projection with the new permission");    mProjection = getProjection();    createVirtualDisplay();}private MediaProjection getProjection() {    MediaProjection projection = mProjectionManager.getMediaProjection(mResultCode,        mResultData);    // Add a callback to be informed if the projection    // will be stopped from the status bar.    mProjectionCallback = new MediaProjection.Callback() {        @Override        public void onStop() {            Log.d(TAG, "MediaProjection.Callback onStop obj:" + toString());            destroyVirtualDisplay();            mProjection = null;        }    };    projection.registerCallback(mProjectionCallback, null);    return projection;}private void createVirtualDisplay() {    if (mProjection != null && mVirtualDisplay == null) {        Log.d(TAG, "createVirtualDisplay WxH (px): " + mWidth + "x" + mHeight +                ", dpi: " + mMetrics.densityDpi);        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;        //flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;        mVirtualDisplay = mProjection.createVirtualDisplay("MyVirtualDisplay",                mWidth, mHeight, mMetrics.densityDpi, flags, mSurface,                null /*Callbacks*/, null /*Handler*/);        mButtonCreate.setEnabled(false);        mButtonDestroy.setEnabled(true);    }}private void destroyVirtualDisplay() {    Log.d(TAG, "destroyVirtualDisplay");    if (mVirtualDisplay != null) {        Log.d(TAG, "destroyVirtualDisplay release");        mVirtualDisplay.release();        mVirtualDisplay = null;        mButtonDestroy.setEnabled(false);        mButtonCreate.setEnabled(true);    }}

Showing Presentation on Virtual Display

PresentationOnVirtualDisplay
Once a virtual display is created you can display a content on it. In our case, it will be a Presentation (android Dialog for secondary display) with LinearLayout as a content view and animated (rotating) TextView on it. To listen for changes in available display devices a DisplayListener must be registered:
mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(mDisplayListener, null);
Then, after creating a virtual display the onDisplayAdded callback will be called. Here we register the number of display ID to create a new instance of MyPresentation class later in another callback – onDisplayChanged. The presentation will be dismissed in onDisplayRemoved if the virtual display showing it is removed.

private final DisplayManager.DisplayListener mDisplayListener =     new DisplayManager.DisplayListener() {    private boolean mNewDisplayAdded = false;    private int mCurrentDisplayId = -1;    private MyPresentation mPresentation;    @Override    public void onDisplayAdded(int i) {        Log.d(TAG, "onDisplayAdded id=" + i);        if (!mNewDisplayAdded && mCurrentDisplayId == -1) {            mNewDisplayAdded = true;            mCurrentDisplayId = i;        }    }    @Override    public void onDisplayRemoved(int i) {        Log.d(TAG, "onDisplayRemoved id=" + i);        if (mCurrentDisplayId == i) {            mNewDisplayAdded = false;            mCurrentDisplayId = -1;            if (mPresentation != null) {                mPresentation.dismiss();                mPresentation = null;            }        }    }    @Override    public void onDisplayChanged(int i) {        Log.d(TAG, "onDisplayChanged id=" + i);        if (mCurrentDisplayId == i) {            if (mNewDisplayAdded) {                // create a presentation                mNewDisplayAdded = false;                Display display = mDisplayManager.getDisplay(i);                mPresentation = new MyPresentation(MainActivity.this, display);                mPresentation.show();            }        }    }};

MyPresentation inner static class:

private final static class MyPresentation extends Presentation {    public MyPresentation(Context context, Display display) {        super(context, display);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.i(TAG, "MyPresentation onCreate");        setContentView(R.layout.my_presentation);        TextView tv = (TextView) findViewById(R.id.textView);        Animation myRotation = AnimationUtils.loadAnimation(getContext(), R.anim.rotator);        tv.startAnimation(myRotation);    }}
原创粉丝点击