2

I'm attempting to read files off of a USB drive for an Android Things app on a Raspberry Pi. I'm able to scan the list of mounted devices like so:

public static List<File> ScanForFiles(Context context){
    ArrayList<File> files = new ArrayList<>();
    try{
        BufferedReader reader = new BufferedReader(new FileReader("/proc/self/mountinfo"));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] columns = line.split(" ");
            Log.i(TAG, "Mounted: " + columns[4]);
            //files.addAll(getListFiles(new File(columns[4])));
        }
    } catch (Exception ex){
        ex.printStackTrace();
    }

    printFileInformation("/proc/partitions");

    return files;
}

private static void printFileInformation(String fileName){
    Log.i("TitanTV", "Reading contents of " + fileName);

    try{
        BufferedReader reader = new BufferedReader(new FileReader(fileName));
        String line;
        while ((line = reader.readLine()) != null){
            Log.i("TitanTV", line);
        }
    } catch (Exception ex){
        ex.printStackTrace();
    }
}

Which displays the following output:

I: Mounted: /
I: Mounted: /dev
I: Mounted: /dev
I: Mounted: /dev/pts
I: Mounted: /dev/memcg
I: Mounted: /dev/cpuctl
I: Mounted: /proc
I: Mounted: /sys
I: Mounted: /sys/fs/selinux
I: Mounted: /sys/fs/pstore
I: Mounted: /acct
I: Mounted: /mnt
I: Mounted: /mnt/runtime/default/emulated
I: Mounted: /mnt/runtime/read/emulated
I: Mounted: /mnt/runtime/write/emulated
I: Mounted: /config
I: Mounted: /data
I: Mounted: /oem
I: Mounted: /gapps
I: Mounted: /storage
I: Mounted: /storage/emulated
I: Mounted: /storage/self
I: Reading contents of /proc/partitions
I: major minor  #blocks  name
I:    1        0       8192 ram0
I:    1        1       8192 ram1
I:    1        2       8192 ram2
I:    1        3       8192 ram3
I:    1        4       8192 ram4
I:    1        5       8192 ram5
I:    1        6       8192 ram6
I:    1        7       8192 ram7
I:    1        8       8192 ram8
I:    1        9       8192 ram9
I:    1       10       8192 ram10
I:    1       11       8192 ram11
I:    1       12       8192 ram12
I:    1       13       8192 ram13
I:    1       14       8192 ram14
I:    1       15       8192 ram15
I:  179        0    7761920 mmcblk0
I:  179        1      65536 mmcblk0p1
I:  179        2       1024 mmcblk0p2
I:  179        3       1024 mmcblk0p3
I:  179        4      32768 mmcblk0p4
I:  179        5      32768 mmcblk0p5
I:  179        6     524288 mmcblk0p6
I:  179        7     524288 mmcblk0p7
I:  179        8         64 mmcblk0p8
I:  179        9         64 mmcblk0p9
I:  179       10       1024 mmcblk0p10
I:  179       11      32768 mmcblk0p11
I:  179       12      32768 mmcblk0p12
I:  179       13     262144 mmcblk0p13
I:  179       14     262144 mmcblk0p14
I:  179       15    2683736 mmcblk0p15
I:    8        0    7847935 sda
I:    8        1    7845888 sda1

However, my thumb drive isn't apart of the list. So I'm guessing I need to mount it in some way. How can I mount the thumb drive and access the files on it?

Onik
  • 19,396
  • 14
  • 68
  • 91
Chris Stillwell
  • 10,266
  • 10
  • 67
  • 77

4 Answers4

2

ADB ONLY SOLUTION

Seem like as of now USB drives aren't mounted automatically. In order to make your code work I had to mount it manually.

As you can see (from /proc/partitions) in the /proc partition the USB drive is detected as sda.

ADB mounting

  • Make a directory to mount to

    mkdir /mnt/usb
    
  • Mount the device

    mount -t vfat -o rw /dev/block/sda1 /mnt/usb
    

Now you should be able to list (and manage) the files on the USB drive both via ADB and from within the app (/mnt/usb will also be logged).

