]> www.average.org Git - WhereAmI.git/blob - src/org/average/whereami/WhereAmI.java
make one retry on failure
[WhereAmI.git] / src / org / average / whereami / WhereAmI.java
1 package org.average.whereami;
2
3 import org.average.whereami.WhereAmIprefs;
4 import org.average.whereami.APIBase;
5 import org.average.whereami.Oracle;
6 import org.average.whereami.PhoneLog;
7 import org.average.whereami.LastLocation;
8
9 import java.util.Random;
10
11 import android.app.Activity;
12 import android.net.wifi.WifiManager;
13 import android.os.Build;
14 import android.os.Bundle;
15 import android.os.AsyncTask;
16 import android.os.Handler;
17 import android.os.SystemClock;
18 import android.net.ConnectivityManager;
19 import android.net.NetworkInfo;
20 import android.content.BroadcastReceiver;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.Context;
24 import android.content.res.Resources;
25 import android.content.SharedPreferences;
26 import android.preference.PreferenceManager;
27 import android.text.format.Time;
28 import android.util.Log;
29 import android.view.View;
30 import android.view.Menu;
31 import android.view.MenuInflater;
32 import android.view.MenuItem;
33 import android.view.Window;
34 import android.view.WindowManager;
35 import android.widget.TextView;
36
37 public class WhereAmI extends Activity
38 {
39     final String TAG = getClass().getName();
40
41     private WifiManager wifiman;
42     private Boolean managewifi = false;
43     private Long updatedelay = 60000L;
44     private Integer runningtasks = 0;
45     private SharedPreferences prefs;
46     private PersistentStore store;
47     private Random random = new Random();
48
49     private class UpdateTarget {
50         private TextView tv;
51         private Oracle updater;
52         private BgUpdate task;
53
54         private class BgUpdate extends AsyncTask<Void, Void, String> {
55             @Override
56             protected String doInBackground(Void... params) {
57                 Log.v(TAG, "BgUpdate " + updater + " starting");
58                 Utterance result = updater.getResult();
59                 if (!result.success) {
60                     SystemClock.sleep(1000 + random.nextInt(1000));
61                     result = updater.getResult();
62                 }
63                 if (!result.success) {
64                     Log.e(TAG, "After second attempt still " +
65                                 result.message);
66                 }
67                 return result.message;
68             }
69         
70             @Override
71             protected void onPostExecute(String str) {
72                 Log.v(TAG, "BgUpdate callback executing");
73                 tv.setText(str);
74                 runningtasks--;
75                 if (runningtasks <= 0) {
76                     if (managewifi) {
77                         boolean wifion = wifiman.setWifiEnabled(false);
78                         Log.v(TAG, "disabling wifi result " + wifion);
79                     }
80                     Time tm = new Time();
81                     tm.setToNow();
82                     tvs.setText(R.string.lasttry);
83                     tvs.append(tm.format(" %d/%m/%Y %H:%M"));
84                 }
85             }
86
87             @Override
88             protected void onCancelled() {
89                 Log.v(TAG, "BgUpdate callback cancelled");
90                 runningtasks--;
91             }
92         }
93
94         public UpdateTarget(TextView tv, Oracle updater) {
95             this.tv = tv;
96             this.updater = updater;
97         }
98
99         public void launch() {
100             tv.setText(R.string.updating);
101             task = new BgUpdate();
102             task.execute();
103         }
104
105         public void cancel() {
106             task.cancel(true);
107         }
108     }
109     private UpdateTarget[] ut;
110
111     private TextView tvt, tvd, tvs;
112     private Resources res;
113     private String[] month;
114     private String[] wday;
115
116     private Handler mHandler = new Handler();
117
118     private Runnable updateClock = new Runnable () {
119         public void run() {
120             long now = System.currentTimeMillis();
121             Time tm = new Time();
122             tm.set(now);
123             tvt.setText(tm.format("%H:%M"));
124             tm.set(now + 60000);
125             tm.second=0;
126             long next = tm.toMillis(false);
127             mHandler.postDelayed(this, next-now+1);
128         }
129     };
130
131     private Runnable updateCal = new Runnable () {
132         public void run() {
133             long now = System.currentTimeMillis();
134             Time tm = new Time();
135             tm.set(now);
136             tvd.setText(
137                        wday[tm.weekDay] +
138                        tm.format("\n%d ") +
139                        month[tm.month] +
140                        tm.format(" %Y"));
141             tm.set(now + 86400000);
142             tm.hour=0;
143             tm.minute=0;
144             tm.second=0;
145             long next = tm.toMillis(false);
146             mHandler.postDelayed(this, next-now+1);
147         }
148     };
149
150     private Runnable updateInfo = new Runnable () {
151         public void run() {
152             Log.v(TAG, "updateInfo starting");
153             if (managewifi) {
154                 IntentFilter intentFilter =
155                     new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
156                 registerReceiver(connChanged,intentFilter);
157                 connChangedRegistered = true;
158                 boolean wifion = wifiman.setWifiEnabled(true);
159                 Log.v(TAG, "enabling wifi result " + wifion);
160             } else {
161                 for (int i = 0; i < ut.length; i++) {
162                     runningtasks++;
163                     ut[i].launch();
164                 }
165             }
166             mHandler.postDelayed(resetInfo, 50000);
167             mHandler.postDelayed(this, updatedelay);
168         }
169     };
170
171     private Runnable resetInfo = new Runnable () {
172         public void run() {
173             Log.v(TAG, "resetInfo starting");
174             if (connChangedRegistered) {
175                 unregisterReceiver(connChanged);
176                 connChangedRegistered = false;
177             }
178             if (runningtasks > 0) {
179                 for (int i = 0; i < ut.length; i++) {
180                     ut[i].cancel();
181                 }
182                 runningtasks = 0;
183                 Time tm = new Time();
184                 tm.setToNow();
185                 tvs.setText(R.string.failtry);
186                 tvs.append(tm.format(" %d/%m/%Y %H:%M"));
187             }
188             if (managewifi) {
189                 boolean wifion = wifiman.setWifiEnabled(false);
190                 Log.v(TAG, "disabling wifi result " + wifion);
191             }
192         }
193     };
194
195     private boolean connChangedRegistered = false;
196     private final BroadcastReceiver connChanged = new BroadcastReceiver() {
197         @Override
198         public void onReceive(Context context, Intent intent) {
199             ConnectivityManager cm = (ConnectivityManager)context.
200                            getSystemService(Context.CONNECTIVITY_SERVICE);
201             NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
202             boolean isConnected = activeNetwork != null &&
203                                   activeNetwork.isConnectedOrConnecting();
204             Log.v(TAG, "Connectivity changed to " + isConnected);
205             if (isConnected) {
206                 for (int i = 0; i < ut.length; i++) {
207                     runningtasks++;
208                     ut[i].launch();
209                 }
210             }
211         }
212     };
213
214     /** Called when the activity is first created. */
215     @Override
216     public void onCreate(Bundle savedInstanceState) {
217         super.onCreate(savedInstanceState);
218         if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO) {
219             Log.v(TAG, "Disabling keepalive for build version " +
220                        Build.VERSION.SDK_INT);
221             System.setProperty("http.keepAlive", "false");
222         } else {
223             Log.v(TAG, "Post-Froyo version " +
224                         Build.VERSION.SDK_INT);
225         }
226         prefs = PreferenceManager.getDefaultSharedPreferences(this);
227         store = new PersistentStore(prefs);
228         wifiman = (WifiManager)getSystemService(Context.WIFI_SERVICE);
229         requestWindowFeature(Window.FEATURE_NO_TITLE);
230         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
231         setContentView(R.layout.main);
232         res = getResources();
233         month = res.getStringArray(R.array.month);
234         wday = res.getStringArray(R.array.wday);
235         tvt = (TextView)findViewById(R.id.time);
236         tvd = (TextView)findViewById(R.id.date);
237         tvs = (TextView)findViewById(R.id.timestamp);
238         APIBase base = new APIBase(res, store);
239         ut = new UpdateTarget[] {
240             new UpdateTarget((TextView)findViewById(R.id.phonecall),
241                              new PhoneLog(base)),
242             new UpdateTarget((TextView)findViewById(R.id.location),
243                              new LastLocation(base))
244         };
245     }
246
247     /** Called when reactivated */
248     @Override
249     public void onResume() {
250         super.onResume();
251         boolean fullscreen = prefs.getBoolean("fullscreen", false);
252         managewifi = prefs.getBoolean("managewifi", false);
253         updatedelay = Long.parseLong(prefs.getString("updateperiod", "1200000"));
254         Log.v("WhereAmI", "fullscreen: " + fullscreen +
255                           ", managewifi: " + managewifi +
256                           ", updatedelay: " + updatedelay);
257         if (fullscreen) {
258             getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
259             getWindow().clearFlags(WindowManager.LayoutParams.
260                                                   FLAG_FORCE_NOT_FULLSCREEN);
261         } else {
262             getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
263         }
264         mHandler.post(updateClock);
265         mHandler.post(updateCal);
266         mHandler.post(updateInfo);
267         Log.v(TAG, "update tasks scheduled");
268     }
269
270     /** Called when put to background */
271     @Override
272     public void onPause() {
273         super.onPause();
274         Log.v(TAG, "going background");
275         resetInfo.run();
276         mHandler.removeCallbacks(updateClock);
277         mHandler.removeCallbacks(updateCal);
278         mHandler.removeCallbacks(updateInfo);
279     }
280
281     /** Called when the activity is destroyed. */
282     @Override
283     public void onDestroy() {
284         super.onDestroy();
285         Log.v(TAG, "going down");
286     }
287
288     /** Called when the menu is activated. */
289     @Override
290     public boolean onCreateOptionsMenu(Menu menu) {
291         MenuInflater inflater = getMenuInflater();
292         inflater.inflate(R.menu.main_menu, menu);
293         return true;
294     }
295
296     /** Called when the menu item is selected */
297     @Override
298     public boolean onOptionsItemSelected(MenuItem item) {
299         switch (item.getItemId()) {
300         case R.id.quit:
301             finish();
302             return true;
303         case R.id.authorize:
304             Log.v(TAG, "authorize requested");
305             startActivity(new Intent(this, Authorize.class));
306             return true;
307         case R.id.settings:
308             Log.v(TAG, "settings requested");
309             startActivity(new Intent(this, WhereAmIprefs.class));
310             return true;
311         default:
312             return super.onOptionsItemSelected(item);
313         }
314     }
315 }