Access Camera Storage via USB Host Mode on Android - 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.

Related

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.

How to get name of the connected Bluetooth device on android

I'm trying to get the name of the device that is connected to the Android phone running android Oreo.
I was searching for an answer for the past two days, and none of them worked. suggestions mostly returning ioexception-read-failed-socket-might-closed-bluetooth error
The question is, is there any way to make Query that returns the connected Bluetooth device?
These are the links and suggestion which not working:
IOException: read failed, socket might closed - Bluetooth on Android 4.3
In Android, how to get the profile of a connected bluetooth device?
list connected bluetooth devices?
I can get information about the device that is previously paired and trying to make a connection or a device trying to pair to the device. what I want is the name or the connection state of the currently paired and connected device.
here is the answer :
String name;
String address;
String threadName;
public void checkConnected()
{
BluetoothAdapter.getDefaultAdapter().getProfileProxy(this, serviceListener, BluetoothProfile.HEADSET);
}
private BluetoothProfile.ServiceListener serviceListener = new BluetoothProfile.ServiceListener()
{
#Override
public void onServiceDisconnected(int profile)
{
}
#Override
public void onServiceConnected(int profile, BluetoothProfile proxy)
{
for (BluetoothDevice device : proxy.getConnectedDevices())
{
name = device.getName();
address = device.getAddress();
threadName = Thread.currentThread().getName();
Toast.makeText(MainActivity.this, name+" " + address+ threadName, Toast.LENGTH_SHORT).show();
txtName.setText(name + " " + address);
Log.i("onServiceConnected", "|" + device.getName() + " | " + device.getAddress() + " | " + proxy.getConnectionState(device) + "(connected = "
+ BluetoothProfile.STATE_CONNECTED + ")");
}
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(profile, proxy);
}
};
Have you tried this?
BluetoothServerSocket bluetoothServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord("abc", uuid);
BluetoothSocket bluetoothSocket = bluetoothServerSocket.accept();
BluetoothDevice device = bluetoothSocket.getRemoteDevice();
String deviceName = device.getName();

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

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);
}
}
}
}
};

Android wifimanager always returns true

This is killing me and any help would be greatly appreciated.
I want to connect to an open network using wifi manager. The problem I am having is that the code claims connection to any network - even non-existing ones. Below is the entire code that gets executed and gets called with the SSID of a network. It does not matter what string you pass to it as the SSID of a network, even if no such network exists in any shape or form, the enableNetwork claims returns true, which I believe means it connected to the network.
What I need to do is to make sure I have a connection. So if I pass a network SSID that does not exist (for example, it is out of range) the API should return a failure when attempting to connect.
Any ideas/hints/suggestions would be greatly appreciated.
public boolean conto (String network){
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configs = null;
int inetId = -1;
// make sure there are no funny stuff in the config
configs = wifi.getConfiguredNetworks();
for (WifiConfiguration config : configs) {
wifi.removeNetwork(config.networkId);
Log.d("********", "Removed Network: SSID=[" + config.SSID + "] and ID=[" + config.networkId + "]");
}
// Now add the network
wifiConfiguration.SSID = "\"" + network + "\"";
wifiConfiguration.hiddenSSID = false;
//wifiConfiguration.priority = 1;
//wifiConfiguration.networkId = 999;
inetId = wifi.addNetwork(wifiConfiguration);
if(inetId < 0) {
Log.d("********", "Could Not Add Network......... [" + wifiConfiguration.SSID + "]");
}
else {
Log.d("********", "Added Network......... [" + wifiConfiguration.SSID + "]");
// Lets be paranoid and double check the config file
Log.d("********", " +++++++++++++++++++++++++ This is what I have in Config File");
configs = wifi.getConfiguredNetworks();
for (WifiConfiguration config : configs) {
Log.d("********", "In the Config file after add, SSID=[" + config.SSID + "], ID=[" + config.networkId + "]");
}
// Now Enable the network
boolean successConnected = wifi.enableNetwork(inetId, true);
//boolean successAssociated = wifi.reassociate(); This did not change the results
if(successConnected) {
Log.d("********", "Connected to......... [" + inetId + "]");
}
else {
Log.d("********", "Could Not Connect to......... [" + inetId + "]");
}
}
return false;
}
I think the problem is that your code is based on the assumption that connecting to a WiFi network is a synchronous process, which it is not. The method enableNetwork() does not block while the connection occurs and then return the resulting success or failure of the connection, it returns immediately and the result is simply whether the request properly reached the WiFi service and the supplicant.
If you want visibility into what is going on with the connection status of the device, you need to monitor the WifiManager. SUPPLICANT_STATE_CHANGED_ACTION and WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION broadcast Intent actions with a BroadcastReceiver. Once you initiate the connection process, these callbacks will tell you how things progress. For example, if you pass in a network that doesn't exist, the connection status should almost immediately go straight to DISCONNECTED. While a valid network will go through the process of associating, authenticating, and connecting. All these steps are enumerated through these broadcasts.

Categories

Resources