android wear development

33
Android Wear Development July 25, 2014 Takahiro Poly Horikawa

Upload: dick

Post on 15-Feb-2016

84 views

Category:

Documents


0 download

DESCRIPTION

Android Wear Development. July 25, 2014 Takahiro Poly Horikawa. Agenda. Android wear’s features and capabilities How to develop? Notification Sending and syncing data Development case study. Concept. Microinteraction. How it works?. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Android Wear Development

Android Wear Development

July 25, 2014Takahiro Poly Horikawa

Page 2: Android Wear Development

Agenda• Android wear’s features and capabilities• How to develop?– Notification– Sending and syncing data

• Development case study

Page 3: Android Wear Development

Concept

• Microinteraction

Page 4: Android Wear Development

How it works?

• Require android (>= 4.3) phone/tablet (referred as handheld)

• Require “Android Wear” app on the handheld• Handheld and wearable communicate each

other via Bluetooth (wearable itself does not connect to internet)

Notifications

Page 5: Android Wear Development

What you can do?

• Receive notifications and react them on the wearable

• Control apps on the phone from the wearable• Run wearable specific app (e.g. compass,

heart rate monitor)• Voice search and voice actionetc…

Page 6: Android Wear Development

Homescreen

Home

Cards(Context stream)

Page 7: Android Wear Development

Cue card

…Cue cards

Voice Search and voice action

Page 8: Android Wear Development

Sensors (Samsung Gear Live)• MPL Rotation Vector (Invensense)• MPL Gravity (Invensense)• MPL Orientation (Invensense)• MPL Linear Accelration (Invensense)• MPU6515 Acceleration Sensor (Invensense)• MPU6515 Gyroscope Sensor (Invensense)• SAMSUNG Tilt Wake Sensor (Samsung Inc.)• SAMSUNG Significant Motion Sensor (Samsung Inc.)• SAMSUNG Game Rotation Vector (Samsung Inc.)• SAMSUNG Step Counter Sensor (Samsung Inc.)• SAMSUNG Step Detector Sensor (Samsung Inc.)• AK8963C Magnetic Sensor UnCalibrated (Asahi Kasei Microdevices)• AK8963C Magnetic field Sensor (Asahi Kasei Microdevices)• ADPD142 HRM Sensor Lib (ADI)

Page 9: Android Wear Development

Application packaging and publishing

• When publishing to user, package a wearable app inside a handheld app

• Wearable app will be installed on user’s wearable automatically when user install handheld app from Google Play Store

• A handheld app has to have the same package name as a wearable app

Page 10: Android Wear Development

ANDROID WEAR APP DEVELOPMENT

Page 11: Android Wear Development

Notification

• Add action

• Add voice reply

• Stacking notification

• Add pages

Page 12: Android Wear Development

Add actionIntent intent = new Intent(context, NotificationLandingActivity.class);PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);

Notification n = new NotificationCompat.Builder(context) .setContentTitle(" 新着メッセージがあります ") .setContentText("xx さんからメッセージが届いています ") .setSmallIcon(R.drawable.ic_launcher) .setContentIntent(pIntent) .addAction(R.drawable.ic_launcher, " 返信 ", pIntent) .addAction(R.drawable.ic_launcher, " 転送 ", pIntent) .build();

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);notificationManager.notify(0, n);

NotificationActivity.java (Handheld)

Page 13: Android Wear Development

Add voice replyString replyLabel = ” 会議に参加しますか? ";String[] replyChoices = {" はい ", " いいえ” };

RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY) .setLabel(replyLabel) .setChoices(replyChoices) .build();

Intent replyIntent = new Intent(ctx, VoiceReceiverActivity.class);PendingIntent replyPendingIntent = PendingIntent.getActivity(ctx, 0, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_launcher, " 返信 ", replyPendingIntent) .addRemoteInput(remoteInput) .build();

Notification notification = new NotificationCompat.Builder(ctx) .extend(new NotificationCompat.WearableExtender().addAction(action)).build();

