Files
Android-pyApi/android_pyapi/android/media_midi.py
T
shuiyu1123 506f9ac725 feat: 新增 42 个 Android API 模块
新增模块覆盖:
系统层 (14): system, security, print, opengl, renderscript, transition,
test, service_notification, service_controls, service_quicksettings,
service_wallpaper, service_autofill, service_dreams, service_vr

应用层 (13): app_admin, app_backup, app_job, app_usage, app_role,
app_people, appwidget, companion, credentials, mtp, sip, telecom, speech

硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb,
hardware_input, media_audiofx, media_browse, media_session, media_tv,
media_midi, media_projection, uwb, se, view_autofill, view_textclassifier,
view_translation

总计 94 个模块,75,342 行代码
2026-06-24 12:00:28 +00:00

315 lines
11 KiB
Python

"""
Android media.midi 组件 — MidiManager, MidiDevice, MidiReceiver, MidiSender 等
方法签名完全对齐 Android SDK
"""
from typing import Any, Callable, Dict, List, Optional, Set
from .._core import Stub, AndroidOnlyError
# ═══════════════════════════════════════════════════════════════
# MidiManager
# ═══════════════════════════════════════════════════════════════
class MidiManager(Stub):
"""MidiManager — MIDI 管理器"""
def __init__(self):
super().__init__()
self._devices: Dict[int, MidiDevice] = {}
self._callbacks: Dict[int, Callable] = {}
self._next_device_id = 1
self._init_default_devices()
def _init_default_devices(self):
info = MidiDeviceInfo(
id=0, inputPortCount=1, outputPortCount=1,
type=MidiDeviceInfo.TYPE_VIRTUAL,
properties={MidiDeviceInfo.PROPERTY_NAME: "Virtual MIDI"}
)
device = MidiDevice(info)
self._devices[0] = device
def getDevices(self) -> List["MidiDeviceInfo"]:
return [d.getInfo() for d in self._devices.values()]
def registerDeviceCallback(self, callback: Callable, handler: Any = None):
cid = id(callback)
self._callbacks[cid] = callback
def unregisterDeviceCallback(self, callback: Callable):
cid = id(callback)
self._callbacks.pop(cid, None)
def openDevice(self, deviceInfo: "MidiDeviceInfo",
callback: Callable, handler: Any = None):
device = self._devices.get(deviceInfo.getId())
if device:
callback(device)
def openBluetoothDevice(self, bluetoothDevice: Any) -> Optional["MidiDevice"]:
return None
def getDefaultDevice(self) -> Optional["MidiDevice"]:
for d in self._devices.values():
return d
return None
def deviceConnected(self, info: "MidiDeviceInfo"):
pass
def deviceDisconnected(self, info: "MidiDeviceInfo"):
pass
# ═══════════════════════════════════════════════════════════════
# MidiDevice
# ═══════════════════════════════════════════════════════════════
class MidiDevice(Stub):
"""MidiDevice — MIDI 设备"""
# ═══════════════════════════════════════════════════════════
# MidiConnection
# ═══════════════════════════════════════════════════════════
class MidiConnection(Stub):
"""MidiDevice.MidiConnection — MIDI 连接"""
def __init__(self):
super().__init__()
def close(self):
pass
def toString(self) -> str:
return "MidiConnection"
def __init__(self, info: "MidiDeviceInfo" = None):
super().__init__()
self._info = info or MidiDeviceInfo()
self._input_ports: List[MidiInputPort] = []
self._output_ports: List[MidiOutputPort] = []
self._closed = False
def getInfo(self) -> "MidiDeviceInfo":
return self._info
def openInputPort(self, portNumber: int) -> Optional["MidiInputPort"]:
if self._closed:
return None
port = MidiInputPort(portNumber)
self._input_ports.append(port)
return port
def openOutputPort(self, portNumber: int) -> Optional["MidiOutputPort"]:
if self._closed:
return None
port = MidiOutputPort(portNumber)
self._output_ports.append(port)
return port
def close(self):
self._closed = True
def toString(self) -> str:
return f"MidiDevice(info={self._info})"
# ═══════════════════════════════════════════════════════════════
# MidiDeviceInfo
# ═══════════════════════════════════════════════════════════════
class MidiDeviceInfo(Stub):
"""MidiDeviceInfo — MIDI 设备信息"""
TYPE_USB = 1
TYPE_BLUETOOTH = 2
TYPE_VIRTUAL = 3
PROPERTY_ALSA_CARD = "alsa_card"
PROPERTY_ALSA_DEVICE = "alsa_device"
PROPERTY_MANUFACTURER = "manufacturer"
PROPERTY_NAME = "name"
PROPERTY_PRODUCT = "product"
PROPERTY_SERIAL_NUMBER = "serial_number"
PROPERTY_USB_DEVICE = "usb_device"
def __init__(self, id: int = 0, inputPortCount: int = 0,
outputPortCount: int = 0, type_: int = TYPE_VIRTUAL,
properties: Optional[Dict[str, str]] = None):
super().__init__()
self._id = id
self._input_port_count = inputPortCount
self._output_port_count = outputPortCount
self._type = type_
self._properties = properties or {}
def getId(self) -> int:
return self._id
def getProperties(self) -> Dict[str, str]:
return dict(self._properties)
def getInputPortCount(self) -> int:
return self._input_port_count
def getOutputPortCount(self) -> int:
return self._output_port_count
def getType(self) -> int:
return self._type
def equals(self, other: Any) -> bool:
if not isinstance(other, MidiDeviceInfo):
return False
return self._id == other._id
def hashCode(self) -> int:
return hash(self._id) & 0x7FFFFFFF
def toString(self) -> str:
return f"MidiDeviceInfo(id={self._id}, type={self._type}," \
f" name={self._properties.get(MidiDeviceInfo.PROPERTY_NAME, '')})"
# ═══════════════════════════════════════════════════════════════
# MidiReceiver
# ═══════════════════════════════════════════════════════════════
class MidiReceiver(Stub):
"""MidiReceiver — MIDI 接收器"""
def __init__(self, maxMessageSize: int = 1024):
super().__init__()
self._max_message_size = maxMessageSize
def send(self, msg: bytes, offset: int, count: int):
self.onSend(msg, offset, count)
def onSend(self, msg: bytes, offset: int, count: int):
pass
def flush(self):
pass
def getMaxMessageSize(self) -> int:
return self._max_message_size
# ═══════════════════════════════════════════════════════════════
# MidiSender
# ═══════════════════════════════════════════════════════════════
class MidiSender(Stub):
"""MidiSender — MIDI 发送器"""
def __init__(self):
super().__init__()
self._receivers: List[MidiReceiver] = []
def send(self, msg: bytes, offset: int, count: int):
for r in self._receivers:
r.send(msg, offset, count)
def onConnect(self, receiver: MidiReceiver):
pass
def onDisconnect(self, receiver: MidiReceiver):
pass
def connect(self, receiver: MidiReceiver):
self._receivers.append(receiver)
self.onConnect(receiver)
def disconnect(self, receiver: MidiReceiver):
if receiver in self._receivers:
self._receivers.remove(receiver)
self.onDisconnect(receiver)
# ═══════════════════════════════════════════════════════════════
# MidiInputPort
# ═══════════════════════════════════════════════════════════════
class MidiInputPort(MidiReceiver):
"""MidiInputPort — MIDI 输入端口"""
def __init__(self, portNumber: int = 0):
super().__init__()
self._port_number = portNumber
self._closed = False
def send(self, msg: bytes, offset: int, count: int):
if not self._closed:
self.onSend(msg, offset, count)
def onSend(self, msg: bytes, offset: int, count: int):
pass
def flush(self):
pass
def close(self):
self._closed = True
# ═══════════════════════════════════════════════════════════════
# MidiOutputPort
# ═══════════════════════════════════════════════════════════════
class MidiOutputPort(MidiSender):
"""MidiOutputPort — MIDI 输出端口"""
def __init__(self, portNumber: int = 0):
super().__init__()
self._port_number = portNumber
def send(self, msg: bytes, offset: int, count: int):
super().send(msg, offset, count)
def onSend(self, msg: bytes, offset: int, count: int):
pass
def getPortNumber(self) -> int:
return self._port_number
# ═══════════════════════════════════════════════════════════════
# MidiEndpoint (stub)
# ═══════════════════════════════════════════════════════════════
class MidiEndpoint(Stub):
"""MidiEndpoint — MIDI 端点"""
def __init__(self):
super().__init__()
# ═══════════════════════════════════════════════════════════════
# MidiDeviceService
# ═══════════════════════════════════════════════════════════════
class MidiDeviceService(Stub):
"""MidiDeviceService — MIDI 设备服务"""
def __init__(self):
super().__init__()
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"MidiManager",
"MidiDevice",
"MidiDeviceInfo",
"MidiReceiver",
"MidiSender",
"MidiInputPort",
"MidiOutputPort",
"MidiEndpoint",
"MidiDeviceService",
]