1 package org.average.whereami;
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;
9 import java.util.Random;
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.KeyEvent;
31 import android.view.Menu;
32 import android.view.MenuInflater;
33 import android.view.MenuItem;
34 import android.view.Window;
35 import android.view.WindowManager;
36 import android.widget.TextView;
38 public class WhereAmI extends Activity
40 final String TAG = getClass().getName();
42 private WifiManager wifiman;
43 private Boolean managewifi = false;
44 private Long updatedelay = 60000L;
45 private Integer runningtasks = 0;
46 private SharedPreferences prefs;
47 private PersistentStore store;
48 private Random random = new Random();
49 private Boolean revive = false;
50 private Context context;
52 private class UpdateTarget {
54 private Oracle updater;
55 private BgUpdate task;
57 private class BgUpdate extends AsyncTask<Void, Void, String> {
59 protected String doInBackground(Void... params) {
60 Log.v(TAG, "BgUpdate " + updater + " starting");
61 Utterance result = updater.getResult();
62 for (int i = 2; !result.success && i <= 3; i++) {
63 SystemClock.sleep(1000 + random.nextInt(1000));
64 result = updater.getResult();
66 if (!result.success) {
67 Log.e(TAG, "After third attempt still " +
70 return result.message;
74 protected void onPostExecute(String str) {
75 Log.v(TAG, "BgUpdate callback executing");
78 if (runningtasks <= 0) {
80 boolean wifion = wifiman.setWifiEnabled(false);
81 Log.v(TAG, "disabling wifi result " + wifion);
85 tvs.setText(R.string.lasttry);
86 tvs.append(tm.format(" %d/%m/%Y %H:%M"));
91 protected void onCancelled() {
92 Log.v(TAG, "BgUpdate callback cancelled");
97 public UpdateTarget(TextView tv, Oracle updater) {
99 this.updater = updater;
102 public void launch() {
103 tv.setText(R.string.updating);
104 task = new BgUpdate();
108 public void cancel() {
112 private UpdateTarget[] ut;
114 private TextView tvt, tvd, tvs;
115 private Resources res;
116 private String[] month;
117 private String[] wday;
119 private Handler mHandler = new Handler();
121 private Runnable reviveSelf = new Runnable() {
123 Log.v(TAG, "trying to revive self");
124 Intent intent = new Intent(Intent.ACTION_MAIN);
125 intent.addCategory(Intent.CATEGORY_LAUNCHER );
126 intent.setClass(context, WhereAmI.class);
127 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
128 intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
129 intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
130 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
131 startActivity(intent);
135 private Runnable updateClock = new Runnable () {
137 long now = System.currentTimeMillis();
138 Time tm = new Time();
140 tvt.setText(tm.format("%H:%M"));
143 long next = tm.toMillis(false);
144 mHandler.postDelayed(this, next-now+1);
148 private Runnable updateCal = new Runnable () {
150 long now = System.currentTimeMillis();
151 Time tm = new Time();
158 tm.set(now + 86400000);
162 long next = tm.toMillis(false);
163 mHandler.postDelayed(this, next-now+1);
167 private Runnable updateInfo = new Runnable () {
169 Log.v(TAG, "updateInfo starting");
171 IntentFilter intentFilter =
172 new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
173 registerReceiver(connChanged,intentFilter);
174 connChangedRegistered = true;
175 boolean wifion = wifiman.setWifiEnabled(true);
176 Log.v(TAG, "enabling wifi result " + wifion);
178 for (int i = 0; i < ut.length; i++) {
183 mHandler.postDelayed(resetInfo, 50000);
184 mHandler.postDelayed(this, updatedelay);
188 private Runnable resetInfo = new Runnable () {
190 Log.v(TAG, "resetInfo starting");
191 if (connChangedRegistered) {
192 unregisterReceiver(connChanged);
193 connChangedRegistered = false;
195 if (runningtasks > 0) {
196 for (int i = 0; i < ut.length; i++) {
200 Time tm = new Time();
202 tvs.setText(R.string.failtry);
203 tvs.append(tm.format(" %d/%m/%Y %H:%M"));
206 boolean wifion = wifiman.setWifiEnabled(false);
207 Log.v(TAG, "disabling wifi result " + wifion);
212 private boolean connChangedRegistered = false;
213 private final BroadcastReceiver connChanged = new BroadcastReceiver() {
215 public void onReceive(Context context, Intent intent) {
216 ConnectivityManager cm = (ConnectivityManager)context.
217 getSystemService(Context.CONNECTIVITY_SERVICE);
218 NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
219 boolean isConnected = activeNetwork != null &&
220 activeNetwork.isConnectedOrConnecting();
221 Log.v(TAG, "Connectivity changed to " + isConnected);
223 for (int i = 0; i < ut.length; i++) {
231 /** Called when the activity is first created. */
233 public void onCreate(Bundle savedInstanceState) {
234 super.onCreate(savedInstanceState);
236 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO) {
237 Log.v(TAG, "Disabling keepalive for build version " +
238 Build.VERSION.SDK_INT);
239 System.setProperty("http.keepAlive", "false");
241 Log.v(TAG, "Post-Froyo version " +
242 Build.VERSION.SDK_INT);
244 prefs = PreferenceManager.getDefaultSharedPreferences(this);
245 store = new PersistentStore(prefs);
246 wifiman = (WifiManager)getSystemService(Context.WIFI_SERVICE);
247 requestWindowFeature(Window.FEATURE_NO_TITLE);
248 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
249 setContentView(R.layout.main);
250 res = getResources();
251 month = res.getStringArray(R.array.month);
252 wday = res.getStringArray(R.array.wday);
253 tvt = (TextView)findViewById(R.id.time);
254 tvd = (TextView)findViewById(R.id.date);
255 tvs = (TextView)findViewById(R.id.timestamp);
256 APIBase base = new APIBase(res, store);
257 ut = new UpdateTarget[] {
258 new UpdateTarget((TextView)findViewById(R.id.phonecall),
260 new UpdateTarget((TextView)findViewById(R.id.location),
261 new LastLocation(base))
265 /** Called when reactivated */
267 public void onResume() {
269 boolean fullscreen = prefs.getBoolean("fullscreen", false);
270 managewifi = prefs.getBoolean("managewifi", false);
271 updatedelay = Long.parseLong(prefs.getString("updateperiod", "1200000"));
272 Log.v("WhereAmI", "fullscreen: " + fullscreen +
273 ", managewifi: " + managewifi +
274 ", updatedelay: " + updatedelay);
276 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
277 getWindow().clearFlags(WindowManager.LayoutParams.
278 FLAG_FORCE_NOT_FULLSCREEN);
280 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
283 mHandler.post(updateClock);
284 mHandler.post(updateCal);
285 mHandler.post(updateInfo);
286 Log.v(TAG, "update tasks scheduled");
289 /** Called when put to background */
291 public void onPause() {
293 Log.v(TAG, "going background");
295 mHandler.removeCallbacks(updateClock);
296 mHandler.removeCallbacks(updateCal);
297 mHandler.removeCallbacks(updateInfo);
299 Log.v(TAG, "scheduling revival");
300 mHandler.postDelayed(reviveSelf, 6000); // 6 second delay
304 /** Called when the activity is destroyed. */
306 public void onDestroy() {
308 Log.v(TAG, "going down");
311 /** Called when the menu is activated. */
313 public boolean onCreateOptionsMenu(Menu menu) {
314 MenuInflater inflater = getMenuInflater();
315 inflater.inflate(R.menu.main_menu, menu);
319 /** Called when the menu item is selected */
321 public boolean onOptionsItemSelected(MenuItem item) {
322 switch (item.getItemId()) {
328 Log.v(TAG, "authorize requested");
329 startActivity(new Intent(this, Authorize.class));
332 Log.v(TAG, "settings requested");
333 startActivity(new Intent(this, WhereAmIprefs.class));
336 return super.onOptionsItemSelected(item);
340 /** Override "back" button. Can still quit via menu. */
342 public boolean onKeyDown(int keyCode, KeyEvent event) {
343 if (keyCode == KeyEvent.KEYCODE_BACK) {
346 return super.onKeyDown(keyCode, event);