Pebble Watch Development

61
Pebble Watch Development First Glance

Transcript of Pebble Watch Development

Pebble Watch DevelopmentFirst Glance

What is Pebble?

Teaser: https://youtu.be/8d2PpY_qrVQ

Unpacking: https://www.youtube.com/watch?v=5Ajh7NFxolk

Watch types

Watch types

Watch types

Pebble DeveloperPortal

https://developer.pebble.com

● Instructions for CloudPebble and SDK

● C Language● Android and iOS SDKs● Guides, examples, blog

Emulators

New Cloud Project

Project types available:

● Pebble C SDK● Simple.js● Pebble.js (beta)

SDK versions available: 2 and 3.

Templates:

● Empty project● Minimal● ButtonClick● HelloWorld● AppMessage

Import Project

● From GitHub● From .zip

CloudPebble IDE

● Editor● Emulator● Save button

Settings

Sensors emulation

Run Build

User Settings

Cloud Build

Cloud Emulator

Controls

Controls

UI Editor - build layout code with WSIWYG

Pebble SDK (with QEMU Based emulator)

https://developer.pebble.com/sdk/install/mac/

https://developer.pebble.com/sdk/

brew install pebble/pebble-sdk/pebble-sdk

Run standalone emulator

pebble install --emulator basalt

iOS and Android SDKs

https://github.com/pebble/pebble-ios-sdk/

CocoaPods and Carthage supported

https://github.com/pebble/pebble-android-sdk/

Gradle, Maven and jar available

Development

App structure

● main() function● app_event_loop() is mandatory● init() and deinit() are optional

Window

● Window type● window_stack_push() to display

TextLayer

● Has coordinates● Need to be added to window

TextLayer formatting

WatchFace TickTimerService

Register with TickTimerService:

static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {...}

tick_timer_service_subscribe(MINUTE_UNIT, tick_handler);

Other example of plain old C

Customizations

● Add resources to appinfo.json, in array media● Use GFont for TextLayer custom fonts● Use GBitmap for BitmapLayer ● Use create_with_resource for loading resources● Use _destroy functions to free resources

Limitations

● Number of resources - 256● Max resource size - 128kB (Aplite), 256kB (Basalt and Chalk)

Worker

1 worker = 1 app

worker_launch_app()

app_launch_worker()

Worker_src

Storage API, AppWorkerMessage (send, subscribe)

Event Services

https://developer.pebble.com/docs/c/Foundation/Event_Service/

https://developer.pebble.com/guides/events-and-services/events/

Handler may listen for event, or use “peek” style to read single data from API

● AppFocusService● AccelerometerService● BatteryStateService● ConnectionService● HealthService● TickTimerService

HealthService

AppInfo.json - add ["capabilities": [ "health" ]

Publishing: Register your App

https://dev-portal.getpebble.com/

Publishing: Category

Dictation

Storage API

Limited to 4KB

persist_write_data(key, &data, sizeof(Data));

persist_read_data(key, &data, sizeof(Data));

Alternative - localStorage API in PebbleKit JS. But it’s not battery efficient

And depends on connection between Watch and Phone

Wakeups

Schedule app wakeups

Communication

PebbleKit JS

● Access to extended storage with localStorage.● Internet access using XMLHttpRequest.● Location data using geolocation.● The ability to show a configuration page to allow users to customize how the

app behaves.

AppMessage API

Bi-directional communication between phone apps and Pebble watchapps.

ACKnowledged or "NACK'ed,"

app_message_open()

APP_MESSAGE_INBOX_SIZE_MINIMUM and APP_MESSAGE_OUTBOX_SIZE_MINIMUM

app_message_inbox_size_maximum() and app_message_outbox_size_maximum()

Companion Apps

PebbleKit Android

dependencies { compile 'com.getpebble:pebblekit:3.0.0' }

PebbleDictionary dict = new PebbleDictionary();

dict.addString(AppKeyContactName, contactName);

final UUID appUuid = UUID.fromString("EC7EE5C6-8DDF-4089-AA84-C3396A11CC95");

// Send the dictionary

PebbleKit.sendDataToPebble(getApplicationContext(), appUuid, dict);

PebbleKit Android

Messages will be received on Pebble Watch in:

AppMessageInboxReceived

PebbleKit.registerReceivedDataHandler(getApplicationContext(), dataReceiver);

PebbleKit Android// Create a new receiver to get AppMessages from the C app

PebbleDataReceiver dataReceiver = new PebbleDataReceiver(appUuid) {

@Override

public void receiveData(Context context, int transaction_id,

PebbleDictionary dict) {

// A new AppMessage was received, tell Pebble

PebbleKit.sendAckToPebble(context, transaction_id);

}

};

PebbleKit Android@Override

public void receiveData(Context context, int transaction_id,

PebbleDictionary dict) {

final int AppKeyAge = 1;

// If the tuple is present...

Long ageValue = dict.getInteger(AppKeyAge);

if(ageValue != null) {

// Read the integer value

int age = ageValue.intValue();

}

}

PebbleKit Android

startAppOnPebble()

closeAppOnPebble()

registerPebbleConnectedReceiver()

registerPebbleDisconnectedReceiver()

PebbleKit iOS

NSUUID *myAppUUID =

[[NSUUID alloc] initWithUUIDString:@"226834ae-786e-4302-a52f-6e7efc9f990b"];

[PBPebbleCentral defaultCentral].appUUID = myAppUUID;

PebbleKit iOS

@interface ViewController () <PBPebbleCentralDelegate>

central = [PBPebbleCentral defaultCentral];

central.appUUID = myAppUUID;

[central run];

PebbleKit iOS

[PBPebbleCentral defaultCentral].delegate = self;

- (void)pebbleCentral:(PBPebbleCentral*)central watchDidConnect:(PBWatch*)watch isNew:(BOOL)isNew {

NSLog(@"Pebble connected: %@", [watch name]);

// Keep a reference to this watch

self.connectedWatch = watch;

}

PebbleKit iOS

[[PBPebbleCentral defaultCentral] run];

PebbleKit iOS

[self.connectedWatch appMessagesPushUpdate:update onSent:^(PBWatch *watch,

NSDictionary *update, NSError *error) {

if (!error) { NSLog(@"Successfully sent message."); }

else { NSLog(@"Error sending message: %@", error); }

}];

PebbleKit iOS

[self.connectedWatch appMessagesAddReceiveUpdateHandler:^BOOL(PBWatch *watch, NSDictionary *update) {

NSLog(@"Received message: %@", update);

// Send Ack to Pebble

return YES;

}];

Publishing App

Pebble Marketplace

Immediate, easy, no validation

Only .PBW and icon - and you are in the market

Thank you!

Constantine Mars@ConstantineMars+ConstantineMarsrx.ConstantineMarsconstantine.mars@gmail.com