Android 6+标准MIDI API:如何按发送方过滤MIDI消息?
按发送方过滤Android MIDI消息的可行方案
好问题!在Android 6+的标准MIDI API里,要按发送设备过滤消息确实有点绕——毕竟官方API没直接暴露端口的连接状态细节。我整理了几个实用的方案,你可以根据自己的场景选择:
1. 追踪输入端口与设备的映射关系
这是最可靠的方案,核心思路是把每个MidiInputPort和它所属的MidiDeviceInfo绑定起来:
- 维护一个全局的映射表,比如
Map<Integer, MidiDeviceInfo> portDeviceMap,键是输入端口的ID,值是对应的发送设备信息。 - 当你通过
MidiManager.openInputPort(portId)获取输入端口时,先通过MidiManager.getDeviceInfo()拿到该端口所属的MidiDeviceInfo,把portId和设备信息存入映射表。 - 自定义你的
MidiReceiver实现,确保每个接收器和对应的输入端口关联(比如在创建Receiver时传入端口ID)。这样在onSend()方法被调用时,你可以通过端口ID去映射表里找到发送消息的设备,轻松判断是否是新设备的消息。 - 别忘了在关闭输入端口时,从映射表里移除对应的条目,避免内存泄漏或者错误的设备关联。
2. 解析SysEx消息中的设备标识
如果你的目标MIDI设备支持发送系统专有(SysEx)消息,这是个精准区分发送方的方法:
- SysEx消息以状态字节
0xF0开头,很多设备会在这类消息里嵌入厂商ID、设备唯一标识等信息。 - 在
MidiReceiver#onSend()中,先判断消息是否为SysEx类型,然后解析消息内容中的设备标识字段,以此作为区分不同发送方的依据。 - 注意:这个方案依赖设备厂商的实现,不是所有MIDI设备都会发送带标识的SysEx消息,所以适用性有限。
3. 结合设备监听与消息时序关联
如果前两个方案都不适用,你可以试试这个“曲线救国”的方法:
- 注册
MidiManager.DeviceCallback,监听onDeviceAdded()和onDeviceRemoved()事件,维护一个当前已连接的设备列表。 - 当收到第一条MIDI消息时,结合最近新增的设备(比如刚触发
onDeviceAdded()的设备),将消息与该设备关联起来。后续再收到消息时,就可以用这个关联来过滤。 - 缺点:这个方法有一定的不确定性,如果多个设备同时连接,可能会出现关联错误,适合对准确性要求不是特别高的场景。
内容的提问来源于stack exchange,提问作者Alejandro H. Cruz
相关产品推荐
相关产品推荐

