You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android系统创建可被其他应用识别的虚拟MIDI设备?

Android 虚拟MIDI设备实现方案(Kotlin)

1. 配置权限与Manifest声明

首先在AndroidManifest.xml中添加必要权限和服务声明:

<uses-permission android:name="android.permission.MIDI" />

<application ...>
    <service
        android:name=".MidiVirtualDeviceService"
        android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
        <intent-filter>
            <action android:name="android.media.midi.MidiDeviceService" />
        </intent-filter>
        <!-- 配置虚拟MIDI设备的元数据 -->
        <meta-data
            android:name="android.media.midi.MidiDeviceService"
            android:resource="@xml/midi_device_info" />
    </service>
</application>

在res/xml目录下创建midi_device_info.xml,定义虚拟设备的基本信息:

<?xml version="1.0" encoding="utf-8"?>
<midi-device-info xmlns:android="http://schemas.android.com/apk/res/android">
    <manufacturer android:value="Custom Manufacturer" />
    <product android:value="Virtual MIDI Hub" />
    <input-port count="1" /> <!-- 配置1个输入端口 -->
    <output-port count="1" /> <!-- 配置1个输出端口 -->
</midi-device-info>

2. 核心服务实现(Kotlin)

创建MidiVirtualDeviceService类,继承MidiDeviceService,负责处理MIDI消息的接收与跨应用转发:

import android.media.midi.MidiDeviceService
import android.media.midi.MidiInputPortReceiver
import android.media.midi.MidiSender
import java.io.IOException

class MidiVirtualDeviceService : MidiDeviceService() {
    // 保存所有连接的输出端口发送器,用于转发MIDI消息
    private val connectedSenders = mutableListOf<MidiSender>()

    override fun onGetInputPortReceivers(): Array<MidiInputPortReceiver> {
        return arrayOf(object : MidiInputPortReceiver() {
            override fun onSend(data: ByteArray, offset: Int, count: Int, timestamp: Long) {
                // 将收到的MIDI消息转发给所有连接的应用
                connectedSenders.forEach { sender ->
                    try {
                        sender.send(data, offset, count, timestamp)
                    } catch (e: IOException) {
                        // 移除失效的连接
                        connectedSenders.remove(sender)
                    }
                }
            }
        })
    }

    override fun onGetOutputPortSenders(): Array<MidiSender> {
        return arrayOf(object : MidiSender() {
            override fun onConnect(sender: MidiSender) {
                connectedSenders.add(sender)
            }

            override fun onDisconnect(sender: MidiSender) {
                connectedSenders.remove(sender)
            }
        })
    }

    override fun onDestroy() {
        connectedSenders.clear()
        super.onDestroy()
    }
}

3. 设备启动与识别

系统会自动扫描并注册该MIDI设备服务,无需手动启动。当其他MIDI应用扫描设备列表时,你的虚拟设备会被识别并列出。

若需主动触发服务启动,可在Activity中添加:

startService(Intent(this, MidiVirtualDeviceService::class.java))

4. 测试验证

  • 使用系统内置的MIDI测试工具或第三方MIDI应用(如MIDI Monitor)扫描设备,确认虚拟设备是否被识别。
  • 在A应用中向虚拟设备的输入端口发送MIDI消息,在B应用中监听虚拟设备的输出端口,验证消息跨应用转发是否正常。

注意事项

  • 最低支持API级别为23(Android 6.0),需将项目minSdkVersion设置为23及以上。
  • 部分定制化Android系统可能对MIDI设备扫描有特殊限制,建议在原生Android设备上测试。

内容的提问来源于stack exchange,提问作者Javier Pérez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:20:15