USB_DEVICE_ATTACHED Намерение не срабатывает - PullRequest
26 голосов
/ 28 мая 2011

Кто-нибудь мог заставить работать android.hardware.usb.action.USB_DEVICE_ATTACHED "?

Хорошо, поэтому я пытаюсь использовать новые функции режима хоста USB, чтобы определить, когда USBУстройство подключено. Для моих целей я хочу получать уведомления в любое время, когда подключено устройство. Я не смог увидеть, как это происходит. Я использую вещательный приемник, который, как я знаю, работает (когда он у меня прослушивается, например, для других целей).нажата кнопка «домой». Неважно, что я пытаюсь, у меня, похоже, нет цели уволиться .... Поэтому, чтобы упростить ситуацию, я решил забыть о своем проекте и попытаться использовать собственный пример кода Google и посмотреть, смогу ли яможет, по крайней мере, сделать эту работу. У меня нет одного из ракетных пусковых установок, но я подумал, что могу, по крайней мере, получить USB_Device_Attached для стрельбы. Нет движения. Я адаптировал код для работы для других устройств. Сначала я попытался настроить устройствофильтр xml. Я добавил свое устройство (клавиатуру):

<usb-device vendor-id="1050" product-id="0010" />

Я получил поставщика и продукт по команде lsusb. Когда устройство подключеноlogcat показывает, что устройство найдено

D/EventHub(  144): No input device configuration file found for device 'Yubico Yubico Yubikey II'.
I/EventHub(  144): New device: id=43, fd=219, path='/dev/input/event8', name='Yubico Yubico Yubikey II', classes=0x80000003, configuration='', keyLayout='/system/usr/keylayout/Generic.kl', keyCharacterMap='/system/usr/keychars/Generic.kcm', builtinKeyboard=false
I/InputReader(  144): Device added: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101
I/ActivityManager(  144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=2/1/1 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=47}
D/MissileLauncherActivity(16191): intent: android.intent.action.MAIN
I/EventHub(  144): Removed device: path=/dev/input/event8 name=Yubico Yubico Yubikey II id=43 fd=219 classes=0x80000003
I/InputReader(  144): Device removed: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101
I/ActivityManager(  144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=48}
D/dalvikvm(  144): GC_EXPLICIT freed 78K, 26% free 14717K/19719K, paused 3ms+3ms
D/MissileLauncherActivity(16191): intent: android.intent.action.MAIN

Xoom находит клавиатуру и ее можно использовать с устройства (я могу использовать ее в браузере для ввода букв).И умышленное срабатывание (но оно запускает только android.intent.action.MAIN), я никогда не получаю намерение DEVICE_ATTACHED.Запись в журнале происходит из примера кода:

Log.d(TAG, "intent: " + intent.getAction().toString());

В функции возобновления.После дополнительных копаний и удаления любых ссылок на usb я обнаружил, что каждое приложение, которое я создаю, получает резюме, вызываемое, когда клавиатура присоединяется / отсоединяется (отсюда и запись в журнале intent: android.intent.action.MAIN).Прямо сейчас, единственное, что я могу понять, это то, что это ошибка в источнике Android.Кстати, я использую Wi-Fi Xoom с ОС 3.1.

Ответы [ 11 ]

21 голосов
/ 30 ноября 2011

У меня тоже была такая же проблема. Я наконец понял, что в фильтре устройств xml мы должны добавить следующую строку.

<usb-device vendor-id-"xxxxx" product-id="yyyyy">

xxxxx и yyyyy должны быть десятичными числами. НЕ шестнадцатеричные коды. Тогда все работает как рекламируется! Я знаю, что уже поздно, но надеюсь, что это поможет.

13 голосов
/ 30 мая 2011

Итак, я нашел решение своей проблемы и многому научился, надеюсь, он может помочь кому-то еще.

Итак, сначала отключите Устройства HID не запускают никаких целей . Они также не отображаются в списке mUsbManager.getDeviceList(). Другие вещи, однако, делают. Я дал карту памяти USB, и что вы знаете, устройство указано в списке устройств. Я также обнаружил, что возвращаемое устройство не имеет класса, подкласса или протокола. Отладка показала, что родительский интерфейс, тем не менее, имел надлежащий класс / подкласс / и протокол. Также, если вы должны иметь фильтр устройства. Я получил class=0008 (USB STORAGE), чтобы работать в моих целях. Я предполагаю, что другие классы также будут работать.

