How to check usb host support on android device programmatically? - android

I know that it was supported starting Android 3.1, i mean "how to check hardware support"

See: http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_USB_HOST
context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_USB_HOST);

I had the same question and after some googling I found this:
http://android.serverbox.ch/?p=549
In summary, your app needs to use the UsbManager system service and enumerate through attached USB devices.
mUsbManager = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> devlist = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviter = devlist.values().iterator();
while (deviter.hasNext()) {
UsbDevice d = deviter.next();
if (mUsbManager.hasPermission(d)) {
UsbInterface usbIf = mDevice.getInterface(1);
for (int i = 0; i < usbIf.getEndpointCount(); i++) {
if (usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
//...
}
}
}
}

Related

How can I get the usb device model through usb serial?

I have a usb device which model is GP-3120TN, productName is Gprinter USB Printer. I plug it with otg and usb-serial line to Android phone(API 19).
Now I want to get the device model like GP-3120TN. I can't find the field in UsbDevice or UsbDeviceConnection. I can only get the productName through below code
`
usbDeviceConnection.claimInterface(usbInterface, true);
byte[] rawDescs = usbDeviceConnection.getRawDescriptors();
String manufacturer, product;
byte[] buffer = new byte[255];
int idxMan = rawDescs[14];
int idxPrd = rawDescs[15];
try {
int rdo = usbDeviceConnection.controlTransfer(UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD, STD_USB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | idxPrd, 0, buffer, 0xFF, 0);
product = new String(buffer, 2, rdo - 2, "UTF-16LE");
DeviceModel deviceModel = new DeviceModel(serialNumber, product, manufacturer, usbDevice, usbInterface);
Log.e(TAG, "deviceModel: " + deviceModel.toString());
String productBase64 = Base64.encodeToString(buffer, 2, rdo - 2, Base64.NO_WRAP);
deviceModel.productNameBase64 = productBase64;
deviceModelList.add(deviceModel);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (usbDeviceConnection != null) {
//usbDeviceConnection.releaseInterface(usbInterface);
usbDeviceConnection.close();
}
}`
In which way can I get the device model? Does the model is written to the hardware? I need the device model to know which kind the usb-printer is?
You can try to use below code to get connected USB device information:
public void getDeviceInfo() {
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();
manager.requestPermission(device, mPermissionIntent);
String Model = device.getDeviceName();
int id = device.getDeviceId();
int vendor = device.getVendorId();
int product = device.getProductId();
int class = device.getDeviceClass();
int subclass = device.getDeviceSubclass();
}}
Edit:
Only above information can be obtained using UsbDevice but it can not detect commercial name of attached USB device.

How to get external usb mass storage path in Android?

