[FoRK] Hacking for Fun: Programming a Wearable Android Device

Eugen Leitl eugen at leitl.org
Tue Sep 18 06:40:10 PDT 2012


http://www.drdobbs.com/tools/hacking-for-fun-programming-a-wearable-a/240007471#.UFeIgfMGZ_0.reddit


Hacking for Fun: Programming a Wearable Android Device

By Mike Riley, September 18, 2012

A look at Recon Instruments' MOD Live Heads-Up Display and the ease of creating and programming useful, on-person computing devices.

If you had the chance to watch (or were even one of the lucky attendees at) the Google I/O 2012 opening keynote, you may recall the exciting moment when Sergey Brin proclaimed the arrival of the Google Glass prototypes to the attendees. Alas, Glass prototype pre-orders cost a cool $1,500 for some future delivery date. This led many developers, including me, to reassess their desire to build an Android-centric, HUD-based application.

But for the astute developers attending the remainder of the conference or watching the real-time streams of the various sessions, all was not entirely lost. Of the announcements being made, one company offered developers a competitively priced Android-based heads-up display (HUD) system that was ready and open for business. Canadian-based Recon Instruments created the first release of their MOD Live system to be predominantly used by high-tech skiers and snowboarding enthusiasts.

Recon Instruments was co-founded in 2008 by four students at the University of British Columbia. One of those students is the company's CEO, Dan Eisenhardt. Being a competitive swimmer, his initial plan was to develop a HUD for swimmers. However, due to the complexities and potential damage of electronic components in water, he refocused the company's efforts on snow sports instead.


Figure 1: MODLive control puck.

By tucking their 428x240 pixel WQVGA heads-up display in the lower right corner of ski goggles, Recon has effectively created an unobtrusive HUD with a decent 600 MHz ARM Cortex A8 processor running Android 2.3.3 (Eclair). Network connections can be made via a Bluetooth-paired Android smartphone running Recon's MOD Live application. The app also provides the ability to answer phone calls, receive and read SMS messages, control audio playback, and map and store GPS coordinates for ski run playback and review.


Figure 2: Inside the MODLive Goggles with the Heads-Up Display (HUD) in the lower right corner.

MOD Live's interface is manipulated via a 4-way directional wireless control puck. This puck can be strapped on like a wrist watch, and is water resistant to withstand being wrapped around the outside sleeve of a ski jacket. The puck also houses MOD Live's GPS unit, and the control buttons are easy enough to find and press even while wearing thick gloves. In general, the whole system is intended to withstand a rugged, snowy outdoor excursion. And yet, because it can have its processor housing and LCD display inconspicuously seated in Recon-ready snow goggles like the Briko Veloce, developers can obtain MOD Live today and immediately start building the HUD apps of their dreams.


Figure 3: A close-up of the Recon Instruments MODLive water resistant control puck.

Note that MOD Live isn't intended to replicate the Google Glass experience. Unlike Glass, MOD Live does not sport an integrated webcam (though a Contour+ Bluetooth video streaming camera can be added if you're willing to spend an additional $500 for the privilege). It also doesn't have any on-board audio device and instead relies on a paired Bluetooth phone for controlled audio output. MOD Live also does not have any WiFi or cellular radios on board. Instead, network connections need to proxy through a Bluetooth connection and rely upon the paired Android smartphone to perform network handshakes and data retrieval.

Given its small, lightweight size and the unlikely scenario of a WiFi access point in range of a swiftly moving outdoor snow sport enthusiast, these restrictions are understandable. Still, after reviewing the Android-based WIMM One watch and witnessing how power-efficient the WiFi chip was in that small wearable product, the addition of such a radio in the MOD Live would have certainly made developing apps for the MOD Live platform a little easier.


Figure 4: A view of the MODLive Dashboard icon.
Developing a MOD Live App

After getting acquainted with the MOD Live hardware, I started dreaming up useful applications that would effectively leverage the platform while utilizing the variety of functions available in the MOD Live SDK. While the primary use case for the device is intended for snow sports requiring goggles, I thought about an app that could be used in skiing, snowboarding, motocross, snowmobiling, and other long-distance outdoor events that make wearing goggles nearly mandatory.

Having recalled a time when I unknowingly ventured out into the snow shortly before the onset of a blizzard, I would have greatly benefited from that knowledge with an app telling me that a snowstorm was coming straight for me and would hit in half an hour. Sure, I could repeatedly scrape the national weather forecast website for current conditions, but that would have been expensive in terms of both battery and bandwidth.

Fortunately, iOS app developer The Dark Sky Company has already done all the hard work of weather data collection and statistical analysis and packaged it in a tidy JSON-based Web service. Their app for iOS, called "Dark Sky," uses this SDK and it works surprisingly well. I have been using it for months, and it still amazes me how uncannily accurate it has been in predicting when rainfall will start and stop in my area within minutes of the real-world event.

The developers of Dark Sky offer free API keys to interested developers for testing and development purposes. Of course, the hope is that you will incorporate their Web service into your app and ultimately offer a percentage of your apps sales as a result. But in the meantime, all you need to do to obtain an API key is visit their developer site and submit your name, email address, and account password so they can send you an API key. You can revoke and request new keys at any time by logging in with your Dark Sky account credentials.
Coding the App

Similar to my experiences developing for other Android embedded hardware like the WIMM One watch or the Parrot Asteroid car radio, I had to recalibrate my application expectations when writing an Android application for the MOD Live platform.

I first had to create a Android Virtual Device (AVD) that matched MOD Live's 428x240 pixel context. Recon Instruments notes that a MOD Live emulator is one of the SDK items on their to-do list, but for now, Android developers will need to either attempt to simulate the MOD Live display via a custom AVD or push and debug the app on to the MOD Live hardware itself.


Figure 5: Coding the MODLive Dark Sky API assisted application.

In addition to limited network connectivity, power and storage constraints, Recon Instruments have extended the Android UI classes to account for the small viewing surface of the HUD. Fortunately, these custom classes go a long way toward improving the user experience, especially when it comes to reading numerical values. In my case, I needed to convey the probability of adverse weather conditions within a 60 minute timeframe based on the MOD Live's GPS latitude and longitude coordinates.

The Dark Sky API also supplies several other values, including current temperature, weather conditions (clear, rain, sleet, snow), a concise 24-hour forecast, and a stream of probabilities of inclement weather occurring over the next couple hours. Since the MOD Live control puck has a temperature sensor embedded in it, I opted to use that data source rather than the value being supplied by Dark Sky. I also narrowed the forecast results to the next hour, since that would be most appropriate for those already outdoors and on the slopes or race circuit to determine if they have enough time to get that last run in before bad weather hits.

After studying the nicely documented sample Recon SDK Application, I sketched the layout of the single screen UI of the program. Next, I launched Eclipse and created a new Android 2.3.3 (Eclair, API Level 9) application. Then, in addition to the usual Android app, content, OS, and widget libraries, I imported Recon's SDK and custom Web API libraries:

import com.reconinstruments.ReconSDK.*;
import com.reconinstruments.webapi.SDKWebService;
import com.reconinstruments.webapi.SDKWebService.ResponseListener;
import com.reconinstruments.webapi.WebRequestMessage.WebMethod;
import com.reconinstruments.webapi.WebRequestMessage.WebRequestBundle;

The first call I made to the ReconSDK was to poll the puck's on-board temperature sensor from the SDK's onReceiveCompleted event. Being in the U.S., where we have to be different from the rest of the world that uses the Celsius scale for temperature, I had to convert the value to Fahrenheit for the display value:

