Android Bluetooth AVRCP

2023-10-31

本篇blog继续以结合日志的形式来分析AVRCP,以手机连接上耳机后,通过耳机控制音乐播放的暂停、播放来分析AVRCP的过程。

1. AVRCP

本章基于A/V Remote Control Profile 1.6.2 – Bluetooth® Technology Website

音频/视频远程控制配置文件 (AVRCP) 定义了所需的功能和程序,以确保在音频/视频分发场景中具有音频/视频控制功能的蓝牙设备之间的互操作性。

在此配置文件中,控制器将检测到的用户操作转换为 A/V 控制信号,然后将其传输到远程蓝牙设备。传统红外遥控器可用的功能可以在此配置文件中实现。除此之外,配置文件使用蓝牙特定的扩展来支持与要在蓝牙设备之间传输的内容相关的元数据的传输。提供浏览功能以允许遥控器导航媒体并控制远程目标设备上的特定媒体播放器。本配置文件中描述的遥控器专为 A/V 控制而设计。其他使用蓝牙无线技术的远程控制解决方案可应用于包括 A/V 设备在内的通用蓝牙设备。

请注意,AVRCP不处理音频/视频流。支持此配置文件的设备还可以通过实现高级音频分发配置文件和/或视频分发配置文件来支持音频/视频流。

如图所示,AVRCP依赖于GAP,对于封面艺术(Cover Art)功能,AVRCP使用基本成像配置文件(Basic Imaging Profile)中的通用成像图像提取(Generic Imaging Image Pull)功能。

1.1 Profile overview

Baseband、LMP 和 L2CAP 是 OSI 第 1 层和第 2 层蓝牙协议。 AVCTP 和 BIP 定义了为控制 A/V 设备而要交换的程序和消息。 SDP 是蓝牙服务发现协议。 OBEX 是 IrOBEX 的蓝牙适配,它是 BIP 的底层传输协议,BIP 是提供功能以交换与媒体相关的图像的实体。 BIP 在图 2.1 的括号中描述,以表明一些 BIP 功能被重用或重新定义用于 AVRCP,但 BIP 不用作独立配置文件。 AV/C 是负责基于 AV/C 命令的设备控制信令的实体。应用程序是 AVRCP 实体,交换本规范中定义的控制浏览命令。

1.1.1 Configuration and roles

为符合AVRCP的设备定义了以下角色:

控制器(Controller,CT), 是通过向目标发送命令帧启动事务的设备。 CT 的示例是个人计算机、PDA、移动电话、遥控器或 AV 设备(例如车载系统、耳机、播放器/录音机、计时器、调谐器、监视器等)。

目标(Target,TG),是接收命令帧并相应生成响应帧的设备。 TG 的示例是音频播放器/记录器、视频播放器/记录器、电视、调谐器、放大器或耳机。

此配置文件通过将 A/V 功能分为四类来确保互操作性:

  • player/recorder
  • monitor/amplifier
  • tuner
  • menu

1.1.2 Scenarios

1.1.2.1 Remote control from separate controller

在下图 2.3 所示的配置中,遥控器(Remote Controller)是事务的 CT。来自遥控器的命令帧发送到便携式光盘播放器(Portable Disc Player)作为 TG。音频流从便携式光盘播放器发送到耳机。耳机只接收音频流,不参与遥控器和便携式光盘播放器之间的事务。当用户希望控制便携式光盘播放器时,由遥控器触发事务。

1.1.2.2 Remote control from car audio system

下图配置中,车载音响系统为CT,手机为TG。用户通过汽车界面浏览手机上的可用媒体。然后,用户可以执行触发从电话检索媒体元数据的动作,并执行其他控制操作。

1.1.2.3 Remote control and audio stream between two devices

在下图 2.5 所示的配置中,耳机是CT,便携式光盘播放器是 TG。当用户希望控制便携式光盘播放器时,由耳机附带的遥控器触发事务。

1.1.2.4 Mutual remote control within a piconet

在下图 2.6 所示的配置中,耳机和便携式光盘播放器都可以作为遥控器工作。例如,便携式光盘播放器如果控制成为 TG 的耳机的音量,就变成了 CT。另一方面,当耳机向便携式光盘发送开始播放或停止播放的命令作为 TG 时,耳机成为 CT。

