Copy files from android to USB drive? - android

Can not find good solution of how to copy files from android device to USB drive. I know that android has API's for that since 3.1 version. However docs are not very clear, where I can use that APIs. Is there someone who has experience on this area? I registered broadcast receiver and after allowing usb connection to app, just wanted to transfer some bytes to USB storage like below:
Set<String> devices = mUsbManager.getDeviceList().keySet();
Object[] array = devices.toArray();
String text = array[0].toString();
byte [] s="hello".getBytes();
UsbDeviceConnection connection=mUsbManager.openDevice(mUsbManager.getDeviceList().get(text));
UsbEndpoint usbEndpoint=mUsbManager.getDeviceList().get(text).getInterface(0).getEndpoint(0);
connection.bulkTransfer(usbEndpoint,s,s.length,10000);
However, I did not get what I expect. Could someone help, please?
Thanks in advance

Found solution on this link: https://github.com/mjdev/libaums. You need to write your file system to interact with the usb drive

Related

data from android studio to matlab via bluetooth

I am new to android studios and I have the task to develop an app which transfers data from an app (Acceleration sensor data - i have created this app already which shows the data) to matlab (on the pc).
I don't really know how I should do this. I've experimented a bit with bluetooth apps, but I don't have a clue how to connect to Matlab.
I would be greatful for your help.
Thanks in advance,
Annika
Unfortunately I can not speak to the android side of things, but MatLab can connect to generic devices with the UART interface, which is fairly low level.
The process with some microprocessors that I am using is to connect the device to the PC, and then note the Outgoing com port.
(In windows 10, these can be found in Bluetooth settings -> More Bluetooth options)
Then you can use
s = serial('COM<what you found in settings>');
s.Baudrate=115200;
s.InputBufferSize = 100;
fopen(s{i});
serials = instrfindall;
to open an connection. The critical command is serial, the other parameters depend on your device/ configuration. Sometimes there can be issues, in which case one options is to build a loop that tries again until it works.
You then collect the data sent via UART via
flushinput(serials);
temp = fscanf(serials,'%s');
and then split the string. If data is sent continuously, you wrap this into a while loop.
After you are done, you can clean up via
fclose(s{i});
delete(instrfind)
instrreset
It should be noted, that establishing a connection takes longer, the more enabled COM ports there are. So it might be worth disabling all those you don't need.
For more specific things matlab can do, check out What Is the MATLAB Serial Port Interface

How can I retrieve an SD card's serial number in Android 7.0+?

N.B.: This question about the serial number of the physical SD card, not the UUID of the mounted volume. These are two independent pieces of data.
In some versions of Android, and other variants of Linux, it's possible to get the serial number of a mounted SD card, e.g. by reading the contents of /sys/class/mmc_host/mmc0/mmc0:0001/serial or /sys/block/mmcblk0/device/serial (specific numbers may vary). In my testing this has worked pretty reliably, as long as the SD card is inserted in a built-in SD card slot (not mounted via USB adapter).
But as of Android 7.0 Nougat, the OS is said to be blocking access to this information, at least on some devices. I tested this by running a test app on a new Alcatel A30 GSM (Android 7.0), and in fact the above approach fails with a permission error:
java.io.FileNotFoundException: /sys/block/mmcblk0/device/serial (Permission denied)
at java.io.FileInputStream.open(Native Method)
For future reference, we (testing from an adb shell) have permissions to ls -ld the following:
/sys/class/mmc_host but not /sys/class/mmc_host/mmc0
/sys/block but not /sys/block/mmcblk0
Since the above approach no longer works,
Is there another way to obtain the serial number of a mounted SD card in Android 7.0 or later?
Failing that, is there any documentation or other statement from Google on plans for providing or not providing this function? I haven't found anything in the Android issue tracker, but maybe I'm not searching right.
To make sure the question is clear, I'm talking about what an ordinary (non-system) app running on a non-rooted device can do, with any permissions that an app can normally request and receive.
FYI, the /sbin directory doesn't seem to be readable, so commands like /sbin/udevadm aren't an option.
In Android N access to /sys nad /proc was significantly restricted, this was done to provide stricter sandboxes where applications run. This is explained in https://issuetracker.google.com/issues/37091475 as intentional. Actually its not said that all the data in /sys is not accessible, and Google is open to allow access to other files from this location:
If there are specific files in /sys you believe should be available to applications, but are not, please file a new bug where the request can be evaluated. For instance, /sys/devices/system/cpu is available to all processes, so it's inaccurate to say all of /sys is restricted.
I have a bad feeling that google is making changes similar to Apple where it is not allowed to gain hardware id-s. If that is not resolved then the solution is to use google account IDs instead. But I am aware it is not always possible, and will require major changes in business logic (licensing etc.).
Hopefully your bug report will be considered positively.
another related SO I found : File system changes in Android Nougat
Use StorageVolume.getUuid() on StorageVolume which you get from StorageManager.
The value is volume ID assigned during formatting of the card, and its length/format differs depending on file system type. For FAT32 it is XXXX-XXXX, for NTFS it's longer hex string, for Internal mass storage it returns null.
public String getSDCARDiD()
{
String sd_cid = null;
try {
File file = new File("/sys/block/mmcblk1");
String memBlk;
if (file.exists() && file.isDirectory()) {
memBlk = "mmcblk1";
} else {
//System.out.println("not a directory");
memBlk = "mmcblk0";
}
Process cmd = Runtime.getRuntime().exec("cat /sys/block/"+memBlk+"/device/cid");
BufferedReader br = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
sd_cid = br.readLine();
//System.out.println(sd_cid);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sd_cid;
}
try this: reference original link :Android get id of SD Card programmatically
adb shell cat /sys/class/mmc_host/mmc1/mmc1:*/cid
You can also try
sudo hwinfo --disk
to get information on your disks, including SD Cards.
Also try
sudo hdparm -I /dev/sdb | more
As an FYI to those looking into UUID or volume serial numbers of FAT type volumes under Android: Some Fujifilm cameras, including the X-T30 (Firmware 1.10) do not write a volume serial number into the FAT volume when formatting.
Under Windows, CHKDSK displays no volume serial number at all.
On Android, calling StorageVolume.getUuid() returns "0000-0000".
This is all fine and dandy, until you on Android mount two Fujifilm-formatted cards via a hub. Then there seems to be identity collision, where the Android OS prompts the user to format one of the cards. Separately they are accessible.
I'm guessing there are two combined problems here:
1) Fujifilm is not writing a volume serial number when formatting, and
2) Android uses the volume serial number as part of the mount point path, leading to collision.
Fujifilm and Google might both want to pay attention to this issue.
EDIT: Card formatted in a Nikon D810 also has the same problem, no Volume Serial Number.

How can I read files from usb device on android?

