Establish communication between two android devices using AOA protocal via USB cable - android

I am trying to connect two Android devices with API 14+ via USB OTG cable,
but I am getting null values when I was accessing two APIs like followings
mUsbManager.getDeviceList();
mUsbManager.getAccessoryList();
Please help me sharing your ideas or any example of sample apps if you have any.

Are you requesting the permission through the intent to even see what is attached?
Are you defining your own custom type and communication layer or trying to do so over adb....? More info here might be good. For now though, you need to know if you can even see the device.
This problem is somewhat defined in the AOA v2 page : https://source.android.com/devices/accessories/aoa2.html
Text copied from : http://mobilemerit.com/android-app-for-usb-host-with-source-code/
private void checkInfo() {
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
/*
* this block required if you need to communicate to USB devices it's
* take permission to device
* if you want than you can set this to which device you want to communicate
*/
// ------------------------------------------------------------------
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
// -------------------------------------------------------------------
HashMap<string , UsbDevice> deviceList = manager.getDeviceList();
Iterator<usbdevice> deviceIterator = deviceList.values().iterator();
String i = "";
while (deviceIterator.hasNext()) {
device = deviceIterator.next();
manager.requestPermission(device, mPermissionIntent);
i += "\n" + "DeviceID: " + device.getDeviceId() + "\n"
+ "DeviceName: " + device.getDeviceName() + "\n"
+ "DeviceClass: " + device.getDeviceClass() + " - "
+ "DeviceSubClass: " + device.getDeviceSubclass() + "\n"
+ "VendorID: " + device.getVendorId() + "\n"
+ "ProductID: " + device.getProductId() + "\n";
}
textInfo.setText(i);
}
private 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
}
} else {
Log.d("ERROR", "permission denied for device " + device);
}
}
}
}
};

Related

Android: bluetooth change events occur before AudioManager changes

I'm trying to detect when a bluetooth earbud or headset is turned on or turned off. The AudioManager class has these methods: isBluetoothA2dpOn() and isBluetoothScoOn() which seem to work fine with my test devices. These methods accurately return the state of the bluetooth devices.
Next I set up a BroadcastReceiver to get notified for changes in bluetooth connectivity status. Here is the code to setup the BroadcastReceiver:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); // catches bluetooth ON/OFF (the major case)
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); // catches when the actual bt device connects.
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); // does NOT catch devices connected/disconnected
registerReceiver(mBroadcastReceiver, intentFilter);
And here is the BroadcastReceiver:
mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent itt) {
String action = itt.getAction();
switch (action) {
// This just gets notified if bluetooth is turned OFF or ON.
case BluetoothAdapter.ACTION_STATE_CHANGED: {
int extraState = itt.getIntExtra(BluetoothAdapter.EXTRA_STATE, MY_ERROR_STATE);
int extraPreviousState = itt.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, MY_ERROR_STATE);
String str = " bluetooth state changed from " + extraPreviousState + " to " + extraState;
Log.d(TAG, str);
break;
}
case AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED: {
int newState = itt.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, MY_ERROR_STATE);
int prevState = itt.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, MY_ERROR_STATE);
String str = " bluetooth device updated from " + prevState + " to " + newState;
Log.d(TAG, str);
break;
}
case BluetoothDevice.ACTION_ACL_CONNECTED: {
BluetoothDevice device = itt.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String str = " connected to bluetooth device: " + device.getName() + ", " + device.describeContents();
Log.d(TAG, str);
break;
}
case BluetoothDevice.ACTION_ACL_DISCONNECTED: {
BluetoothDevice device = itt.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String str = " disconnected from bluetooth device: " + device.getName() + ", " + device.describeContents();
Log.d(TAG, str);
break;
}
}
Log.d(TAG, "bluetooth sco = " + mAudioMgr.isBluetoothScoOn());
Log.d(TAG, "bluetooth a2dp = " + mAudioMgr.isBluetoothA2dpOn());
}
};
Now the BroadcastReceiver is notified whenever there is a change in the various bluetooth and device states. For example, turning on my bluetooth earbuds causes the ACL_CONNECTED to fire (as expected), with the extra data indicating that it is now in an ON state.
But when the code hits the log statements, bluetooth a2dp will still register as turned OFF. Weird, as the code just received a noticed that it was turned on.
If I wait a few seconds, the mAudioMgr.isBluetoothxxx() will return the correct result.
Anyone have an explanation of this seemingly contradictory behavior?

USB opendevice fails even if it has permission - HostAPI is restricted

I'm trying to connect Android and Arduino UNO using the Android USB Host API.
I discover the device using an intent-filter.
I obtain the appropriate UsbInterface and UsbEndpoint. Everything seems fine until I try opening the UsbDeviceConnection, which always fails despite permissions are granted.
What's the reason?
Snippet below:
#Override
protected void onResume() {
super.onResume();
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
Intent intent = getIntent();
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
}
}
public boolean connect(UsbDevice device){
[...] // search for appropriate interfaces/endpoints
Log.i(TAG, "usbInEndpoint = " + usbInEndpoint.toString());
Log.i(TAG, "usbOutEndpoint = " + usbOutEndpoint.toString());
Log.i(TAG, "usbInterface = " + usbInterface.toString());
Log.i(TAG, "permission = " + usbManager.hasPermission(device));
usbDeviceConnection = usbManager.openDevice(device);
Log.i(TAG, "usbDeviceConnection = " + usbDeviceConnection));
[...]
}
Logcat extract below:
usbInEndpoint = UsbEndpoint[mAddress=131,mAttributes=2,mMaxPacketSize=64,mInterval=1]
usbOutEndpoint = UsbEndpoint[mAddress=4,mAttributes=2,mMaxPacketSize=64,mInterval=1]
usbInterface = UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
UsbEndpoint[mAddress=4,mAttributes=2,mMaxPacketSize=64,mInterval=1]
UsbEndpoint[mAddress=131,mAttributes=2,mMaxPacketSize=64,mInterval=1]]
permission = true
D/UsbService: openDevice(/dev/bus/usb/001/002) : HostAPI is restricted
usbDeviceConnection = null
EDIT
I edited the question and the Logcat extract because I noticed UsbService logs that "Host API is restricted" after I call opendevice, so I guess is kind of device security setting. How to check that? I'm using Samsung A8
I answer my own question hoping this would be helpful for others with same issue. This was due to my mobile being managed by a MDM.

