Можно настроить и зарегистрировать BroadcastReceiver примерно так:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
//Регистрация broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbReceiver, filter);
...
Нужно также определить обработчик для события BroadcastReceiver:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))
{
usbdev = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
UsbManager usbmanager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
usbmanager.requestPermission(usbdev, mPermissionIntent);
}
else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))
{
usbdev = null;
}
}
};
Здесь usbdev глобальная для класса Activity переменная типа UsbDevice.
[Ошибка приема события USB_DEVICE_ATTACHED]
На некоторых устройствах Android событие USB_DEVICE_ATTACHED не срабатывает [2], хотя USB_DEVICE_DETACHED отслеживается нормально. Но как тогда определить ситуацию, что устройство USB подключено к Android?
В документации [1] сказано, что можно определить intent-filter в файле AndroidManifest.xml для того, чтобы отследить событие подключения устройства USB к Android как хосту:
...
< intent-filter >
< action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
< /intent-filter >
< meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/all_usb_devices_filter" />
< /activity >
...
Здесь ресурс xml/all_usb_devices_filter задает файл xml/all_usb_devices_filter.xml такого содержания (здесь нет фильтрации по VID и PID устройства, поэтому фильтр будет срабатывать на все подключаемые устройства USB, подробнее см. [1]):
< ?xml version="1.0" encoding="utf-8"? >
< resources >
<usb-device />
< /resources >
События подключения теперь будет отслеживать обработчик onResume экземпляра Activity программы:
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
setIntent(intent);
}
@Override
public void onResume()
{
super.onResume();
Intent intent = getIntent();
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))
{
usbutil.usbdev = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (null != usbutil.usbdev)
{
textDebug.append("USB Attached: " + usbutil.usbdev +"\n");
}
}
}
События отключения будет отслеживать обработчик BroadcastReceiver, как уже было показано выше.
В таком способе определения событий подключения/отключения устройств USB кроется еще одна проблема. Если программа уже запущена, то подключение устройства приводит к запуску второго экземпляра программы (еще одного экземпляра activity), что нежелательно, и может запутать пользователя. Зачем при каждом подключении устройства USB запускать новые экземпляры программы и тратить на это ресурсы?. Чтобы этого избежать, можно определить атрибут android:launchMode для activity в значение singleTask, чтобы программа работала только в одном экземпляре.
...
< activity
android:name="com.usbrelay.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask" >
...
[Ссылки]
1. Android как хост USB. 2. Issue 25703 USB host device plugin notification failure site:code.google.com. |