Is this path valid for all devices?

Asked

Viewed 57 times

2

I am developing an app. It has the function of saving image in an own folder of the app. And I am using the following code :

 File file = new File("storage/emulated/0/PastaTeste/");//PastaTeste é a pasta do app
        if(!file.exists()){
            file.mkdir();
        }
        File image = new File(file, name + ".png");
        fos = new FileOutputStream(image);
    }

My fear is that "Storage/Emulated/0 will not be valid on all devices . Have any method that gets the primary external storage?

1 answer

2


You should take the directory you want through Android methods, as it is common to change from version to version for security reasons and permission. Today, for example, from Android Q (API 29) on an app nay can directly access external folders or files to it.

The method that was used (and now is deprecated) is the getExternalStoragePublicDirectory. Follow free translation of the official notice:

This method was discontinued in API 29.

To improve user privacy, direct access to shared/external storage devices has been discontinued. When an app targets the version Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible. Applications can continue accessing content stored in shared/external storage, migrating to alternatives such as Context#getExternal), Mediastore or Intent#ACTION_OPEN_DOCUMENT.


Internal app files and directories

If you want to access a file or directory that is your app, then follow the documentation recommendation and use getExternalFilesDir(String tipo). From the version Build.VERSION_CODE.KITKAT (API 19), no read or write permissions are required in your app directory. Note that when your application is uninstalled or the user wipes data from it, the contents of that folder will be removed.

Returns absolute paths to application-specific directories on all shared/external storage devices, in which the application can place persistent files it has. These files are internal to the application and are usually not user visible as media.

If you provide a tipo not null, the returned file will be a path to a subdirectory of the specified type. Example: getExternalFilesDir(Environment.DIRECTORY_PICTURES).

So, when using the getExternalFilesDir(null), your return will be something like /storage/emulated/0/Android/data/br.com.seupacote/.

And in your code, it would be applied like this:

File file = new File(getExternalFilesDir(null), "PastaTeste");

User chooses file or directory

If you need to access an external file or directory, you can use a Intent and then the user will be able to navigate with a file manager and choose some. Note that there is a chance that the user does not have a file manager on the mobile. I’ve worked with this mode and on some phones I needed to install the Google Drive app for the user to choose a file in the cloud.

I strongly recommend reading Access Documents and other files from Shared Storage, because there are different examples and use cases.

On devices that run the Android 4.4 (API 19) and above, your app can interact with a document ombudsman, including external storage volumes and storage based on cloud, using the Storage Access Framework.

For the user to choose the file/directory, you will use a Intent. In this example, the selected file will have its content read by the app:

private final int PICK_FILE = 1;

// Chame esse método no clique de um botão, por exemplo
private void onPickFileClick() {
    Intent intent = new Intent()
            .setType("text/*") // Qualquer arquivo do tipo texto
            .setAction(Intent.ACTION_GET_CONTENT); // Leitura do conteúdo
    startActivityForResult(Intent.createChooser(intent, "Escolha um arquivo"), PICK_FILE);
}

And when the user chooses the file, onActivityResult will be called:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (requestCode == PICK_FILE && resultCode == Activity.RESULT_OK) {
        // O "resultData" contém uma URI para o arquivo
        // ou diretório que o usuário selecionou, podendo ser "null"
    }
}
  • In case , on android Q , there is no way to get external storage free? because this method accesses the folder data in android , and I wanted to directly get the external storage, as did the other method that is deprecated .

  • 1

    You can use a Intent and the user chooses the folder/file. The app itself does this is not possible for privacy reasons, as stated in Warning of the method

  • Okay, I get it . Thank you very much.

  • 1

    I added references to documentation to access external files/directories to the app. I also put the example with Intent that I used in an application of mine that was on Kotlin (then maybe there are small errors in the translation that I made to Java)

  • Another question. Can I create a folder for the app in the folder Pictures in android Q?that standard already comes in android. will be able to create a folder in there with the new android?

  • 1

    I believe that with MediaStore you get it, take a look in that question from Soen, but I never got to Mediastore to say.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.