NotificationManagerCompat manager = NotificationManagerCompat.from(ctx);manager.notify(200, notification);

NotificationActivity.java (Handheld)

Page 14: Android Wear Development

Receive voice inputpublic class VoiceReceiverActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_voice_input_receiver); Bundle remoteInput = RemoteInput.getResultsFromIntent(getIntent()); CharSequence message = remoteInput.getCharSequence(NotificationActivity.EXTRA_VOICE_REPLY); ((TextView) findViewById(R.id.message)).setText(String.format(" 音声入力メッセージは「 %s 」です。 ", message)); }

}

VoiceReceiverActivity.java (Handheld)

Page 15: Android Wear Development

Stacking NotificationNotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);

Notification card1 = new NotificationCompat.Builder(context) .setContentText(" 何してますか? ") .setGroup(GROUP_KEY).setSortKey("0”).build();notificationManager.notify(101, card1);

Notification card2 = new NotificationCompat.Builder(context) .setContentText(" 手伝ってもらってもいいですか? ") .setGroup(GROUP_KEY).setSortKey("1”).build();notificationManager.notify(102, card2);

Notification summary = new NotificationCompat.Builder(context) .setContentTitle(" 新着メッセージ 2 件 ") .setGroup(GROUP_KEY).setGroupSummary(true).build();notificationManager.notify(100, summary);

NotificationActivity.java (Handheld)

Page 16: Android Wear Development

Add pagesNotification page = new NotificationCompat.Builder(context) .setStyle(new NotificationCompat.BigTextStyle().bigText(" メンチカツ定食 $7.99")) .build();

Notification notification = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("xx レストラン通信 ") .setContentText(" 本日の日替わりランチ ") .extend(new NotificationCompat.WearableExtender().addPage(page)) .build();

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);notificationManager.notify(300, notification);

NotificationActivity.java (Handheld)

Page 17: Android Wear Development

Notification gotcha

• Notification from the handheld can only open an activity on the handheld

• To open/embed a custom activity on the wearable, you need to send notification from the wearable.

• Open a custom activity • Embed a custom activity

CustomActivity

Page 18: Android Wear Development

Send notification to open an activity on the wearable

Intent viewIntent = new Intent(context, WatchActivity.class);PendingIntent pendingViewIntent = PendingIntent.getActivity(context, 0, viewIntent, 0);

Notification notification = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Wearable から送信 ") .setContentText("Wearable から送信した Notification です。 ") .addAction(R.drawable.ic_launcher, "Open", pendingViewIntent) .setLocalOnly(true) .extend(new NotificationCompat.WearableExtender().setContentAction(0).setHintHideIcon(true)) .build();

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);notificationManager.notify(3000, notification);

WatchActivity.java (Wearable)

Page 19: Android Wear Development

Send notification embedding an activity on the wearable

Intent viewIntent = new Intent(context, NotificationEmbeddedActivity.class);PendingIntent pendingViewIntent = PendingIntent.getActivity(context, 0, viewIntent, 0);

Notification notification = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Wearable から送信 ") .setContentText("Wearable から送信した Notification です。 ") .setLocalOnly(true) .extend(new NotificationCompat.WearableExtender().setDisplayIntent(pendingViewIntent)) .build();

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);notificationManager.notify(4000, notification);

WatchActivity.java (Wearable)

CustomActivity

Page 20: Android Wear Development

Sending and syncing data

• Message API– Fire and forgot, one way request– You can send just a string– Use case example

• Control media player from the wearable

• Data API– Sync data between the handheld and wearable– Payload is a byte array (100KB per item), but you can

use map interface to access data– Use case example

• Send Photo preview from the handheld to wearable

Page 21: Android Wear Development

Connect Google Api Clientprivate GoogleApiClient mGoogleApiClient; @Overrideprotected void onCreate(Bundle savedInstanceState) { mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { Log.d(TAG, "Google Api Client connected"); }

@Override public void onConnectionSuspended(int i) { } }).build(); mGoogleApiClient.connect();}

