Неопределенный USB-аксессуар с Arduino Due подключен к Android MiniPad (MPgio)
У меня проблемы с работой над аксессуаром для Android с Arduino Due, который загружен Blink.ino (и другие примеры тоже). Проблема в том, что я не смог обнаружить какой-либо USB-аксессуар (или список) из UsbManager
получил от getSystemService("USB_SERVICE")
в любом случае с прикреплением или отсоединением.
Мой код ниже.
1. манифест
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.signalhello"
android:versionCode="1"
android:versionName="1.0" >
<!-- <uses-feature android:name="android.hardware.usb.accessory" />
<uses-feature android:name="android.hardware.usb.host" /> -->
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.signalhello.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
<action android:name="android.hardware.usb.action.USB_ACCESSORY_DETACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
</application>
</manifest>
2. accessory-filter.xml в res / xml /
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-accessory manufacturer="Arduino-er"/> // I tried other options like <usb- accessory vendor-id="9025" product-id="62"/>
<usb-device vendor-id="9025" product-id="62"/>
<usb-accessory vendor-id="2341" product-id="003e"/>
<usb-device vendor-id="2341" product-id="003e"/>
</resources>
3. MainActivity
package com.example.signalhello;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class MainActivity extends Activity {
private static final String ACTION_USB_PERMISSION =
"net.hardroid.adk.example.action.USB_PERMISSION";
private PendingIntent mPermissionIntent;
private boolean mPermissionRequestPending;
// USB가 감지되었을 때의 이벤트를 받음.
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("onReceive", "action: " + action);
tv01.setText("action: " + action);
if (ACTION_USB_PERMISSION.equals(action)) {
// 사용자에게 Android Accessory Protocol을 구현한 장비가 연결되면
// 수락할 것인지 문의한 다이얼로그에 대한 사용자의 선택 결과를 받는다.
synchronized (this) {
Log.d("onReceive", "Getting UsbAccessory...");
UsbAccessory accessory = intent
.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Log.d("onReceive", "Accessory is null ? " + (accessory == null) + ", Device is null ? " + (usbDevice == null));
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
Log.d("onReceive", "Connected USB ...");
// 수락했을 경우
showMessage("receiver : USB Host 연결됨.");
}
else {
Log.d("onReceive", "Permission denied....");
Log.d(MainActivity.class.getName(),
"permission denied for accessory " + accessory);
showMessage("permission denied.");
}
openAccessory(accessory);
UsbManager manager = null;
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager
.getDeviceList();
Iterator<UsbDevice> deviceIter = deviceList.values()
.iterator();
while (deviceIter.hasNext()) {
UsbDevice device = deviceIter.next();
// Device's class...
int count = device.getInterfaceCount();
tv01.setText("count:" + count);
for (int i = 0; i < count; i++) {
UsbInterface iface = device.getInterface(i);
tv02.setText(tv02.getText() + "," + iface.getId());
}
}
// 연결 수락 결과를 받았음을 표시
mPermissionRequestPending = false;
tv04.setText("3");
}
}
else
if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
// Android Accessory Protocol을 구현한 장비의 연결이 해제되었을 때
UsbAccessory accessory = intent
.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
// 앱이 사용하고 있는 장비와 같은 것인지 확인
if (accessory != null && accessory.equals(mAccessory)) {
showMessage("USB Host 연결 해제됨.");
closeAccessory();
}
tv04.setText("4");
}
tv04.setText("5");
}
};
private TextView tv01;
private TextView tv02;
private TextView tv03;
private TextView tv04;
/*static class IncomingHandler extends Handler {
private final WeakReference<UDPListenerService> mService;
IncomingHandler(UDPListenerService service) {
mService = new WeakReference<UDPListenerService>(service);
}
@Override
public void handleMessage(Message msg)
{
UDPListenerService service = mService.get();
if (service != null) {
service.handleMessage(msg);
}
}
}*/
/*Handler mIncomingHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
}
});*/
static Handler uiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.d("handleMessage", "msg.what: " + msg.what + ", msg.obj: " + msg.obj);
switch (msg.what) {
case 1:
}
}
};
private UsbAccessory mAccessory;
private AdkHandler handler;
private static UsbManager mUsbManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv01 = (TextView) findViewById(R.id.tv01);
tv02 = (TextView) findViewById(R.id.tv02);
tv03 = (TextView) findViewById(R.id.tv03);
tv04 = (TextView) findViewById(R.id.tv04);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
Log.d("onCreate", "Permission intent getting...");
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
Log.d("onCreate", "registering Receiver..");
Log.d("onCreate", "receiver is null ? " + (mUsbReceiver == null));
registerReceiver(mUsbReceiver, filter);
Log.d("onCreate", "registered Receiver..");
Log.d("onCreate", "Got permission intent...");
tv04.setText("1");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/** 액티비티가 화면에 보일 때 호출 */
@Override
public void onResume() {
super.onResume();
Log.d("onResume", "Getting device list");
// 앱이 화면에 보일 때 안드로이드 장비에 Android Accessory Protocol을
// 구현한 USB Host가 연결되어 있는지 확인
HashMap<String, UsbDevice> devices = mUsbManager.getDeviceList();
Log.d("onResume", "Getting UsbAccessory");
UsbAccessory accessory = getIntent().getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null) { // Android Accessory Protocol를 구현한 장비를 찾았을 경우
Log.d("onResume", "Got accessory");
if (mUsbManager.hasPermission(accessory)) {
Log.d("onResume", "Got permission");
showMessage("onresume : USB Accessory 연결됨.");
openAccessory(accessory);
}
else {
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
mUsbManager.requestPermission(accessory,
mPermissionIntent); // USB 연결을 통해 장비에 연결해도 되는지 사용자에게 문의
mPermissionRequestPending = true; // 연결권한을 물어보드 코드를 실행했음을 표시
}
}
}
}
else {
String device = "";
if (devices != null) {
Set<String> keys = devices.keySet();
for (String key : keys) {
device += key + ": " + devices.get(key).getDeviceName();
}
}
showMessage("mAccessory is null, devices: " + (devices == null ? "null" : device));
Log.d(MainActivity.class.getName(), "mAccessory is null");
}
tv04.setText("2");
}
// 액티비티가 소멸될 때 호출
@Override
protected void onDestroy() {
// 브로드캐스트 리시버를 제거
unregisterReceiver(mUsbReceiver);
super.onDestroy();
}
private void showMessage(String msg){
Log.d("showMessage", msg);
tv03.setText("message: " + msg);
}
private void openAccessory(UsbAccessory accessory){
mAccessory = accessory;
if(handler == null){
Log.d("openAccessory", "Instanciating AdkHandler");
handler = new AdkHandler();
Log.d("openAccessory", "Setting UI Handler to AdkHandler");
handler.setUiHandler(uiHandler);
}
Log.d("openAccessory", "Openning AdkHandler");
handler.open(mUsbManager, mAccessory);
}
private void closeAccessory(){
if(handler != null && handler.isConnected())
handler.close();
mAccessory = null;
}
}
3-1.AdkHandler.java
package com.example.signalhello;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import android.annotation.TargetApi;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
/**
*
* @author Chun, Young-yil. at IBS Inc.
* @since ADK 4.0
* @date 2013. 5. 15.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class AdkHandler implements Runnable {
private ParcelFileDescriptor mFileDescriptor;
private FileInputStream mInputStream;
private FileOutputStream mOutputStream;
private Handler uiHandler;
private boolean running;
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
Log.d("run", "start");
int ret = 0;
byte[] buffer = new byte[16384];
int i;
while (ret >= 0 && running) {
try {
ret = mInputStream.read(buffer);
Log.d("run", "" + ret);
}
catch (Exception e) {
e.printStackTrace();
break;
}
i = 0;
Log.d("run", "i: " + i + ", ret: " + ret);
while ( i < ret && running) {
int len = ret - i;
Log.d("run", "buffer[" + i + "]: " + buffer[i]);
switch (buffer[i]) {
case 0x1:
if (len >= 3) {
Message m = Message.obtain(uiHandler, 1);
int value = composeInt(buffer[i = 1], buffer[i + 2]);
m.obj = value;
uiHandler.sendMessage(m);
Log.d("value", "" + value);
}
i += 3;
break;
default :
Log.d("default", "unknown msg:" + buffer[i]);
i = len;
break;
}
}
}
}
/**
* @param b
* @param c
* @return
*/
private int composeInt(byte high, byte low) {
int val = (int) high & 0xff;
val *= 256;
val += (int) low & 0xff;
return val;
}
public void open(UsbManager usbManager, UsbAccessory accessory) {
Log.d("open", "Getting FileDescriptor");
mFileDescriptor = usbManager.openAccessory(accessory);
if (mFileDescriptor == null) {
Log.d("open", "Failed to get ParcelFileDescriptor");
Log.d("보드연결", "실패");
Message msg = Message.obtain(uiHandler, -1);
msg.obj = "보드연결 실패";
Log.d("open", "Sending fail message to UI Handler...");
uiHandler.sendMessage(msg);
}
else
{
Log.d("open", "Succeeded in getting ParcelFileDescriptor");
Log.d("open", "Getting FileDescriptor from ParcelFileDescriptor");
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
Log.d("open", "Getting FileInputStream...");
mInputStream = new FileInputStream(fd);
Log.d("open", "New Threading..");
Thread thread = new Thread(null, this, "ADK Example");
running = true;
Log.d("open", "Starting thread...");
thread.start();
Log.d("보드연결", "성공");
}
}
public void close() {
Log.d("close", "Closing...");
running = false;
}
/**
* 멤버 uiHandler 을 회수
* @return the uiHandler
*/
public Handler getUiHandler() {
return uiHandler;
}
/**
* sets the uiHandler of this instance to given uiHandler.
* 멤버속성 uiHandler 을 인수 uiHandler 으로 세팅.
* @param uiHandler the uiHandler to set
*/
public void setUiHandler(Handler uiHandler) {
this.uiHandler = uiHandler;
}
/**
* @return
*/
public boolean isConnected() {
return (mInputStream != null && mOutputStream != null);
}
}
_4. acivity_main.xml_
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/ll01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<TextView
android:id="@+id/tv01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="장비미인식" />
<TextView
android:id="@+id/tv02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-1" />
<TextView
android:id="@+id/tv03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-1" />
<TextView
android:id="@+id/tv04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-1" />
</LinearLayout>
</RelativeLayout>
5. logcat (использование adbwireless в рутинной мини-панели MPgio)
- 05-31 12: 16: 12.728: I / wpa_supplicant (400): [CTRL_IFACE] SIGNAL_POLL
- 05-31 12: 16: 15.298: W / PowerUI (207): неизвестное намерение: намерение {act = android.intent.action.ACTION_POWER_CONNECTED flg = 0x10000010}
- 05-31 12: 16: 15.488: I / WindowManager (140): MediaPlayer. Не воспроизводится видео
- 05-31 12: 16: 15.728: I / wpa_supplicant (400): [CTRL_IFACE] SIGNAL_POLL
- 05-31 12: 16: 16.088: I / WindowManager (140): MediaPlayer. Не воспроизводится видео
- 05-31 12:16:17.218: I/USB3G(86): событие {'add', '/ devices / platform / sw_hcd_host0 / usb1 / 1-1', 'usb', '', 189, 15}
- 05-31 12:16:17.218: I/USB3G(86): путь: '/ sys / devices / platform / sw_hcd_host0 / usb1 / 1-1'
- 05-31 12:16:17.218: I/USB3G(86): VID: размер 5, vid_path '/ sys / devices / platform / sw_hcd_host0 / usb1 / 1-1 / idVendor', VID '2341
- 05-31 12:16:17.218: I/USB3G(86): '.
- 05-31 12:16:17.218: I/USB3G(86): PID: размер 5, Pid_path '/ sys / devices / platform / sw_hcd_host0 / usb1 / 1-1 / idProduct', PID '003e
- 05-31 12:16:17.218: I/USB3G(86): '.
- 05-31 12:16:17.218: I/USB3G(86): cmd = / system / etc / usb_modeswitch.sh /system/etc/usb_modeswitch.d/2341_003e &,
- 05-31 12:16:17.228: E / EventHub(140): не удалось получить версию драйвера для /dev/input/mouse0, не пишущая машинка
- 05-31 12:16:17.228: D/EventHub(140): Не найден файл конфигурации устройства ввода для устройства "Arduino LLC Arduino Due".
- 05-31 12: 16: 17.248: I / EventHub(140): новое устройство: id=15, fd=247, путь ='/dev/input/event4', name='Arduino LLC Arduino Due ', классы = 0x8000000b, configuration = '', keyLayout = '/ system / usr / keylayout / Generic.kl', keyCharacterMap = '/ system / usr / keychars / Generic.kcm', builtinKeyboard = false
- 05-31 12: 16: 17.298: I / USB3G (86): excute ret: 0, ошибка: нет такого файла или каталога
- 05-31 12:16:17.318: I/InputReader(140): добавлено устройство: id = 15, name = 'Arduino LLC Arduino Due', sources = 0x00002103
- 05-31 12: 16: 17.318: I / ActivityManager (140): Конфигурация изменена: {1.3 0mcc0mnc ko_KR layoutdir = 0 sw640dp w1066dp h592dp lrg land finger qwerty / v / v -nav / h s.33}
- 05-31 12: 16: 17.338: D / OpenGLRenderer (1631): очистка кешей (режим 0)
- 05-31 12: 16: 17.478: D / Activity (1631): pckname = com.example.signalhello mComponent = com.example.signalhello.MainActivity
- 05-31 12: 16: 17.538: I / StatusBar.HeightReceiver (207): изменена строка состояния изменения размера = ложная высота =36 старых =36
- 05-31 12: 16: 17.658: D / onCreate (1631): получение разрешения на получение...
- 05-31 12: 16: 17.658: D / onCreate (1631): регистрация получателя.
- 05-31 12:16:17.668: D/onCreate(1631): получатель нулевой? ложный
- 05-31 12:16:17.668: D/onCreate(1631): зарегистрированный получатель.
- 05-31 12:16:17.668: D/onCreate(1631): Получено разрешение...
- 05-31 12:16:17.698: D/onResume(1631): получение списка устройств
- 05-31 12:16:17.698: D/onResume(1631): получение UsbAccessory
- 05-31 12: 16: 17.698: D / showMessage (1631): mAccessory is null, устройства:
- 05-31 12: 16: 17.698: D / com.example.signalhello.MainActivity (1631): mAccessory is null
- 05-31 12: 16: 17.728: D / ViewRootImpl (1631): имя_пакета = com.example.signalhello
- 05-31 12: 16: 18.138: I / WindowManager (140): MediaPlayer. Не воспроизводится видео
- 05-31 12: 16: 18.738: I / wpa_supplicant (400): [CTRL_IFACE] SIGNAL_POLL
- 05-31 12: 16: 20.068: D / dalvikvm (140): GC_EXPLICIT освобожден 267K, 24% свободен 8736K/11399K, приостановлено 8мс +13мс
- 05-31 12:16:21.738: I/wpa_supplicant(400): [CTRL_IFACE]SIGNAL_POLL
Я очень запутался в моей ситуации с вышеперечисленными вещами.
Плата Arduino подключена к моему ноутбуку (порт программирования). (Я думаю, что это обеспечивает питание для платы, не так ли?) Поскольку источник питания необходим, другого источника питания у меня нет.
И я собрал Blink.ino
которую я скачал с сайта Arduino. (Я проверил другие эскизы. Но новостей нет.)
И плата работает мигает при загрузке с помощью инструмента написания кода Arduino. Но когда я подключил (подключил) плату через USB-кабель к устройству Android MPgio MiniPad, у меня не было никаких признаков обнаружения с моими кодами выше.
Просто system_process
выдает некоторые странные сообщения (которые включены над сообщениями logcat), такие как " 05-31 12:16:17.228: E / EventHub(140): не удалось получить версию драйвера для /dev/input/mouse0, не пишущая машинка" или "05 -31 12: 16: 17.228: D / EventHub(140): Не найден файл конфигурации устройства ввода для устройства "Arduino LLC Arduino Due ".
Но, чуть ниже, он печатает "Новое устройство: идентификатор......" из тега EventHub system_process.
Я хочу просто обнаружить мою плату Arduino.
3 ответа
Я пытался решить эту проблему на многих сайтах, в блогах и т. Д. И, наконец, у меня возникли сомнения по поводу того, что аппаратное обеспечение - MPgio - поддерживает этот вид приложений. Поскольку я нашел, что некоторые блоги говорят, что все виды устройств на Android обязательно не поддерживают это. Поэтому я позвонил в центр поддержки клиентов MPgio, чтобы я мог связаться с техническим руководителем или консультантом, который мог бы ответить, поддерживает ли устройство приложение ADK - USB Accessory, Host.
Поговорив с другим мужчиной, мне сказали позвонить позже другой человек, у которого есть ответ на этот вопрос. И мне позвонили, когда я возвращался домой. И он задал несколько вопросов о моих просьбах, но не смог ответить правильно, вместо этого он пообещал снова позвонить мне с ответом на этот вопрос. И наконец! Мне позвонили, кто дал обещание, и он сказал, что устройство не поддерживает это. И это была проблема с ядром.
И добавил, что у них есть дела для установки драйвера -FTDI? Я слышал - для распространения которых отвечает конкретным требованиям клиентов (с оплатой, я слышал).
... И меня слышат, что, если мне нужно, я должен заплатить или арендовать - "арендовать", я могу возобновить то, что он сказал, - на это ответили, что я не тот человек, который мог бы ответить на этот вопрос вовремя...
Это все.
Но мне, возможно, придется добавить некоторые для других разработчиков, у которых могут быть проблемы, подобные этой.
Прежде всего, Blink.ino - это не тот хороший случай, в котором нет кода объявления экземпляра ADK, который может быть протоколом, который может взаимодействовать с другим поддерживающим устройством. На самом деле, я проверил другие коды, которые имеют такое объявление. Но все равно успех не удался - в моем случае устройство не поддерживается.
И я должен вкратце написать, что arduino 1.5.2 использует библиотеку ADK, которая заменила библиотеку AndroidAccessory (.h), использовавшуюся в более ранней версии - какую версию я не могу указать конкретно.
В некоторых блогах я следовал способу создания кодов и импортировал библиотеку AndroidAccessory, скомпилированную до отказа. Поэтому я пошел дальше, и в других блогах, в которых я обнаружил случай 1.5.2, используется ADK - сайт находится по http://arduino-er.blogspot.kr/2013/03/hello-world-adk-communication-between.html". На самом деле, эти сайты - последний случай, на который я сейчас ссылаюсь для своих привет кодов.
Но это наверняка не сработало успешно - в моем случае, проблема устройства, которую я упомянул. Если по этому поводу произойдут другие вещи, которые нужно будет опубликовать, я напишу это снова.
Спасибо всем, кто приложил усилия, чтобы решить это в любом случае...
Результат таков. Мы, моя компания, решили изменить модель планшета и платы. Что меня удивило, так это то, что ADK.h в новой версии платы Arduino не работает с новым планшетом, работающим на Jelly Bean (Android SDK 4.2.2), в то время как AndroidAccessory.h работает. Я почти не упомянул тот факт, что мы сменили доску из-за Mega_ADK. Я слышал, что Due не работает с ADK должным образом от моего коллеги, который связался с продавцом в Корее, но на самом деле я не могу в это поверить, потому что я видел, как работает файл U-tube Due с устройством, я не помню модель (вероятно HTC's).
Я успешно закончил работу с USB-аксессуаром на новом планшете ASUS Memo-pad. Я не знаю точную причину не работать с ADK.h в эскизе прямо сейчас.
После моего первого собственного ответа мне нужно было узнать об устройствах, которые могут быть совместимы с ADK 2012, я спросил об этом в группе Google Arduino - https://groups.google.com/a/arduino.cc/group/developers/browse_thread/thread/955aa9342270c2a2/8e03022da7aeab3f - и на другой корейский сайт с именем 'Hardroid' - http://hardroid.net/, и на него были отправлены сообщения, в которых он не был уверен, что может назвать конкретно совместимые устройства. Но он был очень уверен, что эталонные телефоны и планшеты из серии Google Nexus будут совместимы с ADK, что может быть принято в Arduino, потому что я использую.