USB Device Detection and Filtering in Android

Arpit Agarwal
2 min readSep 6, 2020

--

Hi 👋 fellow developers .

This articles discusses code for following things :

  1. Detecting usb plug-in , plug out in Android
  2. Filtering the devices using VendorId ProductId Class SubClass Protocol

Permission required

<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />

Receiver

  1. Make it as a class for manifest declared receiver
class USBReceiver : BroadcastReceiver(){
val TAG = "UsbReceiver"
@SuppressLint("LogNotTimber")
override fun onReceive(context: Context?, intent: Intent?) {
Log.e(TAG, "Intent received" )
if (UsbManager.ACTION_USB_DEVICE_DETACHED == intent?.action) {
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (device?.vendorId == CAMERA_VID && device.productId == CAMERA_PID){
Log.d(TAG, "USB Detached" )
}
} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED == intent?.action){
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (device?.vendorId == CAMERA_VID && device.productId == CAMERA_PID){
Log.d(TAG, "USB Attached" )

}
}
}
}

2. Object instance for context based receiver

val usbReceiver = object : BroadcastReceiver(){
val TAG = "UsbReceiver"
@SuppressLint("LogNotTimber")
override fun onReceive(context: Context?, intent: Intent?) {
Log.e(TAG, "Intent received" )
if (UsbManager.ACTION_USB_DEVICE_DETACHED == intent?.action) {
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (device?.vendorId == CAMERA_VID && device.productId == CAMERA_PID){
Log.d(TAG, "USB Detached" )
}
} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED == intent?.action){
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (device?.vendorId == CAMERA_VID && device.productId == CAMERA_PID){
Log.d(TAG, "USB Attached" )

}
}
}
}

Device Filters for usb

Create device_filters.xml inside xml folder in res .

<resources>
<usb-device vendor-id="12345" product-id="12345" class="123" subclass="1" protocol="1"/>
<usb-device vendor-id="12345" product-id="12345" class="123" subclass="1" protocol="1" />
</resources>

Refer link for finding out the class,subclass,protocol for your usb device .
https://www.usb.org/defined-class-codes

There are multiple ways to get the attach/detach event inside the application :

1. Manifest-declared receivers

<receiver
android:name=".UsbReceiver"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter"
/>

2. Intent filter for activity

<activity android:name=".USBActivity">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter"
/>
</activity>

3. Context-registered receivers

  1. Register local usbReceiver broadcast instance inside onCreate or onStart
registerReceiver(usbReceiver, IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED,UsbManager.ACTION_USB_DEVICE_ATTACHED))

2. Unregister inside onDestroy/onStop depending on where you were registering

unregisterReceiver(usbReceiver)

Other important Links :
1. https://developer.android.com/guide/topics/connectivity/usb/host
2. https://developer.android.com/guide/components/broadcasts

--

--

Arpit Agarwal

IIT Kharagpur | Tech@Lenskart | Software Engineer | TechEnthusiast