How can I let users access the internal storage directory of my app?

arlomedia picture arlomedia · Oct 27, 2014 · Viewed 36.4k times · Source

My app stores files in its internal storage directory (/Android/data/com.mycompany.myapp/files, as returned by getFilesDir()), and I would like to allow users to access those files directly from a file management app on their mobile device or the Android File Transfer desktop appplication.

The Storage Options developer guide says:

By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user).

"By default" implies that I can change the default permissions to allow users to access these files, but I can't find any documentation of how to do that. Currently the com.mycompany.myapp directory is hidden when I browse the /Android/data directory with a file management app.

I'm currently saving file data like this:

String fileName = "myfile.jpg";
String filePath = getFilesDir() + File.separator + fileName;
FileOutputStream fileStream = new FileOutputStream(filePath);
fileData.writeTo(fileStream); // fileData is a ByteArrayOutputStream
fileStream.close();

I tried setting the permissions of the individual files to world-readable, but this didn't make the directory visible:

FileOutputStream fileStream = this.app.openFileOutput(fileName, Context.MODE_WORLD_READABLE);

I also checked the documentation for the AndroidManifest file and didn't see anything there. Does anyone know how I can do this?

Answer

arlomedia picture arlomedia · Oct 27, 2014

I took a closer look at the result of getFilesDir() vs getExternalFilesDir() and found that getFilesDir() returns /data/data/[packagename]/files while getExternalFilesDir() returns /Android/data/[packagename]/files. I thought the app files I was browsing in /Android/data were the internal storage directories, but now I see that those are actually the external storage directories.

If the internal storage directories are indeed never available to regular users, I wish the documentation said that instead of saying they are not available "by default." To me at least, saying "by default" implies that the default behavior can be changed.

Anyway, I tested and confirmed that if I delete my app, files saved to the getExternalFilesDir() are deleted automatically. So that meets my need for a storage location that is clearly connected with the app (uses an app-specific directory name and is deleted with the app) but is accessible to users for occasional manual file management.

Here's a comparison that might be helpful to someone else reading this:

  • getFilesDir() - creates an app-specific directory; hidden from users; deleted with the app
  • getExternalFilesDir() - creates an app-specific directory; accessible to users; deleted with the app
  • getExternalStoragePublicDirectory() - uses a shared directory (e.g., Music); accessible to users; remains when the app is deleted