添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I want to give the users of my application the choice to save to the internal phone memory or to an SD card. If I create a File from the user's choice, the URI (without the file name) is something like:

Internal: content:/com.android.externalstorage.documents/tree/primary%3A

SD: content:/com.android.externalstorage.documents/tree/760E-F734%3A

However, if I try to write a file to these directories using the following code I get the error java.io.IOException: No such file or directory :

File writePath = new File("content:/com.android.externalstorage.documents/tree/primary%3A")
File file = new File(writePath, fileName);
try {
    file.createNewFile();
} catch (IOException e) {
    Log.e("saveSurvey", "Failed to create file!" + e.getMessage());
    return false;

So the file would be written somewhere like this:

content:/com.android.externalstorage.documents/tree/primary%3A/[my file name]

I have declared the WRITE_EXTERNAL_STORAGE permission in the manifest, so I guess it is not a permissions issue but more of an invalid path issue.

If these are not valid file paths, how would I go about writing to the SD card? Using Environment.getExternalStorageDirectory() always writes to the internal storage of my device ('/storage/emulated/0').

You are mixing two concepts when creating the File, you are sending a content URI while it expects a file URI, more info in developer.android.com/reference/java/io/File.html The path returned from Environment.getExternalStorageDirectory() is correct, the AVD usually emulates an external storage in this path, and don't confuse SD card with external storage it can be a different source, more info in developer.android.com/reference/android/os/… – Alberto Méndez May 5, 2017 at 16:15 @AlbertoMéndez Thanks for the info. I understand that the 'external' storage could be either the SD card or the mountable device memory, but how do I write to the SD card as opposed to the device memory? – petehallw May 5, 2017 at 22:40

File works only with filesystem paths, or with file:// URIs, and you have a content:// URI here. (In addition, to create a file from a URI you would pass that as a Uri, not as a string.)

Depending on what you are trying to do with the file, DocumentFile may work for you. It is designed to provide an interface similar to File but built around the Storage Access Framework. You can obtain input and output streams for the file created that way and do some basic file operations.

The one thing that is a pain is anything involving standard Java libraries which expect a File argument, as there is no official way to get from a content:// URI to an actual File instance—apart from hacks which may cease to work after the next update, or on the one device that has not been considered.

You getting this error because the path is different in different devices.

Try to use Environment.getExternalStorageDirectory() as writePath

Keep in mind in android 6 and above you must request permission at runtime

But as I mentioned in my post, this always writes to the device internal storage and not the SD card. – petehallw May 5, 2017 at 22:37 Call a getAbsolutePath() function And checked writePath

File writePath = new File("content:/com.android.externalstorage.documents/tree/primary%3A")
if(writePath.exists() && writePath.isDirectory()) {
    //File extensions can be declared 
       File file = new File(writePath.getAbsolutePath(), fileName+ extensions);
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.