Onik
  • 19,396
  • 14
  • 68
  • 91
  • Right, up until the suggestion that you can do this from an app, which is deeply mistaken in both expectation and method - "su" cannot be "gained" as even when it works (unlikely here!) it applies only to the subprocess it runs, not the requesting process. – Chris Stratton Mar 08 '18 at 06:21
  • @Chris Stratton, _"su cannot be gained as even when it works (unlikely here!)"_ Why is that? Have you `list`ed `system/xbin` for any of versions of `Android Things`? `su` was shipped for the very 1st Developer Preview... – Onik Mar 08 '18 at 15:44
  • @Chris Stratton,_"it applies only to the subprocess it runs, not the requesting process"_ I never told it was the other way. You surely know how to read to/write from a subprocess programmatically. The task is not trivial and goes out of the scope of the question... Downvoting the answer seems to be unreasonable to me... – Onik Mar 08 '18 at 15:48
  • While you may be aware of more details, your post is misleading, and actively confusing people. – Chris Stratton Mar 08 '18 at 17:43
  • While this answer may offer a solution through adb, I think it's clear from the formulation of the OP that the author is looking for a solution to do so programmatically. To be clear: *unless you have root access on Android Things, this solution will not work*, and rooting the device is really an unrealistic approach here. – Paul Lammertsma Jun 05 '18 at 07:41
  • Paul Lammertsma, ...another downvote...you seem to be a friend of Chris Stratton... _"I think it's clear from the formulation of the OP that the author is looking for a solution to do so programmatically"_ Well, OP'd hardly agree with you. _"and rooting the device is really an unrealistic approach here"_ what is it based on? It's interesting to see how people that have some knowledge of Android internals think Android Things is backed as a regular stock phone while lots of `/system/bin` binaries of Android Things are world-executable. – Onik Jun 05 '18 at 19:24
0

I have made an script that every 10 seconds if detects a usb storage units mounts it automatically, the only problem is to launch it on Boot, maybe this could help you, I have my post here: Execute Script on Boot Android Things

And the script:

while true; do

if [ "$( ls -l /dev/block/sd* | wc -l)" -ge 1 ];

then echo "partition available"

if [ "$( mount | grep  "usbAlv" -c)" -ge 1 ]; #if partition not mounted

then echo " Unit Mounted"

else

echo "not  mounted"


//if folder where we mount the partition doesnt exist

if [ !"$( ls -l /sdcard/usbAlv | wc -l)" -ge 1 ];

then mkdir /sdcard/usbAlv

fi

su root << EOSU

mount -t vfat -o rw /dev/block/sd* /sdcard/usbAlv

EOSU

fi

else

echo "not partition available"

fi

sleep 10;

done

Hope it helps, i guess now is the only posible way to do it programatically

Chris Stillwell
  • 10,266
  • 10
  • 67
  • 77
In_va2
  • 21
  • 5
0

I think the only solution is to create a service in init.rc to be able to execute the script with root permisions on Boot. Apparently Android things doesnt have a solution right know. Something like:

on property:dev.bootcomplete=1

start bootcomplete_handler

service bootcomplete_handler /system/bin/sh /system/bin/bc_handler.sh

class late_start

user root

group root

disabled

oneshot

But dont know if this will work

D_Pablo
  • 1
  • 1
0

Working and discarded options

1. Use ADB (working)

As answerer by Onik in this post

2. Use USB API (working)

As Android API for USB allows bulkTransfer, you can code SCSI compatible commands.

You can also try existing libraries such as libaums, posted by Phaestion in response to this similar question

3. Inject shell commands at init.rc at boot.img (NOT working)

Shell commands can be injected to the init.rc file inside the boot.img (not the init.rc file that you can find in the /root directory). However, given the A-B boot nature of the AndroidThings compilation, I have been unable to make it work.

4. Add advanced app permissions (NOT working)

The following permissions seem promising to execute root commands from the app. However, permission denied error continues to block the root command execution.

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_USB" tools:ignore="ProtectedPermissions" />

I even tried to compile an AndroidThings distribution with an app with such permissions but the Android Things console does NOT allow to include the app to the compilation

5. White list the app (NOT working)

There is a white list for priviledged apps. However, this white list is placed in a priviledged directory and cannot be overwritten even from the shell command with root user

6. Install the app at a priviledged location (NOT working) Apps installed in priviledged directories can execute root commands. However, AndroidThings does NOT allow to install apps at such locations (even from the shell with root user)

  • Would you know how to use the MOUNT_UNMOUNT_FILESYSTEMS permission? I see many system permissions on the Manifest permissions, and that's cool. But I don't know how to use any unless there's someone who asked already! Do you know a normal procedure to get to know what to do with the permission? (PS: I have the app installed on system partition, so I can have the permission - just have no idea what to do with it) We call hidden APIs (which I have showing too - I can't understand how to mess with IStorageManager...) or we can directly run supposedly root commands without requesting root? – Edw590 Oct 22 '20 at 12:01