24

I am planning to automate the testing of an application by creating a log to store some results of execution of the app and latter on parse it using a piece of python code and plot a graph.

The application is a WiFi fingerprinter i.e it collects info such as mac id, rss(recieved signal strength and rank(normalized rss) about the wifi devices in the surrounding environment. So to test this application I would have to take it to the location and record the results(as of now manually). So logcat wouldn't serve the purpose.

Automation requires 1. Storing the log in the device 2. Access to the log file in the system through usb

Format of the Log file:

Snapshot: 1
Fingerprint: 1, Rank: 0.23424, Boolean: true
Fingerprint: 2, Rank: 0.42344, Boolean: false
Fingerprint: 3, Rank: 0.23425, Boolean: true

Snapshot: 2
Fingerprint: 1, Rank: 0.75654, Boolean: false
Fingerprint: 2, Rank: 0.23456, Boolean: true
Fingerprint: 3, Rank: 0.89423, Boolean: true 

................

Now I know there are basically 3 approaches for persistent storage(SharedPrefs wouldn't suit this scenario anyway). I tried Internal Storage, but even after setting the mode of the file as MODE_WORLD_READABLE it was impossible to read the file using Device File Explorer in Eclipse.

I am still wary of using external storage for storing the log. Any tutorial on how to write to a file in usb of the device will definitely help.

I thought of structuring the data to be stored so as to use SQLite for storage. But this establishing many unnecessary relations(foreign and domestic) between data and make it complex. If there is no way around, then here be dragons.

Basically I want to write to a file(easier I suppose) in the device and latter on read it in my system by connecting to it via usb. Any help on how to do it would be much appreciated.

Community
  • 1
  • 1
Primal Pappachan
  • 25,857
  • 22
  • 67
  • 84

2 Answers2

14

Wary or not, External Storage still may be the only way to go. Without root access on the device, you can't really get at anything "Internal" unless you're going to be okay with reading within an application on the device. The docs provide pretty solid guidelines for where to create external files, and if you are using API Level 8 or higher, there are a couple of extra functions that can be used. I'm sure you know this page, but here it is anyway: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

If you're in need of any file io example code... I think I could dig some up...

EDIT - I would start by following the guidelines in the above docs to first confirm the state of the storage. I unfortunately don't have any experience with appending a file in Java, so someone else would definitely be more qualified to answer. This doesn't cover appending, but I have a backup routine in one of my personal apps that looks something like this.

    File backupPath = Environment.getExternalStorageDirectory();

    backupPath = new File(backupPath.getPath() + "/Android/data/com.maximusdev.bankrecord/files");

    if(!backupPath.exists()){
        backupPath.mkdirs();
    }

    FileOutputStream fos;
    try {
        fos = new FileOutputStream(backupPath.getPath() + "/recordsbackup.txt");

        if(okaytowrite){
            for(int i = 0; i < count; ++i){
                entry = adapter.getItem(i);
                fos.write(entry.toString().getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.dateTime).getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.sign).getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.cleared).getBytes());
                fos.write("\n".getBytes());
                fos.write(String.valueOf(entry.transDate).getBytes());
                fos.write("\n".getBytes());
                fos.write(entry.category.getBytes());
                fos.write("\n".getBytes());
            }
        }
        fos.close();

        Toast.makeText(this, "Backup Complete", Toast.LENGTH_SHORT).show();

    } catch (FileNotFoundException e) {

        e.printStackTrace();

        AlertDialog.Builder delmessagebuilder = new AlertDialog.Builder(this);

        delmessagebuilder.setCancelable(false);

        delmessagebuilder.setMessage("File Access Error");

        delmessagebuilder.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });

        delmessagebuilder.create().show();

    } catch (IOException e) {

        e.printStackTrace();

        AlertDialog.Builder delmessagebuilder = new AlertDialog.Builder(this);

        delmessagebuilder.setCancelable(false);

        delmessagebuilder.setMessage("File Access Error");

        delmessagebuilder.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });

        delmessagebuilder.create().show();
    }

Once I'm ready to write, I'm pulling a custom object (entry) out of an ArrayAdapter (adapter) and converting field valuse to strings and using getBytes() to pass to the FileOutputStream write function. I've done some research and there are quite a few other options for file writing in Java/Android... the FileWriter Class for instance, so it bears further research.

lanyusea
  • 143
  • 2
  • 14
Maximus
  • 8,351
  • 3
  • 29
  • 37
  • The file io example of writing to external storage code would help. :) – Primal Pappachan Apr 20 '11 at 07:28
  • I'll see what I can do... Java is honestly not my first language so an example of something like this in C would be more my speed. I'll try to post something in Java, but it might get flamed... all the io I do now in Java is pretty hackish at best. If anyone else would like to step in in the meantime, its surely welcomed. Specifically... I haven't done any file appending, unfortunately. – Maximus Apr 20 '11 at 14:35
  • Thanks for the interest. I read that file io for external storage is not different from that in java. So I can manage it. – Primal Pappachan Apr 20 '11 at 14:55
  • Yes, i gather that it's the same. Don't mind my iffy example then... you've probably already got something better :) – Maximus Apr 20 '11 at 15:10
  • Thank you for posting it anyway. :) – Primal Pappachan Apr 20 '11 at 15:12
13

I used a very simple approach to write String messages to the log file by creating a FileWriter object.

    public static BufferedWriter out;
        private void createFileOnDevice(Boolean append) throws IOException {
                /*
                 * Function to initially create the log file and it also writes the time of creation to file.
                 */
                File Root = Environment.getExternalStorageDirectory();
                if(Root.canWrite()){
                     File  LogFile = new File(Root, "Log.txt");
                     FileWriter LogWriter = new FileWriter(LogFile, append);
                     out = new BufferedWriter(LogWriter);
                     Date date = new Date();
                     out.write("Logged at" + String.valueOf(date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + "\n")); 
                     out.close();

            }
        }

Now the function to write a new message to the log file.

    public void writeToFile(String message){
            try {
                out.write(message+"\n");
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
Primal Pappachan
  • 25,857
  • 22
  • 67
  • 84
  • Much nicer example, will likely borrow this method myself. – Maximus Jan 13 '12 at 16:05
  • 1
    You need `out.close()` after the `out.write(...)` statement. Otherwise it won't save the write. (I figured this out the hard way.) – Randy Apr 05 '14 at 15:39
  • Once you `out.close()` the buffer, you cannot rewrite to the file any more. that is, if you `out.close()` in `createFileOnDevice`, you need to create a new `FileWriter` with the same path in `writeToFile` before the next `out.write()`. – lanyusea Aug 03 '15 at 08:28