Search code examples
javaandroidfile-iofile-location

How can I access a file that I have created externally? AKA where is the file?


I'm in the process of trying to create a backup/restore (export/import) process for an SQLite Database App.

Although I appear to have created and populated the file (OK I now know that I have). I cannot see the file in DDMS nor in Windows Explorer. I'd really like to be able to do the latter (see the bottom for a more specific question).

I've successfully written the file and read the file using the following code:

package mjt.sqlitetutorial;

        import android.database.Cursor; //+++++ Added
        import android.os.Build;
        import android.os.Environment;
        import android.support.v7.app.AppCompatActivity;
        import android.os.Bundle;
        import android.util.Log;        //+++++ Added

        import java.io.BufferedOutputStream;
        import java.io.BufferedReader;
        import java.io.File;
        import java.io.FileInputStream;
        import java.io.FileOutputStream;
        import java.io.FileReader;
        import java.io.IOException;
        import java.io.InputStreamReader;
        import java.io.OutputStreamWriter;



public class MainActivity extends AppCompatActivity {

    public int API_VERSION = Build.VERSION.SDK_INT;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (API_VERSION >= 23) {
            ExternalStoragePermissions.verifyStoragePermissions(this);
        }

        final String EXTSTGTAG = "EXTERNSTG";

        File file = getExternalFilesDir("File");
        Log.i(EXTSTGTAG,file.toString());
        //String extstgdirabs = Environment.getExternalStorageDirectory().getAbsolutePath();
        String extstgdirpth = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
        Log.i(EXTSTGTAG,"<=\nEXTERN STG PUB DIR=>" + extstgdirpth);
        String filepath = extstgdirpth + File.separator + "myfile.txt";
        Log.i(EXTSTGTAG,"Full File Path and name is\n\t" + filepath);

        File f = new File(filepath);
        if(!f.exists() ) {
            Log.i(EXTSTGTAG,"File did not exist (path=" + filepath + ")");
            try {
                f.createNewFile();
            }
            catch (IOException e) {
                Log.e(EXTSTGTAG,"Failure Creating New File MSG=" + e.getMessage());
            }
        }
        if(f.exists()) {
            Log.i(EXTSTGTAG,"File Already Exists (" + filepath + ")");
            try {
                Log.i(EXTSTGTAG,"Creating FileOutputStream instance.");
                FileOutputStream fos = new FileOutputStream(f);
                Log.i(EXTSTGTAG,"Creating OutputStreamWriter instance from FileOutputStream.");
                OutputStreamWriter osw = new OutputStreamWriter(fos);
                Log.i(EXTSTGTAG,"Adding Data to OutputStreamWriter.");
                osw.append("My Test Data.");

                Log.i(EXTSTGTAG,"Closing OutputStreamWriter.");
                osw.close();
                Log.i(EXTSTGTAG,"Flushing FileOutputStream.");
                fos.flush();
                Log.i(EXTSTGTAG,"Closing FileOutputStream");
                fos.close();
                Log.i(EXTSTGTAG,"All Done OK.");
            } catch (IOException e) {
                Log.e(EXTSTGTAG, "Failure Trying to write to file." + e.getMessage());
                e.printStackTrace();
            }
        } else  {
            Log.i(EXTSTGTAG,"File doesn't appear to exist when it should????");
        }
        f.setReadable(true);
        f.setWritable(true);
        if(f.exists()) {
            try {
                byte[] bytes;
                FileInputStream fis = new FileInputStream(f);
                InputStreamReader isr = new InputStreamReader(fis);
                BufferedReader br = new BufferedReader(isr);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while((line = br.readLine()) != null) {
                    sb.append(line).append("\n");
                }
                br.close();
                Log.i(EXTSTGTAG,"Read the following data:\n" + sb.toString());
            }
            catch (IOException e) {
                Log.e(EXTSTGTAG,"Failure trying to read file." + e.getMessage());
                e.printStackTrace();
            }
        }

    }
}

Output to the log (using EXTERN as the filter) shows (note the first run when installing the App run fails but requests and sets permissions. I don't believe this is an issue/cause) :-

10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: /storage/emulated/0/Android/data/mjt.sqlitetutorial/files/File
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: <=
                                              EXTERN STG PUB DIR=>/storage/emulated/0/Download
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Full File Path and name is
                                                /storage/emulated/0/Download/myfile.txt
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: File Already Exists (/storage/emulated/0/Download/myfile.txt)
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Creating FileOutputStream instance.
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Creating OutputStreamWriter instance from FileOutputStream.
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Adding Data to OutputStreamWriter.
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Closing OutputStreamWriter.
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Flushing FileOutputStream.
10-18 12:54:40.159 32393-32393/? I/EXTERNSTG: Closing FileOutputStream
10-18 12:54:40.169 32393-32393/? I/EXTERNSTG: All Done OK.
10-18 12:54:40.169 32393-32393/? I/EXTERNSTG: Read the following data:
                                              My Test Data.

The last line indicating that it has read the file (I assume). There are no other log messages during the provided messages (many before and after though).

the device that I'm testing this on is a non-rooted HTC One M8s with an SDcard. However, I believe that /storage/emulated/0/Download, the directory where the file is being written to is on the internal memory.

With DDMS I don't appear to be able to see this (the actual SD card has a Downloads directory as opposed to a Download directory).

In Windows explorer I can see both Internal Storage and SD card as devices under the HTC_0PKV1 device.

In Windows Explorer the Download directory has (via properties) 0 Directories and Files. Neither read only nor hidden are ticked.

I've tried both with and without the setReadable and setWritable().

I've just tried using the file manager on the phone and can now see the file. So more specifically, the question is; Is there any way excluding rooting the phone and moving the file via file manager on the phone, to access the file via Windows Explorer?

I should also state that the App will run on tablets, so the method should be generic rather than specific to a device.


Solution

  • The file becomes visible in Windows explorer after disconnecting and re-connecting the USB cable. I'm not sure if this how MTP is meant to work or it could perhaps be due to ADB as per this snippet:-

    However, if you’ve ever attempted to unlock your device such as to install a new ROM or root it, then you may have at one time or another installed the Android Debug Bridge (ADB) driver on your computer. This driver works great for being able to use the computer to send commands to your device, but it may mess up your easy-peasy file manipulation.

    found at How to Get Your Android Device to Show up in File Explorer (If It Isn’t)