Итак, теперь выясним намерения. Оказывается, что намерение должно быть связано с активностью запуска. Мои попытки прикрепить его к услуге или получателю не принесут никаких плодов. Так что теперь, когда я собираюсь запустить, я вижу всплывающие уведомления, когда я подключаю свое устройство (USB-накопитель), он просит меня установить приложение по умолчанию для этого устройства. Отлично, теперь мое приложение запускается каждый раз, когда я подключаю это устройство. Обратите внимание, что вам будет предложено для каждого уникального устройства. Но только один раз. Похоже, что он зарегистрирован как программы по умолчанию.

Ну, я думаю, что это подводит итог тому, что я нашел. Жаль, что вы не можете получать уведомления, когда подключается клавиатура / мышь. Да, и еще одна вещь. Нет проблем с ядром tiamat, работающим прямо сейчас и без проблем.

7 голосов
/ 22 марта 2012

Я недавно обнаружил решение аналогичной проблемы.

Как кто-то уже заметил, HID devices не запускайте намерение , которое, как мне кажется, было вашей проблемой.

Однако связанная с этим проблема заключается в том, что если ваша программа настроена на запуск при подключении USB-устройства, то даже после запуска приложения вы не сможете зафиксировать действие USB_DEVICE_ATTACHED. Вместо этого система видит это намерение и говорит: «О, это означает, что это приложение хочет запустить (как объявлено в вашем манифесте), а затем отправляет вам действие android.intent.action.MAIN вместо действия USB_DEVICE_ATTACHED, и оно звонки onResume(). Даже если ваше приложение работает. Насколько я могу судить, вы НЕ МОЖЕТЕ захватить намерение USB_DEVICE_ATTACHED, если ваш манифест заявляет, что ваше приложение будет работать, когда подключены USB-устройства. Вам просто нужно поставить некоторый код в onResume(), чтобы проверить, подключен ли USB. Даже если ваша программа работает, onResume будет вызываться снова, когда подключено USB-устройство.

Я отмечу мое решение более подробно здесь: Android 3.1 USB-Host - BroadcastReceiver не получает USB_DEVICE_ATTACHED

2 голосов
/ 18 февраля 2014

Другим обходным решением является использование

new FileObserver("/dev/input") {
  @Override public void onEvent(int event, String path) {
     //gets called on input device insert / remove
  }
};

, которое будет работать для некоторых USB-устройств (клавиатура, мышь)

2 голосов
/ 14 января 2014

У меня была такая же проблема.Мое окончательное решение состояло в том, чтобы использовать старомодную технику опроса.Вот довольно минимальный класс, который решает проблему к моему удовлетворению.

package com.YourCompancy.YourProduct;

import android.app.*;
import android.content.*;

import android.hardware.usb.*;
import java.util.*;
import android.util.*;
import android.os.*;

public class UsbDeviceWatcher extends BroadcastReceiver
{   
    public void onReceive(Context context, Intent intent)
    {
        if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED))
        {
            UsbDevice d = (UsbDevice)
                intent.getExtras().get(UsbManager.EXTRA_DEVICE);

            DeviceConnect(d, false);
        }
    }

    public void DeviceConnect(UsbDevice device, boolean Attached)
    {
            if (Attached)
            {
                            // Some suggestions ...
                            //    play sound effect
                            //    notify consumer software
                            //    determine if interested in device
                            //    etc
                            Log.i("usb", "device attached");

            } else
            {
                Log.i("usb", "device detached");
            }

    }

    public UsbManager manager;
    public Handler handler;

    public UsbDeviceWatcher(Context context, Handler handle)
    {

        this.handler = handle;

        manager = (UsbManager) 
            context.getSystemService(Context.USB_SERVICE);

        IntentFilter dev = new IntentFilter();

        dev.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);

        context.registerReceiver(this, dev);    

        final UsbDeviceWatcher _this = this;

        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                LinkedList<UsbDevice> seen = new LinkedList<UsbDevice>();
                LinkedList<UsbDevice> attached = new LinkedList<UsbDevice>();

                            //there is a need for multithread support here
                                //   so the thread can watch for an exit condition
                while (true)
                {

                    HashMap<String, UsbDevice>
                        D = manager.getDeviceList();

                    for (UsbDevice d : D.values())
                    {
                        if (!seen.contains(d))
                        {
                            if (!attached.contains(d))
                            {
                                final UsbDevice dev = d;

                                handler.post(new Runnable(){
                                    public void run()
                                    {
                                        DeviceConnect(dev, true);
                                    }
                                });
                            }

                            seen.add(d);
                        }
                    }

                    for (UsbDevice d : seen)
                    {
                        if (!D.values().contains(d)) seen.remove(d);
                    }

                    try
                    {
                        Thread.sleep(500);  
                    } catch (InterruptedException exception)
                    {
                        return; 
                    }
                }

            }
        });

        thread.start();
    }
}
2 голосов
/ 30 мая 2011

