pebble/devsite/source/_guides/communication/using-the-sports-api.md
2025-02-24 18:58:29 -08:00

314 lines
No EOL
10 KiB
Markdown

---
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
title: Sports API
description: |
How to use the PebbleKit Sports API to integrate your mobile sports
app with Pebble.
guide_group: communication
order: 6
related_examples:
- title: PebbleKit Sports API Demos
- url: https://github.com/pebble-examples/pebblekit-sports-api-demo
---
Every Pebble watch has two built-in system watchapps called the Sports app, and
the Golf app. These apps are hidden from the launcher until launched via
PebbleKit Android or PebbleKit iOS.
Both are designed to be generic apps that display sports-related data in common
formats. The goal is to allow fitness and golf mobile apps to integrate with
Pebble to show the wearer data about their activity without needing to create
and maintain an additional app for Pebble. An example of a popular app that uses
this approach is the
[Runkeeper](http://apps.getpebble.com/en_US/application/52e05bd5d8561de307000039)
app.
The Sports and Golf apps are launched, closed, and controlled by PebbleKit in an
Android or iOS app, shown by example in each section below. In both cases, the
data fields that are available to be populated are different, but data is pushed
in the same way.
## Available Data Fields
### Sports
{% screenshot_viewer %}
{
"image": "/images/guides/design-and-interaction/sports.png",
"platforms": [
{"hw": "aplite", "wrapper": "steel-black"},
{"hw": "basalt", "wrapper": "time-red"},
{"hw": "chalk", "wrapper": "time-round-rosegold-14"}
]
}
{% endscreenshot_viewer %}
The sports app displays activity duration and distance which can apply to a wide
range of sports, such as cycling or running. A configurable third field is also
available that displays pace or speed, depending on the app's preference. The
Sports API also allows the app to be configured to display the labels of each
field in metric (the default) or imperial units.
The action bar is used to prompt the user to use the Select button to pause and
resume their activity session. The companion app is responsible for listening
for these events and implementing the pause/resume operation as appropriate.
### Golf
{% screenshot_viewer %}
{
"image": "/images/guides/design-and-interaction/golf.png",
"platforms": [
{"hw": "aplite", "wrapper": "steel-black"},
{"hw": "basalt", "wrapper": "time-red"},
{"hw": "chalk", "wrapper": "time-round-rosegold-14"}
]
}
{% endscreenshot_viewer %}
The Golf app is specialized to displaying data relevant to golf games, including
par and hole numbers, as well as front, mid, and rear yardage.
Similar to the Sports app, the action bar is used to allow appropriate feedback
to the companion app. In this case the actions are an 'up', 'ball' and 'down'
events which the companion should handle as appropriate.
## With PebbleKit Android
Once an Android app has set up
{% guide_link communication/using-pebblekit-android %}, the Sports and Golf apps
can be launched and customized as appropriate.
### Launching Sports and Golf
To launch one of the Sports API apps, simply call `startAppOnPebble()` and
supply the UUID from the `Constants` class:
```java
// Launch the Sports app
PebbleKit.startAppOnPebble(getApplicationContext(), Constants.SPORTS_UUID);
```
### Customizing Sports
To choose which unit type is used, construct and send a `PebbleDictionary`
containing the desired value from the `Constants` class. Either
`SPORTS_UNITS_IMPERIAL` or `SPORTS_UNITS_METRIC` can be used:
```java
PebbleDictionary dict = new PebbleDictionary();
// Display imperial units
dict.addUint8(Constants.SPORTS_UNITS_KEY, Constants.SPORTS_UNITS_IMPERIAL);
PebbleKit.sendDataToPebble(getApplicationContext(), Constants.SPORTS_UUID, dict);
```
To select between 'pace' or 'speed' as the label for the third field, construct
and send a `PebbleDictionary` similar to the example above. This can be done in
the same message as unit selection:
```java
PebbleDictionary dict = new PebbleDictionary();
// Display speed instead of pace
dict.addUint8(Constants.SPORTS_LABEL_KEY, Constants.SPORTS_DATA_SPEED);
PebbleKit.sendDataToPebble(getApplicationContext(), Constants.SPORTS_UUID, dict);
```
> Note: The Golf app does not feature any customizable fields.
### Displaying Data
Data about the current activity can be sent to either of the Sports API apps
using a `PebbleDictionary`. For example, to show a value for duration and
distance in the Sports app:
```java
PebbleDictionary dict = new PebbleDictionary();
// Show a value for duration and distance
dict.addString(Constants.SPORTS_TIME_KEY, "12:52");
dict.addString(Constants.SPORTS_DISTANCE_KEY, "23.8");
PebbleKit.sendDataToPebble(getApplicationContext(), Constants.SPORTS_UUID, dict);
```
Read the [`Constants`](/docs/pebblekit-android/com/getpebble/android/kit/Constants)
documentation to learn about all the available parameters that can be used for
customization.
### Handling Button Events
When a button event is generated from one of the Sports API apps, a message is
sent to the Android companion app, which can be processed using a
`PebbleDataReceiver`. For example, to listen for a change in the state of the
Sports app, search for `Constants.SPORTS_STATE_KEY` in the received
`PebbleDictionary`. The user is notified in the example below through the use of
an Android
[`Toast`](http://developer.android.com/guide/topics/ui/notifiers/toasts.html):
```java
// Create a receiver for when the Sports app state changes
PebbleDataReceiver reciever = new PebbleKit.PebbleDataReceiver(
Constants.SPORTS_UUID) {
@Override
public void receiveData(Context context, int id, PebbleDictionary data) {
// Always ACKnowledge the last message to prevent timeouts
PebbleKit.sendAckToPebble(getApplicationContext(), id);
// Get action and display as Toast
Long value = data.getUnsignedIntegerAsLong(Constants.SPORTS_STATE_KEY);
if(value != null) {
int state = value.intValue();
String text = (state == Constants.SPORTS_STATE_PAUSED)
? "Resumed!" : "Paused!";
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
};
// Register the receiver
PebbleKit.registerReceivedDataHandler(getApplicationContext(), receiver);
```
## With PebbleKit iOS
Once an iOS app has set up {% guide_link communication/using-pebblekit-ios %},
the Sports and Golf apps can be launched and customized as appropriate. The
companion app should set itself as a delegate of `PBPebbleCentralDelegate`, and
assign a `PBWatch` property once `watchDidConnect:` has fired. This `PBWatch`
object will then be used to manipulate the Sports API apps.
Read *Becoming a Delegate* in the
{% guide_link communication/using-pebblekit-ios %} guide to see how this is
done.
### Launching Sports and Golf
To launch one of the Sports API apps, simply call `sportsAppLaunch:` or
`golfAppLaunch:` as appropriate:
```objective-c
[self.watch sportsAppLaunch:^(PBWatch * _Nonnull watch,
NSError * _Nullable error) {
NSLog(@"Sports app was launched");
}];
```
### Customizing Sports
To choose which unit type is used, call `sportsAppSetMetric:` with the desired
`isMetric` `BOOL`:
```objective-c
BOOL isMetric = YES;
[self.watch sportsAppSetMetric:isMetric onSent:^(PBWatch * _Nonnull watch,
NSError * _Nonnull error) {
if (!error) {
NSLog(@"Successfully sent message.");
} else {
NSLog(@"Error sending message: %@", error);
}
}];
```
To select between 'pace' or 'speed' as the label for the third field, call
`sportsAppSetLabel:` with the desired `isPace` `BOOL`:
```objective-c
BOOL isPace = YES;
[self.watch sportsAppSetLabel:isPace onSent:^(PBWatch * _Nonnull watch,
NSError * _Nullable error) {
if (!error) {
NSLog(@"Successfully sent message.");
} else {
NSLog(@"Error sending message: %@", error);
}
}];
```
> Note: The Golf app does not feature any customizable fields.
### Displaying Data
Data about the current activity can be sent to either the Sports or Golf app
using `sportsAppUpdate:` or `golfAppUpdate:`. For example, to show a value for
duration and distance in the Sports app:
```objective-c
// Construct a dictionary of data
NSDictionary *update = @{ PBSportsTimeKey: @"12:34",
PBSportsDistanceKey: @"6.23" };
// Send the data to the Sports app
[self.watch sportsAppUpdate:update onSent:^(PBWatch * _Nonnull watch,
NSError * _Nullable error) {
if (!error) {
NSLog(@"Successfully sent message.");
} else {
NSLog(@"Error sending message: %@", error);
}
}];
```
Read the [`PBWatch`](/docs/pebblekit-ios/Classes/PBWatch/) documentation to learn about all
the available methods and values for customization.
### Handling Button Events
When a button event is generated from one of the Sports API apps, a message is
sent to the Android companion app, which can be processed using
`sportsAppAddReceiveUpdateHandler` and supplying a block to be run when a
message is received. For example, to listen for change in state of the Sports
app, check the value of the provided `SportsAppActivityState`:
```objective-c
// Register to get state updates from the Sports app
[self.watch sportsAppAddReceiveUpdateHandler:^BOOL(PBWatch *watch,
SportsAppActivityState state) {
// Display the new state of the watchapp
switch (state) {
case SportsAppActivityStateRunning:
NSLog(@"Watchapp now running.");
break;
case SportsAppActivityStatePaused:
NSLog(@"Watchapp now paused.");
break;
default: break;
}
// Finally
return YES;
}];
```