Upgrade to Pro — share decks privately, control downloads, hide ads and more …

It's Time to Develop a Watch Face

jbarr21
April 10, 2015

It's Time to Develop a Watch Face

How can you fit time, weather, wind, precipitation, and sunlight onto a functional small screen?

The Watch Face API is an exciting way to build customized experiences for wearables. This talk shares pro-tips and lessons learned during the development of the Specialized Bikes Watch Face featured in Google’s watch face collection.

First, the basics; an overview of the API, design considerations, and some common tasks. Next, a guided tour through watch face development dropping practical advice you can use for your own watch face implementations. At the end, we'll go over some optimizations and performance tuning.

jbarr21

April 10, 2015
Tweet

More Decks by jbarr21

Other Decks in Technology

Transcript

  1. It's%Time%to%Develop%a%Watch%Face
    James&Barr
    @jbarr21
    Two&Toasters

    View Slide

  2. What%is%a%Watch%Face?

    View Slide

  3. Watch&Face&Shapes

    View Slide

  4. Watch&Face&Modes

    View Slide

  5. Watch&Face&Device&Proper0es

    View Slide

  6. Watch&Face&System&Objects

    View Slide

  7. Extra&Watch&Face&Data

    View Slide

  8. User%Customiza.on

    View Slide

  9. Watch&Face&API&Overview
    • Provides*base*WatchFaceService*class
    • Has*Canvas*or*OpenGL*ES*2.0*variants
    • Callbacks*for*lifecycle*events,*mode*changes,*&*info
    • Provides*mechanism*for*launching*seEngs*acFvies
    • Packaged*like*a*regular*Wear*app

    View Slide

  10. Watch&Face&Project&Setup
    • Wear&module
    • Mobile&module
    • Common&module

    View Slide

  11. Wear%Module%Setup
    • Add$Gradle$dependencies
    • Set$minSdk$to$API$21
    • Add$permissions$
    • Add$uses$features
    • Declare$service$in$manifest$with$metadata

    View Slide

  12. Watch&Face&Service&Declara/on

    View Slide

  13. Watch&Face&Service&Metadata

    View Slide

  14. Wear%Se'ngs%Screen%Declara.on
    • Add$ac'vity$for$wearable$se4ngs$screen

    View Slide

  15. Mobile'Module'Setup
    • Add$dependencies$and$set$minSdk$to$18
    • Add$mobile$and$wear$permissions

    View Slide

  16. Common%Module%Setup
    • Op$onal,*but*highly*recommended
    • Should*contain*shared*data*such*as:
    • DataMap*&*message*paths
    • U$li$es*for*working*with*DataMap
    • Shared*data*models
    • Shared*image*and*string*resources
    • Bundle*key*names*and*default*seBng*values

    View Slide

  17. CanvasWatchFaceService
    • Provides*an*invalida.on*mechanism*for*drawing*the*watch*face
    • Override*onCreateEngine()*to*return*your*
    CanvasWatchFaceService.Engine*implementa.on

    View Slide

  18. CanvasWatchFaceService.Engine2Lifecycle
    • onCreate(SurfaceHolder)232Init2watch2face2objects2and2set2style

    View Slide

  19. Build&Watch&Face&Style
    • Peek%card%height%&%opacity
    • Peek%card%visibility%in%ambient%mode
    • Hotword%indicator%posi:oning
    • Status%bar%icon%posi:oning
    • Hotword%&%status%bar%icon%background
    • System%:me%UI%visibility

    View Slide

  20. CanvasWatchFaceService.Engine2Lifecycle
    • onCreate(SurfaceHolder)232Init2watch2face2objects2and2set2style
    • onVisibilityChanged(boolean)232Manage2listeners2&2receivers
    • onDraw(Canvas,2Rect)232Draw2the2watch2face2with2given2state
    • onDestroy()232Clean2up2handler2messages

    View Slide

  21. CanvasWatchFaceService.Engine2Callbacks
    • onApplyWindowInsets(WindowInsets)
    • onPeekCardPosi7onUpdate(Rect)
    • onProper7esChanged(Bundle)
    • onAmbientModeChanged(boolean)
    • onInterrup7onFilterChanged(int)
    • onTimeTick()

    View Slide

  22. Drawing(the(Watch(Face
    • Use%bitmaps%efficiently
    • In%ambient%mode:
    • Draw%with%less%color%(usually%grayscale)
    • Update%only%every%minute%via%onTimeTick()
    • Cancel%any%delayed%messages%used%for%update%Bmer

    View Slide

  23. Drawing(the(Watch(Face(in(Special(Modes
    • In$low(bit$ambient$mode:
    • Do$not$an2(alias$text$or$shapes
    • When$burn(in$protec2on$enabled:
    • Don't$draw$within$10px$of$border$since$content$may$shi@
    • Don't$draw$large$patches$of$solid$color

    View Slide

  24. Displaying*the*Time
    • Maintain'a'Time'object
    • Handle'0me'zone'changes
    • Honor'the'12/24;hour'se=ng
    • Manage'a'0mer'used'to'schedule'next'update

    View Slide

  25. View Slide

  26. Displaying*Addi-onal*Info
    • Many&op)ons&(calendar,&sensor,&loca)on)
    • Perform&data&requests&and&computa)ons&on&mobile
    • Use&WearableListenerService&for&response&handling
    • Don't&let&your&watch&face&turn&into&an&app

    View Slide

  27. Allowing(User(Customiza3on

    View Slide

  28. Allowing(User(Customiza3on
    • Wearable(se*ngs(screen
    • Limit(available(op5ons(to(simple(toggles(and(short(lists
    • Indicate(that(more(se*ngs(are(available(on(the(mobile(device
    • Companion(se*ngs(screen
    • Display(full(set(of(possible(customiza5ons
    • Includes(set(and(forget(op5ons(like(units

    View Slide

  29. Syncing'Se)ngs
    • Keep%se'ngs%in%sync%between%devices
    • Use%DataMap%to%manage%buffering%of%updates%and%storage
    • Only%redraw%the%watch%face%when%se'ng%changes%values
    • Prevent%infinite%loops%from%DataMap%callbacks%&%widget%listeners

    View Slide

  30. WearableListView
    • Extension*of*RecyclerView
    • Included*in*wearable*support*library
    • Allows*for*easy*selec8on*of*list*items

    View Slide

  31. Using&WearableListView
    • Don't'set'a'LayoutManager
    • WearableListView.ClickListener'handles'item'selec1on
    • Use'addOnScrollListener(),'not'setOnScrollListener()
    • Animate'the'transi1ons'to/from'the'center'list'item
    • Scroll'1tle'header'text'along'with'list

    View Slide

  32. Performance*Op-miza-ons
    • Don't'draw'unnecessary'transparent'pixels
    • Don't'update'the'display'unnecessarily
    • Don't'do'lengthy'opera7ons'(bitmap'resize/load)'in'onDraw(...)
    • Don't'allocate'objects'in'onDraw(...)

    View Slide

  33. Ba#ery'Life'Op-miza-ons
    • Don't'animate'unnecessarily
    • Update'rate
    • Features'vs'ba8ery
    • Monitor'ba8ery'life

    View Slide

  34. Tes$ng'with'Emulator
    • Use%F7%to%toggle%screen%on/off%for%tes2ng%ambient%mode
    • emulator -avd -prop
    ro.ambient.low_bit_enabled=true
    • emulator -avd -prop
    ro.ambient.burn_in_protection=true

    View Slide

  35. Pro$Tips
    • Install(Wear(APK(directly(to(wearable(during(dev
    • Separate(drawing(logic(from(WatchFaceService
    • Create(a(skeleton(watch(face(with(Android(Studio(1.1
    • Gracefully(handle(wearable(not(connected(to(mobile
    • Use(JobScheduler(for(scheduling(data(requests

    View Slide

  36. Useful'Links
    Google’s(Watch(Face(Training(Docs:
    developer.android.com/training/wearables/watch=faces/index.html
    Watch&Face&API&Blog&Post&on&ToastDroid:
    h8p:/
    /toastdroid.com/tag/watch>face/
    Chron&Watch&Face&Source&Code:
    h1ps:/
    /github.com/twotoasters/chron
    Slide&Deck
    h+ps:/
    /speakerdeck.com/jbarr21

    View Slide

  37. Thanks!
    Specialized*Bikes*Watch*Face*|*Chron*Watch*Face
    @jbarr21(|(h+p:/
    /twotoasters.com

    View Slide