Jak vyvinout úspěšnou aplikaci pro Google GlassMartin Pelant
Prism: 640x360 (25" HDTV as seen from 8')
Camera: 5 MP, 720p videos
CPU: OMAP 4430 CPU, dual-core
Memory: 2 GB RAM, 12 GB usable flash memory
Battery: 570 mAh, (1 day of typical use)
Connectivity: Wi-Fi, Bluetooth 4.0
Sound: Bone Conduction Transducer, microphone
Other: ambient light, proximity, IR sensor; gyroscope;
accelerometer; compass
OS: Android 4.4
Weight: about 43 g
Design for Glass
Don't get in the way
Keep It relevant
Avoid the Unexpected
Development
● Mirror API
o Server side development
o Static cards
● Glass Development Kit
o Offline app that runs on Glass directly
o Live cards & full screen apps (Immersion)
Mirror API
● REST● bootstrap projects for Java, .NET, PHP,
Python, GO, Ruby● Installation - OAuth 2.0 web page
Static card
Timeline cards● text● HTML● images● videos● map● location (option to start directions)● menu items● bundles
Playground
POST /mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: application/json
Content-Length: 26
{ "text": "Hello world" }
Menu items● reply (speech input)● read aloud● share (sharing contacts)● get directions● make a call● delete● pin● custom actions
{
"text": "Are you ready for game night this Saturday?",
"menuItems": [
{
"action": "REPLY"
}
]
...
}
Subscriptions● menu item changes● location changes
o limit 1 callback per 10 min
● like Android intents● mime-types● voice commands:
o “take a note”o “post an update”
Sharing contacts
Glass Development Kit
● Android SDK API v 19● no touchscreen● small screen
<style name="CustomTheme" parent=
"@android:style/Theme.DeviceDefault"
/>
android {
compileSdkVersion "Google Inc.:Glass Development Kit Preview:19"
…}
Card card1 = new Card(context);
card1.setText("This card has a footer.");
card1.setFootnote("I'm the footer!");
View card1View = card1.getView();
res/xml/<my_voice_trigger>.xml
<?xml version="1.0" encoding="utf-8"?>
<trigger command="PLAY_A_GAME" />
<activity | service ...>
<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/my_voice_trigger" />
</activity | service>
AndroidManifest.xml
Unlisted commands permission
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
res/xml/<my_voice_trigger>.xml
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="start my app" />
res/xml/<my_voice_trigger>.xml
<?xml version="1.0" encoding="utf-8"?>
<trigger command="TAKE_A_NOTE">
<input prompt="@string/glass_voice_prompt" />
</trigger>
res/xml/<my_voice_trigger>.xml
<?xml version="1.0" encoding="utf-8"?>
<trigger command="POST_AN_UPDATE">
<constraints
microphone="true"
camera="true"
network="true" />
</trigger>
Immersion
Menu
The same onCreateOptionsMenu from Android SDK
public class MainActivity extends Activity { // ... @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { openOptionsMenu(); return true; } return super.onKeyDown(keyCode, event); }}
Voice commands
Voice commands
@Overridepublic boolean onCreatePanelMenu(int featureId, Menu menu) { if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) { menu.add("Connect").setOnMenuItemClickListener(...);
menu.add("Scan").setOnMenuItemClickListener(...);menu.add("Cancel").setOnMenuItemClickListener(...);
} // Pass through to super to setup touch menu. return super.onCreatePanelMenu(featureId, menu);}
getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS);
Live card
Creating live cards
TimelineManager tm = TimelineManager.from(context);
mLiveCard = tm.createLiveCard(LIVE_CARD_TAG);
mLiveCard.setViews(new RemoteViews(context.getPackageName(),
R.layout.card_text));
mLiveCard.publish(LiveCard.PublishMode.REVEAL); // or SILENT
Updating live cards
mRemoteViews.setTextViewText(R.id.text, "new message");
mLiveCard.setViews(mRemoteViews);
Removing live cards
mLiveCard.unpublish();
Menu in live cards
Starting menu activity
Intent menuIntent = new Intent(this,MenuActivity.class);
mLiveCard.setAction(PendingIntent.getActivity(this, 0,
menuIntent, 0));
mLiveCard.publish(LiveCard.PublishMod
e.REVEAL);
@Override public void onAttachedToWindow() { super.onAttachedToWindow(); openOptionsMenu(); }
@Override public void onOptionsMenuClosed(Menu menu) { // Nothing else to do, closing the activity. finish(); }
Menu activity
Making menu activity transparent
<style name="MenuTheme" parent="@android:style/Theme.DeviceDefault">
<item name="android:windowBackground">@android:color/transparent
</item> <item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item> <item
name="android:windowAnimationStyle">@null</item></style>
Field trip
Glass Tesla
LynxFit
Word Lens
Google Play Music