It seems that:
HANDLE hFind = FindFirstFile(L"mtp://phone/SDcard/music/, &ffd);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
//...
} while(FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
}
doesn't work for devices connected via MTP. Is there a WinAPI function for this?
More precisely: how to list all the filenames (+filesize and modification date) on a device connected to PC via MTP (such as Android phone), in C/C++?
Related
I was using this example with ioctl on android 4.4, 5.1
https://github.com/theicfire/simplewebcam/blob/master/jni/ImageProc.c
I am using this interface to get manual control over parameters like contrast, gain, exposure, white level and etc.
when I tried to move the app to android 7 the fd file fails to open.
fd = open (dev_name, O_RDWR | O_NONBLOCK, 0);
Is there any way to fix this?
I have checked and camera2.api doesn't allow controls over the parameters I need from the camera, and the native code fails because of this error.
edit:
to be more precise, I am using a USB camera connected to the tablet, and android 7 doesn't let met get the device FD even though I am using chmod 666 or 777 to set the permission. is there any way around it or other way to get the controls over exposure, contrast, gain, white lvl?
this is the code I added in the java part, the code fails in the canRead() part
private void InitCameraDevice() throws Exception {
//set permissions to all /dev/video devices before checking them
General.RunAsRoot("chmod 666 /dev/video*");
NativeUtils.setLogName(General.getLogFileName());
File dir = new File("/dev");
File[] videoDevFiles = dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("video");
}
});
boolean cameraFound = false;
for (File deviceFile : videoDevFiles) {
// Process file
if(deviceFile.canRead()) {
cameraFound = (NativeUtils.prepareCamera(deviceFile.getAbsolutePath(), frameWidth, frameHeight) != -1);
if (cameraFound)
break;
}
else
General.logd(STREAM_THREAD_TAG, "Insufficient permissions on [" +
deviceFile.getAbsolutePath() +"].");
}
if(!cameraFound)
throw new Exception("UVC Camera not found!");
}
Thanks for the help
You need to use the Android USB manager APIs to get the FD for your USB device; accessing the /dev node directly bypasses Android's permission enforcement (see the USB guide here) for USB device access.
Applications having access to the /dev node is therefore a security vulnerability that's locked down in more recent Android releases.
Once you have the FD for a USB device from the Java USB API, you can manipulate it in native code if you'd like.
I am trying to read the contents of a USB mass storage flash drive using this guide at android.developers. I am having a problem deciding which drive is actually the flash drive.
I am using this code to iterate through the devices:
protected override void OnResume()
{
usbManager = (UsbManager)this.GetSystemService(Context.UsbService);
monitorUsb();
}
private async void monitorUsb()
{
var deviceList = usbManager.DeviceList;
foreach (var device in deviceList.Values)
{
Debug.WriteLine("USB",device.DeviceName);
Debug.WriteLine("USB",device.DeviceProtocol.ToString());
}
await Task.Delay(30000);
monitorUsb();
}
I have two devices plugged in, a mouse and a flash drive.
The above code produces the following:
[0:] /dev/bus/usb/003/003
[0:] 0
[0:] /dev/bus/usb/003/019
[0:] 0
[0:] /dev/bus/usb/003/020
[0:] 0
By a process of elimination, 020 is the flash drive, and 019 is the mouse. I don't know what 003 is, perhaps something internal or one of the other ports (I have adb connected through onboard ethernet).
According to this documentation, the protocol of USB_CLASS_MASS_STORAGE is 8 and 0 relates to USB_CLASS_PER_INTERFACE
How can I decide in code which of the devices is the flash drive if they both return USB_CLASS_PER_INTERFACE? I have looked at the other properties of UsbDevice and none seem to return anything useful to me.
I was looking the the wrong protocol.
foreach (var device in deviceList.Values)
{
for (int i = 0; i < device.InterfaceCount; i++)
{
var deviceInterface = device.GetInterface(i) as UsbInterface;
Debug.WriteLine("USB", deviceInterface.InterfaceProtocol.ToString());
};
//Debug.WriteLine("USB", device.DeviceName);
//Debug.WriteLine("USB", device.DeviceProtocol.ToString());
}
This returns the protocol as 80 rather than 8 as the documents suggest. I cannot explain this.
I have an app that connects to a usb accessory. Simple, but the accessory stays connected even after the usb cable was unplugged.
This is my code:
public boolean checkOpenAccessory(){
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbAccessory[] accessories = usbManager.getAccessoryList();
UsbAccessory accessory;
if(accessories == null ){
accessory = null;
return false;
} else {
accessory = accessories[0];
if(usbManager.hasPermission(accessory)) {
return (usbManager.openAccessory(accessory) != null);
} else {
return false;
}
}
}
This returns me that I am connected to a usb accessory, but I am not. I have a developer app that monitors everything in the phone and says the same thing:
UsbAccessory[] accessories = usbManager.getAccessoryList();
Accessory is connected. I also tried something like triggering a broadcast or kill background processes. The phone it will show no accessories only if I restart it.
sendBroadcast(new Intent(UsbManager.ACTION_USB_ACCESSORY_DETACHED));
My problem is only a Htc One M9, Api 22, Android version 5.1 .
If you guys can help it would be a great thing, I spent a few days trying to figure it out.
I did some improvements.It works something like this.. but not 100 % sure.
boolean check = checkOpenAccessory();
And then use checkOpenAccessory() when is needed somewhere and will return the real thing.
Basically the second time will work, not 100% sure but it work.
Refer to this link.
I need to "rename" bluetooth paired device of Android phone with programming. But searching results are most discuss about local bluetooth rename method. And it could use setname() to complete. Does there have any method to rename "paired device" of Android phone ?
I know the question is old, but I just needed this and found out how to do it. It uses reflexion so I'm not sure this is the best way to go but it works.
public void renamePairDevice(BluetoothDevice device, String name)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Method m = device.getClass().getMethod("setAlias", String.class);
m.invoke(device, name);
}
I don't think you can rename the name of the paired device. You can only change the name from the paired device's settings.
Think of it like a wifi router, you cannot change the name of the router, but you can only connect to it.
However if you want,you could assign this way
Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
if (devices.size() > 0) {
for(int i=0;i<device.size();i++) {
mDevice[i] = device;
bondedDevices.add(mDevice.getName());
}
}
That way you could get the name of the paired Devices as a mDevice array. Hope it solved your issue
After reading the dot42 comments and trolling Java examples I managed to setup a Bluetooth connection but fail to open the connection. I cannot determine the problem. I followed the docs step by step.
My target device is a HTC Explorer running on 2.3 Gingerbread. Here is my code.
//Target 2.3 (Gingerbread)
[assembly: Application("dot42Application1")]
[assembly: UsesPermission(Android.Manifest.Permission.BLUETOOTH)]
[assembly: UsesPermission(Android.Manifest.Permission.BLUETOOTH_ADMIN)]
namespace dot42Application1
{
[Activity]
public class MainActivity : Activity
{
private TextView txStatus;
protected override void OnCreate(Bundle savedInstance)
{
base.OnCreate(savedInstance);
SetContentView(R.Layouts.MainLayout);
// Find UI controls
txStatus = FindViewById<TextView>(R.Ids.txStatus);
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
var bt = BluetoothAdapter.GetDefaultAdapter();
if (bt != null) //If device has not Bluetooth this will be null
{
if (bt.IsEnabled()) //Is Bluetooth device enabled?
{
var BT_My_Addr = bt.Address; //Get the devices MAC
var BT_Bonded = bt.GetBondedDevices().ToList(); //Get a list of bonded devices- I bonded to a BT2TTL Board earlier.
txStatus.Text = BT_My_Addr + System.Environment.NewLine; //Shows my MAC on screen.
string BT_Remote_Address = string.Empty;
foreach (var BTDevice in BT_Bonded) //Just searchging for string in bonded list
{
if (BTDevice.Name.Contains("linvor"))
{
BT_Remote_Address = BTDevice.Address;
}
}
//Gets remote device
var BT_Remote_Device = bt.GetRemoteDevice(BT_Remote_Address);
//Create a RFCOMM Socket to remote device using popular UUID ofr BT Serial boards
var BTsocket = BT_Remote_Device.CreateInsecureRfcommSocketToServiceRecord(Java.Util.UUID.FromString("00001101-0000-1000-8000-00805F9B34FB"));
//Call anyway to make sure there is no discvoerry in the backgorund. It slows stuff down.
bt.CancelDiscovery();
//Exception here? Dont know why :(
BTsocket.Connect();
//Suppsoed to dump 0 to 99999 to my listening serial device but I never get this far.
var BT_Out = BTsocket.GetOutputStream();
for (int i = 0; i < 99999; i++)
{
BT_Out.Write(Encoding.ASCII.GetBytes(i.ToString()));
}
}
else
{
txStatus.Text = "Bluetooth is disabled :(";
}
}
}
}
And this is what it shows after the socket creation
and the error...
What am I doing wrong? :(
I seem to have solved the problem by analysing various code snippets on the internet. I think the problem was trying to do everything in the OnCreate method. The steps I followed are the following:
Created a button on the main view (MainActivity.xml) and attached a onClick method.
Moved all the code OUT of the OnCreate method. (I think this allows the application to fully initialise.) Created an event handler for the button with two methods.
The two methods are the same as the code I posted in my original question. Just they are separated out and called when the user clicks the button.
findBT() Gets the default adapter. Checks if Bluetooth is enabled if not does the intent filter. Or if it is it will cycle through the bonded list and match a device name and store the BluetoohDevice in a variable. This is another thing that is different from my code. I do not use GetRemoteDevice I just assign the device from the BondedList to my global variable.
openBT() creates the RFCOMM socket (this did not work with unsecure - it threw an exception but using the secure method worked!)
You have to pair to the remote device using the Androids Bluetooth control panel. This code will not scan or connect to devices that are not paired. It will just throw null exceptions.
Also I left the target SDK 2.3.x but I am using the 4.x API.
-Disclosure. I am not a seasoned Android developer and just learning about the life cycle of Java applications in the Android context. I hope this can help other C# developers trying to do the same.