1 package org.average.whereami;
3 import org.average.whereami.CredentialStore;
7 import com.google.api.client.extensions.android2.AndroidHttp;
8 import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse;
9 import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessProtectedResource;
10 import com.google.api.client.http.HttpResponseException;
11 import com.google.api.client.http.HttpTransport;
12 import com.google.api.client.http.javanet.NetHttpTransport;
13 import com.google.api.client.json.JsonFactory;
14 import com.google.api.client.json.jackson.JacksonFactory;
15 import com.google.api.services.latitude.Latitude;
16 import com.google.api.services.latitude.LatitudeRequest;
17 import com.google.api.services.latitude.model.Location;
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.content.res.Resources;
22 import android.text.format.Time;
23 import android.util.Log;
25 public final class LastLocation extends Oracle {
27 final String TAG = getClass().getName();
29 private Latitude latitude;
31 private String[] loc_names;
32 private String[] loc_lats;
33 private String[] loc_lons;
34 private String[] loc_dists;
35 private String myname;
36 private String timestamp;
37 private String longago;
38 private String lessthanhour;
39 private String onehour;
40 private String hours2to4;
41 private String hours5up;
43 public LastLocation(final Resources res, final CredentialStore store) {
44 loc_names = res.getStringArray(R.array.loc_names);
45 loc_lats = res.getStringArray(R.array.loc_lats);
46 loc_lons = res.getStringArray(R.array.loc_lons);
47 loc_dists = res.getStringArray(R.array.loc_dists);
48 myname = res.getString(R.string.myname);
49 timestamp = res.getString(R.string.timestamp);
50 longago = res.getString(R.string.longago);
51 lessthanhour = res.getString(R.string.lessthanhour);
52 onehour = res.getString(R.string.onehour);
53 hours2to4 = res.getString(R.string.hours2to4);
54 hours5up = res.getString(R.string.hours5up);
56 HttpTransport transport = AndroidHttp.newCompatibleTransport();
57 JsonFactory jsonFactory = new JacksonFactory();
58 AccessTokenResponse token = store.read();
59 Log.v(TAG, "tokens - access: \"" + token.accessToken +
60 "\", refresh: \"" + token.refreshToken +
61 "\", client_id: \"" + ClientCredentials.CLIENT_ID +
62 "\", client_secret: \"" +
63 ClientCredentials.CLIENT_SECRET +
65 GoogleAccessProtectedResource accessProtectedResource =
66 new GoogleAccessProtectedResource(
68 transport, jsonFactory,
69 ClientCredentials.CLIENT_ID,
70 ClientCredentials.CLIENT_SECRET,
74 public void onAccessToken(
76 Log.v(TAG, "Update access token to \"" + accessToken + "\"");
77 store.updateAccessToken(
82 Latitude.Builder lbldr = Latitude.builder(transport,
84 lbldr.setHttpRequestInitializer(accessProtectedResource);
85 lbldr.setApplicationName("WhereAmI/1.0");
86 latitude = lbldr.build();
90 public final String getResult() {
92 Log.v(TAG, "entering getResult");
93 Latitude.CurrentLocation.Get request =
94 latitude.currentLocation().get();
95 request.setGranularity("best");
96 Location cloc = request.execute();
97 Double lat = Double.parseDouble(
98 cloc.getLatitude().toString());
99 Double lon = Double.parseDouble(
100 cloc.getLongitude().toString());
101 Long tsm = Long.parseLong(
102 cloc.getTimestampMs().toString());
103 return locationMessage(lat, lon, tsm);
104 } catch (Exception ex) {
105 Log.v(TAG, "exception in getResult: " + ex);
106 ex.printStackTrace();
107 return ex.getMessage();
111 private String locationMessage(Double lat, Double lon, Long tsm) {
112 Log.v(TAG, "entering locationMessage(" + lat +
113 "," + lon + "," + tsm + ")");
114 String locmsg = "<UNSET>";
115 String agomsg = "<UNSET>";
116 for (int i = 0; i < loc_names.length; i++) {
117 Double dist = haversine(lat, lon,
118 Double.parseDouble(loc_lats[i]),
119 Double.parseDouble(loc_lons[i]));
120 Log.v(TAG, "Dist from " + loc_names[i] +
122 if ((loc_dists[i] == "0") ||
123 (dist < Double.parseDouble(loc_dists[i]))) {
124 locmsg = loc_names[i];
128 Long ago = (System.currentTimeMillis() - tsm) / 3600000;
130 agomsg = lessthanhour;
131 } else if (ago < 2) {
133 } else if (ago < 5) {
134 agomsg = "" + ago + " " + hours2to4;
135 } else if (ago < 24) {
136 agomsg = "" + ago + " " + hours5up;
140 return myname + " " + locmsg + ", " + timestamp +
144 private Double toRad(Double deg) {
145 return deg * 3.14159265 / 180;
148 private Double haversine(Double lat1, Double lon1,
149 Double lat2, Double lon2) {
150 Double dlat = toRad(lat2 - lat1);
151 Double dlon = toRad(lon2 - lon1);
152 Double a = Math.sin(dlat / 2) * Math.sin(dlat / 2) +
153 Math.sin(dlon / 2) * Math.sin(dlon / 2) *
154 Math.cos(toRad(lat1)) * Math.cos(toRad(lat2));
155 Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));