With recent advances in wearable technology, it's now possible to create novel fitness experiences without building custom hardware. In this talk we take you through creating a fitness tracker in C# on Android Wear, covering Google Play Services and watch-faces along the way. If this piques your interest, you can build your own Android Wear-based fitness tracker in our code lab!
19. CanvasWatchFaceService.Engine
UI Drawing
Manually draw onto
a Canvas Object
Ambient Mode Changes
Reduced color space
Burn protection
Redraw Intervals
Once a minute in
Ambient – OnTimeTick()
Custom for interactive
– use a System Timer
TimeZone Changes
Use a BroadcastReceiver
Interactive Watch Faces
.SetAcceptsTapEvents() in Builder
Override OnTapCommand()
20. Drawing the watch face
Background
Hour Ticks
Step Count
Minutes Hand
Seconds Hand
Hours Hand
23. var innerTickRadius = centerX - 10;
var outerTickRadius = centerX;
for (var tickIndex = 0; tickIndex < 12; tickIndex++)
{
var tickRot = (float)(tickIndex * Math.PI * 2 / 12);
var innerX = (float)Math.Sin(tickRot) * innerTickRadius;
var innerY = (float)-Math.Cos(tickRot) * innerTickRadius;
var outerX = (float)Math.Sin(tickRot) * outerTickRadius;
var outerY = (float)-Math.Cos(tickRot) * outerTickRadius;
canvas.DrawLine(centerX + innerX, centerY + innerY,
centerX + outerX, centerY + outerY, tickPaint);
}
Drawing the Watch Face - Ticks
24. var width = bounds.Width();
var height = bounds.Height();
var steps = stepCount.ToString();
var stepsWidth = stepcountPaint.MeasureText(steps);
var x = width - stepsWidth - stepCountOffset;
var y = (height + stepCountTextSize) / 2.0f;
canvas.DrawText(steps, x, y, stepcountPaint);
Drawing the Watch Face - Step Count
25. Ambient mode
Reduce color depth
Reduce number of non-black pixels
Use color for < 5% pixels
Watch face updates
once a minute -
don’t show seconds
Save power
Interactive Ambient
47. SENSORS API
Find all sensors, both on and off-device
FindDataSources (GoogleApiClient c, DataSourcesRequest r)
Register for sensor data
Add (GoogleApiClient c, SensorRequest r, IOnDataPointListener l);
Unregister for sensor data
Remove (GoogleApiClient c, IOnDataPointListener l);
48. RECORDING API
Stop recording data types/sources
Unsubscribe (GoogleApiClient c, DataType t)
Unsubscribe (GoogleApiClient c, DataSource s)
What data is being recorded
ListSubscriptions (GoogleApiClient c)
Record from data types/sources
Subscribe (GoogleApiClient c, DataType t)
Subscribe (GoogleApiClient c, DataSource s)
49. HISTORY API
Manually add data
InsertData (GoogleApiClient c, DataSet d)
Remove data
DeleteData (GoogleApiClient c, DeleteDataRequest r)
Retrieve data
void ReadData (GoogleApiClient c, DataReadRequest r)
50. SESSIONS API
Start recording a live session
void StartSession(GoogleApiClient client, Session session);
Stop recording a live session
void StopSession (GoogleApiClient client, String identifier);
Insert a session
void InsertSession (GoogleApiClient client, SessionInsertRequest request)
56. // Read step count deltas from the History API
DataReadRequest DailyStepsForWeek()
{
long midnight = TimeUtility.MidnightLocalPosix ();
long midnightWeekAgo = TimeUtility.DaysAgoPosix (midnight, 7);
return new DataReadRequest.Builder ()
.Aggregate (DataType.TypeStepCountDelta,
DataType.AggregateStepCountDelta)
.BucketByTime (1, TimeUnit.Days)
.SetTimeRange (midnightWeekAgo, midnight,
TimeUnit.Milliseconds)
.Build();
}
Data
Aggregation
Data Read Request
59. // Writing data
googleApiClient = new GoogleApiClient.Builder(context)
.AddApi(...)
.AddConnectionCallbacks(
connectionHint => { // Connected! },
cause => { // Suspended }
).Build();
Writes require
an established
connection
Writing Data