My app should save files to a place where, when you connect your phone/tablet to a computer, you can see them through the system file explorer.

This is the way I implemented file writing:

protected String mDir = Environment.DIRECTORY_DOCUMENTS;
protected File mPath = Environment.getExternalStoragePublicDirectory(mDir);

protected void writeLogFile(String filename) {
    File f = new File(mPath, filename + ".txt");
    try (BufferedWriter bw = new BufferedWriter(new FileWriter(f, false))) {

        // Details omitted.

    } catch (Exception e) {
    makeText("Wrote " + f.getAbsolutePath());

This is what I see when I connect my Sony Xperia Z4 tablet to Windows (notice missing documents folder):

This is the directory to which the file is written (using above implementation):

What is wrong with my implementation?

Solution 1

What is wrong with my implementation?

MediaStore has not discovered your newly-created files yet. What you see in Windows and in many on-device "gallery" apps is based on what MediaStore has indexed.

Use MediaScannerConnection and its scanFile() method to tell MediaStore about your file, once you have written out your data to disk:

public void scanFile(Context ctxt, File f, String mimeType) {
        .scanFile(ctxt, new String[] {f.getAbsolutePath()},
                  new String[] {mimeType}, null);

or, in Kotlin:

fun scanFile(ctxt: Context, f: File, mimeType: String) {
  MediaScannerConnection.scanFile(ctxt, arrayOf(f.getAbsolutePath()), arrayOf(mimeType), null)