Android Marshmallow (v6, API level 23) features a more advanced MIDI API. Phil Burk has written a suite of example apps. Two of them, MidiScope and MidiSynth, are “official Google examples”. Martini Moe also made use of the new API and wrote a basic remote control für digital audio workstations.
I played a bit with the tools and code provided, since the new API also adds Bluetooth low energy as a supported MIDI transport medium. This could save me some cables plus the Raspberry Pi I currently use to control one of my instruments. My current verdict reads like “It’s great, though not straightforward yet”.
In order to send or receive MIDI with a handset or tablet, an OTG adapter is required. I tried to connect three simple USB to MIDI interface cables to the phone, but only one worked. At the target device, the commands arrived corrupted. I assume it has to do with the current the phone is capable to offer – a handset usually provides much less than the usual 500mA.
The Quicco Sound mi.1 is a phatastic device. It just gets plugged into the MIDI ports of any instrument, operates bus powered and translates the signal to Bluetooth LE. It worked absolutely reliably during my first tests.
The software part is much more tricky. An application that wants to access bluetooth MIDI devices must gain location permissions. From the docs:
This LOCATION permission is required because it may be possible to guess the location of an Android device by seeing which BTLE devices are nearby.
The application must then scan for available devices and offer a selection to the user. One more quote:
Once the MIDI/BTLE device has been opened by one app then it will also become available to other apps […]
Exit the app by pressing the Home button, not the Back button.
Exclusive device access
In the abovementioned docs, it is recommended to exit any MIDI application by pressing the Back button. Otherwise the MIDI device is still occupied by the application (at least in case it was written as intended) and not available to other devices:
Exit the application by pressing the Back button.
Actually I tested a couple of applications which did not release the device properly. Add to that the occasional loss of bluetooth connectivity every now and then, it isn’t suprising that the user experience is not that straightforward (First run MidiBtlePairing to make the device accessible, then run an app, then run another app and notice the bluetooth device isn’t availble, retry, reboot, etc.).
According to MidiDeviceMonitor.java, Android 6 features a nasty bug which will be fixed in Android 7:
The MidiManager.unregisterDeviceCallback() method was not working. So if an app was rotated, and the Activity destroyed and recreated, the DeviceCallbacks would accumulate in the MidiServer. This would result in multiple callbacks whenever a device was added. This class allow an app to register and unregister multiple times using a local list of callbacks. It registers a single callback, which stays registered until the app is dead.
MIDI over Bluetooth LE works in Android 6 and IMO is a really great feature. Users should be willing to figure out how to use the tools, though. For my today’s tests, I had to run the MidiBtlePairing tool, the MIDI application and the task manager several times before I got a usable connection. It then worked reliably, thought.