location message complete, font size adjustment
[WhereAmI.git] / src / org / average / whereami / LastLocation.java
1 package org.average.whereami;
2
3 import org.average.whereami.CredentialStore;
4
5 import java.lang.Math;
6
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;
18
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;
24
25 public final class LastLocation extends Oracle {
26
27         final String TAG = getClass().getName();
28
29         private Latitude latitude;
30
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;
42
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);
55
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 +
64                         "\"");
65                 GoogleAccessProtectedResource accessProtectedResource =
66                         new GoogleAccessProtectedResource(
67                                 token.accessToken,
68                                 transport, jsonFactory,
69                                 ClientCredentials.CLIENT_ID,
70                                 ClientCredentials.CLIENT_SECRET,
71                                 token.refreshToken)
72                                 {
73                                         @Override
74                                         public void onAccessToken(
75                                                         String accessToken) {
76                                                 Log.v(TAG, "Update access token to \"" + accessToken + "\"");
77                                                 store.updateAccessToken(
78                                                         accessToken);
79                                         }
80                                 }
81                                 ;
82                 Latitude.Builder lbldr = Latitude.builder(transport,
83                                                                 jsonFactory);
84                 lbldr.setHttpRequestInitializer(accessProtectedResource);
85                 lbldr.setApplicationName("WhereAmI/1.0");
86                 latitude = lbldr.build();
87         }
88
89         @Override
90         public final String getResult() {
91                 try {
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();
108                 }
109         }
110
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] +
121                                 " is " + dist);
122                         if ((loc_dists[i] == "0") ||
123                             (dist < Double.parseDouble(loc_dists[i]))) {
124                                 locmsg = loc_names[i];
125                                 break;
126                         }
127                 }
128                 Long ago = (System.currentTimeMillis() - tsm) / 3600000;
129                 if (ago < 1) {
130                         agomsg = lessthanhour;
131                 } else if (ago < 2) {
132                         agomsg = onehour;
133                 } else if (ago < 5) {
134                         agomsg = "" + ago + " " + hours2to4;
135                 } else if (ago < 24) {
136                         agomsg = "" + ago + " " + hours5up;
137                 } else {
138                         agomsg = longago;
139                 }
140                 return myname + " " + locmsg + ", " + timestamp +
141                         " " + agomsg;
142         }
143
144         private Double toRad(Double deg) {
145                 return deg * 3.14159265 / 180;
146         }
147
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));
156                 return 6371 * c;
157         }
158 }