Exposing a VM on hosted WiFi hotspot for Google Glass

Background

Google Glass is famously frustrating to connect to a WiFi network. It doesn’t handle captive portals, or WiFi using Enterprise WPA2. I’ve also had consistent issues using MyGlass and QR codes to connect to Wifi.

I found myself in a situation where I had to connect Glass to a WiFi network on which a virtual machine was visible. My work’s corporate network was out of the question – it uses Enterprise WPA2. I would have connected my phone to the network and shared it to Glass via Bluetooth, but that was nixed for security reasons. So I had to set up a new network exclusively for Glass.

First thought – let’s just set up an Ad-Hoc wireless network on my laptop! But no, alas Android doesn’t support connecting to ad-hoc networks. Universe, why do you hate me so?

The solution

The solution involves a wireless-enabled Windows machine and VirtualBox – a program for running virtual machines.

An alternative to creating an ad-hoc network on your machine is to create a Wireless Hosted Network. This basically allows your Windows machine to act as a WiFi hotspot which can pass through a (wired) internet connection if you so wish.

My approach was to create a hosted network, connect my phone to it, then pass on the connection via Bluetooth. An admittedly insane chain of connections, but it’s all I had.

Create the WiFi network

  1. Open the Start menu and type “cmd”
  2. Right click and select “Run as Administrator”
  3. Type the following command:
     netsh wlan set hostednetwork mode=allow ssid=mynetworkid key=mypassword

Start the network

You’ll have to do this every time you start the machine, or alternatively set up a batch script to run this on startup.

  1. Type the following command:
     netsh wlan start hostednetwork

You should now see “mynetworkid” (or whatever you called it) in your list of wireless networks.

Create your VirtualBox image

  1. Install VirtualBox
  2. Create a new virtual machine (steps available here) – I’ve chosen to use a linux install
  3. Once your VM is created, go to Settings and choose Network
  4. Set up a Bridged Adapter
    1. Enable a network adapter
    2. Select Attached To: “Bridged Adapter”
    3. Select “Microsoft Virtual WiFi Miniport Adapter” as the Name – this is where the network you’ve just created is hosted.
  5. Start your VM up

Check connectivity

  1. On your Windows machine, open a command line and type:
     ipconfig

    A list of networks should be shown – one of which should be called “Wireless LAN adapter Wireless Network Connection”. Note down the first 9 digits of the IP address listed under this e.g. 192.168.173

  2. In your VM, run the following command:
     /sbin/ifconfig

    And note the networks and IPs that are listed. If no other networks were set up, your eth0 network should have an IP where the first 9 digits of the IP address matches those you noted down earlier. That means that they’re running on the network.

  3. For a laugh, ping your VM from your Windows machine, using the IP address from the previous step. This will confirm that your VM is addressable and contactable from your Windows machine. Given that your Windows machine is now broadcasting a wireless network, that means that the VM should be contactable to anyone on the network too.

Ping your VM from your Android device

As the penultimate proof, try pinging your VM from your Android device.

  1. Install an app which will let you run a ping command (I used PingTools)
  2. Ping the IP address you pinged previously

This should also show a response. And now we’re on the home straight.

Write some Glass code to contact your VM

You can do this however you wish. I wrote some very simple ping code to prove that Glass – once paired to my phone – was sharing the same internet connection as the phone, and the Windows machine, and as the VM.

There are tons of ways of doing it – for example:

InetAddress server = InetAddress.getByName("192.168.173.123");
if (server.isReachable(10000))
{
         // It’s contactable!
         celebrate();
}

Conclusions

That was much, much harder than it should have been. Alternatives I didn’t attempt:

  • Buying a router and broadcasting my corportate ethernet through it
  • Getting a company-approved phone that could have connected to the Enterprise network
  • Binning my Google Glass

PS – Many thanks to this post which acted as a great reference. It’s also worth checking out if you need to pass through internet via your hosted network.

Debugger this! Debugging an Android Service

I recently found out that I couldn’t hit any breakpoints in an Android Service I was developing. I found that this was easily sorted by adding the following line:

android.os.Debug.waitForDebugger()

This approach was suggested on various websites including StackOverflow and HelloAndroid amongst many. Great.

I found out much later than when I ran the code “in the wild” i.e. in a production environment unattached to a debugger, my application was failing.

Long story short, this is caused by the waitForDebugger() call, which will cause any code following your invocation to not be executed if there is no debugger.

I suppose I should have realised, but I had assumed that maybe the runtime or the call itself would be clever enough to know whether the application was in debug mode at all, and ignore it if it wasn’t.

But thankfully, we can do that:

if (android.os.Debug.isDebuggerConnected)
{
    android.os.Debug.waitForDebugger()
}

So I’d recommend this is the approach you take over having to remember to take that call out.

Android Studio – Fix sudden unresolved symbols

Android Studio is a fickle beast. At times surprisingly clever and useful, and other times a flaky nightmare.

The most recent issue I came across was when a Google Glass project suddenly stopped building with unresolved symbol errors. This manifests itself as all your “com.google.android.glass.*” imports failing, and the resulting use of any object from those libs causing compilation errors.

What the hell, Android Studio??
What the hell, Android Studio??

How to fix it

Eventually I checked my project dependencies and explicitly added the GDK as a library. Bingo, that sorted it out.

  1. Copy the gdk.jar

    This will be in your Android SDK directory, under /add-ons/addon-google_gdk-google-19/libs

  2. Paste it into the libs folder in your project directory

    e.g. C:\Projects\MyProject\app\libs

  3. Go to File > Project Structure
  4. Select your module (default name is app)
  5. Click the Dependencies tab
  6. Click the “+” sign
  7. Navigate to the libs folder and select the gdk.jar file
  8. OK through everything

I have zero idea why the issue suddenly arose. As with so many other issues I’ve come across in my short time developing for Android, I’ve learned to FDM: fix, document, and move on.

Using Gradle from behind a proxy

By default Android Studio uses Gradle to build Android projects. This means Android Studio always needs a connection to the internet to check for and retrieve dependencies. If you’re developing from behind a proxy (as I am) then you’ll have to explicitly tell Gradle the proxy details to allow it to connect to its servers.

Steps to fix

  1. Navigate to the “.gradle” folder in your user directory (e.g. C:\Users\bob\.gradle)
  2. Create a “gradle.properties” file
  3. Edit the file to have the following contents (replacing your own values)
systemProp.http.proxyHost=<proxy_host>
systemProp.http.proxyPort=<port>
systemProp.http.proxyUser=<user>
systemProp.http.proxyPassword=<password>
systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost

Gradle should then succeed on the next build.

Note – thanks go to Steve Hanson for these steps.

Update 08 Dec 2014 – As of the update to Android 1.0, these steps are not enough! I’ve documented the new definitive list in this post.