Understanding USB Communication in Android Apps
Last Updated :
24 Apr, 2025
In this article, we are going to see how to interact with USB in Android apps. What things are Required and Also 1 mini Project to Get a Clear Idea of How Things Work When We Need to Interact Android Apps With USB.
USB Endpoints and Interfaces
Endpoints:
Endpoints are the channels through which data is transferred between the USB device and the host (in this case our Android device is the host). They come in two types:
- In Endpoints: These are used by USB devices to send data to the host. For example, a camera might use an In Endpoint to send image data to a computer.
- Out Endpoints: These are used by USB devices to receive data from the host. For example, a printer might use an Out Endpoint to receive print jobs from a computer.
Interfaces:
The interface represents a set of endpoints that perform a specific function. A USB device can have multiple interfaces and each interface is identified by a unique number. For example, a printer might have one interface for printing and another for status information.
Required Components for USB Interaction and Implementing USB Communication in Android Apps
1. USB Host Mode Support:
For Android device to communicate with USB peripherals it must support USB Host Mode.Mostly modern Android devices have this capability.
2. USB Host API:
Android provides a set of APIs for interacting with USB devices. Primary classes for USB communication are UsbManager, UsbDevice, UsbDeviceConnection. These classes allow us to manage the USB devices connected to the host.
- UsbManager: This is the entry point for interacting with USB devices. It allows us to obtain a list of connected devices, request permission to communicate with a device, manage device connections.
- UsbDevice: Represents a connected USB device. It provides information about the device like its vendor and product IDs, interfaces,endpoints.
- UsbDeviceConnection: This class facilitates communication with a connected USB device. It allows us to send and receive data through the device's endpoints.
3. USB Permissions:
Accessing USB devices is a sensitive operation we need to declare the necessary permissions in AndroidManifest.xml file. To ensure that only authorized apps can interact with connected USB devices.
XML
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
4. USB Device Enumeration:
When a USB device is connected Android performs device enumeration to identify its capabilities and characteristics. We can use the UsbManager to obtain list of connected devices and iterate through them to find the one that matches our app requirements.
Java
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> connectedDevices = usbManager.getDeviceList();
for (UsbDevice device : connectedDevices.values()) {
// You can check permissions and more here
}
Kotlin
val usbManager = getSystemService(Context.USB_SERVICE) as UsbManager
val connectedDevices: HashMap<String, UsbDevice> = usbManager.deviceList
for (device in connectedDevices.values) {
}
5. Requesting Permission:
Before communicating with a USB device we need to request permission from the user using pending intent. It is a crucial security measure to ensure that only authorized apps can access the device and it is required.
Java
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, permissionIntent);
Kotlin
val permissionIntent = PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), 0)
usbManager.requestPermission(device, permissionIntent)
6. Managing Endpoints and Interfaces:
Once we have obtained permission to communicate with a device we can access its endpoints and interfaces. Using the UsbDevice and UsbDeviceConnection classes to send and receive data through the appropriate endpoints.
Example Project : Creating an App To Enumerate All the USB Devices List
In this project we are going to create an app to Get all the usb devices list that are connected to our android device with OTG.
What we are going to do:
Step By Step Implementation:
Step 1: Create a new Project and Select Kotlin/java As the programming language
Step 2: We have created a simple UI by adding one Button at Bottom
Step 3: Add Permissions To Interact With Usb that we have seen Earlier
XML
<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-feature android:name="android.hardware.usb.host" />
Step 4: Working on Kotlin File and When the button is clicked it retrieves a list of connected USB devices and displays them in bottom sheet dialog that i have created showing information like device name, vendor ID, manufacturer name, product name,you can add more things. Each device item is clickable and clicking on it displays a toast message indicating the selected device with device name and Vendor Id.
Java
package com.ayush.gfgapp;
import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import java.util.HashMap;
public class MainActivity2 extends AppCompatActivity {
private Button getDevice;
private UsbManager usbManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
// Initialize button and USB manager
getDevice = findViewById(R.id.getDevice);
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Set OnClickListener for the button
getDevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Retrieve the list of connected USB devices
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
showDevicesDialog(deviceList);
}
});
}
private void showDevicesDialog(HashMap<String, UsbDevice> deviceList) {
if (deviceList.isEmpty()) {
// Show a toast if no USB devices are found
Toast.makeText(this, "No USB devices found", Toast.LENGTH_SHORT).show();
} else {
// Inflate the bottom sheet layout to display the list of devices
View bottomSheetView = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_device_list, null);
LinearLayout devicesLayout = bottomSheetView.findViewById(R.id.devicesLayout);
for (UsbDevice device : deviceList.values()) {
// Inflate the layout for each device item
View deviceItemLayout = LayoutInflater.from(this).inflate(R.layout.device_list_item, null);
TextView deviceNameTextView = deviceItemLayout.findViewById(R.id.deviceNameTextView);
TextView vendorIdTextView = deviceItemLayout.findViewById(R.id.vendorIdTextView);
TextView manufacturerTextView = deviceItemLayout.findViewById(R.id.manufacturerTextView);
TextView productNameTextView = deviceItemLayout.findViewById(R.id.ProductNameTextView);
TextView emptyTV = deviceItemLayout.findViewById(R.id.emptyTV);
// Set information about the device in the corresponding TextViews
deviceNameTextView.setText("Device Name: " + device.getDeviceName());
vendorIdTextView.setText("Vendor ID: " + device.getVendorId());
manufacturerTextView.setText("Manufacturer Name: " + device.getManufacturerName());
productNameTextView.setText("Product Name: " + device.getProductName());
emptyTV.setText("Testing:- " + device.getProductId());
// Add an OnClickListener to handle device selection
deviceItemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity2.this, "Device Selected: " + device.getDeviceName() + " (Vendor ID: " + device.getVendorId() + ")", Toast.LENGTH_SHORT).show();
}
});
// Add the device item to the layout
devicesLayout.addView(deviceItemLayout);
}
// Create and display the bottom sheet dialog with the list of devices
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
bottomSheetDialog.setContentView(bottomSheetView);
bottomSheetDialog.show();
}
}
}
Kotlin
package com.ayush.gfgapp
import android.content.Context
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.bottomsheet.BottomSheetDialog
class MainActivity2 : AppCompatActivity() {
private lateinit var getDevice: Button
private lateinit var usbManager: UsbManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
getDevice = findViewById(R.id.getDevice)
// Initialize the USB manager to access USB functionality
usbManager = getSystemService(Context.USB_SERVICE) as UsbManager
getDevice.setOnClickListener {
// Retrieve the list of connected USB devices
val deviceList = usbManager.deviceList
// Call function to show the list of devices
showDevicesDialog(deviceList)
}
}
private fun showDevicesDialog(deviceList: HashMap<String, UsbDevice>) {
if (deviceList.isEmpty()) {
// Show a toast if no USB devices are found
Toast.makeText(this, "No USB devices found", Toast.LENGTH_SHORT).show()
} else {
// Inflate the bottom sheet layout to display the list of devices
val bottomSheetView = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_device_list, null)
val devicesLayout = bottomSheetView.findViewById<LinearLayout>(R.id.devicesLayout)
for (device in deviceList.values) {
// Inflate the layout for each device item
val deviceItemLayout = LayoutInflater.from(this).inflate(R.layout.device_list_item, null) as LinearLayout
val deviceNameTextView = deviceItemLayout.findViewById<TextView>(R.id.deviceNameTextView)
val vendorIdTextView = deviceItemLayout.findViewById<TextView>(R.id.vendorIdTextView)
val manufacturerTextView = deviceItemLayout.findViewById<TextView>(R.id.manufacturerTextView)
val productNameTextView = deviceItemLayout.findViewById<TextView>(R.id.ProductNameTextView)
val emptyTV = deviceItemLayout.findViewById<TextView>(R.id.emptyTV)
// Set information about the device in the corresponding TextViews
deviceNameTextView.text = "Device Name: ${device.deviceName}"
vendorIdTextView.text = "Vendor ID: ${device.vendorId}"
manufacturerTextView.text = "Manufacturer Name: ${device.manufacturerName}"
productNameTextView.text = "Product Name: ${device.productName}"
emptyTV.text = "Testing:- ${device.productId}"
// Add an onClickListener to handle device selection
deviceItemLayout.setOnClickListener {
Toast.makeText(this, "Device Selected: ${device.deviceName} (Vendor ID: ${device.vendorId})", Toast.LENGTH_SHORT).show()
}
// Add the device item to the layout
devicesLayout.addView(deviceItemLayout)
}
val bottomSheetDialog = BottomSheetDialog(this)
bottomSheetDialog.setContentView(bottomSheetView)
// Display the bottom sheet
// dialog with the list of devices
bottomSheetDialog.show()
}
}
}
Layout For Bottom Sheets:
bottom_sheet_device_list.xml:
XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/cardview_shadow_start_color"
android:orientation="vertical">
<LinearLayout
android:id="@+id/devicesLayout"
android:layout_width="match_parent"
android:background="@color/cardview_shadow_start_color"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
device_list_item.xml:
XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/cardview_shadow_start_color"
android:padding="16dp">
<TextView
android:id="@+id/deviceNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#E11919"
android:textAppearance="?android:textAppearanceMedium" />
<TextView
android:id="@+id/vendorIdTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#0EEF12"
android:layout_marginTop="4dp"
android:textAppearance="?android:textAppearanceSmall" />
<TextView
android:id="@+id/manufacturerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#0EEF12"
android:layout_marginTop="4dp"
android:textAppearance="?android:textAppearanceSmall" />
<TextView
android:id="@+id/ProductNameTextView"
android:layout_width="wrap_content"
android:textColor="#0EEF12"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textAppearance="?android:textAppearanceSmall" />
<TextView
android:id="@+id/emptyTV"
android:layout_width="wrap_content"
android:textColor="#3F51B5"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textAppearance="?android:textAppearanceSmall" />
</LinearLayout>
Output:
Similar Reads
Android Networking Bare Skin - Understanding JPost
If you want to create bottom-to-top networking on Android, it is usually quite complicated. As a result, we rely on third-party libraries. But you'll never know what's beneath it. In this example, I've used the networking java.net package to create a networking framework driven by JPost, a class com
8 min read
First Android Application in Kotlin
We can build an Android application using Kotlin and Java. In the Android Studio Kotlin Tutorial, we are using Kotlin language to build the application. In the previous tutorial, we learned how to create a project for Kotlin language but here, we will learn how to run an application using the AVD (A
2 min read
How to Communicate with PC using Android?
In this article, we would be discussing one of the basic ways of communication between a program on a PC and an Android device. Here we will use the concept of Socket programming. We know communication takes place between a sender and a receiver, Socket programming involves a Client-Server setup, wh
5 min read
Encoding and Decoding in Communication Process
In this article, we will go through the concept of Encoding and Decoding the message in Communication Process in Distributed Systems in detail. Encoding and Decoding in Communication Process: Encoding refers to "Codes that are used to convert a body of information from one system to another." The se
4 min read
Chatting Application in Android with Kotlin
Building a Real-Time Chat Application can be a great way to dive into Android Development and Firebase. In this article, we will learn to make a basic chat application using Android Studio IDE with Kotlin and real-time chatting using Google's FirebaseFirestore as a database.Pre-requisitesAndroid Stu
7 min read
Testing an Android Application with Example
Testing is an essential part of the Android app development process. It helps to ensure that the app works as expected, is bug-free, and provides a seamless user experience. Android offers various testing tools and frameworks that can be used to write and execute different types of tests, including
5 min read
User Registration in Android using Back4App
Prerequisite: How to Connect Android App with Back4App? We have seen adding Back4App in our Android App. In this article, we will take a look at adding a User Registration form in Android App so that users can register themselves in the app. What we are going to build in this article? We will be b
5 min read
User Login in Android using Back4App
We have seen implementing User Registration in Android using Back4App. In that article, we have implemented User Registration in our App. In this article, we will take a look at the implementation of User Login in our Android App. What we are going to build in this article? We will be building a s
5 min read
How to Create a News App in Android?
Networking is an integral part of android development, especially when building data-driven clients. The java class mainly used for network connections is HttpUrlConnection. The class requires manual management of data parsing and asynchronous execution of requests. For network operations, we are be
9 min read
Firebase In-App Messaging in Android with Example
Sending tailored, contextual messages to your app's active users that encourage them to use important features can help you engage them. This is possible with Firebase In-App Messaging. For instance, you may ask users to subscribe, view a video, finish a level, or make a purchase by sending them an
4 min read