Счетные устройства

Если ваше приложение заинтересовано в проверке всех USB-устройств, подключенных в данный момент во время работы приложения, оно может перечислить устройства на шине. Используйте метод getDeviceList (), чтобы получить хэш-карту всех подключенных USB-устройств. Если вы хотите получить устройство из карты, в хэш-карту вводится имя устройства USB.

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

При желании вы также можете просто получить итератор из хеш-карты и обработать каждое устройство одно за другим:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
    UsbDevice device = deviceIterator.next()
    //your code
}
1 голос
/ 24 апреля 2015

Это то, что я сделал для обнаружения USB / Media Connect.

Файл манифеста

    <receiver
            android:name=".UsbReceiver"
            android:enabled="true" >
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_MOUNTED"/>
            <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
            <data android:scheme="file"/>
        </intent-filter>
    </receiver>

Я ничего не делал ни в этом задании, ни в моем приемнике.

похоже, что эта строка делает все.

<data android:scheme="file"/>
1 голос
/ 02 апреля 2015

У меня установлено приложение launchMode="singleTop", и в этом режиме кажется, что getIntent().getAction() всегда равно действию, которое первым запустило приложение.

Таким образом, если вы запустите приложение вручную и , затем подключите устройство (даже после отключения от этого приложения), вы получите android.intent.action.MAIN.

Если вы закроете приложение, а затем подключите устройство, вы всегда получите android.hardware.usb.action.USB_DEVICE_ATTACHED, даже если вы переключитесь и вернетесь к своему приложению или даже повернете устройство .

Я на самом деле странно получаю намерения при отключении USB-устройства, что, на мой взгляд, не задокументировано - но, конечно, я получаю USB_DEVICE_ATTACHED, когда мое устройство отключено.

Без singleTop он работает как положено, но затем вы получаете еще одну глупую дополнительную активность, если ваше приложение уже открыто и вы подключаете устройство.

Еще раз, API-интерфейс Android глючит, чрезмерно сложен и сложен в использовании.

1 голос
/ 29 мая 2011

ОК, больше работы, больше сбоев, но некоторый прогресс.

Я узнал больше из документации по SDK. Похоже, что вы должны иметь фильтр устройства, чтобы использовать намерения. поэтому я решил попробовать использовать фильтр классов вместо идентификаторов поставщиков / продуктов. Я полагаю, что это было бы более общим и, надеюсь, поймать скрытое устройство. Я использовал 03h в качестве идентификатора класса, я пробовал различные форматы, я пробовал подклассы, я даже использовал lsusb для обнаружения, класса, подкласса и протокола моего устройства. похоже, это совсем не помогло. поэтому я пошел дальше к документации sdk и решил попробовать перечислить все устройства, чтобы увидеть, что ОС видит целые числа класса / подкласса / протокола. Я скопировал код, вставил его в прослушиватель кликов и добавил операторы log.v. ничего не показывает в logcat.

похоже, что американская система не видит ни одного устройства (даже если устройство действительно работает). Теперь это очень показательно, если подключенное USB-устройство намерено не срабатывать. Теперь я должен сказать, что я использую собственное ядро ​​в моем xoom (tiamat). Я думал, что это может быть как-то связано с проблемой некоторое время назад, поэтому я вернулся к стоковой версии 3.1. и до сих пор прогресс. это было некоторое время назад, до того, как я попытался перечислить, так что теперь я вернусь к agaian и продолжу работать с запасом, пока не буду уверен, что проблема не в ядре. Я вернусь, когда узнаю больше. успех или неудача. Конечно, если кто-то еще понимает это лучше меня, пожалуйста, присоединяйтесь. И последнее замечание. Я очень переживал за весь режим хоста otg, когда увидел это в документации. Заметьте, что коэффициент идентичен, хотя он и ссылается на два метода перечисления. возможно, это просто ошибка авторов переписки, но некоторые все еще переживают в свете всего этого сбоя.

0 голосов
/ 26 апреля 2016

Подключить USB-клавиатуру WONT огонь USB_DEVICE_ATTACHED .

Вместо этого система сработает Intent.ACTION_CONFIGURATION_CHANGED . Однако при изменении конфигурации система перезапустит действие. Вы не поймаете действие при перезапуске Activity. В этом случае вам нужно добавить android: configChanges = "клавиатура | клавиатура скрытая" в свой манифест Android, чтобы действие не перезапускалось после подключения внешней клавиатуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...