GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspective
Android Wear, a developer's perspective
-
Upload
sebastian-vieira -
Category
Engineering
-
view
208 -
download
2
Transcript of Android Wear, a developer's perspective
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