I need to import / export some data from / to a usb stick.
Is there a way to get the path of the mounted usb devices?
My code looks something like this:
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();
UsbInterface deviceInterface = device.getInterface(0);
if(deviceInterface != null && deviceInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE){
// check if path "mnt/usb_storage/*" exist
}
}
I can search if the path "mnt/usb_storage/*" exists when the device is a mass storage.
This works fine if only one usb mass storage is attached or the app is in foreground when a second usb mass storaged is attached.
If you wonder, yes there are Android devices with multiple usb ports.
Is there no way to get the path when I have the UsbManager/UsbDevice/UsbInterface?
Is the path on all devices like "mnt/usb_storage/*"?
Update 1:
Target Android Version 5.1
Requirement: "Filechooser" has to be integrated inside the app, filter for folders, file names und file types have to be applied.
Update 2:
As suggested by #greenapps I gave "ACTION_OPEN_DOCUMENT_TREE" a try:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
intent.putExtra("android.content.extra.FANCY", true);
intent.putExtra("android.content.extra.SHOW_FILESIZE", true);
startActivityForResult(intent, OPEN_DOCUMENT_TREE_REQUEST_CODE);
This does not show the usb stick neither was I able to filter the files and folders.
Same device: es-datei explorer is able to display the usb device.
My requirements are to display a custom file chooser where the user can select files from a customer specific cloud, internal storage or usb devices similar to the es datei explorer.
My solution with searching if the path: "mnt/usb_storage/*" exists works as required I am just wondering if there is a better way.
So I have searched quite a number of SO questions to get the path of a USB devices. I have not quite found an answer yet, but since this is top of the Google search and a fairly recent question, I will post what I have found.
Attempt (fleshed out)
So initially I tried (with my own implementation) as the question contains:
public static String getUSBProblematic(Context context){
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
if (usbManager == null) {
Log.e(TAG, "Unable to get USB_SERVICE");
return "";
}
UsbAccessory[] accessoryList = usbManager.getAccessoryList();
if (accessoryList != null) {
for (UsbAccessory usbAccessory : accessoryList) {
// here we check the vendor
Log.d(TAG, "getUSBProblematic: " + usbAccessory.toString());
}
}
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
if(deviceList != null) {
List<UsbDevice> usbDeviceList = new ArrayList<>(deviceList.values());
for (Iterator<UsbDevice> iterator = usbDeviceList.iterator(); iterator.hasNext();) {
UsbDevice next = iterator.next();
boolean isMassStorage = false;
for (int i = 0; i < next.getInterfaceCount(); i++) {
// Check USB interface type is mass storage
UsbInterface usbInterface = next.getInterface(i);
if(usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE && usbInterface.getEndpointCount() == 2) {
// Check endpoints support bulk transfer
for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(j);
if(endpoint != null) {
if(endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK){
// Valid mass storage
isMassStorage = true;
}
}
}
}
}
if(!isMassStorage) {
iterator.remove();
}
}
for (UsbDevice usbDevice : usbDeviceList) {
Log.d(TAG, "getUSBProblematic: Device Name" + usbDevice.getDeviceName());
Log.d(TAG, "getUSBProblematic: Device Desc" + usbDevice.toString());
}
}
return "";
}
So the best I can get out of this is something like /dev/bus/usb/003, but nothing more than that.
So looking over my mounts file in /proc/mounts (found on the device, see Device File Explorer in Android Studio, I saw that USB specific storage devices are mounted at /mnt/media_rw/. But browsing to /storage, I saw the USB devices I expected or was looking for.
I am not sure if this is a good strategy or device specific (I use a Huawei Mate 10 Pro), but I am using
Possible Solution
public static String getUSB(){
File storageDirectory = new File("/storage");
if(!storageDirectory.exists()) {
Log.e(TAG, "getUSB: '/storage' does not exist on this device");
return "";
}
File[] files = storageDirectory.listFiles();
if(files == null) {
Log.e(TAG, "getUSB: Null when requesting directories inside '/storage'");
return "";
}
List<String> possibleUSBStorageMounts = new ArrayList<>();
for (File file : files) {
String path = file.getPath();
if (path.contains("emulated") ||
path.contains("sdcard") ||
path.contains("self")) {
Log.d(TAG, "getUSB: Found '" + path + "' - not USB");
} else {
possibleUSBStorageMounts.add(path);
}
}
if (possibleUSBStorageMounts.size() == 0) {
Log.e(TAG, "getUSB: Did not find any possible USB mounts");
return "";
}
if(possibleUSBStorageMounts.size() > 1) {
Log.d(TAG, "getUSB: Found multiple possible USB mount points, choosing the first one");
}
return possibleUSBStorageMounts.get(0);
}
EDIT 1
This may also be useful (search for USB)
There mostly is no path on modern Android systems. Nowadays you will try to get a document tree scheme.
There are several options.
You could have a look at the second or third item returned by getExternalFilesDirs(). (Will give a path. But writing not possible.)
For Android 6+ use Intent.ACTION_OPEN_DOCUMENT_TREE to let the user choose the drive. This will give you a content sheme. No file path.
For Android 7+ have a look at Storage Volumes.

Android : how to detect already connected usb device?

I'm trying to detect usb devices which are already connected to android.
I understand there are actions to detect when USB is either attached or detached.
But I don't really get how to check devices after connecting usb device to android.
Also, I've found that each USB device has it's device class code, but how do I figure out what kind of device is connected? For instance, I need to detect both usb mouse and keyboard; how do I differentiate them?
Try this:
First register Broadcast for USB connection.
manifest permission:
:
<intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter>
Get the List of USB Device with details by using this
public void getDetail() {
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();
manager.requestPermission(device, mPermissionIntent);
String Model = device.getDeviceName();
int DeviceID = device.getDeviceId();
int Vendor = device.getVendorId();
int Product = device.getProductId();
int Class = device.getDeviceClass();
int Subclass = device.getDeviceSubclass();
}}
Just to answer Benny's question here is what the mPermissionIntent could look like:
string actionString = context.PackageName + ".action.USB_PERMISSION";
PendingIntent mPermissionIntent = PendingIntent.GetBroadcast(context, 0, new
Intent(actionString), 0);
mUsbManager.RequestPermission(device, permissionIntent);

