If you read my previous article on accessing sensor data in your Android app, your also probably curious about how you can analyze that data outside of the app. Perhaps you want to look for patterns in the data or track historical changes in a third party app. Whatever your reason is, its clear that you’ll need to save your sensor data off and access it in a tool like Excel.
The built in storage on an Android device is divided into two categories. Internal storage consists of app-specific directories that are commonly encrypted to prevent unwanted access by other apps. In other words, the internal storage is read-write accessible to only the owning app. External storage, on the other hand, consists of directories used to save files that may be used by all apps (think photos, videos, and other media). Due to this functional difference, the space allocated for an app’s internal storage is typically much smaller than the space allocated for external storage.
In this article, I’ll walk you through saving this data to the internal storage on your phone.
Where is it?
Despite the summary above, the Android docs never actually define the term “internal storage”. Perhaps worse is the fact that they don’t clearly state where the internal storage is in the file explorer. Fear not. Internal storage is HERE:
Ideally, you’d think the context method getFilesDir() would find this location. That’s not always the case and you’ll frequently encounter a path like “/data/user/0/com.example.appname” that can’t be found in the file tree. This is because the getFilesDir() method actually returns an abstract file path that will change based on the storage system. With this said, you can get the system specific file path by appending getCanonicalFile() to the filesDir call.
Once you have the full path, it’s a breeze finding your files in the Device File Explorer in Android Studio (View -> Tool Windows -> Device File Explorer).
As stated in the reference docs, the calling app does not need any additional permissions to access the returned path.
How do you save a new file?
Now that you can verify files exist, we need to go through the actual process of saving. This can be done using a context’s openFileOutput method which opens (or creates) a file for writing. As you may have guessed, the file is located at the canonical path from above. The Android code snippet is here.
In the example below, the filename variable is a single word (“testfile”, in my example). You do NOT need to include the full path and if you do you’ll get a File contains a path separator error.
Clicking the button saves a file to my device’s internal storage
If you are writing data to a file once, then the above method will suit you fine. The write method of the FileOutputStream will overwrite whatever file is at the specified location. If you want to append data to the file, you’ll need to change the second parameter of the openFileOutput method from Context.MODE_PRIVATE to Context.MODE_APPEND.
Doing this alone won’t be perfect, though. The output will be a string of letters without spaces or new lines. You can alter the output by adding the following modifiers to your string outputs (including the backslashes):
\n — new line \t — tab
Using the MODE_APPEND parameter will work fine even if the file does not exist yet.
How do you read an existing file?
By using a bufferedReader, you can read the file line by line and manipulate those lines individually. Folding is only necessary if you want to manipulate the entire file in a consistent way.
Now that you can use and save sensor data, you’re well on your way to doing some cool things with the device that 99% of the population carries with them.
In my next article, I will be exploring how to stream sensor data to a PC using bluetooth. This would remove the need to constantly plug your device in to pull files from it. Stay tuned!