Always On, Always Connected Week 8

Google Glass

Getting Started

If you have a new or factory reset pair here is where you start.

If you are checking out a pair that hasn't been factory reset, I would suggest doing that first. To do so, tap to turn it on. When you see the time and "ok glass", swipe back until you see "Settings" and then tap. Then swipe forward until you see "Device info" and tap. Swipe forward until you see "Factory reset" and tap and then tap on "Confirm reset".

First of all, you need to have a regular Google account, so if you don't already, that is your first step.

Next, make sure the Glass is fully charged and you have full visibility of the screen.

You should see "Welcome to Glass!" and will have to follow a little getting started tutorial. When you get to the point where it says "Android", swipe forward until you see "Computer" and then on your computer go to https://glass.google.com/u/0/setup On that click the link that says "Continue setup on computer".

When you get to the "Connecting to Wifi" portion, you will have to put in the wifi information for the network that you have available. If you are at ITP, you can use the "itpsandbox" network. The password is "NYU+s0a!+P?". Our Glass are already registered on this network so they should be able to connect without a problem.

Once you scan the QR code, the Glass will be setup under your Google user. Please remember (for both your sake and whomever uses the Glass after you) to do a "Factory Reset" when you are done.

More Information:
Google Glass Help - Getting Started

Developing for Glass

There are two APIs for developing with Glass. The first is the Mirror API which is a web services based API. The second, is the GDK which is essentially regular Android development but with a few extra Glass specific libraries which is what we'll focus our attention on.

Glass Development Kit

Glass Developers

To get started, we need to enable Debugging on our Glass. To do so scroll to Settings, tap and then scroll to Device info, tap and then scroll to Turn on debug and tap. This will allow you to load applications through the ADT/Eclipse as we do on phones.

Now we can get started building apps: GDK Quick Start

Sample Manifest: Take note of the icon in the "activity" and the immersive="true" attribute.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mobvcasting.glassapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        >
        <activity
            android:name="com.mobvcasting.glassapp.MainActivity"
            android:label="@string/app_name" 
            android:icon="@drawable/ic_launcher"
            android:immersive="true">
        	<intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>			
			

Gesture Detection in an Activity: Since we don't have a keyboard or a touch screen, this is how we can get user input.

package com.mobvcasting.glassapp;

import java.util.ArrayList;

import com.google.android.glass.touchpad.Gesture;
import com.google.android.glass.touchpad.GestureDetector;

import android.os.Bundle;
import android.app.Activity;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.TextView;

public class MainActivity extends Activity {

	TextView textView;
	GestureDetector gestureDetector;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		textView = (TextView) this.findViewById(R.id.textview);
		
		gestureDetector = new GestureDetector(this);
		gestureDetector.setBaseListener( new GestureDetector.BaseListener() {
            @Override
            public boolean onGesture(Gesture gesture) {
                if (gesture == Gesture.TAP) {
                    // do something on tap
                	textView.setText("Tap");
                    return true;
                } else if (gesture == Gesture.TWO_TAP) {
                    // do something on two finger tap
                	textView.setText("Two Finger Tap");
                    return true;
                } else if (gesture == Gesture.SWIPE_RIGHT) {
                    // do something on right (forward) swipe
                	textView.setText("Swipe Forward");
                    return true;
                } else if (gesture == Gesture.SWIPE_LEFT) {
                    // do something on left (backwards) swipe
                	textView.setText("Swipe Backwards");
                    return true;
                }
                return false;
            }
        });
		/*
        gestureDetector.setFingerListener(new GestureDetector.FingerListener() {
            @Override
            public void onFingerCountChanged(int previousCount, int currentCount) {
              // do something on finger count changes
            	textView.setText("" + currentCount + " Fingers");

            }
        });
        */
        /*
        gestureDetector.setScrollListener(new GestureDetector.ScrollListener() {
            @Override
            public boolean onScroll(float displacement, float delta, float velocity) {
                // do something on scrolling
            	textView.setText("Scrolling");
            	return true;
            }
        });
        */
	}

	 /*
     * Send generic motion events to the gesture detector
     */    
	@Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        if (gestureDetector != null) {
            return gestureDetector.onMotionEvent(event);
        }
        return false;
    }
    
	@Override
    public boolean onKeyDown(int keycode, KeyEvent event) {
        if (keycode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // Tap
        	textView.setText("Tap");
            return true;
        }
        else if (keycode == KeyEvent.KEYCODE_BACK) {
        	// Swipe Down
        	textView.setText("Swipe Down");
        	return false;
        }
        return false;
    }
}			
			

Starting an app: Glass apps can be launched from the Ok Glass menu by supplying a few things.
First we need to create a phrase for launching the app in our strings.xml:

<string name="glass_voice_trigger">launch my app</string>
			
Then we need to create a new xml file in our res/xml folder with a good name (such as voice_trigger_start.xml). This will point to the string we just created:
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="@string/glass_voice_trigger" />
			
Finally, we need to add an "intent-filter" to our Activity in our manifest file that states that we'll use this trigger:
<activity
	android:name="com.mobvcasting.glassapp.MainActivity"
	android:label="@string/app_name" 
	android:icon="@drawable/ic_launcher"
	android:immersive="true">
	<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" />
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
</activity>