Bluetooth discovering the same device 10 times

I'm working on a Bluetooth App with Android studio. Today, I get a weird issue.
I got 3 Bluetooth devices, a smartphone, a tablet, and another device but we don't really care about it.
I'm executing the same App on both devices but the smartphone is on Android 8.1 (API 27) and the tablet is on Android 4.0.4 (API 15).
On the smartphone, the app work well. When I scan for nearby devices, I get 4 different devices.
But there is the problem. On the tablet, when I scan for nearby devices, I got almost 10 times each devices detected by my smartphone. I don't really know why both devices are not discovering like each other. Maybe the Android version is the reason of that error.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) { // discover devices
Scanned_devices = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
scanned_deviceName = Scanned_devices.getName();
scanned_macAddress = Scanned_devices.getAddress();
mDeviceList.add(scanned_deviceName + "\n" + scanned_macAddress);
Log.i("BT", scanned_deviceName + "\n" + scanned_macAddress);
Set<BluetoothDevice> pairedDevices = blueAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
try {
if (scanned_deviceName.equals(device.getName()) || scanned_macAddress.equals(device.getAddress())) {
Toast.makeText(getApplicationContext(), "Already Paired", Toast.LENGTH_LONG).show();
mDeviceList.remove(scanned_deviceName + "\n" + scanned_macAddress);
} //else {
//mDeviceList.add(scanned_deviceName + "\n" + scanned_macAddress);
//Log.i("BT", scanned_deviceName + "\n" + scanned_macAddress);
//}
}catch(Exception e)
{
Log.d("tag", "not working");
Toast.makeText(getApplicationContext(), "not working..", Toast.LENGTH_LONG).show();
}
}
}
Scanned_devices_ListView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, mDeviceList));
}
}
};
After trying a lot of thing to detect if the device already exist in my ArrayList, I tried this code :
if (!mDeviceList.contains(scanned_deviceName + "\n" + scanned_macAddress))
{
mDeviceList.add(scanned_deviceName + "\n" + scanned_macAddress);
Log.i("BT", scanned_deviceName + "\n" + scanned_macAddress);
}
This will check if an Array contain this String :
DeviceName
DeviceMac#
If the condition is true, the String is added to the ArrayList.
If it's false (there is another String with the same contents in the ArrayList), the String isn't added to the ArrayList.

Getting UUID for a particular bluetooth device

I am using the below snippet to get the UUID for the devices that are in the range. Now i need to get only UUID's(services) for the devices that i select. How should i pass the name of the bluetooth device so that i get services for that device only.
if(BluetoothDevice.ACTION_UUID.equals(action))
{
BluetoothDevice device =intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
for (int i = 0; i < uuidExtra.length; i++) {
String abc=uuidExtra[i].toString());
}
}
else if(BluetoothDevice.ACTION_UUID.equals(action)){
Iterator<BluetoothDevice> itr = mDeviceList.iterator();
while (itr.hasNext()) {
// Get Services for paired devices
BluetoothDevice device = itr.next();
showToast("\nGetting Services for " + device.getName() + ", " + device);
if(!device.fetchUuidsWithSdp()) {
showToast("\nSDP Failed for " + device.getName());
}
}
}

Access Camera Storage via USB Host Mode on Android

I'm trying to access the SD Card on my DSLR via USB Host using my OTG cable. I believe this is through PTP. I've seen a couple of apps that could do this w/o root permission also, not only can they access it they can also control shutter speed and stuff. But I'm only interested in accessing the SD Card on the DSLR. I got stuck after connecting to the USB Device. See attached code
private void checkInfo() {
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
/*
* this block required if you need to communicate to USB devices it's
* take permission to device
* if you want than you can set this to which device you want to communicate
*/
// ------------------------------------------------------------------
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
// -------------------------------------------------------------------
HashMap<String , UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
String i = "";
while (deviceIterator.hasNext()) {
device = deviceIterator.next();
manager.requestPermission(device, mPermissionIntent);
i += "\n" + "DeviceID: " + device.getDeviceId() + "\n"
+ "DeviceName: " + device.getDeviceName() + "\n"
+ "DeviceClass: " + device.getDeviceClass() + " - "
+ "DeviceSubClass: " + device.getDeviceSubclass() + "\n"
+ "VendorID: " + device.getVendorId() + "\n"
+ "ProductID: " + device.getProductId() + "\n";
}
textInfo.setText(i);
}
Could someone please tell me how can I read then eventually download the photo from the DSLR's SD Card to my android application.
UPDATE
So I tried this library https://github.com/mjdev/libaums
Its awesome but the thing is it only supports USB Mass Storage. It wont recognise my camera storage.
Any help is appreciated.
Open connection using UsbDeviceConnection
Open MTP device using MtpDevice#open
Android's documentation uses general MTP terminology but it really only supports the PTP subset, which is good because that is the protocol you are asking about.

Categories

Resources