Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 996
arlomedia Avatar asked Oct 27 '14 01:10

arlomedia


People also ask

How do I give permission to internal storage on Android?

Storage permissions Android defines two permissions related to storage: READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE . As you can see, permissions are only defined for accessing external storage. That means that every app, by default, has permissions to access its internal storage.

How do I access internal storage files?

Managing files on your Android phone With Google's Android 8.0 Oreo release, meanwhile, the file manager lives in Android's Downloads app. All you have to do is open that app and select the "Show internal storage" option in its menu to browse through your phone's full internal storage.

What can an app do with storage permission?

When an app is granted storage permission, it can access the device storage at any time. This means it can upload personal files or even delete sensitive information from the device, so it's better to think twice before giving storage permission to untrusted apps, as it can be harmful.


2 Answers

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
like image 170
arlomedia Avatar answered Sep 16 '22 21:09

arlomedia


I think you are getting confused by the developers documentation, I can't blame you, it's not the best documentation I've ever read. Anyway, Android provides two ways of saving files to the file system:

  1. Using the Internal Storage
  2. Using the External Storage

The Internal Storage is ALWAYS available and is ONLY accessible to your app, no other app in the system can access the files your app saved to this partition.

Now, I think what you need is the External Storage because it is "world-readable" and can be accessed by anyone and any any apps. The downside is that it may not be available since the user could mount it on a USB device - which can be removed by the user at anytime.

You shouldn't use neither MODE_WORLD_WRITEABLE nor MODE_WORLD_READABLE as per the documentation states, because it is very dangerous. Furthermore, these constants have been deprecated since API Level 17

Recommendation

If you need to make your files public, then save them to the External Storage. You will need to declare a permission in your manifest file to avoid your app from crashing everytime it access the External Storage...

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

because the External Storage might not be available you will need to determine the state of it before you perform any operation, otherwise your app will crash...

public enum StorageState{
  NOT_AVAILABLE, WRITEABLE, READ_ONLY
}

public StorageState getExternalStorageState() {
    StorageState result = StorageState.NOT_AVAILABLE;
    String state = Environment.getExternalStorageState();

    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return StorageState.WRITEABLE;
    }
    else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return StorageState.READ_ONLY;
    }

    return result;
}

There is more information on the documentation and things that you should be aware of. For example, you can give your app ownership of these files so that when your app is uninstalled the system can automatically delete these files. For more info please refer to the documentation on the Android Developers Site

like image 40
Leo Avatar answered Sep 20 '22 21:09

Leo