package com.geoloqi.rpc; import java.io.IOException; import java.util.ArrayList; import org.apache.http.Header; import org.apache.http.ParseException; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.content.SharedPreferences; import android.util.Log; import com.geoloqi.ADB; import com.geoloqi.Installation; import com.geoloqi.data.Game; import com.geoloqi.interfaces.GeoloqiConstants; import com.geoloqi.interfaces.RPCException; public class MapAttackClient implements GeoloqiConstants { private final String TAG = "MapAttackClient"; private static final int TIMEOUT = 60000; private static final HttpParams httpParams = new BasicHttpParams(); private static HttpClient client; private static MapAttackClient singleton = null; private Context context; public static MapAttackClient getApplicationClient(Context context) { if (singleton == null) { singleton = new MapAttackClient(context); } return singleton; } private MapAttackClient(Context context) { this.context = context; HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT); HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT); client = new DefaultHttpClient(httpParams); } public void createAnonymousAccount() throws RPCException { try { String name, deviceID, platform, hardware; {// Initialize variables. name = context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE).getString("initials", null); deviceID = Installation.getIDAsString(context); platform = android.os.Build.VERSION.RELEASE; hardware = android.os.Build.MODEL; } MyRequest request; { request = new MyRequest(MyRequest.POST, URL_BASE + "user/create_anon"); request.addHeaders(new BasicScheme().authenticate(new UsernamePasswordCredentials(GEOLOQI_ID, GEOLOQI_SECRET), request.getRequest())); request.addEntityParams(pair("name", name), pair("device_id", deviceID), pair("platform", platform), pair("hardware", hardware)); } JSONObject response = send(request); {//Save Results saveToken(new OAuthToken(response)); context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE).edit().putString("userID", response.getString("user_id")).commit(); } } catch (JSONException e) { throw new RuntimeException(e.getMessage()); } catch (AuthenticationException e) { throw new RuntimeException(e); } } protected void saveToken(OAuthToken token) { context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE).edit().putString("authToken", token.accessToken).commit(); } public boolean hasToken() { return context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE).contains("authToken"); } public String getToken() { return context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE).getString("authToken", null); } public ArrayList<Game> getGames(Double latitude, Double longitude) throws RPCException { MyRequest request = new MyRequest(MyRequest.GET, GAME_LIST_ADDRESS + "&latitude=" + latitude + "&longitude=" + longitude); Header authHeader; try { authHeader = new BasicScheme().authenticate(new UsernamePasswordCredentials(GEOLOQI_ID, GEOLOQI_SECRET), request.getRequest()); } catch (AuthenticationException e) { throw new RPCException(e.getMessage()); } request.addHeaders(authHeader); JSONObject response = send(request); try { JSONArray gamesArray = response.getJSONArray("nearby"); ArrayList<Game> games = new ArrayList<Game>(); for (int i = 0; i < gamesArray.length(); i++) { games.add(new Game(gamesArray.getJSONObject(i))); } return games; } catch (JSONException e) { throw new RuntimeException(e); } } /** * Get the best guess intersection name for the given latitude and longitude. * * @param latitude * @param longitude * @return The nearest intersection as a String or null. */ public String getNearestIntersection(final Double latitude, final Double longitude) { // Build the request final MyRequest request = new MyRequest(MyRequest.GET, String.format("%slocation/context?latitude=%s&longitude=%s", URL_BASE, latitude, longitude)); try { // Sign the request Header authHeader = new BasicScheme().authenticate( new UsernamePasswordCredentials(GEOLOQI_ID, GEOLOQI_SECRET), request.getRequest()); request.addHeaders(authHeader); try { // Get the response JSONObject response = send(request); return response.getString("best_name"); } catch (RPCException e) { Log.e(TAG, "Got an RPCException when fetching the nearest intersection name!", e); } catch (JSONException e) { Log.e(TAG, "Got a JSONException when fetching the nearest intersection name!", e); } } catch (AuthenticationException e) { Log.e(TAG, "Got an AuthenticationException when fetching the nearest intersection name!", e); } return null; } public void joinGame(String id) throws RPCException { String token, email, initials; {// Initialize variables SharedPreferences prefs = context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); token = prefs.getString("authToken", null); email = prefs.getString("email", null); initials = prefs.getString("initials", null); } MyRequest request; {// Initialize the request. request = new MyRequest(MyRequest.POST, "http://mapattack.org/game/" + id + "/join"); request.addEntityParams(pair("access_token", token), pair("email", email), pair("initials", initials)); } try {// Send will throw a RuntimeException for the non-JSON return value. send(request); } catch (RuntimeException e) { } } protected synchronized JSONObject send(MyRequest request) throws RPCException { ADB.log("param " + request.getRequest().getURI()); JSONObject response; try { response = new JSONObject(EntityUtils.toString(client.execute(request.getRequest()).getEntity())); } catch (ParseException e) { ADB.log("ParseException: " + e.getMessage()); throw new RuntimeException(e.getMessage()); } catch (JSONException e) { ADB.log("JSONException: " + e.getMessage()); throw new RuntimeException(e.getMessage()); } catch (ClientProtocolException e) { ADB.log("ClientProtocolException: " + e.getMessage()); throw new RPCException(e.getMessage()); } catch (IOException e) { ADB.log("IOException: " + e.getMessage()); throw new RPCException(e.getMessage()); } if (response.has("error")) { try { throw new RPCException(response.getString("error")); } catch (JSONException e) { throw new RuntimeException(e); } } else { return response; } } private static BasicNameValuePair pair(String key, String val) { return new BasicNameValuePair(key, val); } }