Android OpenAccessory (AOA) is a protocol developed by Google (introduced on May 2011), which enables a hack-free connection of peripherals to Android devices. The protocol is supported in Android 2.3.4 and higher, and on a limited number of devices. Android 4.x devices generally support AOA.
Naturally, it makes sense for IOIO to communicate with the Android device using this protocol whenever it is available, avoiding the need for running the Android device with USB debugging enabled. In addition, the OpenAccessory connection also has some performance gains over ADB.
The OpenAccessory-enabled firmware and software support OpenAccessory in addition to ADB. Both will know how to "do the right thing" and use ADB whenever appropriate.
Both ADB and OpenAccessory are based on a USB connection. The IOIO firmware is built in such a way that if an Android device is connected, on which ADB is enabled, ADB will be used. If OpenAccessory is supported, OpenAccessory will be used. If both are available, ADB wins, and the Android-IOIO communication will use ADB. So you should be aware that in order to use OpenAccessory you should switch USB debugging off.
As you'll see below, your Android application also needs to be built in a certain way in order to be able to use OpenAccessory. Luckily, changing an existing IOIO application to use OpenAccessory a technical and very simple process.
Another important aspect is that your application has to be based on
IOIOAndroidApplicationHelper for this to work. These classes take care of all the gory details (and believe me, they are gory) of communicating with an Android accessory.
Using OpenAccessory gives some nice improvements in comparison to ADB:
Simply use the software / firmware with versions 3.21 or greater, from the Downloads page. You may use the IOIO Manager Application to upgrade the firmware. Note that this firmware requires a V3.x bootloader, so very old IOIO's that haven't had their bootloader upgraded may need a bootloader upgrade in order to install this firmware.
Notice that the examples shipped with the software bundle have OpenAccessory support, so you can use them as reference or just modify them to your needs.
In the software zip file, you'll find the IOIOLibAccessory library.
Some changes are required to the AndroidManifest.xml file of your application in order to utilize OpenAccessory. This file is found under the root directory of your project. Double-click it to edit inside Eclipse, using a specialized editor.
com.android.future.usb.accessoryin the "name" box on the right, and
falsein the "required" box (to enable graceful degradation). This tells Android that your application would like to use the OpenAccessory system library, if it's available.
android.hardware.usb.action.USB_ACCESSORY_ATTACHEDin the "name" box on the right. This tells Android that your application would like to register itself as one that can work with an accessory.
singleTask. This will make sure that no two instances of your application will be running at the same time (which would cause lots of problems with regards to communicating with the IOIO).
android.hardware.usb.action.USB_ACCESSORY_ATTACHEDand Resource to
@xml/accessory_filter. This tells Android that your application works with a specific kind of accessories, as described in an XML resource file.
resdirectory of your project, create a directory called
xml. Create a file called
accessory_filter.xmlin this directory. Edit it to include the contents below.
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-accessory model="IOIO" /> </resources>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:a="http://schemas.android.com/apk/res/android" package="ioio.examples.hello" a:versionCode="1" a:versionName="1.0"> <uses-sdk a:minSdkVersion="7" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <application a:icon="@drawable/icon" a:label="@string/app_name"> <uses-library a:name="com.android.future.usb.accessory" a:required="false" /> <activity a:name="MainActivity" a:label="@string/app_name" a:launchMode="singleTask"> <intent-filter> <action a:name="android.intent.action.MAIN" /> <category a:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action a:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> </intent-filter> <meta-data a:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" a:resource="@xml/accessory_filter" /> </activity> </application> </manifest>
Ideally, you'd want a single .apk file that would be compatible with any Android version, possibly taking advantage of later features, if they exist. The IOIO libraries are all built with that property in mind. Unfortunately, the Android libraries aren't...
If you look above, you'll see that we declared that our application would like to use the com.android.future.usb.accessory library. It also mentions that it doesn't require it. So far so good. But the
required attribute itself was only added in API-7 (Android 2.1). So earlier versions of Android won't let your application run as result of the library not being available, and thus there is no known way of having a single .apk that will work both with OpenAccessory AND with API < 7. If anyone knows of a workaround, please report it. Converting your application to work on API < 7 (without OpenAccessory, of course), is a simple matter of removing the
<uses-library> element, changing
minSdkVersion to 3 and rebuilding.