Как реализовать Android Open Accessory в качестве сервиса? - PullRequest
4 голосов
/ 01 ноября 2011

Я играл с Android Open Accessory Development Kit. Следуя примеру DemoKit, предоставленному Google , у меня не возникло проблем с адаптацией решения к моему приложению. Я могу распознавать, общаться и отсоединять аксессуар просто отлично.

Однако мне нужно было бы запустить все это как сервис. У меня есть базовое действие, которое запускается намерением USB_ACCESSORY_ATTACHED (то есть, когда аксессуар подключен), и это прекрасно работает. Но как только я запускаю свой сервис и запускаю в нем идентичный код, по сравнению с моим рабочим решением в рамках обычной деятельности, я получаю IOException («такого устройства нет») всякий раз, когда я пытаюсь связаться с аксессуаром ( мониторинг arduino показывает успешное соединение USB). Это происходит, даже если я указал правильный BroadcastReceiver в службе, зарегистрировал его в методе обратного вызова onStartCommand и настроил конечные точки связи с openAccessory(). Соответствующий код выглядит следующим образом.

@Override
public void onCreate() {
    Log.d(TAG, "ONCREATE");

    manager = UsbManager.getInstance(this);
    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
            ACTION_USB_PERMISSION), 0);

    // Register broadcastreceiver for filtering accessory events
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
    registerReceiver(mUsbReceiver,filter);
    super.onCreate();
}

public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "ONSTARTCOMMAND METHOD ACCESSED");

    if (mInputStream != null && mOutputStream != null) {
        return START_NOT_STICKY;
    }

    UsbAccessory[] accessories = manager.getAccessoryList();
    mAccessory = (accessories == null ? null : accessories[0]);

    if (mAccessory != null) {
        if (manager.hasPermission(mAccessory)) {
            openAccessory();
        } else {
            synchronized (mUsbReceiver) {
                if (!mPermissionRequestPending) {
                    manager.requestPermission(mAccessory,
                            mPermissionIntent);
                    mPermissionRequestPending = true;
                }
            }
        }
    } else {
        Log.d(TAG, "mAccessory is null");
    }
    return START_NOT_STICKY;
}

метод openAccessory:

/**
 * Open the accessory
 */
private void openAccessory() {
    Log.d(TAG, "openAccessory: "+mAccessory);
    mFileDescriptor = manager.openAccessory(mAccessory);
    if (mFileDescriptor != null) {
        FileDescriptor fd = mFileDescriptor.getFileDescriptor();
        mInputStream = new FileInputStream(fd);
        mOutputStream = new FileOutputStream(fd);
        Thread thread = new Thread(null,this,"AccessoryThread");
        thread.start();
    }
}

Есть идеи для возможного решения?

Ответы [ 2 ]

3 голосов
/ 21 апреля 2012

Решение было простым.

if (intent.getAction().equals(USB_ACCESSORY_ATTACHED)) {
    Intent i = new Intent(this, YourServiceName.class);
    i.putExtras(intent);
    startService(i);
}

По сути, скопируйте намерение, полученное при запуске действия, которое вы используете для запуска службы, поскольку намерение содержит сведения о дополнительном устройстве, которое необходимо для реализации ADK.

Затем в сервисе перейдите к реализации оставшейся части ADK точно так же, как и раньше.

0 голосов
/ 04 апреля 2012

В настоящее время я не могу дать вам подходящее решение вашей проблемы. Но может быть это Пример github показывает, как решить вашу проблему:

Я собираюсь проанализировать код, приведенный на github, чтобы реализовать то же самое, что и вы.

...