1.1.2.5 Remote controller with LCD 

在下图 2.7 所示的配置中,带有 LCD 遥控器的耳机是 CT。它通过向媒体播放器(即 TG)发送命令来接收媒体元数据和浏览信息。遥控器可以有一个 LCD 来将接收到的数据呈现给用户。

1.1.2.6 Car Kit with full display

在下图 2.8 所示的配置中,全屏显示的 carkit 是 CT 类别 1。它通过向 TG 移动设备发送命令来接收浏览信息。 CT 使用封面艺术功能来检索与浏览或播放的媒体项目相关的封面艺术。

1.2 Control interoperability requirements

在此配置文件中,协议信号通过在通信设备中启动过程和通过交换消息来交换。信令图使用图 1.2 的约定:信令约定。

1.2.1 Procedures

1.2.1.1 AVCTP connection establishment/release

用于 AVCTP 控制的 L2CAP 连接建立可以由 CT 或 TG 发起。如果两个设备都支持浏览通道,则可以在控制通道之后建立浏览通道。控制通道应始终在浏览通道之前建立。

浏览通道应配置为使用 L2CAP 增强重传模式。

在 AVCTP 实体之间只能建立一个用于控制的 L2CAP 连接和一个用于浏览的 L2CAP 连接(如果两个设备都支持)。如果连接已经存在,CT/TG 不应发起连接请求。

 AVCTP 的 L2CAP 连接释放可由 CT 或 TG 发起。如果存在浏览通道,则应在控制通道之前释放。如果不再需要浏览通道,可以在不释放控制通道的情况下释放浏览通道。如果浏览通道已经被释放,只要控制通道仍然存在,可以在需要时重新建立。 

1.2.1.2 AV/C command

当用户产生内部或事件时,如果此时尚未建立连接,CT 将发起连接建立。一旦建立连接,它就可以发送一个 AV/C 命令。

下面是可能的命令:

1.2.2 Protocol concepts

(1)AV/C commands

AVRCP 中存在两组 AV/C 命令。 PASSTHROUGH 命令集、UNIT 和 SUBUNIT INFO 命令在 AV/C 规范中定义。还存在一组命令,以下称为 AVRCP 特定 AV/C 命令,定义为蓝牙 SIG 供应商相关扩展。这些命令使用 AV/C Vendor Dependent Opcode 和 Vendor Unique PASSTHROUGH 操作 id。它们通过 AVCTP 控制通道发送。

(2)Browsing commands

浏览命令集使用 AVCTP 浏览通道。直接使用 AVCTP,不经过 AV/C 层。 AVCTP 分片不应应用于浏览通道。这意味着 AVRCP 实体可以从 AVCTP 浏览通道 MTU 确定对等实体可以接受多少数据。然后,发送者可以采取必要的措施来限制发送的数据量,同时保留用户体验。例如,当向 TG 发送搜索命令时,CT 应限制用户可以输入的搜索字符串长度,以使搜索命令适合 L2CAP MTU。

(3)Cover Art commands

AVRCP 中使用的封面艺术命令被 BIP 重用或覆盖。 BIP 通用成像图像拉取功能用于提供允许 CT(作为成像启动器)检索与 TG(作为成像响应器)上的媒体相关联的图像的功能。这些命令通过 OBEX 发送。

2. AVCTP

AVCTP(Audio/Video Control Transport Protocol )描述了用于交换消息以控制音频和/或视频设备的传输机制。

AVCTP 用于传输为通过点对点连接控制远程 A/V 设备而交换的命令/响应消息。 AVCTP 没有描述用于控制 A/V 设备的命令和/或响应帧的格式和编码;命令和/或响应格式和编码规则由相关的控制配置文件指定。

 此协议可以与其他 A/V 协议共存于同一设备中,并且应该能够共享一个公共 ACL 链接。

 控制器通过向作为该事务目标的远程设备发送命令来启动事务。一个完整的 AVCTP 事务由一个包含发给目标的命令的消息和零个或多个包含目标返回给控制器的响应的消息组成。