I'm trying to create something like file explorer through connected usb devices(via OTG or usb ports on android TV).
All I need for this is a path something like "/storage/sda4" and device identifier, and then I can work with device through simle android class File. Is sounds simple but I can't find any info about this, but all file explorers can do it (for example ESExplorer).
Ok, I find a simple way to get all connected usb devices with identifier
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
usbManager.getDeviceList();
but how can I get an info about path? deviceName contains something like this "/dev/bus/usb/00x" but it can't help me, I need simple emulated android path ("/storage/sda4"). This page https://developer.android.com/guide/topics/connectivity/usb/host.html tells that I need to get UsbInterfaces and make UsbConnection to bulk transfer and other bullshit, I done it all but didn't find path to device or any other info about usb file list.
Ok, I find another way to get (that don't requires permission!) to get path to all connected devices
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
Method getVolumeListMethod = StorageManager.class.getDeclaredMethod("getVolumeList");
Object[] storageVolumeList = (Object[]) getVolumeListMethod.invoke(storageManager);
and it works but I need to identify a device(because I want to cache files of different usb storages) but all that I can get from volume object is mStorageId, mDescriptionId, mPrimary, mRemovable, mEmulated, mMtpReserveSpace, mAllowMassStorage, mMaxFileSize, mOwner, mUuid, mUserLabel, mState, mSubSystem.
None of this can not identify the device: mDescriptionId and mStorageId are
unique fot usb port, mUuid is null, mUserLabel is not unique.
Environment.getExternalFilesDirs() won't help, it don't provide any device id and works only with one device.
I find a similar question here, but it has no right answer Android list files from USB Drive.
Well, is a simple way to get list of usb devices with path and identifier exists?
All I need for this is a path something like "/storage/sda4" and device identifier, and then I can work with device through simle android class File
No, because you do not have arbitrary access to removable storage, including USB OTG drives, on Android 4.4+.
all file explorers can do it (for example ESExplorer)
Pre-installed "file explorer" apps may have additional rights granted to them by the device manufacturer or custom ROM developer. Otherwise, they too do not have arbitrary access to removable storage.
is a simple way to get list of usb devices with path and identifier exists?
Not with a filesystem path, no. getStorageVolumes() on StorageManager will give you a list of storage volumes, which includes external storage and removable storage. You can then use createAccessIntent() on StorageVolume to ask the user for permission to work with the volume. If they grant permission, you get a Uri back that:
Serves as a temporary identifier for the volume (i.e., will no longer be usable as an identifier if the user ejects the media, but until then, can distinguish one volume from another), and
Lets you work with a portion of the contents of that volume, though using Uri values, not filesystem paths

Android transfer sqlite database to USB flash drive from sdcard programatically

I have a custom built Android device which is Single Board Computer with a display unit. It has Android 4.1 installed on it and has a USB port. Within an app I created an sqlite database. I want to transfer the database to a usb flash drive using the aforementioned USB port. I understand Android documentation enough to be able to establish a connection between USB host and Accessory. I am able to detect my flash drive using an intent filter.
The following is a code snippet to transfer a byte array using USB classes.
private Byte[] bytes
private static int TIMEOUT = 0;
private boolean forceClaim = true;
...
UsbInterface intf = device.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
UsbDeviceConnection connection = mUsbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
Here a bytearray is transferred using the USB interface. I want to be able to transfer an sqlite database using the same. Is that possible? How can I do it?
As is documented in several other questions here, Android APIs support only raw transfers, so you would have to implement an entire filesystem in your app.
Since your device is custom, you would be better off creating a Linux-level daemon or (bulletproof!) setuid tool to mount the USB drive at operating system level, and leverage the filesystem code already present in the Lunux kernel. Then you can simply perform normal file operations to it. You might even be able to modify Android's vold to do this - because you control the Android install, you have this class of options which a typical 3rd party developer targeting locked down phones does not.

Is there a way to exclude my Android proxy app from the Data Usage screen?

I have a system app that sets a forwarding proxy inside android devices. The problem is that since all traffic is redirected to that app, the Data usage screen under settings shows as if all traffic is coming from my app and not other apps.
Reading this: https://source.android.com/devices/tech/datausage/index.html helped me understand that you cannot exclude an app from the data usage unless it is built with the system image. (However, VPNService is able to exclude itself from data usage, so if I could find a hack to do this, it would work for me).
When looking at the android system file /proc/net/xt_qtaguid/ctrl it clearly shows that all socket connections are being tagged with my app's uid.
I looked at qtaguid.c (https://github.com/cgjones/android-system-core/blob/master/libcutils/qtaguid.c) and tried to implement the same mechanism but the problem is that I can't even get the file descriptor from my socketChannel. Since android uses SocketChannelImpl, I tried to use reflection to get the fd, but this did not work:
clientChannel = server.accept();
Class<?> clientChannelImpl = Class.forName("java.nio.SocketChannelImpl");
Method method = clientChannelImpl.getDeclaredMethod("getFD", new Class<?>[0]);
FileDescriptor fd = (FileDescriptor) method.invoke(clientChannel, null);
Class fileDescriptorClass = FileDescriptor.class;
Field field = fileDescriptorClass.getDeclaredField("fd");
field.setAccessible(true);
I guess even if this worked, I have no idea how the TAG is generated so that I can switch it out with every connection. I know the last 4 bytes of this tag is the uid of the app creating the socket in hex, but thats about it.
Is any of this even possible? Thank you!
I guess it's too late, but anyway.
You should tag client socket, the one you use to establish a remote connection, and not a server socket.

Categories

Resources