精华内容
下载资源
问答
  • android 双屏异显

    2017-11-24 17:30:44
    android 双屏异显 android 双屏异显android 双屏异显android 双屏异显
  • 最近在做一个Android双屏异显的项目,要实现一台Android设备通过HDMI连接两个显示器,然后在一个App中同时显示两个不同的画面。 标题实际上Android并不存在真正的像Windows一样的双屏异显,Android的双屏异显实际上...

    最近在做一个Android双屏异显的项目,要实现一台Android设备通过HDMI连接两个显示器,然后在一个App中同时显示两个不同的画面。

    标题实际上Android并不存在真正的像Windows一样的双屏异显,Android的双屏异显实际上是将一个View覆盖在了主显(或副显)上,从而实现两个显示器显示不同画面的效果。

    在网上查找相关资料,发现基本都是使用 Android 的 Presentation 这个类来实现双屏异显的效果。但是在我的实际使用中效果并不理想。通过查看Prentation类的源码,得知其实际上是一个封装好的Dialog。在使用Presentation过程中,有时会出现无法产生第二画面的问题,各种查找资料无果,无奈智能另寻方法。

    所以,我来介绍一个全新,简单,稳定的双屏异显解决方法。该方法只有几行核心代码。很简单,话不多说,我们直接放码过来。( Talk is cheap, show me the code. — Linus )

    MediaRouter mediaRouter = (MediaRouter)getSystemService(Context.MEDIA_ROUTER_SERVICE);
    
    MediaRouter.RouteInfo routeInfo = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
    
    Display secondDisplay = routeInfo.getPresentationDisplay();
    
    WindowManager windowManager = (WindowManager)this.createDisplayContext(secondDisplay).getSystemService(WINDOW_SERVICE);
    
    Context secondDisplayContext = this.createDisplayContext(secondDisplay);
    
    View view = View.inflate(secondDisplayContext, R.layout.viewLayout, null);
    
    windowManager.addView(view, new WindowManager.LayoutParams(2003,3,3));
    
    展开全文
  • linux4.1关于双屏异显实例,打印双屏信息及双屏红绿蓝切换效果
  • 康金荣+彭宏利摘 要:提出了一种在ARM/Android平台上实现双屏异显功能的方法。所谓双屏异显,即在同一软硬件平台上,实现同时驱动两块LCD屏幕,并且这两块屏幕所显示的内容可以不同。这种功能的实现一方面降低了硬件...

    康金荣+彭宏利

    摘 要:提出了一种在ARM/Android平台上实现双屏异显功能的方法。所谓双屏异显,即在同一软硬件平台上,实现同时驱动两块LCD屏幕,并且这两块屏幕所显示的内容可以不同。这种功能的实现一方面降低了硬件设备成本,另一方面对于提高消费场景的交互性具有重要意义。

    关键词:Android;POS;双屏异显;LCD;消费场景

    DOIDOI:10.11907/rjdk.162114

    中图分类号:TP319

    文献标识码:A文章编号:1672-7800(2016)012-0118-03

    0 引言

    近年来,随着ARM SOC与Android 生态组合的快速发展,其应用已经从智能移动终端(如智能手机、平板电脑等消费电子领域)渗透到各行各业。但受制于芯片体系结构和操作系统架构设计,在Android 平台上,通常只能实现同步双屏的一些应用,如基于智能手机的显示器应用或者基于平板电脑的投影仪应用。在这样的应用中,大屏只能作为小屏的延伸,两块不同的屏上只能显示相同的内容,专业上可称为同步双显或称双屏同显技术。但在现实应用场景中,双屏异显功能更能满足人们的需要。

    本文提出了一种在Android平台上实现双屏异显的方案。该方案以瑞芯微公司推出的RK3288芯片为硬件平台,以Android为移动操作系统,通过开发的APP实现双屏异显功能。

    1 实现原理

    Android框架中与显示相关的组件主要有Activity、Windows、WindowState、Windows Manager Service、Display Manager Service、Surface Manager/Surface Flinger、Display HAL(Hardware Abstraction Layer)以及Linux Kernel中显示方面的驱动等。Android平台的显示框架如图1所示。

    各层模块功能说明如下[1-2]:①Activity:应用程序的主要生命周期载体,显示过程中的内容提供者;②Windows:窗体组件为应用显示的载体组件,应用的界面交互将全部通过窗体组件呈现;③WindowState:窗体组件的实例,用于窗体状态运营和各属性的组成传递;④Windows Manager Service:窗口管理服务是Android系统整个运行状态中所有应用窗体的各管理服务,主要负责窗体状态的转换和上下层之间的信息传递;⑤Display Manager Service:显示设备管理服务是管理Android系统中逻辑显示设备的服务,主要响应显示参数获取和相关状态;⑥Surface Manager/Surface Finger:系统级显示管理服务,处理图形合成,显示状态切换及硬件设备参数调整等;⑦Display HAL(Hardware Abstraction Layer):对于硬件操作的抽象层,通过封装部分JNI的接口与Framework以及APP层进行互动;⑧Kernel Driver:内核驱动处理显示硬件设备细节参数运行。

    2 详细设计

    2.1 Android平台下双屏异显设计

    Android 平台在4.2版本之后新增了对于多屏的支持,主要有3种屏幕类型:主屏幕(Primary Display)、外屏幕(External Display)和虚拟屏幕(Virtual Display)。其中自带屏幕一般识别为主屏幕,而HDMI将会被设为外屏幕。为了方便APP访问上述3种屏幕,Android还提供了一个统一的屏幕管理服务DisplayManagerService。虽然屏幕被划分为3种类型,但是建立于它们之上的窗口合成以及渲染依然统一由SurfaceFlinger管理。这些新特性的引入确保了双屏异显的框架基础。

    2.1.1 Application到Framework

    Android的应用以Activity为基础。应用在启动时会向系统申请建立新的Activity,系统通过Activity Manager Service创建Activity并赋予相应的运行环境,系统通过调用返回给Activity一个可操作WindowState的对象用于显示。应用显示的过程将会通过系统和自己拥有的WindowState与底层进行交换,而内容最终生成于WindowState指向的Surface之中。

    2.1.2 Framework到本地库

    应用的Activity所需显示部分将由ActivityManagerService通过View -> ViewRoot -> Window 的关系最终向WindowsManagerService申请一个新Window。WindowsManagerService通过系统本地运行调用,最终生成一个新的Surface封装在WindowState中提供给Activity。DisplayManagerService是用于管理显示的逻辑设备的一个中间层服务,主要用于维护已注册的显示设备对象列表并向系统提供各显示设备的参数和运行情况。WindowsManagerService在运行过程中将会评估当前设备的显示设备对象,通过DisplayManagerService获取当前已经在线的显示设备对象进行操作。其主要操作是将WindowState、Surface等软件中抽象的对象与实际的逻辑显示设备对象进行绑定,此外,将对比当前显示参数和逻辑显示设备的实际参数,最终将对比结果提供给下层用于图像的适配和变形。

    2.1.3 本地库与Kernel

    本地库中显示子系统中的最重要部分——Surface Manager/Surface Flinger。Surface Manager将负责管理显示与存取操作间的互动,Surface Flinger将已传送的各Surface内容以及应用所申请2D、3D的绘图进行系统级合成,并且管理双FB刷新机制。合成结果将直接送入Framebuffer进行显示。其中如果硬件有相应的加速设备可通过OpenGL/ES进行图像硬件加速,Display Manager Service则可通过Surface 和Display HAL获取较多的硬件设备参数。

    2.2 Android平台下双屏异显实现

    2.2.1 概述

    Android支持多屏幕框架为双屏异显工作提供了诸多便利,如Surface Manger在识别到当前设备拥有多个逻辑显示设备时,可根据需要创立对应的Surface; 通过Display Manager Service 也可方便地获取到显示设备列表并进行操作。下文将对双屏异显中的技术核心点进行阐述。

    2.2.2 Window Manager Service的改造

    Window Manager Service是一个显示控制方面的核心服务,选择通过Window Manager Service进行改造会较为方便地获取到各个运行的显示相关服务的通讯通路,以及所有窗体的状态控制,从而可以减少对于原生系统框架的修改,减少引入Bug和统一性降低的风险[3]。

    Android系统通过一个WindowState的列表维护当前窗体栈,列表从开始直至结束代表当前窗体显示的窗体景深(前后)布局顺序。该列表与当前显示默认设备绑定,而WindowState 本身包含着当前窗体的Surface信息。以上实现了默认显示设备、WindowState列表以及各Window 的Surface的连接关系。

    修改双屏异显功能如图2所示。

    根据当前显示情况进行判断,若当前是双屏同显状态,有应用请求显示至第二块屏幕上。首先按照默认窗体栈,也即默认WindowState列表创立一个新的窗体栈——第二窗体栈,通过Display Manager Service获取第二块屏幕操作上下文对象DisplayContent并将新创建的第二窗体栈与获取的上下文对象绑定。这时从第一窗体栈中查找当前应用的窗体状态对象WindowState,获取后将其添加到第二窗体栈中,并从默认窗体栈中将这个窗体对象移除。

    若当前显示状态已经为双屏异显状态,则查找默认窗体栈获取当前应用的窗体对象WindowState,将第二窗体栈中的应用窗体移动到默认窗体栈栈顶,然后将当前应用的窗体对象移动给第二窗体栈[4]。

    伪代码表示:

    moveAppToSecondDisplay(CurrnetID)

    {

    //查找第二块屏幕

    displayCount=mDisplayContents.size();

    defaultContent=getDefaultDisplayContent();

    secondDisplayContent = null;

    for(int i = 0; i < displayCount;i++)

    {

    tempContent=mDisplayContents.valueAt(i);

    if(tempContent != defaultContent){

    secondDisplayContent = tempContent;

    break;

    }

    }

    //查找当前应用窗体并绑定显示屏幕

    currentWindowState = null;

    defaultWindowList=defaultContent.getWindowList();

    secondWindowList=secondDisplayContent.getWindowList();

    for(int i=defaultWindowList.size()-1;i>=0;i--)

    {

    currentWindowState=defaultWindowList.get(i);

    if(currentWindowState.groupId; == CurrnetID) break;

    defaultWindowList.remove(win);

    currentWindowState.DisplayContent = secondDisplayContent;

    //移动窗体

    SecondDisplayAppMoveBack();

    secondWindowList.add(currentWindowState);

    }

    撤销双屏异显时,将第二窗体栈中的应用窗体移动至默认窗体栈栈顶,销毁创建的第二窗体栈,有Display状态配置成双屏同显。

    3 结语

    本文从硬件到软件,自上而下分层分模块地描述了在ARM/Android的软硬件平台上双屏异显应用于智能POS的实现方法,该方法相对而言具有低成本、低功耗以及高开放度的硬软件组合等特点,所实现的双屏异显不仅能应用在智能POS上,而且针对各行各业需要交互的场景都具有很好的参考价值。

    参考文献:

    [1] 文泉.无线POS机系统的设计与实现[D].成都:电子科技大学,2013.

    [2] CHANDRIAN P.Efficient Java native interface for Android based mobile devices[D].Arizona:Arizona State University,2011.

    [3] 曹凯.基于Android的POS机刷卡器驱动设计[D].青岛:中国海洋大学,2013.

    [4] 范锋.Android的架构与应用开发研究[J].信息与电脑:理论版,2012(5):34.

    (责任编辑:孙 娟)

    展开全文
  • android双屏异显

    热门讨论 2016-06-28 16:02:00
    android双屏异显
  • 在各种产品脑洞大开的时代,需求也是日益新异,笔者最近开发了一套双屏异显app。现在做一些总结1.双屏异显第一种实现方式(官方提供的Presentation)Android 提供了一个叫 Presentation 类,来实现第二屏, 继承 ...

    在各种产品脑洞大开的时代,需求也是日益新异,笔者最近开发了一套双屏异显app。现在做一些总结

    1.双屏异显第一种实现方式(官方提供的Presentation)

    Android 提供了一个叫 Presentation 类,来实现第二屏, 继承 Presentation 实现第二屏,相当于一个特殊的弹窗窗口(具体实现)

    public class DifferentDislay extends Presentation{

    public DifferentDislay(Context outerContext, Display display){

    super(outerContext,display);

    }

    @Override

    protected void onCreate(Bundle savedInstanceState){

    super.onCreate(savedInstanceState);

    setContentView(R.layout.diffrentdisplay);

    }

    }

    引用:

    //双屏显示

    DisplayManager mDisplayManager;//屏幕管理类

    Display[] displays;//屏幕数组

    mDisplayManager =(DisplayManager)MainActivity.this.getSystemService(Context.DISPLAY_SERVICE);

    displays =mDisplayManager.getDisplays(); //得到显示器数组

    DifferentDislay mPresentation =new DifferentDislay

    (getApplicationContext(),displays[1]);//displays[1]是副屏

    mPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

    mPresentation.show();

    所需权限:

    注:以上是以 Presentation 实现的双屏异显,这种方式比较适合双屏独立操作没有交际的时候,如果存在双屏同显,或者两者之际要有一些数据同步,后比较麻烦,

    比如:主屏播放适配 - >投影到第二屏,上面这种方法不适用了,因为涉及到适配同步显示,还有主副屏幕都要启动一个播放器才能实现,性能极大的浪费,设备性能比较好,还可以以这种方式实现,如果设备性能不是很好,使用这种方式后照成视频卡顿,严重者可能解码失败,照成视频无法播放等等一些列并发问题

    针对上面开启第二屏 双屏同显,播放视频,我在原来的基础上做了极大的改善,可以避免启动两个播放器,照成性能的浪费

    2.双屏异显(同显)实现方式

    相信做双屏异显的同胞们,肯定看过来Presentation 的源码 ,源码中显示 Presentation 是继承与 Dialog 来实现的,在文章的开头我也有提到过,第二屏可以看作一个特殊的 Dialog 来实现

    在研究Presentation 源码的时候发现它是通过  Window w = getWindow();  来获取了一个窗口,做我们android 开发的都知道 Window是android 顶级窗口,看到这里我在想为何自己不能直接去创建一个窗口然后获取屏幕数组放置在第二屏幕上呢?往下看

    public void addPresentation(Context paramContext){

    Display display = ((MediaRouter) paramContext.getSystemService(Context.MEDIA_ROUTER_SERVICE)).getSelectedRoute(2).getPresentationDisplay();

    this.secondDisplay = display;

    if (display != null) {

    this.windowManager = (WindowManager) paramContext.createDisplayContext(display).getSystemService(Context.WINDOW_SERVICE);

    this.secondDisplayContext = paramContext.createDisplayContext(this.secondDisplay);

    return;

    }

    }

    上述代码我们获取窗口管理器,通过paramContext创建了第 paramContext.createDisplayContext(this.secondDisplay);  第二屏幕

    创建好第二屏幕以后我们去给第二屏屏幕添加一个view

    public View addView(int paramInt){

    this.view = View.inflate(this.secondDisplayContext, paramInt, null);

    this.layoutParams = new WindowManager.LayoutParams(2003, 3, 3);

    if (Build.VERSION.SDK_INT >= 23) {

    this.layoutParams.type = 2038;

    } else {

    this.layoutParams.type = 2003;

    }

    this.windowManager.addView(this.view, this.layoutParams);

    return this.view;

    }

    这样我们的第二屏幕就已经完成,只需要根据自己的需求创建一个布局,调用addView方法添加进去,把添加进去的view返回出去,在主类中进行操作,就解决了数据数据同步问题

    以下是完整代码

    public class HelpHandPresentation{

    private WindowManager.LayoutParams layoutParams;

    private Display secondDisplay;

    private Context secondDisplayContext;

    private View view;

    private WindowManager windowManager;

    public void addPresentation(Context paramContext){

    Display display = ((MediaRouter) paramContext.getSystemService(Context.MEDIA_ROUTER_SERVICE)).getSelectedRoute(2).getPresentationDisplay();

    this.secondDisplay = display;

    if (display != null) {

    this.windowManager = (WindowManager) paramContext.createDisplayContext(display).getSystemService(Context.WINDOW_SERVICE);

    this.secondDisplayContext = paramContext.createDisplayContext(this.secondDisplay);

    return;

    }

    }

    public View addView(int paramInt){

    this.view = View.inflate(this.secondDisplayContext, paramInt, null);

    this.layoutParams = new WindowManager.LayoutParams(2003, 3, 3);

    if (Build.VERSION.SDK_INT >= 23) {

    this.layoutParams.type = 2038;

    } else {

    this.layoutParams.type = 2003;

    }

    this.windowManager.addView(this.view, this.layoutParams);

    return this.view;

    }

    public void presentationAddView(){

    this.windowManager.addView(this.view, this.layoutParams);

    }

    public void removeLayoutView(){

    this.windowManager.removeView(this.view);

    }

    }

    相当于一个工具类,只复制到项目里可以直接使用

    以下是调用方式

    HelpHandPresentation helpHandPresentation = new HelpHandPresentation();

    helpHandPresentation.addPresentation(context);

    View view = helpHandPresentation.addView(layout);

    三行代码即可,调用方便

    3.双屏异显还有一种方式是通过 投影来实现的,每次投影都会弹提示框,进行确认,有一定的局限性

    (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

    有兴趣的可以看看 MediaProjectionManager 源码实现,这里就在叙述了

    完结

    这篇文章呢,作为一个开头,后续笔者会针对这一模块 发布一套三方sdk,方便大家使用,节省开发时间

    欢迎业界各位同胞提一些好的意见,我会总结归纳,进行梳理,更好的完善sdk的开发进度与工作

    有缘留个关注把

    文章来源: blog.csdn.net,作者:我居然是个凡人,版权归原作者所有,如需转载,请联系作者。

    原文链接:blog.csdn.net/g1998_7_9/article/details/111373249

    展开全文
  • RK3399、RK3288实现双屏异触、双屏异显,标准demo apk
  • 双屏异显设计

    2018-04-23 16:29:06
    一种双屏异显的设计方法,可以通过单cpu接两个lcd,分别显示不同内容
  • rk3288 双屏异显

    2017-08-13 13:56:21
    rk3288 双屏异显
  • 本发明涉及一种Android系统双屏异显的两路音频实现方法。背景技术:关于Android系统的双屏异显两路音频的实现目前还没有通用的方法,Android系统的双屏异显两路音频的需求是:主屏的声音从主屏对应的声卡输出、副屏...

    本发明涉及一种Android系统双屏异显的两路音频实现方法。

    背景技术:

    关于Android系统的双屏异显两路音频的实现目前还没有通用的方法,Android系统的双屏异显两路音频的需求是:主屏的声音从主屏对应的声卡输出、副屏的声音从副屏对应声卡输出,不能有混音。

    如图1所示,现有的Android系统音频整个框架包括应用层APP、framework层、lib层、hal层、驱动以及硬件。

    应用层APP,这是整个音频体系的最上层,因而并不是Android系统实现异显两路音频输出的重点。比如厂商根据特定需求自己写的一个音乐播放器,游戏中使用到声音,或者调节音频的一类软件等等。

    Framework层,Android提供了两个功能类,AudioTrack和AudioRecorder;除此以外,Android系统还为我们控制音频系统提供了AudioManager、AudioService及AudioSystem类。这些都是framework为便利上层应用开发所设计的。

    Libraries层,framework层的很多类,实际上只是应用程序使用Android库文件的“中介”而已。因为上层应用采用java语言编写,它们需要最直接的java接口的支持,这就是framework层存在的意义之一。而作为“中介”,它们并不会真正去实现具体的功能,或者只实现其中的一部分功能,而把主要重心放在库中来完成。比如上面的AudioTrack、AudioRecorder等等在库中都能找到相对应的类,这些库多数是C++语言编写的。除了上面的类库实现外,音频系统还需要一个“核心中控”,或者用Android中通用的实现来讲,需要一个系统服务,这就是AudioFlinger和AudioPolicyService。

    HAL层,从设计上来看,硬件抽象层是AudioFlinger直接访问的对象。这说明了两个问题,一方面AudioFlinger并不直接调用底层的驱动程序;另一方面,AudioFlinger上层(包括和它同一层的MediaPlayerService)的模块只需要与它进行交互就可以实现音频相关的功能了。因而我们可以认为AudioFlinger是Android音频系统中真正的“隔离板”,无论下面如何变化,上层的实现都可以保持兼容。音频方面的硬件抽象层主要分为两部分,即AudioFlinger和AudioPolicyService。实际上后者并不是一个真实的设备,只是采用虚拟设备的方式来让厂商可以方便地定制出自己的策略。抽象层的任务是将AudioFlinger/AudioPolicyService真正地与硬件设备关联起来,但又必须提供灵活的结构来应对变化——特别是对于Android这个更新相当频繁的系统。比如以前Android系统中的Audio系统依赖于alsa-lib,但后期就变为了tinyalsa,这样的转变不应该对上层造成破坏。因而AudioHAL提供了统一的接口来定义它与AudioFlinger/AudioPolicyService之间的通信方式,这就是audio_hw_device、audio_stream_in及audio_stream_out等等存在的目的,这些Struct数据类型内部大多只是函数指针的定义,是一些“壳”。当AudioFlinger/AudioPolicyService初始化时,它们会去寻找系统中最匹配的实现(这些实现驻留在以audio.primary.*,audio.a2dp.*为名的各种库中)来填充这些“壳”。根据产品的不同,音频设备存在很大差异,在Android的音频架构中,这些问题都是由HAL层的audio.primary等等库来解决的,而不需要大规模地修改上层实现。换句话说,厂商在定制时的重点就是如何提供这部分库的高效实现了。

    本发明是基于Android系统的双屏异显两路音频的需求以及现有的Android系统音频整个框架,来实现两路音频输出的。

    技术实现要素:

    本发明要解决的技术问题,在于提供一种Android系统双屏异显的两路音频实现方法,从而弥补了Android系统的双屏异显两路音频输出的空白。

    本发明是这样实现的:一种Android系统双屏异显的两路音频实现方法,包括进入双屏模式过程、播放音频过程和退出双屏模式过程;

    所述进入双屏模式过程包括:

    步骤S11、响应用户操作而进入双屏模式,首先模拟上报声卡插入事件;

    步骤S12、在AudioManager打开第二个声卡;

    步骤S13、在AudioFlinger创建新的PlaybackThread;

    所述播放音频过程包括;

    步骤S21、App要播放声音前先判断是否是主屏播放声音,若是进入步骤S22,若否,进入步骤S23;

    步骤S22、设置主屏声音的streamType,根据streamType在第一个声卡播放声音;

    步骤S23、设置副屏声音的streamType,根据streamType在第二个声卡播放声音;

    所述退出双屏模式过程包括:

    步骤S31、响应用户操作而退出双屏模式,首先模拟上报声卡断开事件;

    步骤S32、在AudioManager关闭第二个声卡;

    步骤S33、在AudioFlinger销毁第二个PlaybackThread,结束。

    进一步的,所述步骤S12实现之前需是在PhoneWindow.java的superDispatchKeyEvent里面预先添加force_speaker广播,并设置media.audio.device_policy.db的属性,异显状态下设置该属性为“speaker”,同显状态设置该属性为“hdmi”,然后在InputManagerService.java的start里面接收广播,收到广播后,触发耳机线控事件。

    进一步的,所述步骤S12具体是:系统声音默认从hdmi输出,当switchValues为0时,mHeadState的状态设置成BIT_HDMI_AUDIO;当switchValues的值为1时,mHeadState的状态设置包括BIT_HDMI_AUDIO和BIT_USB_HEADSET_DGTL,目的是同时打开hdmi和speaker两路输出,这种情况会触发AudFlinger中的openDuplicateOutput创建两个MixerThread,从而打开第二个声卡。

    进一步的,所述步骤S21中,所述App判断是否是主屏播放声音是通过判断media.audio.device_policy.db的属性来实现,若该属性为“speaker”,则判断为异显状态,若该属性为“hdmi”,则判断为同显状态。

    进一步的,本发明方法还包括主副屏切换过程,所述主副屏切换过程是:

    系统默认从hdmi输出,同屏时声音也从hdmi输出;异显时,副屏的声音从speaker输出,主屏的声音从hdmi输出;首先获取副屏上activity的pid,并设置为“media.audio.activity.pid”属性的值,同屏时,属性值设置为-1

    在moveTransitionToSecondDisplay中添加

    SystemProperties.set("media.audio.activity.pid",String.valueOf(win.mSession.mPid));

    在updateDisplayShowSynchronization中添加

    SystemProperties.set("media.audio.activity.pid",String.valueOf(-1));

    在audiopolicy的Engine.cpp的getDeviceForStrategyInt中添加

    返回AUDIO_DEVICE_OUT_WIRED_HEADSET表示声音最终从speaker输出;

    返回AUDIO_DEVICE_OUT_AUX_DIGITAL表示声音最终从hdmi输出。

    进一步的,本发明方法还包括输出设备的修改过程:

    修改的文件路径:/device/rockchip/common/audio_policy_rk30board.conf

    修改的内容包括:

    (1)更改全局配置里的输出设备,由AUDIO_DEVICE_OUT_SPEAKER改为AUDIO_DEVICE_OUT_AUX_DIGITAL;

    (2)更改primary默认输出设备;

    (3)添加dgtl输出。

    进一步的,本发明方法还包括增加dgtl库:

    复制hardware/rockchip/audio/tinyalsa_hal到hardware/rockchip/audio/tinyalsa_hal_dgtl,并修改Android.mk;

    将audio_hw.c中connect_hdmi的值改为false,屏蔽hdmi;

    编译生成audio.dgtl.rk30board.so;

    最终,如果输出要求是hdmi,AudioFlinger会调用audio.dgtl.primary.so;如果输出要求是speaker,AudioFlinger会调用audio.dgtl.rk30board.so。

    本发明具有如下优点:本发明方法通过软件和硬件上的设置,使主屏的声音从主屏对应的声卡输出、副屏的声音从副屏对应声卡输出,最终实现了Android系统双屏异显的两路音频输出,填补了这一技术领域的空白。

    附图说明

    下面参照附图结合实施例对本发明作进一步的说明。

    图1为现有的Android系统的音频框架示意图。

    图2为本发明方法执行流程图。

    具体实施方式

    请参阅图2所示,本发明的Android系统双屏异显的两路音频实现方法,包括进入双屏模式过程、播放音频过程和退出双屏模式过程;

    所述进入双屏模式过程包括:

    步骤S11、响应用户操作而进入双屏模式,首先模拟上报声卡插入事件;

    步骤S12、在AudioManager打开第二个声卡;

    步骤S13、在AudioFlinger创建新的PlaybackThread;

    所述播放音频过程包括;

    步骤S21、App要播放声音前先判断是否是主屏播放声音,若是进入步骤S22,若否,进入步骤S23;

    步骤S22、设置主屏声音的streamType,根据streamType在第一个声卡播放声音;

    步骤S23、设置副屏声音的streamType,根据streamType在第二个声卡播放声音;

    所述退出双屏模式过程包括:

    步骤S31、响应用户操作而退出双屏模式,首先模拟上报声卡断开事件;

    步骤S32、在AudioManager关闭第二个声卡;

    步骤S33、在AudioFlinger销毁第二个PlaybackThread,结束。

    所述步骤S12实现之前需是在PhoneWindow.java的superDispatchKeyEvent里面预先添加force_speaker广播,并设置media.audio.device_policy.db的属性,异显状态下设置该属性为“speaker”,同显状态设置该属性为“hdmi”,App即可通过该属性来判断是否是主屏播放声音,添加和设置的具体代码实现过程如下:

    然后在InputManagerService.java的start里面接收广播,收到广播后,触发耳机线控事件。具体代码的实现过程是:

    所述步骤S12具体是:系统声音默认从hdmi输出,当switchValues为0时,mHeadState的状态设置成BIT_HDMI_AUDIO;当switchValues的值为1时,mHeadState的状态设置包括BIT_HDMI_AUDIO和BIT_USB_HEADSET_DGTL,目的是同时打开hdmi和speaker两路输出,这种情况会触发AudioFlinger中的openDuplicateOutput创建两个MixerThread,从而打开第二个声卡,输出是hdmi还是speaker通过AudioPolicy来进行控制。具体是:

    MixerThread*thread1=checkMixerThread_l(output1);

    MixerThread*thread2=checkMixerThread_l(output2);

    所述步骤S21中,所述App判断是否是主屏播放声音是通过判断media.audio.device_policy.db的属性来实现,若该属性为“speaker”,则判断为异显状态,若该属性为“hdmi”,则判断为同显状态。

    本发明方法还包括主副屏切换过程,所述主副屏切换过程是:

    系统默认从hdmi输出,同屏时声音也从hdmi输出;异显时,副屏的声音从speaker输出,主屏的声音从hdmi输出;首先获取副屏上activity的pid,并设置为“media.audio.activity.pid”属性的值,同屏时,属性值设置为-1。其代码实现过程是:

    在moveTransitionToSecondDisplay中添加

    SystemProperties.set("media.audio.activity.pid",String.valueOf(win.mSession.mPid));

    在updateDisplayShowSynchronization中添加

    SystemProperties.set("media.audio.activity.pid",String.valueOf(-1));

    接着在audiopolicy的Engine.cpp的getDeviceForStrategyInt中获取并解析media.audio.device_policy.db的属性,即在audiopolicy的Engine.cpp的getDeviceForStrategyInt中添加:

    如果该属性里面的值是speaker,则返回AUDIO_DEVICE_OUT_WIRED_HEADSET,表示声音最终从speaker输出;

    如果该属性里面的值是hdmi,则返回AUDIO_DEVICE_OUT_AUX_DIGITAL,表示声音最终从hdmi输出。

    本发明方法还包括输出设备的修改过程:

    由于原来系统只有一个输出,要满足两路输出,因此需添加一个输出。

    修改的文件路径:/device/rockchip/common/audio_policy_rk30board.conf

    修改的内容包括:

    (1)更改全局配置里的输出设备,由AUDIO_DEVICE_OUT_SPEAKER改为AUDIO_DEVICE_OUT_AUX_DIGITAL,代码实现过程是:

    (2)更改primary默认输出设备,代码实现过程是:

    (3)添加dgtl输出,即添加一个虚拟输出,代码实现过程是。

    本发明方法还包括增加dgtl库,这个库是硬件抽象层的修改,为了给第二个音频输出设备使用,实现两路音频设备同时输出声音,互不冲突,代码实现过程是:

    复制hardware/rockchip/audio/tinyalsa_hal到hardware/rockchip/audio/tinyalsa_hal_dgtl,并修改Android.mk;具体如下:

    LOCAL_MODULE:=audio.dgtl.$(TARGET_BOARD_HARDWARE)

    将audio_hw.c中connect_hdmi的值改为false,屏蔽hdmi;

    connet_hdmi=false;

    编译生成audio.dgtl.rk30board.so;

    最终,如果输出要求是hdmi,AudioFlinger会调用audio.dgtl.primary.so;如果输出要求是speaker,AudioFlinger会调用audio.dgtl.rk30board.so。

    最后打上补丁,这些补丁即前面说明的代码实现过程,最后弄了一个整体完整的补丁包:

    在framework/base/下打上补丁Dual_Audio_framework_base.patch;

    在framework/av/下打上补丁Dual_audio_framework_av.patch;

    在hardware/libhardware/下打上补丁Dual_audio_hardware_libhardware.patch。

    虽然以上描述了本发明的具体实施方式,但是熟悉本技术领域的技术人员应当理解,我们所描述的具体的实施例只是说明性的,而不是用于对本发明的范围的限定,熟悉本领域的技术人员在依照本发明的精神所作的等效的修饰以及变化,都应当涵盖在本发明的权利要求所保护的范围内。

    展开全文
  • 双屏异显 完美code

    2018-05-06 15:31:26
    基于 某方案的双屏异显全部code
  • android rk3288 rk3399 双屏双触 双屏异显 验证apk,android rk3288 rk3399 双屏双触 双屏异显 验证apk,android rk3288 rk3399 双屏双触 双屏异显 验证apk
  • Android双屏异显1

    2018-01-10 17:40:12
    最近在做超市收银系统,需要双屏异显,全局设置客户屏显示内容,做一下笔记
  • android 双屏异显demo源码
  • 现在越来越多的Android设备有多个屏幕,双屏异显应用场景最多的应该就是类似于收银平台那种设备,在主屏上店员能够对点商品进行选择录入,副屏则是展示给我们的账单详情,但是它只通过了一个软件系统就实现了双屏异...
  • 基于rk3399 android7.1 通过presentationactivity来实现双屏异显的demo
  • android双屏异显.rar

    2019-07-30 10:08:17
    android双屏异显.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • Android双屏异显

    千次阅读 热门讨论 2018-01-10 16:46:46
    Android的双屏异显 最近在做超市收银系统,需要双屏异显,全局设置客户屏显示内容,做一下笔记。 1.客户屏:继承Presentation public class CustomerDisplay extends Presentation { private Context mContext...
  • 全志A20 android4.4双屏异显 双屏同显终于可以了

    万次阅读 热门讨论 2016-05-07 18:10:25
    全志A20 android4.4双屏异显 双屏同显终于可以了
  • android 双屏异显 api 含实例代码
  • android双屏是克隆模式,如果要在第二屏幕显示不同内容,需要自定义一个Presentation类1.先设置权限(刚开始折腾很久没有效果,后来发现是没设置权限)2.自定义类public class DifferentDislay extends Presentation{...
  • Android实现双屏异显

    千次阅读 2019-02-21 19:33:38
    Android实现双屏异显
  • 概述Android实现双屏异显的实现方式有2种。方式一:在Android4.2及以上平台上,按照标准Android SDK提供的API,使用Presentation类,将一个APP的相关内容显示到指定的屏幕上,具体请参考...
  • 双屏异显页面切换副屏可控
  • 最近公司项目中遇到一个问题,双屏异显双屏异显的代码网上很好找,大家写的时候注意权限就好了。可是遇到一个问题,就是我的两个屏幕,主屏是竖屏,副屏是横屏,这样子一个横屏一个竖屏,副屏上所有的控件都变形了...
  • 双屏异显——Presention 双屏异显——Presention是一个应用于辅助屏显示的一个组件 一个双屏收银 主屏选择商品 副屏给客户显示需求 Presention相当于一个在Window上显示的一个Dialog 与Activity一样Presention也是...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 361
精华内容 144
关键字:

双屏异显