Connect Android to RambO (Reprap) via USB

Hy Guys
i try to connect my Rambo Board (http://reprap.org/wiki/Rambo) with android using https://code.google.com/p/usb-serial-for-android/. The app allready starts when i plug in the usb port, but i cant open the device.
The testoutput of the vendor id and product id is right but "UsbSerialProber.acquire(mUsbManager, device);" returns null?
what can i do?
My App Works with an Arduino.
Thank you
Markus
protected void onResume() {
super.onResume();
//Markus K hinzugefügt um device zu finden
mUsbManager.getDeviceList();
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
mTitleTextView.setText(mTitleTextView.getText()+""+ deviceList.size()+"Geräte gefunden");
UsbDevice device=null;
while(deviceIterator.hasNext()){
device = deviceIterator.next();
mTitleTextView.setText(mTitleTextView.getText()+ device.getDeviceName()+" vendorid: "+device.getVendorId()+" productid"+device.getProductId());
//abfrage auf richtige vendor id!!
}
mSerialDevice = UsbSerialProber.acquire(mUsbManager, device);
mTitleTextView.setText(mTitleTextView.getText()+ "Resumed, mSerialDevice=" + mSerialDevice);
if (mSerialDevice == null) {
mTitleTextView.setText(mTitleTextView.getText()+ "No serial device.");
} else {

Reading raw mouse data on android

In my Android app, I read the values from a 3DConnexion SpaceNavigator via USB-OTG to control an AR.Drone.
Now I want to do the same with a mouse. However, Android is grabbing the mouse and presenting a mouse-cursor. When I write a device-filter with the vendor and product ID of the mouse, I do not get it like with the SpaceNavigator (strangely, both are HID -- I get no cursor with the SpaceNavigator).
Is there a way to get the raw mouse data without the cursor?
Would be perfect with stock Android. but I would also consider altering the ROM for that.
As soon as your Application claims the Mouse (as a USB HID device while being Host), Android should hide the cursor and you can read the raw data. This should work on stock android, but your device has to support USB Host mode and a USB OTG cable will be needed to connect the mouse.
Basic procedure:
enumerate devices
ask for permission to access the USB device
claim the device
read a data package from the HID endpoint
parse the X and Y position, button clicks and scroll wheel rotation from the data package
Example Code that works for me (Android 5.0):
UsbManager usbManager;
UsbDevice usbDevice;
private void connect() {
this.usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
// just get the first enumerated USB device
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
if (deviceIterator.hasNext()) {
this.usbDevice = deviceIterator.next();
}
if (usbDevice == null) {
Log.w(TAG, "no USB device found");
return;
}
// ask for permission
final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
// call method to set up device communication
Log.i(TAG, "permission granted. access mouse.");
// repeat in a different thread
transfer(device);
}
}
else {
Log.d(TAG, "permission denied for device " + device);
}
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
// TODO:
// call your method that cleans up and closes communication with the device
// usbInterface.releaseInterface();
// usbDeviceConnection.close();
}
}
}
};
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(mUsbReceiver, filter);
usbManager.requestPermission(usbDevice, mPermissionIntent);
}
private void transfer(UsbDevice device) {
int TIMEOUT = 0;
boolean forceClaim = true;
// just grab the first endpoint
UsbInterface intf = device.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
UsbDeviceConnection connection = this.usbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
byte[] bytes = new byte[endpoint.getMaxPacketSize()];
connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
// depending on mouse firmware and vendor the information you're looking for may
// be in a different order or position. For some logitech devices the following
// is true:
int x = (int) bytes[1];
int y = (int) bytes[2];
int scrollwheel = (int) bytes[3]
// call a listener, process your data ...
}

Categories

Resources