public void onReceiveCompleted(int status, ReconDataResult result)
{
	// check status first
  	if (status != ReconSDKManager.STATUS_OK)
  	{
Toast toast = Toast.makeText(this, 
     "Communication Failure with Transcend Service",    
     Toast.LENGTH_LONG);
  		toast.show();
  		return;
  	}
  		
  	// Grab on-board temperature sensor reading and convert to Fahrenheit
  	ReconTemperature temp = (ReconTemperature)result.arrItems.get(0);
  	the_current_temp = String.format(" %.2f", (temp.GetTemperature() * 1.8) + 32 );
  	mCurrentTemp.setText("Currently: " + the_current_temp + "F");
}

I also needed to capture the current latitude and longitude GPS coordinates from the MOD Live wrist puck so I could pass these values to the Dark Sky API for the current weather forecast information:

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context); 

Criteria mycriteria = new Criteria(); 
mycriteria.setAccuracy(Criteria.ACCURACY_FINE); 
mycriteria.setAltitudeRequired(false); 
mycriteria.setBearingRequired(false); 
mycriteria.setCostAllowed(true); 
mycriteria.setPowerRequirement(Criteria.POWER_LOW); 
String provider = locationManager.getBestProvider(mycriteria, true); 

Location location = locationManager.getLastKnownLocation(provider); 
updateWithNewLocation(location); 
locationManager.requestLocationUpdates(provider, 1000, 0, locationListener); 


I declared the latitude and longitude variables as public so I could access the values from my other private methods in the MainActivity class:

public double latitude;
public double longitude;

And then set the values of them when the updateWithNewLocation event was fired:

private void updateWithNewLocation(Location location) { 
	String latLong; 
	TextView myLocation; 
	myLocation = (TextView) findViewById(R.id.myLocation);

	if(location!=null) { 
    	latitude = location.getLatitude(); 
    	longitude = location.getLongitude(); 
    	latLong = "Latitude:      " + latitude + "\nLongitude:  " + longitude;     	
	} else { 
		latLong = "Unable to obtain a GPS Location Fix"; 
	}
		myLocation.setText(latLong); 
	}

I passed the latitude and longitude values as arguments into the constructed Dark Sky JSON call, along with the API key that Dark Sky issued me when I requested a developer test account, and made the call to the api.darksyapp.com server via Recon's WebRequestBundle method :

WebRequestBundle wrb = new 
WebRequestBundle("com.reconinstruments.weptest","https://api.darkskyapp.com/v1/forecast/"
+DARK_SKY_API_KEY+"/"+latitude+","+longitude, 
WebMethod.GET, "", new ArrayList<NameValuePair>());

I ran the response string received from Recon's SDKWebService onComplete method through the JSON library, parsed for the hourSummary and daySummary strings, and set the text in the appropriate TextView control:

BufferedReader in = new BufferedReader(new StringReader(response));
String line;
while ((line = in.readLine()) != null) {
	JSONArray jarray = new JSONArray("["+line+"]");

	for (int i = 0; i < jarray.length(); i++) {
		JSONObject jobject = (JSONObject) jarray.get(i);
		mNextHour.setText("Next Hour: " + jobject.getString("hourSummary"));
		mNextDay.setText("Today: " + jobject.getString("daySummary"));
	}
}

The current temperature, forecast, and latitude/longitude results show up in the main window. I also remembered to disable the Android titlebar via the android:theme=@android:style/Theme.NoTitleBar.FullScreen directive in the Android Manifest file) using Recon's recommended Eurostyle 24 sp typeface (though Recon says this is being deprecated for Google's ICS Roboto font in the next release) for easy reading:

<TextView
    android:id="@+id/current_temp"
    android:text="@string/current_temp"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#FFF"
    android:textSize="24sp"
    android:textStyle="bold"        
    android:padding="8dp" />

I also needed to add the necessary location access permissions to the Android Manifest file:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />   

