Android Wear Development

Android Wear Development

2015.01.28 @ Android Taipei

8a6e58b272b266faf22d8a3b2927624f?s=128

Johnny Sung

January 28, 2015
Tweet

Transcript

  1. Android Wear Development Johnny Sung 2015.01.28 @ Android Taipei

  2. https://fb.com/j796160836 Johnny Sung Mobile devices Developer https://plus.google.com/+JohnnySung http://about.me/j796160836

  3. Agenda • Overview • Basic Setup • Notifications • Layout

    • Data Layer • Comparison with WatchKit
  4. http://www.droid-life.com/wp-content/uploads/2014/03/android-wear.png https://www.youtube.com/watch?v=CZrGDo9Grgk (30sec)
 https://www.youtube.com/watch?v=QrqZl2QIz0c (1.5min) TVCF

  5. http://img1.lesnumeriques.com/news/33/33684/gg-android-wear-tag.jpg

  6. Android Wear 設計理念 • Launched automatically (⾃自動啟動) • Glanceable (可⼀一眼瞥⾒見)

    • All about suggest and demand (推薦與需求) • Zero or low interaction (盡可能減少點擊滑動步驟)
  7. http://core0.staticworld.net/images/article/2014/06/android_wear_sports_score-100314393-orig.jpg

  8. http://i2.tudocdn.net/img/type28/width646/height284/id106674.jpg

  9. Basic setup

  10. Debugging over Bluetooth • ⼿手機設定 Debugging over bluetooth • ⼿手錶設定

    ADB Debug
 & Debugging over bluetooth • 執⾏行 ConnectDebugWear.sh
 https://gist.github.com/j796160836/9b135a8de4c44846fd82
  11. Debugging over Bluetooth

  12. https://www.youtube.com/watch?v=q3a2fdTy_6A Connect use USB?

  13. Android Wear Emulator
 & Phone Emulator

  14. Android Wear Emulator
 & Phone Emulator • Choose x86 Emulator

    (faster) • Install Google Search (2min)
 com.google.android.googlequicksearchbox-3.6.16.1614640.x86.apk • Install Android Wear (2min)
 com.google.android.wearable.app • Be patient
  15. None
  16. WearHost for Genymotion • Install ARM Translation Installer
 Genymotion-ARM-Translation_v1.1.zip •

    Install GApps
 gapps-lp-20141109-signed.zip
 gapps-kk-20140606-signed.zip
 gapps-jb-20130813-signed.zip • Install Google Search
 com.google.android.googlequicksearchbox • Install Android Wear
 com.google.android.wearable.app • Run Script: ConnectWearEmulator.sh
 https://gist.github.com/j796160836/91e77ca819c11ed7bf01
  17. Eclipse user?

  18. Compile Wear in Eclipse • Install Google Repository in SDK

    Manager • Find wearable-1.1.0.aar in SDK
 android-sdks/extras/google/m2repository/com/google/android/support/ wearable/1.0.0/wearable-1.1.0.aar • Rename aar to zip and unzip it • Import from existing code • Check it Is Library • Import google-play-service-lib https://medium.com/@tangtungai/ef1b34126a5d
  19. Compile Wear in Android Studio • Edit Gradle dependencies {

    compile fileTree(dir: compile compile } [Wearable module]
  20. Packaging structure Android App Android App Code Resources Code Resources

    Wear App WearApp Module HandledApp Module
  21. Packaging Wearables using Ant 1. Export and Sign Wearable Apps

    APK
 (eg: demowearapp.apk) 2. Add a meta-data tag in AndroidManifest.xml 3. Put your wearable binary in res/raw directory
 (eg: res/raw/demowearapp.apk) 4. Write reference descriptions xml
 (eg: res/xml/wearable_app_desc.xml) 5. Turn off Asset Compression https://developer.android.com/training/wearables/apps/packaging.html#PackageManually https://medium.com/@tangtungai/ef1b34126a5d
  22. Packaging Wearables in Eclipse 1. Export and Sign Wearable Apps

    APK
 (eg: demowearapp.apk) #!/bin/bash cd ../wearable-1.1.0 android update lib-project --path . ant clean release cd ../DemoWearApp android update project --path . ant clean release key.store= key.store.password= key.alias= key.alias.password= config.logging=true ant.properties Generate build.xml [Wearable project]
  23. Packaging Wearables in Eclipse 2. Add a meta-data tag in

    AndroidManifest.xml <application <meta-data </application> [Smartphone project]
  24. Packaging Wearables in Eclipse 3. Put your wearable binary in

    res/raw directory
 (eg: res/raw/demowearapp.apk) 4. Write reference descriptions xml
 (eg: res/xml/wearable_app_desc.xml) <?xml <wearableApp <versionCode>1</versionCode> <versionName>1.0</versionName> <rawPathResId>demowearapp</rawPathResId> </wearableApp> [Smartphone project]
  25. Packaging Wearables in Eclipse 5. Turn off Asset Compression <target

    name= <do-only-if-not-library <aapt <res <res </aapt> </do-only-if-not-library> </target> http://stackoverflow.com/questions/7937368/how-to-pass-arguments-to-aapt-when-building-android-apk From <sdks_dir>/tools/ant/build.xml, search -package-resources Add this [Smartphone project]
  26. [Smartphone module] dependencies { compile fileTree(dir: compile compile wearApp project(

    } Packaging Wearables in Android Studio • Edit Gradle
  27. Code Examples AndroidWearable-Samples
 http://goo.gl/q8qfm8 DemoWearApp
 http://goo.gl/pIJzr4

  28. Notifications

  29. 世新廣播電臺 Personal Works

  30. Shih Hsin Radio Station • Actions • WearableExtender • Background

    • Page
  31. Notification 整理 • Notification 到底要怎麼發? • 從⼿手機發送 • 同步到⼿手錶(含變更樣式) •

    不同步到⼿手錶 • 從⼿手錶發送 mBuilder.setLocalOnly(true);
  32. Notification 整理 • Notification 變更樣式? • 從⼿手機發送 • 設定⼿手機樣式,再變更⼿手錶樣式 •

    ⾃自訂樣式(只適⽤用於⼿手機) • 從⼿手錶發送 • ⾃自訂樣式(只適⽤用於⼿手錶) WearableExtender WearableExtender
 setDisplayIntent RemoteView
  33. 基本款 Notification NotificationCompat = new mBuilder mBuilder mBuilder Notification int

    NOTIFICATION_ID NotificationManager = getSystemService mNotificationManager 建⽴立 發送
  34. Notification notification 基本款 Notification 舊寫法 (deprecated  in  API  level  11)

    拜託別再寫了哈~
  35. 基本款 Notification NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_launcher); mBuilder.setContentTitle("Awesome app");

    mBuilder.setContentText("The description"); Notification notification = mBuilder.build();
  36. Android  4.1  (API  16) BigTextStyle String msg = "\"The quick

    brown fox …"; NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_launcher); mBuilder.setContentTitle("Awesome app"); mBuilder.setContentText(msg); mBuilder.setStyle( new NotificationCompat.BigTextStyle() .bigText(msg)); Notification notification = mBuilder.build(); http://developer.android.com/training/notify-user/expanded.html
  37. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.drawable.photo); mBuilder.setContentTitle("Awesome app"); mBuilder.setContentText("The description");

    Bitmap bg = BitmapFactory.decodeResource( getResources(), R.drawable.bg); NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle(); style.bigPicture(bg); style.setBigContentTitle("My title"); style.setSummaryText("The description"); mBuilder.setStyle(style); Notification notification = mBuilder.build(); BigPictureStyle Android  4.1  (API  16)
  38. Notification Height Limit • Normal view layouts: 64 dp •

    Expanded view layouts: 256 dp. 256dp 64dp
  39. WearableExtender

  40. 基本款 Notification + 背景 • Background size • 400 x

    400 • 640 x 400 (Parallax scrolling) • Put the picture at /res/drawable-nodpi NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.drawable.photo); mBuilder.setContentTitle("Awesome app"); mBuilder.setContentText("The description"); Bitmap bg = BitmapFactory.decodeResource( getResources(), R.drawable.bg); NotificationCompat.WearableExtender wearExt = new NotificationCompat.WearableExtender() .setBackground(bg); mBuilder.extend(wearExt); Notification notification = mBuilder.build();
  41. RemoteControlClient Android  4.0  (API  14) METADATA_KEY_ARTIST

  42. RemoteControlClient Android  4.0  (API  14) • Attribute Keys • METADATA_KEY_ARTIST

    • METADATA_KEY_TITLE • Attribute Keys • METADATA_KEY_TITLE • METADATA_KEY_ALBUM RemoteView
  43. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.drawable.photo); mBuilder.setContentTitle("Awesome app"); mBuilder.setContentText("The description");

    Intent clickInt = new Intent(MainActivity.this, SecondActivity.class); PendingIntent clickPenInt = PendingIntent.getActivity(this, 0, clickInt, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(clickPenInt); Notification notification = mBuilder.build(); 按鈕按下的⾏行為
  44. 24dp 48dp The Problem is…

  45. NotificationCompat = new mBuilder mBuilder mBuilder mBuilder ( mBuilder (

    NotificationCompat wExt ( Notification http://stackoverflow.com/questions/25026616/android-wear-action- item-icon-sizing-vs-phone-notification-action-item-sizing The solutions
  46. Code Examples Wearable Notifications https://github.com/googlesamples/android-Notifications Basic Notifications https://github.com/googlesamples/android-BasicNotifications Custom Notifications

    https://github.com/googlesamples/android-CustomNotifications
  47. • WatchViewStub • 指定 Round layout • 指定 Rect layout

    • BoxInsetLayout • 設定 app:layout_box="all" Layout http://developer.android.com/training/wearables/ui/layouts.html
  48. Layout • Card • 繼承 CardFragment • CardScrollView + CardFrame

    http://developer.android.com/training/wearables/ui/cards.html
  49. UI Structure

  50. Data Layer

  51. Google  Play  Services

  52. Bluetooth Mini

  53. Data Layer 資料傳輸層 • DataApi • MessageApi • NodeApi

  54. Data Items • Path
 唯⼀一的字符串,必須以正斜線開始
 例如:/path/to/data • Payload
 ⼀一個字節數組,你可允許進⾏行對象的序列化 (Serialize)

    與反序列化 (Deserialize)
 ⼤大⼩小不能超過100KB。 1BUI 1BZMPBE 100KB
  55. 連接⽅方式 • 在 Activity 中建⽴立連線,實作 Callback 監聽 • 使⽤用 WearableListenerService

    • Callback • DataApi.DataListener • MessageApi.MessageListener • NodeApi.NodeListener
  56. Listener • DataApi.DataListener • NodeApi.NodeListener • MessageApi.MessageListener public void onPeerConnected(Node

    node) public void onPeerDisconnected(Node node) public void onDataChanged(DataEventBuffer dataEvents) public void onMessageReceived(MessageEvent messageEvent)
  57. 連接⽅方式 • onCreate() 建⽴立 GoogleApiClient,掛載 Callbacks @Override protected void onCreate(Bundle

    savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); }
  58. 連線 Callback public void onConnected(Bundle connectionHint) public void onConnectionFailed(ConnectionResult result)

    • GoogleApiClient.ConnectionCallbacks • GoogleApiClient.OnConnectionFailedListener public void onConnectionSuspended(int cause) https://developer.android.com/google/auth/api-client.html
  59. 連接⽅方式 • onStart() 呼叫 connect() 做連線 @Override protected void onStart()

    { super.onStart(); if (!mResolvingError) { mGoogleApiClient.connect(); } } @Override //ConnectionCallbacks public void onConnected(Bundle connectionHint) { Log.d(TAG, "Google API Client was connected"); mResolvingError = false; Wearable.DataApi.addListener(mGoogleApiClient, this); Wearable.MessageApi.addListener(mGoogleApiClient, this); Wearable.NodeApi.addListener(mGoogleApiClient, this); } • onConnected() 時候,掛載 Listener
  60. @Override protected void onStop() { if (!mResolvingError) { Wearable.DataApi.removeListener(mGoogleApiClient, this);

    Wearable.MessageApi.removeListener(mGoogleApiClient, this); Wearable.NodeApi.removeListener(mGoogleApiClient, this); mGoogleApiClient.disconnect(); } super.onStop(); } 連接⽅方式 • onStop() 移除Listener,並且斷線
  61. WearableListenerService • 在系統需要的時候就會⾃自動綁定 <service android:name=".DataLayerListenerService" > <intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />

    </intent-filter> </service> public class DataLayerListenerService extends WearableListenerService { @Override public void onDataChanged(DataEventBuffer dataEvents) { // Do Somthing } @Override public void onMessageReceived(MessageEvent messageEvent) { // Do Somthing } } AndroidManifest.xml
  62. DataApi http://android-wear-docs.readthedocs.org/en/latest/data.html

  63. DataItem private void sendSampleDataItem() { final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE");

    final DataMap map = putRequest.getDataMap(); map.putInt("num", 12345); map.putString("example", "Sample String"); Wearable.DataApi.putDataItem(mGoogleApiClient, putRequest.asPutDataRequest()); } @Override public void onDataChanged(DataEventBuffer dataEvents) { final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents); dataEvents.close(); for(DataEvent event : events) { String path = event.getDataItem().getUri().getPath(); if(path.equals("/SAMPLE")) { final DataMap map = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); // read your values from map: int num = map.getInt("num"); String str = map.getString(“example"); Log.v(TAG, " num = " + num + " str = " + str); } } } • 傳送 • 接收
  64. MessageApi http://android-wear-docs.readthedocs.org/en/latest/sync.html

  65. String msg = "Sample String"; NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi .getConnectedNodes(mGoogleApiClient).await();

    for (Node node : nodes.getNodes()) { SendMessageResult result = Wearable.MessageApi.sendMessage( mGoogleApiClient, node.getId(), "/SAMPLE", msg.getBytes()) .await(); if (result.getStatus().isSuccess()) { // Success } else { // Error } } @Override public void onMessageReceived(MessageEvent messageEvent) { if (messageEvent.getPath().equals("/SAMPLE")) { final String message = new String(messageEvent.getData()); // Do Something } } • 傳送Message (AsyncTask) • 接收Message Message
  66. Code Examples WearMessageBringFront
 http://goo.gl/jdKkHL WearDataLayerDemo
 http://goo.gl/HL84YQ DataLayer
 https://github.com/googlesamples/android-DataLayer

  67. vs Apple Watch (WatchKit) Android Wear

  68. Android Wear WatchKit Packaging structure Android App Android App Code

    Resources Code Resources Wear App WearApp Module HandledApp Module
  69. Android Wear Google Play Services Google Play Services Android Device

    Controller Model View Mini Controller View Model Controller View Model App structure Android Wear WatchKit iOS App
  70. 好像少講了什麼?

  71. 震動 。 超⾃自然 的

  72. 震動 <uses-permission android:name="android.permission.VIBRATE" /> Vibrator mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); myVibrator.vibrate(100);

    AndroidManifest.xml
  73. 震動 mVibrator.vibrate(new long[]{80, 150, 80, 150, 80, 150}, -1); Repeat

    Pattern mVibrator 震動 Pattern 取消
  74. Q & A

  75. Troubleshooting: ⼿手錶 Offline 解決⽅方式 • Android Wear (設定 > 應⽤用程式)

    1. 停⽤用 2. 清除資料 3. 啟⽤用 • Google Play 服務 (設定 > 應⽤用程式) 4. 清除所有資料(管理空間) • 硬體 5. 重置⼿手錶 6. ⼿手機重新啟動 http://melix.github.io/blog/2014/10/android-moto360.html $ adb devices List of devices attached dcfbbafd device localhost:4444 offline
  76. Android Wear
 (設定 > 應⽤用程式) Google Play 服務 (設定 >

    應⽤用程式 > 管理空間) 重置 Moto360 Troubleshooting: ⼿手錶 Offline 解決⽅方式
  77. Troubleshooting: ⼿手錶 unauthorized 解決⽅方式 • 請使⽤用 Eclipse 做第⼀一次連接 $ adb

    devices List of devices attached dcfbbafd device localhost:4444 unauthorized