双屏异显小记录
分屏/多屏参考
多屏
Android Automotive 14(2) 多屏模拟器-CSDN博客
Android12 双屏异显/异触流程分析 - sheldon_blogs - 博客园
Android双屏异显以及原理分析_图像显示系统 - 多屏异显 - 原理及架构设计-CSDN博客
android 多屏幕显示activity,副屏,无线投屏-CSDN博客
android使用系统隐藏接口ActivityView实现主界面分窗显示三方应用Activity-CSDN博客
android 10车载桌面ActivityView触摸事件源码详解分析_android activityview-CSDN博客
android freeform模式定制桌面系统-CSDN博客
应用如何嵌套式显示第三方应用_app 嵌套app-CSDN博客
分屏
Android多窗口模式-SplitScreen基于Android R版本分析 分屏 和PIP模块一样,Split Sc - 掘金
Android分屏功能原理(基于Android12L)分屏功能原理(基于Android12L) 分屏功能目的是为了提高用 - 掘金
android 14分屏实战之小米su7的3分屏实现方案讨论及线索征集_小米su7分屏-CSDN博客
Android12 车载开发TaskView实现分屏_android taskview-CSDN博客
Android 把屏幕划分3等份;应用显示在中间区域_android 屏幕分配左右两边显示仪表,中间显示应用-CSDN博客
实现思路:
上述是基于Android 9.0平台
需要熟悉PhoneWindowManager,对Android系统窗口的理解,然后修改app可显示的区域为X坐标(640-1280)
这样app就固定在中间了,那边两边的区域我们就可以通过windowManger 弹窗出来显示,注意把view的层级设置为最高。
在配置下view的属性,也能接收触摸事件。
弊端:
左右两边区域无法显示第三方app,只能显示自行开发的view窗口
中间区域某些第三方app显示不协调,这个自己判断
源码中的双屏异显demo
1.使用media router
使用MediaRouter的getPresentationDisplay()获取Presentation设备
development/samples/ApiDemos/src/com/example/android/apis/app/PresentationWithMediaRouterActivity.java文件有如下的代码段:
MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
if (route != null) {
Display presentationDisplay = route.getPresentationDisplay();
if (presentationDisplay != null) {
Presentation presentation = new MyPresentation(context, presentationDisplay);
presentation.show();
}
}
2.使用display manager
使用DisplayManager的getDisplay(String)和DISPLAY_CATEGORY_PRESENTATION类型来获得Presentation设备
development/samples/ApiDemos/src/com/example/android/apis/app/PresentationActivity.java有如下的代码段:
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();
}
副屏可以通过android开发者 选项 ,模拟出一个副屏!!!
adb命令
adb shell am start -n com.android.demo/com.android.demo.MainActivity --display 1
adb shell am start -n com.android.demo/com.android.demo.MainActivity --user 0 --display 1
参数--display指定屏幕, display 0,表示第一块屏幕; display 1,表示第2块屏幕。
参数--user可以启动指定的用户,在多用户下有效,系统默认是--user 0。
Presentation 就是一个特殊的dialog,将内容显示在第二屏幕上
MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();---先获取RouteInfo,再获取Display
//MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(ROUTE_TYPE_USER)
if(route != null) {
Display presentationDisplay = route.getPresentationDisplay();
if (presentationDisplay != null) {
Presentation presentation = new MyPresentation(context, presentationDisplay);
presentation.show();
}
}
DisplayManager mDisplayManager = getSystemService(Context.DISPLAY_SERVICE);
Display displays = mDisplayManager.getDisplay(1);
8.0之后通过activity 显示
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(1); //这里一直display0是第一块屏;display1是第二块屏
Intent secondIntent = new Intent();
ComponentName cn= new ComponentName("com.android.demo","com.android.demo.SecondActivity");
secondIntent .setComponent(cn);
//该句很重要,不添加则无法推送到副屏
secondIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(secondIntent, options.toBundle());
使用ActivityOptions指定显示屏幕
为Intent增加标志Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK
//如何反射调用
private static ActivityOptions getActivityOptions(){
ActivityOptions options = ActivityOptions.makeBasic();
try {
Method method = ActivityOptions.class.getMethod("setLaunchWindowingMode",int.class);//Integer.TYPE
method.invoke(options,5);
}catch (Exception e){
}
return options;
}
private void freeStart(){
Intent intent = new Intent(this,xxx.class);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityOptions options = getActivityOptions();
options.setLaunchBounds(new Rect(10,10,10,10));
Bundle bundle = options.toBundle();
startActivity(intent,bundle);
}
指定屏幕Toast
public static void showToast(int displayid , String message) {
DisplayManager displayManager = SettingApplication.getApplication().getSystemService(DisplayManager.class);
Display display = displayManager.getDisplay(displayid);
// 生成指定屏幕 上下文
Context context = getApplicationContext().createDisplayContext(display);
Toast toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
toast.show();
}

浙公网安备 33010602011771号