I want to detect the MTP/PTP device when it plugs in the android device. I know there is one method using Intent: android.hardware.usb.action.USB_DEVICE_ATTACHED and then defining meta-data which using resource like <usb-device class="6" subclass="1" protocol="1">, but it doesn't work. The system doesn't send this intent to the registered application.
Thus, does anyone know how to do it?
Have you set the machine to act as USB host by adding into
AndroidManifest.xml:
<uses-feature android:name="android.hardware.usb.host" />
could you please specify what is the device you are using for testing?
It is very likely that your device has no PTP/MTP specific values in class, subclass and protocol for the USB device descriptor and/or interface descriptor.
See this: http://events.linuxfoundation.org/sites/events/files/slides/Media%20Transfer%20Protocol.pdf
Some devices advertise themselves as Mass Storage devices or Vendor Specific.
If that is the case the only way is to try matching the vendor id and product id of the devices you would like to support.
Here is also a list of MTP devices with their vendor id and product id: http://sourceforge.net/p/libmtp/code/ci/HEAD/tree/src/music-players.h.
Hope this helps.
Related
I would like to send data from my Windows computer to my Android Mobile.
For this, I need to activate the Accessory mode of the Android device and the USB Host mode on the Windows device.
On my Windows computer, I have a USB Composite device for the Android Mobile. This Composite USB device bundles several interfaces: Enumeration of USB Composite Devices.
Unfortunately, I can't find information how I can access the single devices of a Composite device.
I want to get a device id / path, which I can open with CreateFile to use the created HANDLE for opening a WinUsb handle with WinUsb_Initialize.
But if I try to open a Composite USB device with CreateFile, I get a ERROR_NOT_ENOUGH_MEMORY result.
I'm using this code:
_deviceHandle = CreateFile(
deviceId, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_NONE, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
... with the filename "\?\USB#VID_04E8&PID_6864#RF8NB0NMT0X#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
It's a GUID_DEVINTERFACE_USB_DEVICE device id for a Samsung Galaxy mobile with enabled USB debugging.
As the driver Windows uses ssudbus2.sys, Version 2.17.16.0 (2021-09-14) from Samsung Electronics Co. Ltd.
The app MyPhoneExplorer can access to my mobile. So it a solution without a special driver must be possible.
How can I get this device id / path of the single USB devices inside a Composite USB device?
The filename you are using represents the overall USB device; it doesn't represent any particular instance. A filename that represents interface will have something like &mi_01 right after the product name, where 1 is the 0-based interface number.
You might be able to just insert the appropriate &mi_xx string into your filename at the appropriate place and get it work. I think you'd also need to modify the GUID at the end of the string, which is the device interface GUID.
The more standard way to find the filename in code is to use the SetupAPI and the configuration manager (CM) API to iterate through all the child devices of your USB device. Look for a child whose device instance ID (retrieved with CM_Get_Device_ID) contains MI_xx where xx is the two-digit interface number you are looking for.
It takes a lot of effort to write up this code in standalone form, and test it, and debug it, so I will not be presenting you with a working code example. Instead, I encourage you to look at the working code in the get_interface_composite function of libusbp which does what you need to do:
https://github.com/pololu/libusbp/blob/759f48d/src/windows/interface_windows.c#L86
There are some more steps to get the path of that device node. And then the code that actually calls CreateFile and WinUsb_Initialize is here:
https://github.com/pololu/libusbp/blob/759f48d/src/windows/generic_handle_windows.c#L56-L77
I want to exchange (or only read) the NFC tag ID from one Android device to another but I don't know if I should use peer-to-peer mode or emulate an NFC tag with HCE.
If I use HCE, is the emulated tag ID unique?
What is the better option or is there a simpler one?
Neither P2P nor HCE will provide you a unique ID, least not on any phone I'm aware of. With P2P it's required that the ID exchanged in ATR is random. With HCE the emulated tag ID is usually set to 08h plus a random number. There may be API call to set but I'm not aware of such. But it makes a lot of sense that a phone can not be uniquely identified by just anyone reading.
How can I read the NFC ID of another Android device?
I assume you are talking about the anti-collision identifier/UID here. On the reading Android device, you can use the reader-mode API to access devices in HCE mode:
nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
public void onTagDiscovered (Tag tag) {
byte[] uid = tag.getId();
// TODO: do something with the UID ...
}
}, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
Is the emulated tag ID unique?
See Stephen's answer. Typically, neither P2P mode nor HCE should provide a unique and stable ID. However, there are some exceptions to this and the point of time when a non-stable ID changes may vary (also see this answer). It could be that:
The device has a secure element and uses the static UID of that secure element.
The device generates a new random UID whenever it is turned on, but continues to use the same UID until it is powered off.
The device generates a new random UID on every activation by an external reader device. I.e. whenever an external HF field is applied to the NFC antenna of the Android device.
Also note that some NFC devices will use randomly generated UIDs that do not start with the random-prefix 0x08.
Can I force a device to use a fixed/stable UID?
Android does not provide an API to influence the UID/anti-collision identifier, so the short answer is no. However, if rooting or creating a custom ROM is an option, there are some possibilities to change the UID and other protocol parameters:
Editing Functionality of Host Card Emulation in Android
Host-based Card Emulation with Fixed Card ID
Should you use the UID to identify (or even authenticate) a device?
No, you should definitely not do this. While you sometimes do not have much choice when you try to integrate a HCE device into some legacy system, you should definitely think about a different design.
First of all, as Stephen already wrote, if an NFC device exposes a fixed/stable identifier, this could possibly introduce a privacy issue as anyone could read and track the ID.
Second, while many systems still use these IDs to authenticate(!) cards, UIDs are not necessarily unique (particularly there are less 4-byte UIDs than cards out there) and UIDs can easily be cloned. See this answer for further details.
I am working with Alert Notification Profile (ANP) in Bluetooth Low Energy between Samsung Galaxy S3 and peripheral device.
I can not find any information related to specific UUID's ANP at Android Developer Site.
But in ANCS Specifications (iOS Developer Site), They define specific UUID's ANCS :
The Apple Notification Center Service is a primary service whose service UUID is 7905F431-B5CE-4E99-A40F-4B1E122D00D0.
I feel worry about this different, so anyone can tell me about :
What is specific UUID's ANP in Android?
P/s : From UUID in Wiki, I know this :
Anyone can create a UUID and use it to identify something with reasonable confidence that the same identifier will never be unintentionally created by anyone to identify something else.
But actually, Google Developer has not confirmed about specific UUID's ANP yet?
The basic Bluetooth is : 0000xxxx-0000-1000-8000-00805f9b34fb.
"xxxx" is Assigned Number you need replace in it, you can declared.
But the other thing, at firmware side also define that UUID for Mobile Application can communicate with Firmware.
You dont need to know the uuid of profile. You need to know the uuids of services belong to this profile. It has one services and the uuid is 00001811-0000-1000-8000-00805f9b34fb
Also yoou need to know the uuids characteristics belong to this services to get the value of them. It has 5 characteristics:
1- New Alert Category : 00002A47-0000-1000-8000-00805f9b34fb
2- New Alert : 00002A46-0000-1000-8000-00805f9b34fb
3- Supported Unread Alert Category : 00002A48-0000-1000-8000-00805f9b34fb
etc..
I guess you are trying to use the Phone to send Alert to an external device ?
If I understand correctly the bluetooth specs, https://developer.bluetooth.org/TechnologyOverview/Pages/ANS.aspx , your Phone is supposed to be turned into a peripheral, not a central to do that.
Peripheral = slave, server
central = master, client
The issue is, android phones can't be turned into peripherals (so far) https://code.google.com/p/android/issues/detail?id=59693
While it is probable that a future update fixes this, it is not an available feature yet.
Of course you could always hack your way into making it available ;-) but that'd be a dirty solution http://blog.cozybit.com/enabling-peripheral-mode-in-android-kitkat-4-4/
I have bought a new android 4.0.3 tablet- Micromax Funbook P300 to learn developing android applications.
I started with Wifi Direct, so that the tablet could be used as a remote for robotic platform.
To my disappointment the stock OS doesn't provide this function in the settings menu.
Is it possible to check if we can programatically start wifi direct feature?
If not can someone direct to some tutorials which addresses this?
Thanks.
The Android SDK contains a sample application for using the DirectWiFi mode:
WiFiDirectDemo - Wi-Fi Direct Demo
The used API itself is located in android.net.wifi.p2p
WiFi Direct should be supported by Android 4.0.3 (it has been around since Android API 14, or Android 4.0). It is possible that your tablet does not support WiFi Direct due to a hardware limitation, but I doubt it. You probably aren't seeing it in the settings because there is a custom Android skin running on the tablet that prevents you from seeing it, or maybe the WiFi Direct settings interface wasn't implemented until Android 4.1 or something.
Whatever the case, you can test it easily in the code.
First, put the proper permissions in your manifest.xml
http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html#permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.nsdchat"
...
<uses-permission
android:required="true"
android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.INTERNET"/>
...
Next, try initializing the Android WiFiP2pManager class to see if it is supported.
http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html
public void onCreate(Bundle savedInstanceState) {
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
WifiP2pManager.Channel channel = manager.initialize(this, getMainLooper(), null);
}
Where I put null, you could pass a callback to check for failure. If it works, follow the rest of the Wi-Fi Direct guide to create your app.
He's not asking for a coded program example, so much as a way to programatically switch on the technology (ie one line of code). As far as I am aware there is no way to do this. It all has to be done from within your devices settings. While some devices allow Wi-Fi Direct to be switched on, other devices treat it the same as having regular Wi-Fi enabled - have you tried this? And have you checked if the P300 even supports Wi-Fi Direct?
I am attempting to leverage the USB host capability on the Samsung Galaxy Tablet. I purchased the attachment dongle from samsung (http://www.samsung.com/us/mobile/galaxy-tab-accessories/EPL-1PL0BEGSTA). When I first connected a usb device via this dongle, I had a high power error from the Galaxy Tablet -- FYI use an externally powered USB hub and you can bipass this.
Now that the device itself is acknowledging the existance of a USB peripheral when I attach it, I attempted to use Android's android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager; library. I saw that there are two methods for recognizing a USB device, registering a broadcast receiver to listen for the intents via
IntentFilter usbIntentFilter = new IntentFilter();
usbIntentFilter.addAction("android.hardware.usb.action.USB_DEVICE_ATTACHED");
usbIntentFilter.addAction("android.hardware.usb.action.USB_DEVICE_DETACHED");
registerReceiver(mUsbReceiver,usbIntentFilter);
This is not firing any intents when I attach any devices, strange...ok. So I went on to try the next method: explicitly querying for a device list via the UsbManager -- this was accomplished as follows:
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
int count = deviceList.size();
Iterator<UsbDevice> iterator = deviceList.values().iterator();
if(iterator.hasNext()){
UsbDevice deviceVal = iterator.next();
testTxtView1.setText("set device " + deviceVal);
}
This would presumably grab the one (only one USB device currently supported per Google Documentation) USB device that is currently connected. To test this I would call the above code upon a button click and display the device results. For some reason, I am getting a device from the device list every time, whether a USB dongle is connected or not. Furthermore, the device is the same every time regardless of the USB dongle (or lack thereof). The output is as follows:
device usbDevice[mName=/dev/bus/usb/001/002,mVendorId=1256,mProductId=27033,mClass=0,mSubClass=0,mProtocol=0,mInterfaces=[Landroid.os.Parcelable;#406ff4d8]
^^ the #406ff4d8 value changes every time I query this code (I just put a single instance of it up)
I have searched everywhere and have not been able to find any similar problems or solutions that may apply to my situation. I have tried implementing google's USB examples (which is exactly what I have essentially, I ripped theirs) and am running into these problems.
I should also mention the makeup of my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.mit.ll.drm4000"
android:versionCode="1"
android:versionName="1.0">
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".DRM4000Activity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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/device_filter" />
</activity>
</application>
and device filter:
(I removed criteria on the device filter but have also tried inserting specific information about the device I am looking for...both to no avail.)
Any help regarding this problem would be much appreciated!
Another update: The device I complained about always being enumerated on the device list
device usbDevice[mName=/dev/bus/usb/001/002,mVendorId=1256,mProductId=27033,mClass=0,mSubClass=0,mProtocol=0,mInterfaces=[Landroid.os.Parcelable;#406ff4d8]
must be the android side usb port or something...because I started attaching a bunch of different devices to my code and found that (similar to this link:
USB_DEVICE_ATTACHED Intent not firing) HID devices, arduino devices..and sadly... my USB device do not appear to fire an intent or get enumerated by the USB hub. I tried with a USB flash drive and it DID enumerate it and worked...however it shows up as the SECOND device on the list, the first being the ever-present usbDevice listed above. Intents do fire with it though.
Does anyone know a workaround to making intents fire with HID devices and other USB devices except the select few android seems to do now?
SOO unfortunately it looks like the Samsung Galaxy Tablet just does not play nicely with the UsbManager and about half of the USB devices in the world. The kernel in Samsung seems to fire intents for storage devices and the like, but not for HID and other random devices (such as arduino, and my usb sensor, and HID devices as well.) It seems to be a bug in samsung kernel. Interestingly, the HID devices WORK on the tablet, but are not enumerated on the UsbManager. I have found several links of the same problem, and it seems like a kernel patch (or the acer tablet) are the only ways around this atm. hopefully samsung will fix in the future. Here is a link to a guy who did a kernel patch if rebuilding the kernel is your thing and you really need to get UsbManager working. I have not tested but plan to eventually, and will leave a comment on my thoughts.
http://forum.xda-developers.com/showthread.php?t=1233072
I am facing same problem but you can use one method deviceName(), after enumerating device you can store device name in a string using device.getdeviceName() method.
you will get exact device name appart from full information of device.
Samsung has removed the USB API from the Android Kernal
i think you should define the device you want to recognize in resource/xml/device_filter.xml.
you can referring the android api.
There may be another (nasty) reason why you can't see your HID device.
UsbHostManager.beginUsbDeviceAdded() "Called from JNI in monitorUsbHostBus() to report new USB devices". This method calls a private method isBlackListed() which will unconditionally filter out all HUB's, and HID's with subclass BOOT.
This may be the reason why you don't see HID devices when you do a getDeviceList()
If anyone has a workaround to this, I think that there are a fair amount of users out there who would appreciate see this.
I have had succesfully attached my Arduino Uno to my samsung galaxy tab 10 P7500.
If you have a problem connecting it, It is because the tablet deny permission for the usb devices that doesn't have external power.
Try to power your device externally using 5 or 3.3 Volt AC/DC Adaptor, for the first time, if you find your device attached and fire the intent, unplug the power adaptor, and your device would operate without external power, the tablet itself would give the power through USB OTG