简体   繁体   English

Android通过OTG电缆将文件写入USB

[英]Android write files to USB via OTG cable

I've been searching for many topics about android file writing, yet most of them wanted to write files to android internal storage. 我一直在寻找有关android文件写入的许多主题,但大多数人都希望将文件写入android内部存储。 Others who wanted to write files on external SD card didn't success at all. 其他想要在外部SD卡上写入文件的人根本没有成功。 My case is quite similar but I think that writing files to external USB is a totally different case. 我的情况非常相似,但是我认为将文件写入外部USB是完全不同的情况。

I am using Samsung galaxy Note II running stock TouchWiz 4.4.2 [not rooted]. 我使用的是三星银河Note II运行的TouchWiz 4.4.2 [未扎根]。 My phone supports micro-USB-OTG and I can mount my USB as rwxrwx--x without rooting. 我的手机支持micro-USB-OTG,我可以将USB挂载为rwxrwx--x,而无需生根。 The complete path of my USB is /storage/UsbDriveA. 我的USB的完整路径是/ 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. 我尝试使用Environment.getExternalStorageDirectory()来获取路径或直接使用路径(上述),但它们均未成功。 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. 在Android Manifest中,所以我想知道为什么我的代码无法正常工作。

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. 而且,我可以使用Root Browser(无需root用户使用)和Simple Browser将任何内容写入USB,因此,我相信有办法做到这一点。

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!!! 提前致谢!!!

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 ). 从android 4.4开始,您可以使用Storage Access Framework访问可移动媒体(请参阅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. 例如,我尝试成功将pdf文件从本地内存复制到通过OTG适配器连接的可移动内存。 The only limitation: the user has to choose a destination folder. 唯一的限制:用户必须选择目标文件夹。

1) call Intent.ACTION_CREATE_DOCUMENT: 1)调用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 2)拦截返回意图

@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 3)使用ContentResolver打开outputStream并使用它复制文件

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

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

Starting in Android 4.4, ... 从Android 4.4开始,...

The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. WRITE_EXTERNAL_STORAGE权限只能授予对设备上主要外部存储的写访问权限。 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. 因此,从具有多个外部存储的设备中的Android 4.4开始,您将只能在主要外部存储上进行写入。 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. 外部存储可以由物理介质(例如SD卡)提供,也可以通过内部存储层通过仿真层提供。

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 看看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. 我已经在我的项目中使用了它,但是正如作者所说,它离理想的解决方案还很遥远,并且不能保证它可以在即将到来的Android版本上使用,因此您一定不能让所有应用程序都依靠这种解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM