Developing Google Glass

Developing Google Glass

Developing Google Glass
2014.08.27 @ Android Taipei

8a6e58b272b266faf22d8a3b2927624f?s=128

Johnny Sung

August 27, 2014
Tweet

Transcript

  1. Johnny Sung Developing 2014.08.27 @ Android Taipei

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

  3. 這是什麼? 好酷喔 這要怎麼⽤用 Ok, Glass Ok, Glass 怎麼沒有螢幕? 你可以幫我測⼀一下戰⾾鬥⼒力嗎? 他有什麼功能?

    要怎麼拍照? 要怎麼開? 你怎麼會有 真假 要抬頭啦 抬頭才有螢幕
  4. None
  5. None
  6. ⼀一窺Google 眼鏡 的 內部構造

  7. http://www.catwig.com/google-glass-teardown/

  8. rrr

  9. MyGlass 連接 Google Glass

  10. None
  11. Timeline (時間軸) https://www.youtube.com/watch?v=jK3WLILYhQs

  12. Clock Live Card Static Card

  13. Clock Static Card Now Past

  14. Clock Live Card Settings

  15. Glass development • Mirror API • Glass Development Kit (GDK)

  16. Glass development • Mirror API • Periodic notifications & Static

    Card
 (Push notifications) • Glass Development Kit (GDK) • Ongoing task & Live Card (活動卡⽚片,即時卡⽚片) • Immersion (沉浸式體驗,獨佔式體驗) • Hybrid
  17. Periodic notifications (Static Card)

  18. Ongoing task (Live Card)

  19. Hybrid Model

  20. Glass Development Kit (GDK)

  21. Glass Development Kit Sneak Peek 4.0.3 (API 15 Glass Development

    Kit Preview
 4.4.2 (API 19) Glass Development Kit Sneak Peek
 4.0.3 (API 15) Android 4.4.2 KitKat (API 19) Android L
  22. = . .

  23. 等⼀一下,先不要這麼著急... 開新專案 :)

  24. 因為會變成這副德性

  25. What the …

  26. Glass development • Glass Development Kit (GDK) • Ongoing task

    & Live Card (活動卡⽚片,即時卡⽚片) • Low Frequency Rendering • High Frequency Rendering • Immersion (沉浸式體驗,獨佔式體驗)
  27. LiveCard

  28. Low Frequency Rendering

  29. public class LiveCardService extends Service { ! private LiveCard mLiveCard;

    private RemoteViews mLiveCardView; ! @Override public int onStartCommand(Intent intent, int flags, int startId) { if (mLiveCard == null) { mLiveCard = new LiveCard(this, "LiveCardDemo"); mLiveCardView = new RemoteViews(getPackageName(), R.layout.main_layout); // ... Intent menuIntent = new Intent(this, MenuActivity.class); menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0)); mLiveCard.publish(PublishMode.REVEAL); } return START_STICKY; } ! @Override public void onDestroy() { if (mLiveCard != null && mLiveCard.isPublished()) { mLiveCard.unpublish(); mLiveCard = null; } super.onDestroy(); } // ... } Low-frequency Livecard AndroidManifest.xml (因版⾯面限制,故隱藏省略部分內容)
  30. ! mLiveCardView.setTextViewText(R.id.sample_text, "Hello, World."); mLiveCard.setViews(mLiveCardView); Update Remote Views http://developer.android.com/reference/android/widget/RemoteViews.html

  31. Code Examples http://goo.gl/ceX1QI Referance: https://developers.google.com/glass/develop/gdk/live-cards Low-frequency Livecard Demo

  32. High Frequency Rendering

  33. @Override public int onStartCommand(Intent intent, int flags, int startId) {

    if (mLiveCard == null) { mLiveCard = new LiveCard(this, LIVE_CARD_TAG); ! mLiveCard.setDirectRenderingEnabled(true).getSurfaceHolder() .addCallback(mHelloDrawer); ! Intent menuIntent = new Intent(this, MenuActivity.class); menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0)); mLiveCard.attach(this); mLiveCard.publish(PublishMode.REVEAL); } else { mLiveCard.navigate(); } ! return START_STICKY; } @Override public void onDestroy() { if (mLiveCard != null && mLiveCard.isPublished()) { mLiveCard.unpublish(); } super.onDestroy(); } HelloService.java onStartCommand() & publish live card (因版⾯面限制,故隱藏省略部分內容)
  34. public class HelloDrawer implements DirectRenderingCallback { ! private SurfaceHolder mHolder;

    ! @Override public void surfaceCreated(SurfaceHolder holder) { mHolder = holder; } ! @Override public void surfaceDestroyed(SurfaceHolder holder) { mHolder = null; } ! public void draw() { Canvas canvas; try { canvas = mHolder.lockCanvas(); } catch (Exception e) { return; } mHolder.unlockCanvasAndPost(canvas); } ! // ... } HelloDrawer.java SurfaceHolder (因版⾯面限制,故隱藏省略部分內容)
  35. public HelloDrawer(Context context) { mView = new HelloView(context); mView.setListener(mListener); this.context

    = context; } ! @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // Measure and layout the view with the canvas dimensions. int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); ! mView.measure(measuredWidth, measuredHeight); mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight()); draw(); } ! public void draw() { Canvas canvas = mHolder.lockCanvas(); // ... mView.draw(canvas); // ... mHolder.unlockCanvasAndPost(canvas); } HelloDrawer.java Init HelloView & Drawing (因版⾯面限制,故隱藏省略部分內容)
  36. public HelloView(Context context, AttributeSet attrs, int style) { super(context, attrs,

    style); ! LayoutInflater.from(context).inflate(R.layout.card_main, this); sampleTextview = (TextView) findViewById(R.id.sample_txt); updateText(); } ! protected void updateText() { if (mChangeListener != null) { mChangeListener.onChange(); // call draw() to update view } } ! public void changeText(String text) { sampleTextview.setText(text); updateText(); } HelloView.java Inflate View & Change text (因版⾯面限制,故隱藏省略部分內容)
  37. @Override public void surfaceCreated(SurfaceHolder holder) { // ... context.registerReceiver(mBroadcast, new

    IntentFilter(MY_MESSAGE)); } ! @Override public void surfaceDestroyed(SurfaceHolder holder) { // ... context.unregisterReceiver(mBroadcast); } ! private BroadcastReceiver mBroadcast = new BroadcastReceiver() { @Override public void onReceive(Context mContext, Intent mIntent) { if (mIntent.getAction().equals("change_text")) { mView.changeText("I'm lovin' it."); } } }; HelloDrawer.java BroadcastReceiver (因版⾯面限制,故隱藏省略部分內容)
  38. Code Examples Referance: https://developers.google.com/glass/develop/gdk/live-cards http://goo.gl/6M4gnG HelloGlass

  39. Immersion ?

  40. public class HelloActivity extends Activity { ! private TextView sampleTextview;

    ! @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.card_main); ! sampleTextview = (TextView) findViewById(R.id.sample_txt); } } As same as android :D
  41. Voice trigger ok glass, show me a demo

  42. Voice trigger AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.helloglass" android:versionCode="1" android:versionName="1.0" > !

    <uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" /> ! <application> <service android:name=".HelloService" android:icon="@drawable/ic_note" android:label="@string/app_name" > <intent-filter> <action android:name="com.google.android.glass.action.VOICE_TRIGGER" /> </intent-filter> <meta-data android:name="com.google.android.glass.VoiceTrigger" android:resource="@xml/voice_trigger_start" /> </service> </application> </manifest> (因版⾯面限制,故隱藏省略部分內容)
  43. Voice trigger • res/xml/voice_trigger_start.xml • res/values/strings.xml ! <?xml version="1.0" encoding="utf-8"?>

    <trigger keyword="@string/glass_voice_trigger" /> <?xml version="1.0" encoding="utf-8"?> <resources> <string name="glass_voice_trigger">Hello Glass Activity</string> </resources>
  44. VoiceTriggers.Command • add an event • calculate • call me

    a car • capture a panorama • check me in • check this out • control my car • control my home • explore nearby • explore the stars • find a bike • find a dentist • find a doctor • find a hospital • find a passage • find a place • find a place to stay • find a product • find a recipe • find a video • find a website • find reviews • find the exchange rate • find the price • flip a coin • give me feedback • help me sign in • keep me awake • learn an instrument • learn a song Pick one you like !
  45. Layout

  46. Layout • https://developers.google.com/glass/develop/gdk/ui-widgets • https://developers.google.com/glass/design/style • Screen Size: 640 x

    320 • Padding: 40 x 40 • Bottom Bar: 560 x 40
  47. Layout

  48. Touch input

  49. Keypad Swipe down translates to KEYCODE_BACK. A camera button press


    translates to KEYCODE_CAMERA. Tap translates to KEYCODE_DPAD_CENTER.
  50. Keypad @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if

    (keyCode == KeyEvent.KEYCODE_CAMERA) { // ... return true; } return false; } @Override public boolean onKeyLongPress(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_CAMERA) { // ... return true; } return false; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_CAMERA) { // ... return true; } return false; } MainActivity.java
  51. ! @Override public boolean onGenericMotionEvent(MotionEvent event) { if (mGestureDetector !=

    null) { return mGestureDetector.onMotionEvent(event); } return false; } ! public GestureDetector mGestureDetector; ! @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.control_main); ! mGestureDetector = createGestureDetector(this); } GestureDetector MainActivity.java
  52. ! private GestureDetector createGestureDetector(Context context) { GestureDetector gestureDetector = new

    GestureDetector(context); // Create a base listener for generic gestures gestureDetector.setBaseListener(new GestureDetector.BaseListener() { @Override public boolean onGesture(Gesture gesture) { if (gesture == Gesture.TAP) { Log.v(TAG, "TAP"); ! return true; } else if (gesture == Gesture.TWO_TAP) { Log.v(TAG, "TWO_TAP"); ! return true; } return false; } }); return gestureDetector; } GestureDetector MainActivity.java
  53. • SWIPE_DOWN • TWO_SWIPE_DOWN • SWIPE_LEFT • TWO_SWIPE_LEFT • SWIPE_RIGHT

    • TWO_SWIPE_RIGHT • SWIPE_UP • TWO_SWIPE_UP Gestures • TAP • TWO_TAP • THREE_TAP • LONG_PRESS • TWO_LONG_PRESS • THREE_LONG_PRESS
  54. Q & A

  55. http://fb.com/groups/glassdev.taiwan Google glass developer Taiwan