Android write files to USB via OTG cable

10,083

Solution 1

From android 4.4, you can use Storage Access Framework to access to removable media (see https://commonsware.com/blog/2014/04/09/storage-situation-removable-storage.html). For example, I tried with success to copy a pdf file from local memory to removable memory connected by OTG adapter. The only limitation: the user has to choose a destination folder.

1) call Intent.ACTION_CREATE_DOCUMENT:

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_TITLE, file.getName());
startActivityForResult(intent, REQUEST_CODE);

2) intercept the return intent

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if(requestCode == REQUEST_CODE) {
        if (resultCode != RESULT_OK) return;
        copyFile(fileToCopy, data.getData());
    }
}

3) use the ContentResolver to open the outputStream and use it to copy the file

private void copyFile(File src, Uri destUri) {
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;

    try {
        bis = new BufferedInputStream(new FileInputStream(src));
        bos = new BufferedOutputStream(getContentResolver().openOutputStream(destUri));
        byte[] buf = new byte[1024];
        bis.read(buf);
        do {
            bos.write(buf);
        } while(bis.read(buf) != -1);
    } catch (NullPointerException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bis != null) bis.close();
            if (bos != null) bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Solution 2

From https://source.android.com/devices/storage/

Starting in Android 4.4, ...

The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.

So, starting from Android 4.4 in devices with multiple external storages you will be able to write only on the primary external storage. Take into account that External Storage does not mean only "real external" devices. It is defined as follows (from the External Storage reference)

External storage can be provided by physical media (such as an SD card), or by exposing a portion of internal storage through an emulation layer.

Anyway there is a workaround to write to secondary external storage using the media content provider. Take a look at http://forum.xda-developers.com/showthread.php?t=2634840

I have used it on a project of mine, but as the author says, it's far from the ideal solution, and it is not guaranteed to work on coming Android versions, so you must not let all your app to rely on this workaround.

Share:
10,083
Admin
Author by

Admin

Updated on June 14, 2022

Comments

  • Admin
    Admin about 2 years

    I've been searching for many topics about android file writing, yet most of them wanted to write files to android internal storage. Others who wanted to write files on external SD card didn't success at all. My case is quite similar but I think that writing files to external USB is a totally different case.

    I am using Samsung galaxy Note II running stock TouchWiz 4.4.2 [not rooted]. My phone supports micro-USB-OTG and I can mount my USB as rwxrwx--x without rooting. The complete path of my USB is /storage/UsbDriveA.

    I've tried to use Environment.getExternalStorageDirectory() to get the path or use the path (mentioned above) directly but neither of them succeed. The first one returns internal storage path and the second one returns an error with "permission denied". I have already put the

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    in Android Manifest so I wondered why my code didn't work.

    Moreover, I can write anything to my USB using Root Browser (use it without root) and Simple Browser thus I believe that there's a way to do that.

    Here's my code:

    File file = new File(path.getAbsolutePath(), "test.txt");
    // File file = new File("/storage/extSdCard","test.txt");
    err = false;
      try {
        FileOutputStream f = new FileOutputStream(file);
        PrintWriter pw = new PrintWriter(f);
        pw.print(get);
        pw.flush();
        pw.close();
        f.close();
      }catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(MainActivity.this, "writing error",Toast.LENGTH_LONG).show();
                    err = true;
       }
       Log.i("File Path:", file.getPath());
    

    Thanks in advance!!!

  • Admin
    Admin over 9 years
    I've tried to use the class(xda) you mention above, but it needs android.permission.WRITE_MEDIA_STORAGE, which can only be applied in system apps. I don't want to put the app in /system 'cause it's meaningless. So I want to know if there is another way to do it? Anyway, thanks a lot.
  • rmanalo
    rmanalo about 5 years
    I tried this and it caused an error Caused by: java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/document/DCD‌​2-B740%3Afake_title.‌​pdf