Android Wear, a developer's perspective

Post on 15-Jul-2015

206 views 2 download

transcript

Android Weardeveloper’s perspective

Sebastian VieiraS

Topics

NotificationsNative AppsWatchfaces

What kind of apps?Launched automatically “suggests”

Context Stream cards

GlanceableSee the content in a split second

All about suggest and demandA personal assistant: it interrupts only when necessary

Zero or low interactionUser input only when necessary: touch, swipes, voice

What kind of apps?

Three ways to develop for Android WearAndroid notificationsNative android wear appsWatchfaces

adb -d forward tcp:5601 tcp:5601

Notifications

It is standard notifications but…You have to use NotificationCompatNotificationCompat.WearableExtender

Helper class to add wearable extensions, actions...

Notifications - Voice

We want to dictate to the watchRemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)...build()

NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), intent)

.addRemoteInput(remoteInput)

.build();

Your Android phone receives it:Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);CharSequence reply = remoteInput.getCharSequence(EXTRA_VOICE_REPLY);

Notifications - Voice

Predefined text responses<string-array name="reply_choices">

<item>Yes</item>

<item>No</item>

<item>Maybe</item>

</string-array>

RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)

.setLabel(replyLabel)

.setChoices(replyChoices)

.build();

Notifications - Pages

NotificationWearableExtender:addPage(Notification notif)// Create a big text style for the second page

BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();

secondPageStyle.setBigContentTitle("Page 2").bigText("A lot of text...");

// Create second page notification

Notification secondPageNotification = new NotificationCompat.Builder(this).setStyle(secondPageStyle).build();

// Extend the notification builder with the second page

Notification notification = notificationBuilder.extend(new NotificationCompat.WearableExtender()

.addPage(secondPageNotification)).build();

Notifications - Stacking

NotificationCompat.Builder(ctx)setGroup(String key)

Important to add summarysetGroupSummary(true)

Wear Apps

Direct access to HW of the watchTimeout period after which watch goes to sleepBundled within a bigger appAccess to all Android APIs except:

webkit, print, backup, appwidgets and usb

Wear App project

Notifications:support library v4

Data LayerGoogle Play Service

Wearable UI support libraryUnofficial library (wtf?)

Wear App UIBoxInsetLayout - A FrameLayout that's aware of screen shapeCardFragment - Vertically scrollable card.CircledImageViewConfirmationActivity - An activity that displays confirmation animationsCrossFadeDrawableDelayedConfirmationView - Circular countdown timerDismissOverlayView - Long-press-to-dismiss.DotsPageIndicator - Page indicator for GridViewPager that identifies the current pageGridViewPager: GridPagerAdapter, FragmentGridPagerAdapterWatchViewStub - A class that can inflate a specific layout, based on the device's screen.WearableListView - An alternative version of ListView

Wear App UI

Since the library is not supported, it can change (and it does break pretty badly)

https://developer.android.com/reference/android/support/wearable/view/package-summary.html

Voice

Voice is an important part of Android WearTwo types of voice actions:

System providedTask based build in the OS ("OK Google, what’s my bpm?")

App providedApp based (‘Start’+Activity Name)

Sytem Voice Actions

Taxi, notes, alarm, timer, bike, run, workout,heart rate, step count

Action, Mime Type, Extras, Category in manifest<activity android:name="MyNoteActivity">

<intent-filter>

<action android:name="android.intent.action.SEND" />

<category android:name="com.google.android.voicesearch.SELF_NOTE" />

</intent-filter>

</activity>

Form free speech input

Speech Recogniser, useful for dictating textIntent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

startActivityForResult(intent, SPEECH_REQUEST_CODE);

if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {

List<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

String spokenText = results.get(0);

}

Data layer API

To communicate with the watch:Create an instance of GoogleApiClient

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)

.addConnectionCallbacks(new ConnectionCallbacks() {...})

.addOnConnectionFailedListener(new OnConnectionFailedListener() {...})

// Request access only to the Wearable API

.addApi(Wearable.API)

.build();

Use one separate instance for Android Wear!

Data layer APIData ItemsData storage with automatic syncing.

MessageApiGood for remote procedure calls (RPC)Fire and Forget commands

AssetSending binary blobs of data, such as images. With caching for large assets (to avoid Bluetooth bandwith issues)

Data layer API

WearableListenerService (for services)Listen for important data layer events in a service. The system manages its lifecycle binding to the service when it needs to send data items or messages and unbinding the service when no work is needed.

DataListener (for foreground activities)Listen for important data layer events when an activity is in the foreground. Using this instead of the WearableListenerService lets you listen for changes only when the user is actively using your app.

Watch Faces

Plan for square and round devicesSupport all display modes (ambient, interactive) Support special screen technologiesMake sure indicators are visibleIntegrate data like calendar requests or weatherProvide configuration options

Watch Faces

They are services… wait… what?CanvasWatchFaceService

Equivalent to View classCanvasWatchFaceService.Engine

onDraw and callbacks of time, properties, configurations changes

Watch Faces - Drawing

Create a timer that invalidates the engine(ambient mode has system timer with callback onTimerTick)

Engine.onVisibilityChanged()Where you start the timer and update the time zone

Engine.onAmbientModeChangedTime to disable antialiasing, for example

Engine.onDraw(Canvas canvas, Rect bounds)… where the fun starts

Lets say we want to show the weather…Create a class inside your CanvasWatchFaceService.Engine implementation that extends AsyncTask and add the code to retrieve the data you’re interested in.

Engine.onVisibilityChanged(boolean visible)This method initializes the timer when the watch face becomes visible

Quite a manual process

Watch Faces - Show Info

Watch Faces - Configuration

Create a Wearable Configuration ActivityRuns in the watch: do not make it too complex

Create a Companion Configuration ActivityThis runs on the device within the Android Wear app - It can be as complex as you want

Create a Listener Service in the Wearable App...because we have to sync configurations between device and watchUse the WearableListenerService interface from the Wearable Data Layer API The Watchface will redraw itself when the configuration changes

Thanks!

Sebastian Vieirasebastian.vieira@local.ch@seviu