In Step 1 of bringing My StepCounter to Android I investigate the raw sensor APIs available in Android. It was extremely nice to see that it was easy to tap into the step counter and detectors by simply implementing: ISensorEventListener and register for events. In my first example I was doing this all in my Main Activity, which seems like it would be alright if I was using step counter since it would return a total count since I registered for events, but I would have no way of detecting the current day, if the phone was reset, and just how accurate this data was. So this means that I need to have a background service running so my application can constantly be receiving notifications that steps have been happening.
Services have a few ways of notifying applications that data has changed. We can either use a broadcast and a receiver to parse the data or we can create a bound service from our main activity. The latter is what we will want to do as I don’t trust the speed of the broadcast receiver compared to a nice bound service which gives our activity full access to the services properties. This is sort of what it looks like:
Luckily the Xamarin documents have great documentation on bound services so it was really easy to implement. We need to create 3 different things:
- StepServiceBinder: Is set in our activity when it requests a BoundService and gives it access to the Service
- StepServiceConnection: Our activity starts a connection which does the binding to the ServiceBinder.
- StepService: This is our service, now doing all the processing!
This code is pretty straight forward actually, which all it does is pass in a reference to the service or a reference to the activity which it wants to bind to:
Our service now is pretty powerful and doesn’t have to do anything special to become a bound service, it will just automatically bind. However one thing that I wanted to have happen was for my Main Activity to be able to get property change notifications so it knows when to update the UI when we step. So all I needed to do was have my Service implement INotifyPropertyChanged and I created a public property called StepsToday which will have an up to date count of total steps taken:
Now all I had to do was go back to my MainActivity and OnStart I will attempt to bind to my service, OnStop will unbind, and when my StepServiceBinder gets set from the StepServiceConnection I will register for PropertyChangedNotifications:
And there you have it I am now able to get property changed notifications from my background service! Now of course I will want to start this service when the Activity starts, but I will also want to start the service when the user reboots their phone so I don’t loose any information. I will need to give my app it’s only permission it required which is ReceiveBootCompleted:
Then I will go ahead and create a boot receiver which will start my service automatically:
I am all set, now just to calculate proper steps and animate the UI!
If you want to learn more about bound services please watch Nina Vyedin video from Monkey Space.