android 多屏幕显示activity,副屏,无线投屏
Posted 王二の黄金时代
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 多屏幕显示activity,副屏,无线投屏相关的知识,希望对你有一定的参考价值。
目录
1. 1 可以通过代码的形式自己创建VirtualDispaly ,创建副屏。
1.2 或者,在手机的开发者模式中直接开启模拟副屏,也是可以的。
2.2 克隆主屏幕的内容,就是主屏幕显示什么,副屏显示同样的内容,镜像模式。
2.3 将一个activity 从第二个屏幕上启动,作为一个独立的屏幕
首先说明一下这个多屏幕的概念,这里不是指分屏显示。
分屏显示:是 一个屏幕分出多个窗口,分别显示不同app.
多屏支持:是一个设备有多个屏幕,怎么让不同的屏幕显示不同的app,或者是一个app同时用两个屏幕来显示不同的页面内容。
多屏幕显示,现在的车机都逐渐趋向于多个屏幕,一个android系统多个屏幕也越来越普遍,就算是手机,也出现比如多屏协作的场景。我猜它的原理也是在手机端创建虚拟无线屏,然后将app的activity单独在无线屏中启动。
本篇在手机上,验证将app的activity启动到另一个屏幕上。
1. 首先,需要一个副屏
1. 1 可以通过代码的形式自己创建VirtualDispaly ,创建副屏。
1.2 或者,在手机的开发者模式中直接开启模拟副屏,也是可以的。
将会在屏幕上看到一个叠加的小窗口,就是虚拟的第二个屏幕。
2.0 怎么利用这个副屏幕?
2.1 用作 presentation 演示ppt:
presentation 顾名思义就是用来做演示的,一个窗口,好比windows 打开ppt的时候接上投影仪或者第二个屏幕,就可以开启演示模式,只是将ppt的内容输出到第二个屏幕,而电脑自己的控制桌面都是在自己的屏幕上。 关于怎么使用者presentation,不赘述。
2.2 克隆主屏幕的内容,就是主屏幕显示什么,副屏显示同样的内容,镜像模式。
开发者模式中创建的虚拟副屏默认就是这种模式,createVirtualDispaly的时候可以指定flag.
2.3 将一个activity 从第二个屏幕上启动,作为一个独立的屏幕
需要用startActivity()方法,这个Activity将只会在一个屏幕上显示
- 给activity的启动选项里面,加上要启动的设备ID。
- Intent中添加上Intent.FLAG_ACTIVITY_NEW_TASK
代码如下:
// 多次创建副屏 则副屏的id都是增加的,所以不一定是1,这里还是获取一下
int SecondeDid = 0;
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
for (Display display : displayManager.getDisplays())
Log.d(TAG, "dispaly: " + display.getName() + ", id " + display.getDisplayId() + " :" + display.toString());
if (display.getDisplayId() != 0)
SecondeDid = display.getDisplayId();
// 先检查一下是不是支持在第二屏上显示activity这个特性,
// 在ActivityOptions.java setLaunchDisplayId 上面有相关的说明
PackageManager packageManager = getPackageManager();
boolean ret = packageManager.hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
Log.d(TAG, "onCreate: have " + PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS + " " + ret);
// 要加上Intent.FLAG_ACTIVITY_NEW_TASK
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(SecondeDid);
Intent intent = new Intent(StartActivity.this, CameraServerActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, options.toBundle());
如下,将一个只是预览摄像头的 activity给显示在了虚拟副屏上。
2.3 方式,如果把用户的输入信息都加入进来,结合上无线投屏就是 多屏协作了,在电脑端独立使用手机的应用。
rk3288 android7副屏旋转显示异常与满屏修改
rk3288 android7副屏旋转显示异常与满屏修改
主屏使用的是HDMI,副屏使用的lvds
主屏是HMDI转lvds 由于转接模块不支持1280x800 所以设置了hdmi输入源为1280x720 为了保证主屏正常显示 修改了framebuffer为1280x800
就是由于修改了framebuffer导致副屏显示旋转异常,一定不要设置persist.sys.framebuffer.main这个参数
persist.sys.framebuffer.main=1280x800
查找rk资料了解到,双屏同显时,副屏显示是在主屏显示的基础上进行的缩放,双屏异显时,副屏显示是按照副屏实际物理分辨率重新进行了UI绘制
下面的patch能解决副屏旋转后显示异常及同显时不满屏的问题
修改patch如下
---
device/rockchip/rk3288/system.prop | 13 ++++++-----
.../server/display/LocalDisplayAdapter.java | 20 ++++++++++++++++-
.../com/android/server/display/LogicalDisplay.java | 26 +++++++++++++++++++++-
.../services/surfaceflinger/DisplayDevice.cpp | 3 ++-
4 files changed, 53 insertions(+), 9 deletions(-)
diff --git a/device/rockchip/rk3288/system.prop b/device/rockchip/rk3288/system.prop
index 358f0fd..f34c991 100755
--- a/device/rockchip/rk3288/system.prop
+++ b/device/rockchip/rk3288/system.prop
@@ -48,9 +48,10 @@ ro.rk.displayd.enable=false
sys.hwc.device.primary=HDMI-A
sys.hwc.device.extend=LVDS
-persist.sys.framebuffer.main=1280x800
-persist.sys.resolution.main=1920x1080
-persist.sys.resolution.aux=480x1280
-ro.same.orientation=false
-#ro.orientation.einit=0
-ro.rotation.external=false
+#persist.sys.framebuffer.main=1280x800
+#persist.sys.resolution.main=1280x720
+#persist.sys.resolution.aux=480x1280
+#ro.same.orientation=false
+#ro.rotation.external=false
+ro.orientation.einit=270
+persist.sys.rotation.efull=true
diff --git a/frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 68be9ce..be69c7e 100755
--- a/frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -422,8 +422,26 @@ final class LocalDisplayAdapter extends DisplayAdapter {
// For demonstration purposes, allow rotation of the external display.
// In the future we might allow the user to configure this directly.
- if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
+ /*if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
mInfo.rotation = Surface.ROTATION_270;
+ }*/
+ String rotation = SystemProperties.get("ro.orientation.einit","0");
+ switch(Integer.valueOf(rotation)) {
+ case 0:
+ mInfo.rotation = Surface.ROTATION_0;
+ break;
+ case 90:
+ mInfo.rotation = Surface.ROTATION_90;
+ break;
+ case 180:
+ mInfo.rotation = Surface.ROTATION_180;
+ break;
+ case 270:
+ mInfo.rotation = Surface.ROTATION_270;
+ break;
+ default:
+ mInfo.rotation = Surface.ROTATION_0;
+ break;
}
// For demonstration purposes, allow rotation of the external display
diff --git a/frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java b/frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
index 287a25a..acc4c9f 100755
--- a/frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -26,7 +26,7 @@ import java.util.Arrays;
import java.util.List;
import libcore.util.Objects;
-
+import android.os.SystemProperties;
@@ -137,6 +137,22 @@ final class LogicalDisplay {
mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi;
mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi;
}
+ if(mDisplayId!=Display.DEFAULT_DISPLAY){
+ String rotation = SystemProperties.get("ro.orientation.einit","0");
+ int rot = Integer.valueOf(rotation)/90;
+ if(rot%2!=0) {
+ mInfo.appWidth = mPrimaryDisplayDeviceInfo.height;
+ mInfo.appHeight = mPrimaryDisplayDeviceInfo.width;
+ mInfo.logicalWidth = mPrimaryDisplayDeviceInfo.height;
+ mInfo.logicalHeight=mPrimaryDisplayDeviceInfo.width;
+ }else{
+ mInfo.appWidth = mPrimaryDisplayDeviceInfo.width;
+ mInfo.appHeight = mPrimaryDisplayDeviceInfo.height;
+ mInfo.logicalWidth = mPrimaryDisplayDeviceInfo.width;
+ mInfo.logicalHeight=mPrimaryDisplayDeviceInfo.height;
+ }
+ }
+
}
return mInfo;
}
@@ -349,6 +365,14 @@ final class LogicalDisplay {
mTempDisplayRect.right += mDisplayOffsetX;
mTempDisplayRect.top += mDisplayOffsetY;
mTempDisplayRect.bottom += mDisplayOffsetY;
+ if(SystemProperties.getBoolean("persist.sys.rotation.efull", false)) {
+ if(device.getDisplayDeviceInfoLocked().type!=Display.TYPE_BUILT_IN){
+ mTempDisplayRect.left=0;
+ mTempDisplayRect.right=physWidth;
+ mTempDisplayRect.top=0;
+ mTempDisplayRect.bottom=physHeight;
+ }
+ }
device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect);
}
diff --git a/frameworks/native/services/surfaceflinger/DisplayDevice.cpp b/frameworks/native/services/surfaceflinger/DisplayDevice.cpp
index 0c63381..68f93ce 100755
--- a/frameworks/native/services/surfaceflinger/DisplayDevice.cpp
+++ b/frameworks/native/services/surfaceflinger/DisplayDevice.cpp
@@ -538,6 +538,7 @@ void DisplayDevice::setProjection(int orientation,
#endif
#if !RK_VR & RK_HW_ROTATION
+#if 0
bool isHdmiScreen = mType == DisplayDevice::DISPLAY_EXTERNAL;
if (isHdmiScreen) {
int eInitOrientation = 0;
@@ -599,7 +600,7 @@ void DisplayDevice::setProjection(int orientation,
}
ALOGV("update frame [%d,%d]",frame.getWidth(),frame.getHeight());
}
-
+#endif
if (mType == DisplayDevice::DISPLAY_PRIMARY) {
mClientOrientation = orientation;
orientation = (mHardwareOrientation + orientation) % 4;
--
2.7.4
参考资料
以上是关于android 多屏幕显示activity,副屏,无线投屏的主要内容,如果未能解决你的问题,请参考以下文章