mr.burns
mr.burns

Reputation: 513

Android app - how to write to Android device's Documents folder?

I want to create a XML file inside my Android app. This file I want to write into the documents folder of my Android device. Later I want to connect my Android device to my PC using USB and read that XML file out of the documents folder. My Device is an Android Galaxy Tab Pro 10.1, Android 4.4.2.

I tried already:

String fileName = "example.xml";
String myDirectory = "myDirectory";

String externalStorage = Environment.getExternalStorageDirectory().getAbsolutePath();

File outputFile = new File(externalStorage + File.separator + myDirectory + File.separator + fileName);

But no file is created. I also want later to read that file out of the documents folder into may app again.

Any help is appreciated, thanks!

Upvotes: 17

Views: 41711

Answers (5)

Vivek Vashistha
Vivek Vashistha

Reputation: 1042

From Android 10 onwards, Android started using Scoped Storage model to protect user privacy. If you want to share this file with the User, then you should write this file in Shared Storage. To write a file in Shared Storage, this has to be done in 3 steps:-

Step 1: Launch System Picker to choose the destination by the user. This will return Uri of the destination directory.

private ActivityResultLauncher<Intent> launcher; // Initialise this object in Activity.onCreate()
private Uri baseDocumentTreeUri;
public void launchBaseDirectoryPicker() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        launcher.launch(intent);
 }

Step 2: Launch System Picker to choose the destination by the user. This will return the Uri of the destination directory. Also, you can optionally persist the permissions and Uri for future use.

@Override
    public void onActivityResult(ActivityResult result) {
        if (result.getResultCode() == Activity.RESULT_OK) {
            baseDocumentTreeUri = Objects.requireNonNull(result.getData()).getData();
            final int takeFlags = (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            // take persistable Uri Permission for future use
            context.getContentResolver().takePersistableUriPermission(result.getData().getData(), takeFlags);
            SharedPreferences preferences = context.getSharedPreferences("com.example.fileutility", Context.MODE_PRIVATE);
            preferences.edit().putString("filestorageuri", result.getData().getData().toString()).apply();
        } else {
            Log.e("FileUtility", "Some Error Occurred : " + result);
        }
}

Step 3: Write CSV content into a file.

public void writeFile(String fileName, String content)  {
        try {
            DocumentFile directory = DocumentFile.fromTreeUri(context, baseDocumentTreeUri);
            DocumentFile file = directory.createFile("text/*", fileName);
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(file.getUri(), "w");
            FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
            fos.write(content.getBytes());
            fos.close();
        } catch (IOException e) {
            
        }
}

For more explanation, you can read "How to Save a file in Shared Storage in Android 10 or Higher" or Android official documentation.

Upvotes: 1

TheoKanning
TheoKanning

Reputation: 1639

I know this is late, but you can get the documents directory like this:

File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
File file = new File(dir, "example.txt");

//Write to file
try (FileWriter fileWriter = new FileWriter(file)) {
fileWriter.append("Writing to file!");
} catch (IOException e) {
    //Handle exception
}

Upvotes: 24

jbr000
jbr000

Reputation: 441

Try restarting you device and then check if the file exists. If so, you are creating it (which it looks like you should be based on your code) but it is not showing up until the media is scanned on your device. Try implementing MediaScannerConnectionClient so it will show become visible after creation.

public class MainActivity extends Activity implements MediaScannerConnectionClient {

private MediaScannerConnection msConn;
private File example;

...

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...

    msConn = new MediaScannerConnection(this.getApplicationContext(), this);

    String dir = Environment.getExternalStorageDirectory() + "/Documents/";
    example = new File(dir, "example.xml");

    msConn.connect();

}

@Override
public void onMediaScannerConnected() {
    msConn.scanFile(example.getAbsolutePath(), null);
}

@Override
public void onScanCompleted(String path, Uri uri) {
    msConn.disconnect();
}       

Upvotes: 0

KrisPrajapati
KrisPrajapati

Reputation: 196

Set permission in Android Manifest

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

Use this code to write to external directory

String fileName = "example.xml";
String dirName = "MyDirectory";
String contentToWrite = "Your Content Goes Here";
File myDir = new File("sdcard", dirName);

/*if directory doesn't exist, create it*/
if(!myDir.exists())
    myDir.mkdirs(); 


File myFile = new File(myDir, fileName);

/*Write to file*/
try {
    FileWriter fileWriter = new FileWriter(myFile);
    fileWriter.append(contentToWrite);
    fileWriter.flush();
    fileWriter.close();
}
catch(IOException e){
    e.printStackTrace();
}

Upvotes: 7

VikasGoyal
VikasGoyal

Reputation: 3376

Before creating file you have to create directory in which you are saving the file. Try like this one:- String fileName = "example.xml"; String myDirectory = "myDirectory";

String externalStorage = Environment.getExternalStorageDirectory().getAbsolutePath();

File outputDirectory = new File(externalStorage + File.separator + myDirectory );

if(!outputDirectory.exist()){
    outputDirectory.mkDir();
}

File outputFile = new File(externalStorage + File.separator + myDirectory + File.separator + fileName);

outputFile.createFile();

Upvotes: 0

Related Questions