图 3.1 显示了一个基本事务的示例,其中目标在收到命令消息后执行内部操作,然后返回响应。

2.1 AVCTP Message Format

AVCTP 消息在一个或多个 AVCTP 数据包中传输。

包头格式取决于消息是否分片。

2.1.1 Non-Fragmented AVCTP Message

下表描述了封装在单个 L2CAP 数据包中的 AVCTP 消息的通用格式。

 Transaction label:由应用程序提供;

Packet_type :设置为零 (00) 以指示命令/响应消息在单个 L2CAP 数据包中传输;

C/R:指示消息是传送命令帧 (0) 还是响应帧 (1),由应用程序提供;

IPID:在响应消息中设置,以指示在同一事务的命令消息中接收到无效的配置文件标识符;否则该位设置为零。在命令消息中,该位设置为零。

Profile Identifier (PID):指示命令/响应帧是根据所识别的配置文件定义的规则进行编码的。该值应与蓝牙分配编号文档中为此配置文件定义的服务类别的 16 位 UUID 相同。

图 6.1 描述了在单个 L2CAP 数据包中传输符合 MTU 要求的命令/响应消息的封装过程。

2.1.2 Fragmented AVCTP Message

以下部分描述了用于传输无法放入单个 L2CAP 数据包的 AVCTP 命令/响应消息的 AVCTP 数据包格式。

在发送 AVCTP 实体中应发生分段,以将过大的消息信息划分为小于或等于 L2CAP 协商的 MTU 限制的 AVCTP 数据包,然后再将它们发送到 L2CAP 层。

分段消息在序列的每个数据包中由特定的数据包类型代码标记。分片消息包中使用了三种可能的类型:

  • start packet——序列中的第一个packet;
  • continue packet——介于start packet与end packet之间的packet;
  • end packet——序列中的最后一个packet;

在接收端,AVCTP 实体通过识别属于同一事务的数据包并检查每个数据包的类型来重组完整的消息。

L2CAP 通道保证单个 AVCTP 数据包的完整性按正确顺序传送而不是整个消息的完整性

由于通道可能不可靠,因此序列中的一些 AVCTP 数据包可能会丢失。

start packet提供了重组完整消息所需的 AVCTP 数据包数量,因此 AVCTP 接收实体应实施一致性检查并丢弃任何不完整的消息。

无论它是否在不同的 PID 或事务标签上.不允许在同一个 AVCTP 连接上交错不同的数据包片段。

分片消息的接收方可以基于起始包长度和第一包提供的包信息元素的数量来分配用于消息重组的资源:

  • 封装分段 AVCTP 消息的start和continue数据包的 L2CAP 数据包的有效负载应具有相同的长度。
  • 封装 AVCTP 消息的end包的 L2CAP 包的有效负载不应大于start或continue包的长度;

下面3个表描述了Start、Continue和End包的格式:

Transaction label:由应用程序提供,并由序列的每个数据包中的消息发送者复制。它在接收端用于识别属于同一消息的数据包。

Packet_ type:将 AVCTP 数据包限定为开始 (01)、继续 (10) 或结束 (11) 数据包。

C/R:指示消息是传送命令帧 (0) 还是响应帧 (1)。该字段由应用程序提供,存在于消息的每个数据包中。

 IPID:在响应消息中设置,以指示在同一事务的命令消息中收到无效的 Profile Identifier;否则该位设置为零。在命令消息中,该位设置为零。该字段仅存在于消息的开始数据包中。

Number of AVCTP Packets:存在于每个起始数据包中,以指示属于同一消息的 AVCTP 数据包的总数。由于起始包也算在内,所以这个值总是大于1。

RFA:取代了Continue或End数据包中的 IPID 字段。它是为将来添加而保留的,应设置为0。

Profile Identifier (PID) :表示消息信息部分是根据所标识的配置文件定义的规则进行编码的。该值应与Assigned Numbers文档中为此配置文件定义的服务类别的 16 位 UUID 相同。该字段仅存在于消息的开始数据包中。

3. 日志分析

