package com.thehopemachine.locobird;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.Date;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import org.json.JSONStringer;
import android.location.Location;
import android.util.Log;
public class WimaxLocationProvider {
private static String CLP_ADDRESS = "http://testlocation.clearwire-wmx.net:8000/json/";
private static Long STALE = 60000l; //one minutes worth of milliseconds
private static String HOST = "host";
private static String VERSION = "version";
private static String VERSION_VAL = "1.1.0";
private static String LATITUDE = "latitude";
private static String LONGITUDE = "longitude";
private static String ACCURACY = "accuracy";
private static String LOCATION = "location";
private static String ERROR = "error";
private static String QUERYARG = "/?app_id=";
private Location mLastFix = null;
public static String WIMAX = "the Clear 4G Network";
private String mHost = null;
private String mAppID = null;
private Date mLastCall = null;
public WimaxLocationProvider (String host, String appID)
{
mHost = host;
mAppID = appID;
}
public Location getLocation() throws Exception
{
//www.example.com/?app_id=freiu4898fhjrh4yshefheoiuhr
//do we have a last fix? is it still good?
String hostValue = mHost + QUERYARG + mAppID;
if (mLastFix != null && !isStale())
{
Log.d("locobird", "returning last fix");
return mLastFix;
}
//now test if called too quick
if (mLastCall != null && (new Date().getTime() - mLastCall.getTime() <= Locobird.SPURIOUS_FILTER))
{
//this implies we've been getting errors since we have no last fix but do have a last call
throw new CLPException("unable to provide location from CLP");
}
//else get a fix
Location l = null;
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost post = new HttpPost(CLP_ADDRESS);
HttpResponse response = null;
HttpEntity entity = null;
InputStream input = null;
//create a json request (basic)
String request = null;
try
{
request = new JSONStringer().object().key(HOST).value(hostValue).key(VERSION).value(VERSION_VAL).endObject().toString();
post.setEntity(new StringEntity(request));
JSONObject locationData = null;
StringBuffer data = new StringBuffer(512);
//send the request (POST it)
response = httpclient.execute(post);
entity = response.getEntity();
//get IO stream from entity and turn into JSON object
input = entity.getContent();
//look at response code
if (response.getStatusLine().getStatusCode() >= HttpURLConnection.HTTP_BAD_REQUEST)
{
//400 bad request, 404 not found, 500 server error ,etc
//do not try to parse json- will cause error
l = null;
}
else if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK)
{
byte[] buffer = new byte[512];
int x = 0;
while ((x = input.read()) != -1)
{
data.append((char)x);
}
//create location from the response
Log.d("locobird", "CLP response= " + data.toString());
locationData = new JSONObject(data.toString());
//test for location object in the json (if you just query you will get an exception)
if (!locationData.has(LOCATION))
{
//get the error object and examine it for cause
//{"error":"server error"}
if (locationData.has(ERROR))
{
String errorCause = locationData.getString(ERROR);
//could return error message in a bundle or just throw an error
throw new CLPException(errorCause);
}
else
{
//neither location nor error so a clp problem
throw new CLPException("Missing location and error objects from CLP response");
}
}
else
{
JSONObject jsonLocation = locationData.getJSONObject(LOCATION);
//we have a good location object from the CLP
//load the location object with the locationData
l = new Location(WIMAX);
l.setLatitude(jsonLocation.getDouble(LATITUDE));
l.setLongitude(jsonLocation.getDouble(LONGITUDE));
l.setAccuracy((float) jsonLocation.getDouble(ACCURACY));
}
}
}
finally
{
//ensure call time is recorded
mLastCall = new Date();
try
{
if (entity != null)
{
entity.consumeContent();
input.close(); //may not be needed
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//can return null in case of error. if this happens, do not update the fix- keep old one.
if (l == null)
{
throw new CLPException("unable to provide location from CLP");
}
else
{
mLastFix = l;
mLastFix.setTime(new Date().getTime());
Log.d("locobird", "returning new fix");
return l;
}
}
//if time since last fix exceed STALE, the fix is stale so get a new one.
private boolean isStale()
{
return ((new Date().getTime() - mLastFix.getTime()) > STALE);
}
}