The Glass Class - Tutorial 2 - Mirror API
-
Upload
gun-lee -
Category
Technology
-
view
120 -
download
1
description
Transcript of The Glass Class - Tutorial 2 - Mirror API
![Page 1: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/1.jpg)
The Glass Class: Mirror API
July 7th – 11th 2014
Mark Billinghurst, Gun Lee
HIT Lab NZ
University of Canterbury
![Page 2: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/2.jpg)
An Introduction to
Glassware Development
Mirror API using Java Servlet
Gun Lee
* Images in the slides are from variety of sources,
including http://developer.android.com and http://developers.google.com/glass
![Page 3: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/3.jpg)
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/
![Page 4: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/4.jpg)
Mirror API
REST API
Java servlet, PHP, Go,
Python, Ruby, .NET
Timeline based apps
Static cards
- Text, HTML, media attachment (image & video)
- Standard and custom menu items
Manage timeline
- Subscribe to timeline notifications
- Sharing with contacts
- Location based services
https://developers.google.com/glass/develop/mirror/index
![Page 5: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/5.jpg)
Mirror API based Web App
3. Insert a static card
User sees the card
Glassware Web app
https://developers.google.com/glass/develop/mirror/stories
![Page 6: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/6.jpg)
Develop with Mirror API
Prepare a web server
https callback required for OAuth 2.0
Minimum storage for credentials
Create a Google APIs Console project
Enable Mirror API and get Client ID & secret
Create a web application
Java servlet, PHP, Go, Python, Ruby, .NET
Implement OAuth 2.0 authorization
Use Mirror API to make REST API calls
- Wrapper classes/methods provided
![Page 7: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/7.jpg)
Google App Engine
Free web server space!
You can skip this step if you have another server
Upgrade to paid service based on storage and traffic
needed
https://developers.google.com/appengine/
Python, Java, PHP, Go
Cloud Storage
Easy integration with Google APIs
![Page 8: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/8.jpg)
Google APIs Console
http://console.developers.google.com
Login with your own Google account
Create a New Project
The Project ID becomes your URL
- http://your-project-id.appspot.com
![Page 9: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/9.jpg)
Google APIs Console
In the project’s APIs & auth section,
enable Google Mirror API
![Page 10: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/10.jpg)
Google APIs Console
APIs & auth > Credentials > OAuth: Create
New Client ID
Choose "Web Application"
Type in your website and OAuth callback
address https://your-app-id.appspot.com
https://your-app-id.appspot.com/oauth2callback
![Page 11: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/11.jpg)
Google APIs Console
Note both Client ID and Client secret
![Page 12: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/12.jpg)
Google APIs Console
APIs & auth > Consent screen
Fill in the Product Name and Homepage URL
This information is shown when users
authorizing your web app
![Page 13: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/13.jpg)
Live Demo
- Setup Google App Engine
- Setup Google APIs Console
![Page 14: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/14.jpg)
Dev. Env. Setup
ADT Bundle (Eclipse + Andriod SDK)
http://developer.android.com/sdk/index.html
GAE plugin for Eclipse
http://dl.google.com/eclipse/plugin/4.2
- Google App Engine Tools for Android
- Google Plugin for Eclipse
- SDK > Google App Engine Java SDK
Sign in on Eclipse GAE plugin
Use the Google account that will host your
web app on GAE
![Page 15: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/15.jpg)
Create a Web App for GAE
File > New > (Other > Google > )
Web Application Project
Fill in the Project name and Java package
namespace to use
Check on option Use Google App Engine
Uncheck option Use Google Web Toolkit
Select option Use App Id then click Browse
button to choose your app id
Check on Generate project sample code
Click Finish
![Page 16: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/16.jpg)
Anatomy of a Web App Project
Web App Project
src (source folder)
- Java classes organized in namespaces
war (web application archive)
- WEB-INF (settings and JAR libraries)
• appengine-web.xml
• web.xml
• lib
- index.html
- favicon.ico
![Page 17: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/17.jpg)
Deploying to GAE
Right click on the Project
Google > Deploy to App Engine
Uncheck option Launch app in browser ...
Click Deploy
Open your GAE site on a browser
http://your-app-id.appspot.com
![Page 18: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/18.jpg)
Live Demo
- Creating a new Web App project
- Anatomy of a Web App project
- Deploy to GAE
![Page 19: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/19.jpg)
Adding Mirror API library
Right click on the Project
Google > Add Google APIs
Choose Google Mirror API
Click Finish
![Page 20: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/20.jpg)
Authorization with OAuth 2.0 Authorizing your web app to access timeline on user’s
Google account
Programming Google Glass - The Mirror API by Eric Redmond
http://pragprog.com/book/erpgg/programming-google-glass
![Page 21: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/21.jpg)
Authorization with OAuth 2.0
Enable HTTP sessions on GAE
Force https access only
Filter out inappropriate access
Implement OAuth 2.0 callback servlets
Code from Quick Start sample project
- https://developers.google.com/glass/develop/mirror
/quickstart/index
Add a new servlet to logout
https://developers.google.com/glass/develop/mirror/authorization
![Page 22: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/22.jpg)
Enable sessions on GAE
war/WEB-INF/appengine-web.xml
<appengine-web-app ...>
...
<sessions-enabled>true</sessions-enabled>
</appengine-web-app>
![Page 23: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/23.jpg)
Force https access only
war/WEB-INF/web.xml
<web-app ...>
...
<!-- force https only -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
...
</web-app>
![Page 24: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/24.jpg)
Define Auth Filters war/WEB-INF/web.xml
<web-app ...>
...
<!-- filters -->
<filter>
<filter-name>authFilter</filter-name>
<filter-class>com.google.glassware.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
<filter>
<filter-name>reauthFilter</filter-name>
<filter-class>com.google.glassware.ReauthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>reauthFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
</web-app>
![Page 25: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/25.jpg)
Define Auth Servlet
war/WEB-INF/web.xml <webapp ...>
…
<servlet>
<servlet-name>oauth2callback</servlet-name>
<servlet-class>com.google.glassware.AuthServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>oauth2callback</servlet-name>
<url-pattern>/oauth2callback</url-pattern>
</servlet-mapping>
...
</webapp>
![Page 26: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/26.jpg)
Add Java classes for Auth
Create com.google.glassware package in
the src folder
Right click on src folder > New > Package
Copy Java classes for Auth
Drag and drop the following .java files into the
created package
AuthFilter.java, AuthServlet.java,
AuthSettings.java, AuthUtil.java,
ReauthFilter.java, WebUtil.java
![Page 27: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/27.jpg)
Add Java classes for Auth
In AuthSettings.java
Fill in your CLIENT_ID and CLIENT_SECRET
strings you’ve noted from Google APIs
Console’s credential section
public static String CLIENT_ID =
"567615950876-14k9b9sggrtpulhu9s72le4vsejjscak.apps.googleusercontent.com";
public static String CLIENT_SECRET = "lo9hajhpQFneXP5K8YR0gEVK";
![Page 28: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/28.jpg)
Add a New Servlet for Logout
Add LogoutServlet class
Right click on your app package in src folder
New > Class
Name: LogoutServlet
Superclass: javax.servlet.http.HttpServlet
![Page 29: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/29.jpg)
Add a New Servlet for Logout
Implement LogoutServlet class
Open LogoutServlet.java
Source > Override/Implement Methods ...
Check on doGet(…) the click OK
Call AuthUtil.clearUserId(req) in the method
// log out
AuthUtil.clearUserId(req);
// print out results on the web browser
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().println(
"<html><head><meta http-equiv=\"refresh\" content=\"3;url=/index.html\"></head> " +
"<body>Good bye!<br></body></html>" );
![Page 30: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/30.jpg)
Add a New Servlet for Logout
Add servelt tag to war/WEB-INF/web.xml <webapp ...>
…
<servlet>
<servlet-name>Logout</servlet-name>
<servlet-class>org.hitlabnz.hw.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Logout</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
...
</webapp>
![Page 31: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/31.jpg)
Add a New Servlet for Logout
Add a link to the LogoutServlet in
index.html
<a href="logout">Logout</a>
![Page 32: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/32.jpg)
Live Demo
- Enable HTTP sessions on GAE
- Filter out inappropriate access
- Implement OAuth 2.0 callback
- Add logout servlet
![Page 33: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/33.jpg)
Get Access to Mirror API
In HelloWorldServlet class
Add method getMirror(req)
private Mirror getMirror(HttpServletRequest req) throws IOException {
// get credential
Credential credential = AuthUtil.getCredential(req);
// build access to Mirror API
return new Mirror.Builder( new UrlFetchTransport(),
new JacksonFactory(), credential)
.setApplicationName("Hello Glass!")
.build();
}
![Page 34: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/34.jpg)
Insert a Card to Timeline
In HelloWorldServlet class
Add code in doGet(...) method // get access to Mirror API
Mirror mirror = getMirror(req);
// get access to the timeline
Timeline timeline = mirror.timeline();
// create a timeline item (card)
TimelineItem timelineItem = new TimelineItem()
.setText( "Hello World!" )
.setDisplayTime(new DateTime(new Date()))
.setNotification(new NotificationConfig().setLevel("DEFAULT"));
// insert the card into the timeline
timeline.insert(timelineItem).execute();
![Page 35: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/35.jpg)
Insert a Card to Timeline
In HelloWorldServlet class
Modify code in doGet(...) method for richer
response on the web browser
// print out results on the web browser
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().println(
"<html><head>“ +
"<meta http-equiv=\"refresh\"content=\"3;url=/index.html\">" +
"</head> " +
"<body>A card is inserted to your timeline.<br></body></html>" );
![Page 36: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/36.jpg)
Live Demo
- Access to Mirror API
- Insert a Card into Timeline
![Page 37: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/37.jpg)
HTML in a Card
Follows CSS for the Glass UI https://mirror-api-playground.appspot.com/assets/css/base_style.css
String html = "<article><section><p class=\"text-auto-size\">" +
"<em class=\"yellow\">Hello World!</em><br>" +
"Welcome to the <strong class=\"blue\">Glass Class</strong> at HIT Lab NZ." +
"</p></section></article>";
timelineItem.setHtml(html);
![Page 38: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/38.jpg)
Google Mirror API Playground
https://developers.google.com/glass/tools-
downloads/playground
To try it with your Glass
Go to Google API console
- https://console.developers.google.com
- Login and open your project
Create a new Client ID with the following URL
- https://mirror-api-playground.appspot.com
Use the generated Client ID to authorize
access on the Playground site
![Page 39: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/39.jpg)
Multiple Pages in a Card
Auto paginate
Manually paginate
Multiple articles
<article class="auto-paginate">
Very long article ...
</article>
<article class="cover-only">
<section>
<p class="text-auto-size">This is the cover
page.</p>
</section>
</article>
<article>
<section>
This is second page.
</section>
</article>
<article>
<section>
Third page.
</section></article>
https://developers.google.com/glass/develop/mirror/timeline
![Page 40: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/40.jpg)
Grouping Multiple Cards
Bundle – a set of cards grouped under a
cover card (or the latest card)
timelineItem.setBundleId( “UniqueBundleID” )
timelineItem.setIsBundleCover( true );
https://developers.google.com/glass/develop/mirror/timeline
![Page 41: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/41.jpg)
Built-in Actions with Menu READ_ALOUD, DELETE, OPEN_URI, PLAY_VIDEO,
TOGGLE_PINNED, VOICE_CALL, NAVIGATE, REPLY,
SHARE
List<MenuItem> menuItemList = new ArrayList<MenuItem>();
menuItemList.add(new MenuItem().setAction("READ_ALOUD"));
timelineItem.setSpeakableText("Hello World!");
menuItemList.add(new MenuItem().setAction("TOGGLE_PINNED"));
menuItemList.add(new MenuItem().setAction("DELETE"));
timelineItem.setMenuItems(menuItemList);
https://developers.google.com/glass/develop/mirror/static-cards#creating_menu_items
![Page 42: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/42.jpg)
Live Demo
- Cards with HTML
- Add Menu Items
![Page 43: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/43.jpg)
Say hello to me
Add web form in index.html
Override doPost(...) method and get
parameter from the request
<form action="helloworld" method="post">
Hello <input type="text" name="custom_name" value="World"> !
<input type="submit" value="Submit">
</form>
String custom_name = req.getParameter("custom_name");
String message = "Hello " + custom_name = "!";
![Page 44: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/44.jpg)
Image attachment
Adding static resources to the server
Edit war/WEB-INF/web.xml
Add a folder named static under the war
folder and add image files in it
<web-app ...>
...
<static-files>
<include path="/static/*" />
</static-files>
...
</web-app>
![Page 45: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/45.jpg)
Image attachment
Attached image will be used as the
background of the card
In low-level HTTP Multipart attachment
// get an image to use with the card
URL url = new URL("http://hello-world-mirror.appspot.com/static/hitlabnz.jpg");
InputStreamContent attachment =
new InputStreamContent("image/jpeg", url.openStream());
// insert the card into the timeline
timeline.insert(timelineItem, attachment).execute();
https://developers.google.com/glass/develop/mirror/static-cards#inserting_a_timeline_item_with_media
![Page 46: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/46.jpg)
Live Demo
- Input from web forms
- Image attachment
![Page 47: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/47.jpg)
Managing Timeline Items
List
Delete
https://developers.google.com/glass/v1/reference/timeline/list
// request for list of the timeline items
Mirror.Timeline.List listRequest = timeline.list();
listRequest.setMaxResults(5L);
TimelineListResponse listResponse = listRequest.execute();
// retrieve results
List<TimelineItem> timelineItemList = listResponse.getItems();
mirror.timeline().delete(deleteItemId).execute();
![Page 48: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/48.jpg)
Update Pinned Timeline Item
Simulating Live Cards with Mirror API
Ask the user to pin the item
Update the item regularly TimelineItem timelineItem = getSavedTimelineItem();
// If a saved item exists, isn't deleted, and is pinned
if (timelineItem != null
&& !(timelineItem.getIsDeleted() != null && timelineItem.getIsDeleted()) &&
(timelineItem.getIsPinned() != null && timelineItem.getIsPinned()))
{
// update the pinned item
timelineItem.setHtml( new_html );
timeline.update( timelineItem.getId(), timelineItem ).execute();
} else {
// create a new one and save the id for latter use
}
https://developers.google.com/glass/v1/reference/timeline/update#examples
![Page 49: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/49.jpg)
Live Demo
- List Timeline Items
- Delete Timeline Items
![Page 50: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/50.jpg)
Location
Get latest known location
Draw maps in your card
Location location = mirror.locations().get("latest").execute();
double latitude = location.getLatitude();
double longitude = location.getLongitude();
https://developers.google.com/glass/develop/mirror/location
<article>
<figure>
<img src="glass://map?w=240&h=360&marker=0;42.369590,-71.107132"
height="360" width="240">
</figure>
<section>
<div class="text-auto-size">
<p>Map shown on the left</p>
</div>
</section>
</article>
![Page 51: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/51.jpg)
Navigate Menu Item
Set Location to the timeline item and add the
NAVIGATE menu item ...
timelineItem.setLocation(
new Location()
.setLatitude( -43.522087 )
.setLongitude( 172.582823 )
.setAddress("University of Canterbury, Ilam, Christchurch")
.setDisplayName("HIT Lab NZ") );
// add menu items with built-in actions
List<MenuItem> menuItemList = new ArrayList<MenuItem>();
menuItemList.add(new MenuItem().setAction("NAVIGATE"));
timelineItem.setMenuItems(menuItemList);
// insert the card to the timeline
timeline.insert(timelineItem).execute();
![Page 52: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/52.jpg)
Live Demo
- Locate My Glass
- Add a Navigation Card
![Page 53: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/53.jpg)
Subscriptions
Mirror API (server) calls back your web app with
notification POST
Your web app can subscribe to
Location updates
Timeline updates
- Share, reply, delete, custom menu item, launch with voice
Your web app must respond with a 200 OK
HTTP status code if no error occurred.
If not, Mirror API might resend notifications.
https://developers.google.com/glass/develop/mirror/static-cards#subscriptions
![Page 54: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/54.jpg)
Subscribe
Add subscription to the mirror api
Better check if already subscribing
Subscription subscription = new Subscription();
subscription.setCollection("locations"); // or "timeline"
subscription.setCallbackUrl("https://your_web_app/notification");
subscription.setUserToken( AuthUtil.getUserId(req) );
mirror.subscriptions().insert(subscription).execute();
![Page 55: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/55.jpg)
Unsubscribe
Add subscription to the mirror api // find subscription to delete
SubscriptionsListResponse subslist_resp =
mirror.subscriptions().list().execute();
List<Subscription> subsclist = subslist_resp.getItems();
String subscription_id_to_delete = null;
for (Subscription subsc : subsclist) {
if (subsc.getId().equals("locations")) { // or “timeline"
subscription_id_to_delete = subsc.getId();
break;
}
}
// delete the subscription
mirror.subscriptions().delete(subscription_id_to_delete).execute();
![Page 56: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/56.jpg)
Handle Notification Callback
Create a callback Servlet that
handles notification POST
responds with a 200 OK HTTP status code
Make sure your callback Servlet URL is
not filtered in AuthFilter.java
Use the user ID provided by
notification.getUserToken() to call Mirror
APIs subsequently
![Page 57: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/57.jpg)
Handle Notification Callback protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
// Respond with OK and status 200 to prevent redelivery
resp.setContentType("text/html");
Writer writer = resp.getWriter();
writer.append("OK");
writer.close();
// extract notification object
JsonFactory jsonFactory = new JacksonFactory();
Notification notification =
jsonFactory.fromInputStream(req.getInputStream(), Notification.class);
// Figure out the impacted user and get their credentials for API calls
String userId = notification.getUserToken();
Credential credential = AuthUtil.getCredential(userId);
Mirror mirror = new Mirror.Builder(new UrlFetchTransport(),
new JacksonFactory(), credential)
.setApplicationName("Hello World")
.build();
if (notification.getCollection().equals("locations")) { // or “timeline“
...
![Page 58: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/58.jpg)
Handle Notification Callback
Handling location updates
Handling timeline updates
User action type
- REPLY, DELETE, CUSTOM, LAUNCH, SHARE
// get notified location
Location location = mirror.locations().get(notification.getItemId()).execute();
location.getLatitude();
location.getLongitude();
...
// Get the timeline item which triggered notification
TimelineItem notifiedItem = mirror.timeline().get(notification.getItemId()).execute();
if(notification.getUserActions().contains(new UserAction().setType("REPLY")))
{
String message = "Hello " + notifiedItem.getText() + "!";
...
https://developers.google.com/glass/develop/mirror/subscriptions
![Page 59: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/59.jpg)
Live Demo
- Subscribe to Location Updates
- Subscribe to Timeline Updates:
REPLY
![Page 60: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/60.jpg)
Contact
LAUNCH and SHARE user actions need
contact of your web app
Contact helloWorldContact = new Contact();
helloWorldContact.setId("org.hitlabnz.helloworld");
helloWorldContact.setDisplayName("Hello World");
ArrayList<String> imageUrlList = new ArrayList<String>();
imageUrlList.add("http://hello-world-mirror.appspot.com/static/hitlabnz.jpg");
helloWorldContact.setImageUrls(imageUrlList);
ArrayList<Command> commandList = new ArrayList<Command>();
commandList.add(new Command().setType("POST_AN_UPDATE")); // TAKE_A_NOTE
helloWorldContact.setAcceptCommands(commandList);
https://developers.google.com/glass/develop/mirror/contacts
https://developers.google.com/glass/develop/mirror/subscriptions
![Page 61: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/61.jpg)
Live Demo
- Subscribe to LAUNCH
![Page 62: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/62.jpg)
DIY
- CUSTOM menu item
- Subscribe to SHARE
https://developers.google.com/glass/develop/mirror/contacts
https://developers.google.com/glass/develop/mirror/subscriptions
![Page 63: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/63.jpg)
More Tips
Templates
JSP
http://freemarker.org
Scheduled jobs on server
CRON settings on GAE
Programming Google Glass - The Mirror API
By Eric Redmond
http://pragprog.com/book/erpgg/programming-google-glass
Quick Start Samples https://developers.google.com/glass/develop/mirror/quickstart/in
dex
![Page 64: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/64.jpg)
Sample Code Online
Mirror-QuickStartSample-Java-GAE
https://glass-mirror-java-sample.appspot.com
Mirror0-HelloGlass
https://hello-glass-mirror.appspot.com
Mirror1-HelloWorld
https://hello-world-mirror.appspot.com
![Page 65: The Glass Class - Tutorial 2 - Mirror API](https://reader034.fdocuments.in/reader034/viewer/2022052504/54c87fa24a7959b10b8b4575/html5/thumbnails/65.jpg)
More Information
Website
https://developers.google.com/glass
http://arforglass.org
http://www.hitlabnz.org
Gun Lee
Mark Billinghurst