DataActivity.java (Handheld)

Page 22: Android Wear Development

Message APIprivate void sendMessageToStartActivity() { Collection<String> nodes = getNodes(); for (String node : nodes) { Wearable.MessageApi.sendMessage(mGoogleApiClient, node, START_ACTIVITY_PATH, null).await(); }}

private Collection<String> getNodes() { HashSet<String> results = new HashSet<String>(); NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await(); for (Node node : nodes.getNodes()) { results.add(node.getId()); } return results;}

DataActivity.java (Handheld)

Page 23: Android Wear Development

Message API

public class DataLayerListenerService extends WearableListenerService { @Override public void onMessageReceived(MessageEvent messageEvent) { if (START_ACTIVITY_PATH.equals(messageEvent.getPath())) { Intent intent = new Intent(this, WatchActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); return; } }}

<service android:name=".DataLayerListenerService"> <intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> </intent-filter></service>

AndroidManifest.xml (Wearable)

DataLayerListenerService.java (Wearable)

Page 24: Android Wear Development

Data APIsend data from handheld

int count = 0;

private void sendCount() { PutDataMapRequest dataMap = PutDataMapRequest.create(COUNT_PATH); dataMap.getDataMap().putInt(COUNT_KEY, ++count); PutDataRequest request = dataMap.asPutDataRequest(); PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi .putDataItem(mGoogleApiClient, request); pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() { @Override public void onResult(DataApi.DataItemResult dataItemResult) { Log.d(TAG, "count updated:" + count); } });}

DataActivity.java (Handheld)

Page 25: Android Wear Development

Data APIdetect data change on wearable

public class DataLayerListenerService extends WearableListenerService { @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { DataItem dataItem = event.getDataItem(); if (COUNT_PATH.equals(dataItem.getUri().getPath())) { DataMap dataMap = DataMapItem.fromDataItem(dataItem).getDataMap(); int count = dataMap.getInt(COUNT_KEY);…. } } }}

DataLayerListenerService.java (Wearable)

Page 26: Android Wear Development

Data APIaccess to the existing data

private void restoreCurrentCount() { String localNodeId = getLocalNodeId(); Uri uri = new Uri.Builder().scheme(PutDataRequest.WEAR_URI_SCHEME).authority(localNodeId).path(COUNT_PATH).build(); Wearable.DataApi.getDataItem(mGoogleApiClient, uri).setResultCallback(new ResultCallback<DataApi.DataItemResult>() { @Override public void onResult(DataApi.DataItemResult dataItemResult) { DataItem dataItem = dataItemResult.getDataItem(); if (dataItem != null) { DataMap dataMap = DataMapItem.fromDataItem(dataItemResult.getDataItem()).getDataMap(); count = dataMap.getInt(COUNT_KEY); } } });}

private String getLocalNodeId() { NodeApi.GetLocalNodeResult nodeResult = Wearable.NodeApi.getLocalNode(mGoogleApiClient).await(); return nodeResult.getNode().getId();}

DataActivity.java (Handheld)The uri of data is

wear://<NODE_ID>/<PATH>

Page 27: Android Wear Development

Combination (1)

• Update embedded activity in notification from the handheld

Data API Notification with DisplayIntent

Data API Notification with DisplayIntent

Data API Notification with DisplayIntent

Example: Google Map navigation on wearable

Page 28: Android Wear Development

Combination (2)

• Send notification from handheld to wearable to open a custom activity on wearable

Data API Notification Tap to open

Custom Activity

Message API

Example: Remote shutter for Google Camera app

Page 29: Android Wear Development

DEVELOPMENT CASE STUDY

Page 31: Android Wear Development
Page 32: Android Wear Development

Random stuff I leaned

• Prevent default behavior of wearable (right swipe to dismiss app)

– Place close menu on the second screen, but it is very confusing

• Starting app from cue card is a little bit annoying, it’s better to use notification

• Using Message API to share bitmap on the handheld works great

Page 33: Android Wear Development