以一台手机连接蓝牙耳机听歌为例,通过蓝牙耳机控制音乐的开始、暂停。日志链接:AndroidBluetoothA2DP&&AVRCPBugreport-Android文档类资源-CSDN下载

3.1 SDP流程

连接耳机后,首先是通过SDP发现Service的过程。

 Frame#844由Slave发起,查询是否支持AVRCP的TG以及AVCTP。

 Frame#845是Master发给Slave的response,PSM0x0017表示AVCTP,AVCTP版本为1.4,AVRCP版本为1.6,支持Catagory:player/recorder。

Frame#958是Master发给Slave的对于AVRCP的查询。

 Frame#971是Slave发给Master的response,表示支持AVRCP,并且支持AVRCP的CT。支持AVCTP,版本为1.4。支持AVRCP,版本为1.6,且支持Catagory:Player/Recorder和Monitor/Amplifier。支持AVRCP的TG。

这边我们可以看到最后面的PSM处被截断了,详细的内容可以参考BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part B 4.3 PARTIAL RESPONSES AND CONTINUATION STATE。

在客户端收到部分响应和伴随的Continuation状态参数后,它可以重新发出原始请求(使用新的事务 ID),并将Continuation状态包含在新请求中,向服务器指示原始响应的剩余部分是想要的。

Frame#974重新发出原始请求,使用新的事务ID 0x0001,并包含了Continuation状态。

 Frame#988,提示了数据是重构的,下图中之前传输过的数据被我折叠了,仅展示之前被分割开的。最后的Bytes for continuation length: 0表示完整的一帧。

3.2 AVRCP流程

下图贴了AVRCP的部分流程,逐帧去分析。

在上面1.2.1.2部分,我们知道了AV/C Comand的流程了,这里我们具体看发出来的frame。

AV/C Command可以阅读

3.2.1 AV/C Command & response

根据文档AV/C Digital Interface Command Set General Specification Version 4.1的第7章,这部分讲了AV/C Frame的详细信息。

在AVRCP展示的帧中,Ctype可以看到三种类型(已标红),其实有下面几种:

  • CONTROL
  • STATUS
  • SPECIFIC INQUIRY
  • NOTIFY
  • GENERAL INQUIRY

(1)CONTROL commands

控制命令由控制器发送到另一个设备,即目标,以指示目标执行操作。目标中的 AV/C 单元或子单元可能是命令的接收者,由命令帧中的 subunit_type 和 subunit_ID 字段确定。其余字段 opcode 和operand[n] 指定命令。下图显示了 CONROL 命令的命令和响应事务。

NOT IMPLEMENTED:目标没有执行由 ck 列中标记的opcode 和operand[n] 指定的 CONTROL 命令,或者该命令的地址是目标未执行的子单元。目标的状态不会被修改。

INTERIM:如果执行了由 ck 列中标记的 opcode 和operand[n] 指定的 CONTROL 命令,但目标无法在 100 毫秒内响应 ACCEPTED 或 REJECTED,则它应返回指示 INTERIM 的响应帧。在 INTERIM 的第一个响应之后,目标不应为此命令发送任何额外的 INTERIM 响应。除非随后的总线复位导致 AV/C 事务被中止,否则目标最终将返回一个响应代码为 ACCEPTED 或 REJECTED 的响应帧。

其他的response都很好理解了。

 (2)STATUS commands

STATUS 命令由控制器发送到设备,以请求设备在命令上下文中的当前状态。 STATUS 命令可以发送到 AV/C 单元或子单元。 STATUS 命令不应改变目标的状态。

 IN TRANSITION:目标执行由 ck 列中标记的opcode and operand[n]指定的 STATUS 命令,但目标状态处于转换中,可能是因为已确认的命令或手动操作。在未指定的未来时间,后续的STATUS命令可能会导致返回 STABLE 状态。注意,IN TRANSITION 响应帧应包括目标正在转换到的预期状态

STABLE:目标执行由 ck 列中标记的 opcode 和operand[n] 指定的状态命令,请求的信息在 AV/C 响应帧中的 opcode 和operand[n] 值中报告。

(3)NOTIFY commands

