Tutorial 3: Android and GDK (Glass Development Kit)
The Glass Class at HIT Lab NZ
Learn how to program and develop for Google Glass.
https://www.youtube.com/watch?v=BRpedu1PRf8&list=PLsIGb72j1WOlLFoJqkhyugDv-juTEAtas
http://arforglass.org
http://www.hitlabnz.org
1. The Glass Class: Android & GDK
July 7th – 11th 2014
Mark Billinghurst, Gun Lee
HIT Lab NZ
University of Canterbury
2. An Introduction to
Glassware Development
GDK
Gun Lee
* Images in the slides are from variety of sources,
including http://developer.android.com and http://developers.google.com/glass
3. Glassware Development
Mirror API
Server programming, online/web application
Static cards / timeline management
GDK
Android programming, Java (+ C/C++)
Live cards & Immersions
https://developers.google.com/glass/
4. GDK
Glass Development Kit
Android 4.4.2 + Glass specific APIs
Use standard Android Development Tools
5. GDK
GDK add-on features
Timeline and cards
Menu and UI
Touch pad and gesture
Media (sound, camera and voice input)
6. Dev. Env. Setup
JDK (1.6 or above, using 1.7 for the tutorial)
http://www.oracle.com/technetwork/java/javase/downl
oads/index.html
ADT Bundle (Eclipse + Android SDK)
http://developer.android.com/sdk/index.html
With Android SDK Manager (select Window>Android
SDK Manager from Eclipse menu) install:
- Tools > Android Build-tools (latest version)
- Android 4.4.2 (API19) SDK Platform, Google APIs, Glass
Development Kit Preview
- Extras > Google USB Driver (only for Windows Platform)
8. Android App Components
Activity
A single screen with a user interface.
Most widely used main component.
Service
Performs operations in the background
without a user interface.
Content provider
Manages a shared set of app data.
Broadcast receiver
Responds to system-wide broadcast announcements.
9. Activities & Back Stack
An app usually consists of multiple activities that
are loosely bound to each other.
An app launches with the "main" activity
An activity can start another activity.
Navigation between activities managed in Back Stack
10. Intent and Activity
An Intent is a messaging object used to request
an action from another app component.
Start an Activity or Service, or broadcast.
Target component can be either
explicit(class name) or implicit (intent filter)
Can carry extra information (key-value pairs)
http://developer.android.com/guide/components/intents-filters.html
13. Create an Android App Project
In Eclipse
File > New > (Other > Android>)
Android Application Project
Fill in the Application name, Project name, and
Java package namespace to use
Choose SDK API 19: Android 4.4.2 for all SDK
settings
Minimum Required SDK might need to be lower
version (API 15) to match your device
Use default values for the rest
14. Anatomy of an Android App Project
Android App Project
AndroidManifest.xml
- Package name, version, SDK ver., app settings &
permissions, app components (activities)
src (source folder)
- Java classes organized in namespaces
res (resource folder)
- layout, drawable, menu, values, raw, xml
gen (generated Java files)
- res identifier classes
assets (other raw assets)
15. Live Demo
- Creating a new Android App Project
- Anatomy of an Android App Project
16. User Interface Layout
Views
Draw on screen + Handle events = UI elements
(labels, input controls, ...)
Group views with layouts
LinearLayout, RelativeLayout, ...
Layout parameters
XML+GUI (res/layout) or Java code
http://developer.android.com/guide/topics/ui/overview.html
17. Handling UI Events
XML android:onClick attribute designates
the name of a public method in your
Activity to handle the click event
public void yourHanlderMethod(View v)
<Button
…
android:text=“Send"
android:onClick=“sendMessage" />
public void sendMessage(View v) {
// Do something on button click
}
res/layout/layout.xml MyActivity.java
http://developer.android.com/guide/topics/ui/controls/button.html
18. Toast
Provides simple feedback about an
operation in a small popup.
Brief notification message
Customizable view
Toast.makeText(this,
“Message sent.", Toast.LENGTH_SHORT).show();
// Toast with custom view
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(viewWithLayout);
toast.show();
http://developer.android.com/guide/topics/ui/notifiers/toasts.html
20. Handling views in runtime
Programmatically referencing to views (UI
elements) in an Activity
View findViewById(int resId)
Listeners = Java interface
Button button = (Button)findViewById(R.id.button_reset);
button.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// Do something in response to button click
}
}
);
http://developer.android.com/guide/topics/ui/controls/button.html
http://developer.android.com/guide/topics/ui/ui-events.html
21. Menu
Fill in the options menu items at creation
onCreateOptionsMenu(Menu menu)
Default implementation loads xml resource in
res/menu/main.xml
Override callback method in the Activity
onOptionsItemSelected(MenuItem item)
item.getItemId() gives resource id of the item
http://developer.android.com/guide/topics/ui/menus.html
26. More Information
User Interface
http://developer.android.com/guide/topics/ui
Animation and Graphics
http://developer.android.com/guide/topics/graphics
Data Storage
http://developer.android.com/training/basics/data-storage
http://developer.android.com/guide/topics/data
Media and Camera
http://developer.android.com/guide/topics/media
Location and Sensors
http://developer.android.com/guide/topics/sensors
Connectivity and Networking
http://developer.android.com/guide/topics/connectivity
http://developer.android.com/reference/java/net/package-summary.html
34. Live Cards vs. Immersions
Live cards display frequently updated
information to the left of the Glass clock.
Integrate rich content into the timeline
Simple text/images to full-blown 3D graphics
Immersions let you build a user
experience outside of the timeline.
Build interactive experiences
Extra control, less user input constraints
38. Develop with GDK
Android 4.4.2 (API 19) SDK and GDK Preview
from the Android SDK Manager.
Project settings:
Minimum and Target SDK Versions: 19
Compile with: GDK Preview
Theme: None (allows the Glass theme to be applied.)
GDK samples
File > New Project > Android Sample Project
On Glass, turn on USB debugging
Settings > Device Info > Turn on debug
39. Hello World - Immersion
App/Activity without theme
Allows the Glass theme to be applied.
Add voice trigger for launching
Touch input and Menu
Voice recognition for text input
41. Voice Trigger for Launching
Add intent filter your main Acivitiy in
AndroidManifest.xml
Add xml/voice_trigger.xml to res folder
Can use additional follow up voice recognition
prompt if needed
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="hello world" />
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
…
<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" />
https://developers.google.com/glass/develop/gdk/input/voice
42. Official Voice Triggers on MyGlass
listen to
take a note
post an update
show a compass
start a run
start a bike ride
find a recipe
record a recipe
check me in
start a stopwatch
start a timer
start a round of golf
translate this
learn a song
tune an instrument
play a game
start a workout
https://developers.google.com/glass/develop/gdk/input/voice
43. Live Demo
- Apply Glass Theme (remove Theme)
- Add Voice Trigger for Launching
44. Touch Input as Key Input
Touch input translated as DPAD key input
Tap => KEYCODE_DPAD_CENTER
Swipe down => KEYCODE_BACK
Camera button => KEYCODE_CAMERA
https://developers.google.com/glass/develop/gdk/input/touch
@Override
public boolean onKeyDown(int keycode, KeyEvent event) {
if (keycode == KeyEvent.KEYCODE_DPAD_CENTER) {
// user tapped touchpad, do something
return true;
}
…
return false;
}
45. Touch Input
onGenericMotionEvent(MotionEvent e)
https://developers.google.com/glass/develop/gdk/input/touch
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onGenericMotionEvent(event);
}
46. Touch gestures
GDK provides GestureDetector for Glass
com.google.android.glass.touchpad.GestureDetector
- NOT android.view.GestureDetector
BaseListener, FingerListener, ScrollListener,
TwoFingerScrollListener
Pass MotionEvent from onGenericMotionEvent()
gestureDetector.onMotionEvent(event);
https://developers.google.com/glass/develop/gdk/input/touch
https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/touchpad/GestureDetector
48. Menu
Open options menu on tap
openOptionsMenu()
Add 50x50 pixel icons in the menu
resource XML
android:icon="@drawable/icon"
- https://developers.google.com/glass/tools-
downloads/menu_icons.zip
Show/hide/update menu items if needed
onPrepareOptionsMenu()
https://developers.google.com/glass/develop/gdk/ui/immersion-menus
50. Voice Input
Start activity for result with system action
Customize prompt with intent extra
Recognized strings returned in intent data
of onActivityResult()
https://developers.google.com/glass/develop/gdk/input/voice
intentData.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
http://developer.android.com/reference/android/speech/RecognizerIntent.html
intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
startActivityForResult(intent, 0);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
"What is your name?");
52. Hello World - Immersion ++
Play Sounds & Text-to-speech
Take a picture with camera
Card based info page
53. Playing Sounds & TTS
Glass system sounds
Text-to-speech
Create/destroy TTS in onCreate/onDestroy()
https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/media/Sounds
AudioManager am =
(AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.playSoundEffect(Sounds.ERROR);
// DISALLOWED, DISMISSED, ERROR, SELECTED, SUCCESS, TAP
TextToSpeech tts = new TextToSpeech(context, ttsOnInitListener);
…
tts.speak(“Hello world!”, TextToSpeech.QUEUE_FLUSH, null);
tts.shutdown();
http://developer.android.com/reference/android/speech/tts/TextToSpeech.html
54. Playing Custom Sounds
Put sound files in res/raw
Load sounds to SoundPool object to play
soundPool = new SoundPool(MAX_STREAM,
AudioManager.STREAM_MUSIC, 0);
int soundOneID = soundPool.load(context, R.raw.sound1, 1);
int soundTwoID = soundPool.load(context, R.raw.sound2, 1);
…
soundPool. play(int soundID, float leftVolume, float rightVolume,
int priority, int loop, float rate)
http://developer.android.com/reference/android/media/SoundPool.html
56. Camera
Calling the Glass built-in camera activity
with startActivityForResult() and Action
Intent, returned with file path to
image/video through Intent extra data.
Low level access to camera with the
Android Camera API.
http://developer.android.com/reference/androi
d/hardware/Camera.html
https://developers.google.com/glass/develop/gdk/media-camera/camera
57. Camera with Action Intent
https://developers.google.com/glass/develop/gdk/media-camera/camera
private void takePicture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {
String picturePath =
data.getStringExtra(Intents.EXTRA_PICTURE_FILE_PATH);
// smaller picture available with EXTRA_THUMBNAIL_FILE_PATH
processPictureWhenReady(picturePath); // file might not be ready for a while
}
super.onActivityResult(requestCode, resultCode, data);
}
59. Using Cards as Views
Create a Card object then call getView()
Card card = new Card(this);
card.setText("The HIT Lab NZ");
card.setFootnote("http://www.hitlabnz.org");
card.setImageLayout(ImageLayout.LEFT);
card.addImage(R.drawable.hitlabnz);
setContentView(card.getView());
https://developers.google.com/glass/develop/gdk/ui/theme-widgets
61. Scrolling Cards in Activity
Set a CardScrollView as the content view
Use a custom class extending the
CardScrollAdapter class to populate the
CardScrollView
https://developers.google.com/glass/develop/gdk/ui/theme-widgets
https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/widget/package-summary
CardScrollView cardScrollView = new CardScrollView(this);
cardScrollView.setAdapter(new InfoCardScrollAdapter());
cardScrollView.activate();
setContentView(cardScrollView);
62. Scrolling Cards in Activity
In your custom CardScrollAdapter class
Create a list of cards
Implement abstract methods in your custom
CardScrollAdapter class
- int getCount() => return the number of cards (items)
- Object getItem(int position) => return the card at the position
- View getView(int position, View convertView, ViewGroup
parentView) => return the view of the card at the position
- int getPosition(Object item) => find and return the position of
the given item (card) in the list. (return -1 for error)
https://developers.google.com/glass/develop/gdk/ui/theme-widgets
https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/widget/package-summary