Note that I did not have to add an "android.permission.INTERNET" permission to the manifest, since Recon's WebAPI proxies through the Bluetooth connection via a pre-released developer's build of Recon's HQ Mobile application, required to run on the host's Android smartphone. This network-proxy-capable pre-release build of HQ Mobile will be made available on the Google Play marketplace once Recon has fully tested it with its development partners.

Finally, I polished off the app with its own square 245x245 pixel icon. And voil�, a new MOD Live app was born.
Running the Application

Because my Dark Sky-powered app requires an Internet connection to retrieve the latest forecast, I first had to pair the MOD Live with my Android smartphone via a Bluetooth connection. Then I had to execute Recon's MOD Live application on my phone. The app requires nearly every permission in the Android arsenal, so if you're paranoid about privacy or unauthorized data leakage, this may make you nervous. Yet unlike a lot of other apps in the Android Play store, Recon has explicitly spelled out in the application's description page which services are being used in the app and why they are necessary. Still, without the Recon app running on your phone, you will receive a "Paired but not connected" error if your phone has been associated with MOD Live via the Bluetooth connection, but you don't have the Recon MOD Live app running as a service on your phone.

Assuming these dependencies are met and you have had the MOD Live powered on long enough to obtain a GPS lock, scrolling through the icon menu and selecting the app to launch it should submit the latitude and longitude to the Dark Sky Web service and display the next hour's weather conditions on the HUD.


Figure 6: The running MODLive Dark Sky API assisted application.
Improving the Application

Time permitting, I would improve the application by iconifying the results rather than making the user read the resulting forecast text. For example, if snow was expected in 20 minutes, I would display a snowflake icon followed by the number 20. That number would count down with each passing minute.

If the user needed more forecast details, I could provide two additional screens, accessed via the right and left control puck buttons. These screens would show extended forecast data such as "next three hours" and "next 24 hours," while the second detail screen would call upon national weather service maps of the area for an up-to-date precipitation snapshot.

A few more graphic accoutrements such as better icons and graphic layouts along with friendlier error trapping for network connection problems would also need to be added before considering submitting such an app to Recon for inclusion into their upcoming MOD Live online app store. And yet, the key takeaway from building an application for the MOD Live platform is how the whole user experience needs to be accounted for when building HUD-based Android applications. As the MOD Live design guidelines recommend, HUD apps should only require a split second of attention to impart the data feed to the user. Any longer than that will negatively impact the user experience.
The MOD Live Developer Experience

I have used a number of HUDs in the past, ranging from proprietary embedded OSs to ones connected to a Windows CE hip pack, and each suffered from the problem of discomfort after 10 minutes of use. This discomfort manifests itself in the form of a headache either from eyestrain, the weight of unbalanced gear strapped on the head, or both. Remarkably, Recon Instruments has alleviated these problems by keeping the HUD below eye level, intended for quick glances. By combining the HUD hardware with a comfortable pair of well-cushioned, well-balanced ski goggles, the HUD's weight is equally distributed across the goggles so that the HUD's added mass is negligible. But the fact remains that HUDs in general are still a bit intrusive and will have to be further miniaturized to enter the realm of mass consumer adoption.

Nevertheless, for very specific present-day user scenarios like traveling at high speed down a ski slope or furiously peddling through a mud-soaked BMX race track, a quick glimpse at performance data surely heightens the experience. The immediate feedback also helps correct in-flight errors and offers greater situational awareness compared to non-augmented activities.

For early adopting technology enthusiasts, the MOD Live platform today offers a far less expensive glimpse into the future of visual data field augmentation. Compared to the nebulous Google Glass early developer release that costs more than triple the price of the MOD Live (assuming you even qualify to eventually get your hands on Google's hardware), Recon Instruments offers an affordable glimpse into a post-smartphone world.

For more information about the MOD Live system, visit www.reconinstruments.com.

Mike Riley is a blogger for Dr. Dobb’s and the author of Programming Your Home: Automate with Arduino, Android, and Your Computer (2012) from Pragmatic Programmers. 


More information about the FoRK mailing list