希望接收设备状态未来变化通知的控制器可以使用 NOTIFY 命令。对 NOTIFY 命令的响应应指示目标的当前状态,然后在未来某个不确定的时间指示目标的更改状态。下图展示了 NOTIFY 命令的命令和响应机制

如下图为AV/C command frame格式:

如下图为 AV/C response frame格式:

Frame#918为CT发出的AV/C Command:

Command Type: STATUS用于查询TG的状态,对应的Code为0x01。

Subunit Type和Subunit ID字段的描述如下面三表:

Subunit Type占5位,Subunit ID占3位,合起来二进制表达就是01001000,即0x48。

Operation code: VENDOR-DEPENDENT,其值就为0x00。

  对于VENDOR-DEPENDENT command,其帧格式如下:

 对于AVRCP,company_ID被写死为[0x001958],详见AVRCP 4.3.1。

  

AVRCP 中使用了两种 PDU 格式。在控制通道上,所有命令和响应都是 AVRCP 6.3.1 节中定义的 AV/C 通用 PDU 或 AVRCP 特定 AV/C PDU。在浏览通道上,所有命令和响应都是AVRCP 6.3.2 节中定义的 AVRCP 特定浏览 PDU。

供应商相关命令/响应帧中的供应商相关数据字段应为 AVRCP 特定 AV/C PDU。每个 PDU 由一个 PDU 标识符、所有参数的长度(不包括参数长度字段)和 PDU 特定的参数组成。

AVRCP表 4.5 包含 AVRCP 特定命令。命令分为两组 - 命令类型为 AV/C CType的AV/C VENDOR DEPENDENT 命令和浏览命令。 AV/C 命令应在 AVCTP 控制信道上发送。浏览命令应在 AVCTP 浏览通道上发送

Packet type: Non-Fragmented表示消息不分片,即0x00。若分片,对应的Start、Continue和End Packet的packet type分别为0x01,0x10,0x11。

Capability ID允许的值如下:

Frame#921为AV/C Response。如之前所述AV/C Command应在控制通道上发送,相应的response也应在控制通道上回复。回复的EventID是针对Command中的Capability ID进行的回复。在AVRCP 附录H中也有相应的说明。

CT知道TG的Events Supported后,就发出Notify Commands,这样TG相应的状态变化时会通知CT。

Frame#926 927 1597是一轮Notify Command的过程。

Frame#926是CT(本轮CT为Slave,即耳机)发出Notify Command,Transaction Label: 2用于标识本次的事务,区分后续的CHANGED Response。Operands中的Event ID字段,表示本次注册的是EVENT_TRACK _CHANGED的通知。

 Frame#927是TG返回的一个INTERIM response,表示未来某个时刻会再给你返回一个REJECT或者CHANGED response。

Frame#1597是TG发给CT的CHANGED response,表示本轮跟踪的状态已经发生改变。

另一个跟踪的事件EVENT PLAYBACK STATUS CHANGED,TG在Frame#1598发出了CHANGED response,Current Play Status切换到PLAYING。

上面两个CHANGED response发出来是因为我在手机的音乐播放器上按了播放音乐的开始按键。

CT(本轮CT为Slave,即耳机)知道TG当前状态处于PLAYING就发出了新的STATUS Command——Get Element Attribute,获取歌曲的信息。

TG在List of Attributes and their values中回复了详细信息。

 3.2.2 PASS THROUGH command

PASS THROUGH 命令用于将正确的用户操作传达给目标(对用户透明)。无论目标的状态如何,都可以传输 PASS THROUGH 命令。 PASS THROUGH 控制命令的格式如下,注意msb与lsb之间是8位大小。

state_flag 字段表示“按下或释放按钮”的用户操作,作为遥控器操作。当按下按钮时,该字段的值应为0;释放时,该值应为 1。当用户按下然后释放按钮时,控制器通常会发送此命令两次,即按下和释放。具有按下值的命令在目标发送回命令响应后两秒内有效。当希望命令保持有效时,控制器应继续在 operation_id 字段中发送具有相同操作 id 值的按下值。如果目标在两秒内没有收到按下的命令,或者目标收到带有另一个操作id的按下命令,则目标认为释放的命令已发送但未接收。在这些情况下,当目标在超时或接收到新按下的命令后收到这个释放的命令时,目标将忽略释放的命令。

