1 / 33

Android Wear Development

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?.

dick
Download Presentation

Android Wear Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Android Wear Development July 25, 2014 Takahiro Poly Horikawa

  2. Agenda • Android wear’s features and capabilities • How to develop? • Notification • Sending and syncing data • Development case study

  3. Concept • Microinteraction

  4. 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

  5. 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 action etc…

  6. Homescreen Home Cards (Context stream) … …

  7. Cue card Voice Search and voice action … Cue cards

  8. 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)

  9. 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

  10. Android Wear APP DEVELOPMENT

  11. Notification • Add action • Add voice reply • Stacking notification • Add pages

  12. Add action NotificationActivity.java (Handheld) Intent intent = new Intent(context, NotificationLandingActivity.class); PendingIntentpIntent = 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(); NotificationManagerCompatnotificationManager = NotificationManagerCompat.from(context); notificationManager.notify(0, n);

  13. Add voice reply NotificationActivity.java (Handheld) 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); String replyLabel = ”会議に参加しますか?"; String[] replyChoices = {"はい", "いいえ”}; RemoteInputremoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY) .setLabel(replyLabel) .setChoices(replyChoices) .build(); Intent replyIntent= new Intent(ctx, VoiceReceiverActivity.class); PendingIntentreplyPendingIntent= PendingIntent.getActivity(ctx, 0, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

  14. Receive voice input VoiceReceiverActivity.java (Handheld) public class VoiceReceiverActivityextends 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)); } }

  15. Stacking Notification NotificationActivity.java (Handheld) NotificationManagerCompatnotificationManager = 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);

  16. Add pages NotificationActivity.java (Handheld) Notification 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(); NotificationManagerCompatnotificationManager = NotificationManagerCompat.from(context); notificationManager.notify(300, notification);

  17. 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 Custom Activity

  18. Send notification to open an activity on the wearable WatchActivity.java (Wearable) Intent viewIntent = new Intent(context, WatchActivity.class); PendingIntentpendingViewIntent = 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(); NotificationManagerCompatnotificationManager= NotificationManagerCompat.from(context); notificationManager.notify(3000, notification);

  19. Send notification embedding an activity on the wearable WatchActivity.java (Wearable) Intent viewIntent = new Intent(context, NotificationEmbeddedActivity.class); PendingIntentpendingViewIntent = 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(); NotificationManagerCompatnotificationManager= NotificationManagerCompat.from(context); notificationManager.notify(4000, notification); Custom Activity

  20. 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

  21. Connect Google Api Client DataActivity.java (Handheld) private GoogleApiClientmGoogleApiClient; @Override protected 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(inti) { } }).build(); mGoogleApiClient.connect(); }

  22. Message API DataActivity.java (Handheld) private 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; }

  23. Message API AndroidManifest.xml (Wearable) public class DataLayerListenerServiceextends WearableListenerService{ @Override public void onMessageReceived(MessageEventmessageEvent) { 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> DataLayerListenerService.java(Wearable)

  24. Data APIsend data from handheld DataActivity.java (Handheld) int count = 0; private void sendCount() { PutDataMapRequestdataMap = 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.DataItemResultdataItemResult) { Log.d(TAG, "count updated:" + count); } }); }

  25. Data APIdetect data change on wearable DataLayerListenerService.java (Wearable) public class DataLayerListenerServiceextends WearableListenerService { @Override public void onDataChanged(DataEventBufferdataEvents) { for (DataEvent event : dataEvents) { DataItemdataItem = event.getDataItem(); if (COUNT_PATH.equals(dataItem.getUri().getPath())) { DataMapdataMap = DataMapItem.fromDataItem(dataItem).getDataMap(); int count = dataMap.getInt(COUNT_KEY); …. } } } }

  26. Data APIaccess to the existing data DataActivity.java (Handheld) The uri of data is wear://<NODE_ID>/<PATH> 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.DataItemResultdataItemResult) { DataItemdataItem = dataItemResult.getDataItem(); if (dataItem != null) { DataMapdataMap= DataMapItem.fromDataItem(dataItemResult.getDataItem()).getDataMap(); count = dataMap.getInt(COUNT_KEY); } } }); } private String getLocalNodeId() { NodeApi.GetLocalNodeResultnodeResult = Wearable.NodeApi.getLocalNode(mGoogleApiClient).await(); return nodeResult.getNode().getId(); }

  27. Combination (1) • Update embedded activity in notification from the handheld Example: Google Map navigation on wearable Data API Notification with DisplayIntent Data API Notification with DisplayIntent Notification with DisplayIntent Data API

  28. Combination (2) • Send notification from handheld to wearable to open a custom activity on wearable Example: Remote shutter for Google Camera app Custom Activity Data API Notification Tap to open Message API

  29. Development case study

  30. Draw Watch for Android Wear • https://play.google.com/store/apps/details?id=com.polysfactory.drawwatch

  31. 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 toshare bitmap on the handheld works great

More Related