Technical details
This just scratches the surface of the very basic concepts used in Roameo, just a few words about the parts that are not visible.
Behind the scenes
Roameo's main component is the SensorService
, a background service listening to the phone state, receiving events whenever a call is incoming or initiated by yourself. The service then registers itself to the phone's sensor manager to receive information whenever the step count sensor triggers an event - i.e. when one or more steps are counted. If your phone doesn't have a step counter ..you shouldn't be able to install the app in the first place, so nothing to handle here.
Each step counter event is buffered internally by storing the current time stamp with the amount of steps counted since the last event. Once the call is finished, the actual processing is done: the buffered timestamp-counter value gets transformed into a minute-by-minute list, storing the amount of steps for each minute within the call. This list gets stored along with all the other call information into the internal SQLite database.
Database schema
To store all the information, two tables are used and mapped to the app via ActiveAndroid: on for call sessions, one for the minute-by-minute step list associated to each call session.
Call Sessions
Mapped as CallSession
, all basic call information gets stored here:
- call time stamp
- call duration
- incoming or outgoing call
- phone number (if enabled in the settings)
- steps counted
Yes, counted steps could be derived from the minute based list, but the information is static. Once a call session is recorded, it won't change, no need to calculate it in the app or database every time the value is needed.
A couple helper methods are added for easy filtering when displaying or otherwise using the data.
Minutes List
Mapped as MinuteSteps
, every minute of each call session gets an entry here with the amount of steps counted for that specific minute. And that is all there is.
If no steps were counted for a specific minute, it still gets stored with value zero. Admittedly, this wastes some space, but again, further processing is a lot more efficient if you don't have to check every time for zero values between minutes and calculate if the end of the call was already reached or was there just no movement.
A note on step counters
I haven't done extensive testing with different devices here, mostly just with two, three same devices. But I noted already here that the accuracy of the phone's step counter sensor can vary vastly. It might be related to the position of the accelerometer inside the phone, or some filtering in the driver, or then it's just physics and the way you hold the phone. Never really looked into it, just noticed very bad step count behavior in one of the devices - as in, most of them are missed.
Well, the step count sensor is mostly meant for full-time fitness tracking, so when you carry your phone most of the time in a pocket. Detecting steps from the movement and acceleration data with the phone in your pants pocket is a different story than detecting them while holding the phone to your face. Head and arms are easily absorbing a lot of the forces necessary to detect movement.
So.. this said, your experience might suck and most of your walked steps are actually lost.
Not much that can be done from app level. You might just have to step a lot harder while walking or use hands-free..
External libraries
Can't do everything from scratch, so Roameo make use of a few external libraries:
- ActiveAndroid, as already mentioned, as ORM
- Gson to export the database content as JSON
- HelloCharts to create all the charts
- Iconify to have some happy little icons here and there
- Joda-Time for date and time handling
Also, Google Play Services are used for uploading sessions to Google Fit.