-1

I recently started my first app (for a psychology study) and I want to create .txt files which will record the participants' answers. (but for now it's just a test file with only one line "this is a test file")

My first problem is that I can't find the file that is supposed to be created. I get no error so I suppose it is created somewhere.

I have read that the files might be in "data/data" folder, which apparently I can't access without rooting my phone (I would like to avoid that).

So my question is, how can I modify the path so the file is created in the Downloads folder or anywhere that I can access? I tried using this.getExternalFilesDir(null), Environment.getExternalStorageDirectory(), Context.getFilesDir() but I can't find my file on the local storage or on the SD card.

I did add the WRITE_EXTERNAL_STORAGE permission in the manifest but I don't know if I need to do something else. For instance, I don't know if I have to create a folder for my app (like those com.domain.app folders) of if it's supposed to do it automatically.

Thanks! I know similar questions have been posted but so far I couldn't find an answer that works for me. If I didn't mention something important, don't hesitate to point it out because my guess is I forgot something really basic.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Ensael
  • 1
  • 2
  • You can always provide a full path to create the file. On a side note: use a database to store data, not txt files. – m0skit0 Dec 12 '18 at 19:05
  • @m0skit0 Thanks, I'll look into that. Since there will not be much data, I thought txt files would have been enough and simpler. – Ensael Dec 12 '18 at 19:11
  • The duplicate should help with your `this.getExternalFilesDir(null)` and `Environment.getExternalStorageDirectory()` problems. Beyond that, you might consider providing a [mcve], and you might be interested in learning more about [external storage](https://commonsware.com/blog/2017/11/14/storage-situation-external-storage.html) and [removable storage](https://commonsware.com/blog/2017/11/15/storage-situation-removable-storage.html). – CommonsWare Dec 12 '18 at 23:12

1 Answers1

0

This does not directly answer your question but I thought it might be worth mentioning SharedPreferences, which tends to be simplest way to store application data, especially since you mentioned there won't be that much data being stored.

SharedPreferences allows you to store key/value pairs using methods like putString() and getString(). Note that modifying the shared preferences must be done on the SharedPreferences editor.

SharedPreferences sharedPrefs = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
// Save answer
// Don't forget to call apply() at the end, or commit() to block until the write is complete
sharedPrefs.edit().putString("KEY_TO_ANSWER_1", "My answer").apply();
// Read answer
sharedPrefs.getString("KEY_TO_ANSWER_1", "Default value if not found");

If you're using a good amount of these across your application it helps to keep it all together. This is a pattern I find myself using quite often:

public enum Preferences {

    INSTANCE;

    private static final String PREFS_A1 = "answer1";

    private SharedPreferences mPrefs;

    private static SharedPreferences getPrefs(Context context) {
        if (INSTANCE.mPrefs == null) {
            INSTANCE.mPrefs = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
        }
        return INSTANCE.mPrefs;
    }

    public static void setAnswer1(Context context, String answer) {
        getPrefs(context).edit().putString(PREFS_A1, answer).apply();
    }

    public static String getAnswer1(Context context) {
        getPrefs(context).getString(PREFS_A1, "No answer provided");
    }

    public static void clearAnswer1(Context context) {
        getPrefs(context).edit().remove(PREFS_A1).apply();
    }

}
Danny Buonocore
  • 3,731
  • 3
  • 24
  • 46
  • 1
    Thanks! This looks convenient but since it's for a study, multiple people will use the app (we will record data on one phone, one participant at a time). If I understand correctly, everytime someone answers a question, this would erase the answers from the previous participants? Or is it possible to create the preferences in a loop, like sharedPrefsID1, sharedPrefsID2, etc? – Ensael Dec 12 '18 at 20:00
  • Correct, this setup would overwrite the value each time. Looping them with IDs like you suggested would work, but it might be cleaner to use a StringSet. This will allow you save multiple answers to each question. Perhaps this will help: https://stackoverflow.com/questions/29195164/android-setting-and-fetching-a-stringset-from-sharedpreferences (requires API 11+) – Danny Buonocore Dec 12 '18 at 20:12
  • Another approach, though a little more work, would be to serialize a more complex object that will allow you to easily combine multiple answers, such as a JSON or even a CSV (depending on what exactly you would be storing), however at that point it might be easier just to use a SQLite database. – Danny Buonocore Dec 12 '18 at 20:14