USB Host

Most people's experience with Android and USB is the phone acting as a USB device — plugging it into a computer to transfer files. USB Host mode flips that relationship: the Android device becomes the USB host, and it talks to an attached USB accessory — a scanner, a scale, a controller — the same way a desktop computer would.

Scope note upfront: RecipeBox itself has no need for USB host mode. This lesson exists for completeness of the hardware-integration section of this track, covering a capability you'd reach for only in specialized apps — for example, an app connecting to a USB barcode scanner to look up packaged ingredients, or a dedicated kitchen appliance that happens to expose a USB interface.

Checking for USB Host Support

Access starts with the UsbManager system service:

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

for (UsbDevice device : deviceList.values()) {
    Log.d("UsbHost", "Found device: " + device.getDeviceName()
        + " (vendorId=" + device.getVendorId() + ")");
}
Explanation: getDeviceList() returns whatever USB devices are currently physically attached (typically via a USB-OTG cable/adapter). An empty map simply means nothing is plugged in — or the hardware doesn't support host mode at all.

Requesting Permission for a Specific Device

Before you can open and communicate with a particular UsbDevice, the user must grant permission for that specific device:

private static final String ACTION_USB_PERMISSION = "com.recipebox.USB_PERMISSION";

private void requestUsbAccess(UsbDevice device) {
    PendingIntent permissionIntent = PendingIntent.getBroadcast(
        this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_MUTABLE);

    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(usbPermissionReceiver, filter);

    usbManager.requestPermission(device, permissionIntent);
}

private final BroadcastReceiver usbPermissionReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
            UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            boolean granted = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
            if (granted && device != null) {
                // Safe to open a connection to this device now
            }
        }
    }
};
A separate permission model: This is not the same runtime permission system covered in Runtime Permissions (no entry in the manifest's dangerous permissions list, no ActivityCompat.requestPermissions() call). USB device access is granted per individual physical device via UsbManager.requestPermission(), and the user sees a system dialog naming that specific device the first time your app tries to use it.

The Alternative: UsbAccessory Mode

Everything above assumes the Android device is the host, and something else is the attached device. The USB API also supports the opposite relationship through UsbAccessory: here, the Android device is the USB accessory, and some other hardware (often a microcontroller board) acts as the host driving the connection. Which mode applies depends entirely on which side of the USB cable your Android device sits on for the hardware you're integrating with.

Quick Reference

ConceptRole
USB Host modeAndroid device is the host; it talks to an attached USB device
UsbManager.getDeviceList()Lists attached USB devices
UsbManager.requestPermission()Asks the user to allow access to one specific device
USB Accessory modeAndroid device is the accessory; other hardware is the host
That wraps up Media & Hardware. Next, we move into Firebase, starting with connecting RecipeBox to a Firebase project in Setup & Analytics.