RK Android7.1 双屏显示旋转方向
一.参考 Rockchip_Developer_Guide_Dual_Display_Rotation_Direction_Debugging_CN.pdf
1 2 3 4 | persist.sys.rotation.einit = 0 / 1 / 2 / 3 : persist.sys.rotation.efull = false / true : 备注:当主副屏宽高比不同时,persist.sys.rotation.efull 为 false ,则副屏会出现黑边, 所以这种情况,建议将 persist.sys.rotation.efull 设置为 true ,些许的拉伸不会影响显示效果。 |
二.frameworks\base\services\core\java\com\android\server\display\LogicalDisplay.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public DisplayInfo getDisplayInfoLocked() { if (mInfo == null ) { mInfo = new DisplayInfo(); mInfo.copyFrom(mBaseDisplayInfo); if (mOverrideDisplayInfo != null ) { mInfo.appWidth = mOverrideDisplayInfo.appWidth; mInfo.appHeight = mOverrideDisplayInfo.appHeight; mInfo.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth; mInfo.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight; mInfo.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth; mInfo.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight; mInfo.logicalWidth = mOverrideDisplayInfo.logicalWidth; mInfo.logicalHeight = mOverrideDisplayInfo.logicalHeight; mInfo.overscanLeft = mOverrideDisplayInfo.overscanLeft; mInfo.overscanTop = mOverrideDisplayInfo.overscanTop; mInfo.overscanRight = mOverrideDisplayInfo.overscanRight; mInfo.overscanBottom = mOverrideDisplayInfo.overscanBottom; mInfo.rotation = mOverrideDisplayInfo.rotation; mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi; mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi; } if (mDisplayId!=Display.DEFAULT_DISPLAY){ String rotation = SystemProperties.get( "persist.sys.rotation.einit" , "0" ); if (Integer.valueOf(rotation)% 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; } } } |
双屏属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # Dual - display configuration # 主屏 eDP sys.hwc.device.primary=eDP # 副屏 sys.hwc.device.extend=LVDS #persist.sys.framebuffer.main=800x1280 persist.sys.resolution.main=1920x1080 persist.sys.resolution.aux=800x1280 # 副屏是否全屏显示 persist.sys.rotation.efull = true # 主屏的旋转方向( 0 90 180 270 ) ro.sf.hwrotation= 0 # 副屏输出旋转方向对应 0 / 90 / 180 / 270 ( 0 1 2 3 ) +persist.sys.rotation.einit = 1 #副屏也随着 g-sensor 旋转(只关注方向,黑边不关注) ro.sys.rotation.sensor = false // 主副屏orientaion是否相同 ro.same.orientation= false // 副屏是否随主屏旋转 ro.rotation.external= false |
三.写了个apk 控制属性
3.1.布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http://schemas.android.com/tools" android:layout_width= "match_parent" android:layout_height= "match_parent" android:orientation= "vertical" android:gravity= "center" tools:context= "com.gatsby.systemdisplay.MainActivity" > <Button android:id= "@+id/btn1" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:text= "0" android:textSize= "32sp" /> <Button android:id= "@+id/btn2" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:text= "90" android:textSize= "32sp" /> <Button android:id= "@+id/btn3" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:text= "180" android:textSize= "32sp" /> <Button android:id= "@+id/btn4" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:text= "270" android:textSize= "32sp" /> <TextView android:id= "@+id/text1" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:text= "@string/hello_world" android:textSize= "200sp" /> </LinearLayout> |
3.2.code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | package com.gatsby.systemdisplay; import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Method; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { Button btn1, btn2, btn3, btn4; TextView text1; String rotation_einit; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = (Button) findViewById(R.id.btn1); btn2 = (Button) findViewById(R.id.btn2); btn3 = (Button) findViewById(R.id.btn3); btn4 = (Button) findViewById(R.id.btn4); text1 = (TextView) findViewById(R.id.text1); btn1.setOnClickListener( this ); btn2.setOnClickListener( this ); btn3.setOnClickListener( this ); btn4.setOnClickListener( this ); rotation_einit = getProperty( "persist.sys.rotation.einit" ); text1.setText(rotation_einit); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.btn1: setProperty( "persist.sys.rotation.einit" , "0" ); RootCommand( "reboot" ); break ; case R.id.btn2: setProperty( "persist.sys.rotation.einit" , "1" ); RootCommand( "reboot" ); break ; case R.id.btn3: setProperty( "persist.sys.rotation.einit" , "2" ); RootCommand( "reboot" ); break ; case R.id.btn4: setProperty( "persist.sys.rotation.einit" , "3" ); RootCommand( "reboot" ); break ; } } @SuppressWarnings ( "finally" ) public String getProperty(String key) { String value = "unknown" ; try { Class<?> c = Class.forName( "android.os.SystemProperties" ); Method get = c.getMethod( "get" , String. class , String. class ); value = (String) (get.invoke(c, key, "unknown" )); } catch (Exception e) { e.printStackTrace(); } finally { return value; } } public void setProperty(String key, String value) { try { Class<?> c = Class.forName( "android.os.SystemProperties" ); Method set = c.getMethod( "set" , String. class , String. class ); set.invoke(c, key, value); } catch (Exception e) { e.printStackTrace(); } } public void RootCommand(String cmd) { Process process = null ; DataOutputStream os = null ; DataInputStream is = null ; try { process = Runtime.getRuntime().exec( "su" ); os = new DataOutputStream(process.getOutputStream()); os.writeBytes(cmd + "\n" ); os.writeBytes( "exit\n" ); os.flush(); int aa = process.waitFor(); is = new DataInputStream(process.getInputStream()); byte [] buffer = new byte [is.available()]; is.read(buffer); String out = new String(buffer); } catch (Exception e) { e.printStackTrace(); } finally { try { if (os != null ) { os.close(); } if (is != null ) { is.close(); } process.destroy(); } catch (Exception e) { } } } } |
分类:
RockChip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】