Presentation双屏异显,主屏后台运行副屏保持显示


在Android4.2版本以后,Google也是提供了Presentation类,可以实现在两块屏幕上同时显示不同的内容。

创建Presentation

Presentation是一种特殊的对话框,属于Dialog的子类,创建方式如下:

public class MyPresentation extends Presentation {

    /**
     * 重写构造函数
     *
     * @param outerContext 上下文必须为Activity,否则会报错
     * @param display      副屏的Display
     */
    public MyPresentation(Context outerContext, Display display) {
        super(outerContext, display);
    }

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

在创建Presentation时若使用默认的Dialog类型,则只能使用activity类的context,不可以使用getApplicationContext()作为创建时的context,否则会报如下错误:

11-11 09:23:39.837 E/AndroidRuntime(17598): FATAL EXCEPTION: main
11-11 09:23:39.837 E/AndroidRuntime(17598): Process: com.will.Screen, PID: 17598
11-11 09:23:39.837 E/AndroidRuntime(17598): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.view.ViewRootImpl.setView(ViewRootImpl.java:683)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:380)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.app.Dialog.show(Dialog.java:322)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.app.Presentation.show(Presentation.java:237)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at com.will.Screen.MainActivity$1.onClick(MainActivity.java:48)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.view.View.performClick(View.java:5647)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.view.View$PerformClick.run(View.java:22443)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.os.Handler.handleCallback(Handler.java:751)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.os.Handler.dispatchMessage(Handler.java:95)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.os.Looper.loop(Looper.java:154)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at android.app.ActivityThread.main(ActivityThread.java:6119)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at java.lang.reflect.Method.invoke(Native Method)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
11-11 09:23:39.837 E/AndroidRuntime(17598):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

而使用activity类的context时,当程序转到后台运行时,副屏会退出MyPresentation设定的界面显示,变为和主屏同步。要副屏在程序转到后台时能够表示显示,则context必须设置为application,此时的dialog类型需要设置为全局dialog。

选择Display

在presentation创建时,需要指定其显示的具体设备。获取系统Display的方式共有两种。

1、通过MediaRouter获取display
MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
                MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
Display presentationDisplay = route != null ? route.getPresentationDisplay() : null;

// Dismiss the current presentation if the display has changed.
if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) {
    mPresentation.dismiss();
    mPresentation = null;
}

// Show a new presentation if needed.
if (mPresentation == null && presentationDisplay != null) {
    mPresentation = new MyPresentation(context, presentationDisplay);
    try {
        mPresentation.show();
    } catch (WindowManager.InvalidDisplayException ex) {
        mPresentation = null;
    }
}
2、通过DisplayManager获取display
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if (presentationDisplays.length > 0) {
    Display display = presentationDisplays[0];
    if (mPresentation != null && mPresentation.getDisplay() != display) {
        mPresentation.dismiss();
        mPresentation = null;
    }
    if (mPresentation == null) {
        mPresentation = new MyPresentation(context, display);
        try {
            mPresentation.show();
        } catch (WindowManager.InvalidDisplayException e) {
            mPresentation = null;
        }
    }
}

activity后台运行副屏保持显示

创建普通的Presentation时,传入的必须是Activity的上下文,副屏会随创建它的Activity显示或隐藏。要实现activity后台运行时副屏能够保持显示,则需要Presentation拥有系统弹窗权限,此时传入Presentation的上下文可以是Application或Service。
实现方式如下:

  • 添加权限
    AndroidManifest.xml中声明系统弹窗权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  • 设置系统弹窗
    给创建的presentation设置权限
mPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

其他

  • Presentation实际上是一个Dialog,所以里面无法弹出Dialog、PopupWindow等依赖于Activity的小窗口,同样也无法使用Fragment。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游逸丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值