Frame#1958为CT(本轮CT为Slave,即耳机)发出按下按钮命令,State flag: Button Pushed值为0,Operation id为Play,对应0x44。

 另一个Frame#1960为CT(本轮CT为Slave,即耳机)发出释放按钮命令,State flag: Button Released,值为1,和Operation id合起来就是0xC4。

其他的,例如Browse Command,本文没有去抓取相关日志,感兴趣的可以自己去抓取研究。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Bluetooth AVRCP 的相关文章

  • Android 在打开应用程序时会广播吗?

    例如 如果我想知道Youtube何时打开 是否有与之相关的广播 我当然知道我可以轮询 logcat 消息来检查活动 但我可以通过广播来做到这一点吗 因为它会少得多的耗电 此链接似乎表明这是不可能的 如何跟踪 Android 中的应用程序使用
  • Android 上的 SVG 支持

    Android 支持 SVG 吗 有什么例子吗 最完整的答案是这样的 Android 2 x 默认浏览器本身不支持 SVG Android 3 默认浏览器支持 SVG 要将 SVG 支持添加到 2 x 版本的平台 您有两个基本选择 安装功能
  • 安卓定位不准确

    我正在尝试获取当前用户的位置 我试图重构我的代码以获得更好的结果 但我只是不断得到关于准确度的荒谬位置 它在 900 600 米之间 如何才能得到更好的结果 使其精度达到50m以内 这是我的代码 package com agam mapsl
  • ffmpeg视频已压缩但无法在浏览器中播放

    我已经集成了ffmpeg4android lib 视频压缩工作正常 但视频无法在除 safari 浏览器之外的浏览器中播放 上传到服务器后 我使用了以下命令 ffmpeg y i
  • 播放 SoundCloud 曲目

    我可以在 Android 应用程序中播放 SoundCloud 中的曲目吗 我正在尝试这段代码 但它不起作用 String res https api soundcloud com tracks 84973999 stream client
  • 带操作按钮的颤动本地通知

    我在我的 flutter 项目中尝试了 flutter 本地通知插件 它在简单通知上工作正常 但我需要带有操作按钮的通知功能 请帮助我或建议我实现此功能 不幸的是 flutter local notifications 插件尚不支持操作按钮
  • 如何在React Native Android中获取响应头?

    您好 我想在获取 POST 请求后获取响应标头 我尝试调试看看里面有什么response with console log response 我可以从以下位置获取响应机构responseData但我不知道如何获取标题 我想同时获得标题和正文
  • 如何解决 Firebase AuthUi 中无法找到显式活动?

    使用 firebase UI 时 我无法找到显式活动类 com firebase ui auth KickoffActivity protected void onCreate Bundle savedInstanceState super
  • 如何在android线性布局上获得阴影? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在android中为View设置阴影 https stackoverflow com questions 4406524 how to set shadow to a view in androi
  • 放置在 NavigationDrawer 顶部的片段

    我正在尝试添加一个PreferenceFragment在我的应用程序中 问题是 它自动放置在我的顶部NavigationDrawer public class SetPreferenceActivity extends Activity O
  • Android Studio:未找到 Gradle DSL 方法:“classpath()”

    首先 我已阅读所有其他解决方案帖子以及有关迁移到 1 0 的官方文档 到目前为止 还没有任何效果 Error Error 23 0 Gradle DSL method not found classpath Possible causes
  • 如何在TableLayout中创建三列

    我正在开发一个使用的屏幕TableLayout 在这里我可以轻松创建两列 但我怎样才能创建三列呢 这里有一个例子
  • 使用 PhoneGap 使 Android 应用程序易于访问(对于残障人士)

    有人有过使用 PhoneGap 使 Android 应用程序可访问的经验吗 至少我们需要使我们的应用程序符合第 508 条规定 我尝试实现一些标准的辅助功能 文本框标签 向 div 添加标题属性等 但是 当在 Android 中使用 Tal
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A
  • 如何在 Viewpager 中禁用预加载下一页? [复制]

    这个问题在这里已经有答案了 如何在 Viewpager 中禁用页面预加载 I tried viewPager setOffscreenPageLimit 0 但它不起作用 用这个viewPager setOffscreenPageLimit
  • 哪些 Flutter 插件或功能可以利用外部 iOS/Android 显示器来显示与主显示器不同的内容

    我正在构建一个跨平台应用程序 需要在外部显示器上显示不同的视图 通常通过连接到 LCD 投影仪的 HDMI 适配器电缆连接 Flutter 是否能够在内置的外部显示器上显示不同的屏幕 在现有的 Flutter 插件中还是使用现有的 Flut
  • 按钮 - 单击时更改背景颜色

    我的活动中有 8 个按钮 我正在寻找的是 按钮具有默认背景 单击按钮时 背景颜色应更改为其他颜色 这部分非常简单 但是 当我单击任何其他按钮时 第一个按钮的背景颜色应该变回默认颜色 我知道这将使用 选择器状态 来完成 但我不太确定如何实现它
  • Android:RecyclerView 不显示片段中的列表项

    有人可以帮我尝试让我的 RecyclerView 出现吗 如果我不在片段中实现它 就会出现这种情况 然而 当我尝试将其实现到片段中时 CarFront 中的其他 XML 代码与 RecyclerView 分开显示 我的日志中收到此错误 E
  • 错误:无法创建新会话,因为找不到需要 HttpClient、InputStream 和 long 的“createSession”

    我正在尝试自动化 Android 混合应用程序 但出现以下错误 1 线程 main org openqa selenium WebDriverException中出现异常 无法创建新会话 因为未找到需要 HttpClient InputSt
  • Android 中循环事件的星期几和时间选择器

    我想创建一个控件 允许用户在我的 Android 活动中选择一周中的某一天 星期一 和一天中的某个时间 下午 1 00 找不到任何关于此的好帖子 好吧 我想我已经明白了 我只是不喜欢这个解决方案 因为我在一周中的某一天使用的微调器与时间选择

随机推荐

  • MySQL 日期相减得到秒、分、天

    文章目录 一 MySQL中两个DateTime字段相减 二 MySQL中两个Time字段相减 一 MySQL中两个DateTime字段相减 这种方式两字段跨天 月 年都无问题 得到两个日期字段之间的秒数 selec t UNIX TIMES
  • 医学影像组学之病理切片分割(免费训练数据,标注数据,免费代码,免费教程)三天走完影像组学全部流程

    谁规定说影像组学只能从写代码 学语言耗费半年时间才能开始实验 三天让你走完影像组学完整流程 训练数据已经集成好 标注数据也已备好 代码也备好了 训练过程是这样的 另外笔者整理了其他影像组学的教学小视频 有兴趣的可以在下面评论
  • 华为HCIE云计算之部署Fusion Access及云桌面发放实战

    华为HCIE云计算之部署Fusion Access及云桌面发放实战 一 在FC上安装FA01虚拟机 1 选择创建类型 2 创建虚拟机基本配置 3 创建数据存储 4 选择虚拟机配置 5 虚拟机创建完成 二 安装FA01系统 1 进入系统安装界
  • 以太坊入门学习资料

    区块链分类 区块链按照访问和管理权限分为公有链 联盟链和私有链 公有链 完全开放 所有节点均可加入 代表链 比特币Bitcoin 以太坊Ethereum 联盟链 有多个组织和机构共同管理 获得组织和机构许可的节点可以加入 代表链 超级账本H
  • uniapp弹窗实现

  • java comparable与_详解Java中Comparable和Comparator接口的区别

    详解Java中Comparable和Comparator接口的区别 本文要来详细分析一下Java中Comparable和Comparator接口的区别 两者都有比较的功能 那么究竟有什么区别呢 感兴趣的Java开发者继续看下去吧 Compa
  • string.h的strcmp的性能比较

    string h基于汇编实现strcmp 和普通strcmp 针对循环调用次数和字符串查找长度2个纬度做了一次性能对比效测试 include
  • Windows 安装 nvm

    最近安装了最新版的node js之后 发现一个问题 版本太高 有些vue项目运行不起来了 于是找解决办法 发现安装 nvm 可以解决这个问题 nvm全名node js version management 是一个nodejs的版本管理工具
  • 哈夫曼树的应用

    温馨提示 这篇文章是基于哈夫曼树的构建之上 来说说哈夫曼树的应用 强烈建议在学习http 124 222 190 191 8090 archives E5 93 88 E5 A4 AB E6 9B BC E6 A0 91 E7 9A 84
  • 滤波电容计算举例

    例 输入电压220VAC 功率4W 要求输出电压波动不超过5 试计算滤波电容容量 解 1 电容的储能公式为 Wc 1 2CU 2 当电容充电到峰值电压 即220x1 414 310V 时 电容储存能量最大为 Wc max 1 2CU 2 0
  • 点估计(矩估计法和最大似然估计法)

    估计即是近似地求某个参数的值 需要区别理解样本 总体 量 值 大致的题型是已知某分布 其实包含未知参数 从中取样本并给出样本值 我只是一个初学者 可能有的步骤比较繁琐 请见谅 1 矩估计法 做题步骤 1 E x 求总体均值 一般含有未知参数
  • 为什么需要自动化测试?软件测试师带你测评不同软件测试工具

    软件从桌面转移到了我们接触到的几乎所有东西 从智能恒温器到输液泵再到汽车 软件无孔不入 而且在不断增长 来自物联网 IoT 的所谓 东西 越来越多地携带更多的逻辑 随之而来的是更大的故障风险 这些设备中的许多被用于安全关键领域 如医疗和汽车
  • 在Windows上使用gcc编译器

    在Windows上使用gcc编译器 第一步 安装QT 第二步 找到qt文件夹下的bin目录 如下所示 第三步 将该目录配置到环境变量中 第四步 打开cmd 输入gcc v 出现下面的图片证明gcc配置成功 第五步 编写一个 c文件进行测试
  • web前端技术笔记(十三)jQuery动画、jquery事件

    jQuery jquery动画 滑动选项卡案例 尺寸相关 滚动事件 加入购物车案例 菜单吸顶案例 jquery属性操作 jquery循环 手风琴格局案例 jquery事件 绑定事件的其他方式 取消绑定事件 事件冒泡 什么是事件冒泡 事件冒泡
  • 使用poi-ooxml-full.jar包过程中出现的版本问题

    先看报错信息 Exception in thread main org apache poi ooxml POIXMLException org apache logging log4j Logger atTrace Lorg apache
  • 数字政府2.0时代来临!阿里胜算几何?

    科技行业有一个共识 第三方数据机构的报告 C端看QuestMobile B端看IDC 在云计算市场 IDC的报告就是一种权威 日前 IDC发布的 中国数字政府大数据市场份额2018 报告显示 随着数字政府建设不断推进 2018年中国数字政府
  • Java : 方法 PrintStream.println(Object)不适用 (实际参数列表和形式参数列表长度不同)

    报错原因 之前一直使用python 用 习惯了 在Java中 应该作为String类型才能被识别 不能直接使用 连接两个变量 贴报错代码和修改之后的代码 public class Operator public static void ma
  • WIN10登陆时出现“被引用的帐户当前被锁定且可能无法登录”,如何解决?

    解决方法 一旦遇到 被引用的帐户当前被锁定且可能无法登录 错误 建议离开PC 30分钟 这是一个等待时间 通常由系统管理员设置 如果用户输入了错误的密码 等待30分钟后 登录屏幕可能会解锁 您可能有第二次机会访问桌面 如果您已成功访问桌面
  • 文献按时间排序_论文参考文献详解~

    论文参考文献标注方法一般是顺序编码制 顺序编码制 Numerical References Method 是一种文后参考文献的标注体系 即引文采用序号标注 参考文献按引文的序号排序 在论文中的引用处以右上标 小四宋体 加方括号的方式表示 不
  • Android Bluetooth AVRCP

    本篇blog继续以结合日志的形式来分析AVRCP 以手机连接上耳机后 通过耳机控制音乐播放的暂停 播放来分析AVRCP的过程 1 AVRCP 本章基于A V Remote Control Profile 1 6 2 Bluetooth Te