guard against leaving or double-unregistering the broadcast receiver
[WhereAmI.git] / src / org / average / whereami / WhereAmI.java
1 package org.average.whereami;
2
3 import android.app.Activity;
4 import android.net.wifi.WifiManager;
5 import android.os.Bundle;
6 import android.os.AsyncTask;
7 import android.os.Handler;
8 import android.os.SystemClock;
9 import android.net.ConnectivityManager;
10 import android.net.NetworkInfo;
11 import android.content.BroadcastReceiver;
12 import android.content.Intent;
13 import android.content.IntentFilter;
14 import android.content.Context;
15 import android.content.res.Resources;
16 import android.text.format.Time;
17 import android.util.Log;
18 import android.view.View;
19 import android.view.Menu;
20 import android.view.MenuInflater;
21 import android.view.MenuItem;
22 import android.view.Window;
23 import android.view.WindowManager;
24 import android.widget.TextView;
25
26 public class WhereAmI extends Activity
27 {
28     private WifiManager wifiman;
29     private Integer runningtasks = 0;
30
31     private class UpdateTarget {
32         private TextView tv;
33         private Integer updater; // will be the function/object
34         private BgUpdate task;
35
36         private class BgUpdate extends AsyncTask<Void, Void, String> {
37             @Override
38             protected String doInBackground(Void... params) {
39                 Log.w("WhereAmI", "BgUpdate " + updater + " starting");
40                 SystemClock.sleep(5000); // real job do be done here
41                 Log.w("WhereAmI", "BgUpdate about to return");
42                 return "5 seconds passed in " + updater;
43             }
44         
45             @Override
46             protected void onPostExecute(String str) {
47                 Log.w("WhereAmI", "BgUpdate callback executing");
48                 tv.setText(str);
49                 runningtasks--;
50                 if (runningtasks <= 0) {
51                     boolean wifion = wifiman.setWifiEnabled(false);
52                     Log.w("WhereAmI", "disabling wifi result " + wifion);
53                     Time tm = new Time();
54                     tm.setToNow();
55                     tvs.setText(R.string.lasttry);
56                     tvs.append(tm.format(" %d/%m/%Y %H:%M:%S"));
57                 }
58             }
59
60             @Override
61             protected void onCancelled() {
62                 Log.w("WhereAmI", "BgUpdate callback cancelled");
63                 runningtasks--;
64             }
65         }
66
67         public UpdateTarget(TextView tv, Integer updater) {
68             this.tv = tv;
69             this.updater = updater;
70         }
71
72         public void launch() {
73             tv.setText(R.string.updating);
74             task = new BgUpdate();
75             task.execute();
76         }
77
78         public void cancel() {
79             task.cancel(true);
80         }
81     }
82     private UpdateTarget[] ut;
83
84     private TextView tvt, tvd, tvs;
85     private Resources res;
86     private String[] month;
87     private String[] wday;
88
89     private Handler mHandler = new Handler();
90
91     private Runnable updateClock = new Runnable () {
92         public void run() {
93             long now = System.currentTimeMillis();
94             Time tm = new Time();
95             tm.set(now);
96             tvt.setText(tm.format("%H:%M"));
97             tm.set(now + 60000);
98             tm.second=0;
99             long next = tm.toMillis(false);
100             mHandler.postDelayed(this, next-now+1);
101         }
102     };
103
104     private Runnable updateCal = new Runnable () {
105         public void run() {
106             long now = System.currentTimeMillis();
107             Time tm = new Time();
108             tm.set(now);
109             tvd.setText(
110                        wday[tm.weekDay] +
111                        tm.format("\n%d ") +
112                        month[tm.month] +
113                        tm.format(" %Y"));
114             tm.set(now + 86400000);
115             tm.hour=0;
116             tm.minute=0;
117             tm.second=0;
118             long next = tm.toMillis(false);
119             mHandler.postDelayed(this, next-now+1);
120         }
121     };
122
123     private Runnable updateInfo = new Runnable () {
124         public void run() {
125             Log.w("WhereAmI", "updateInfo starting");
126             IntentFilter intentFilter =
127                 new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
128             registerReceiver(connChanged,intentFilter);
129             connChangedRegistered = true;
130             boolean wifion = wifiman.setWifiEnabled(true);
131             Log.w("WhereAmI", "enabling wifi result " + wifion);
132             mHandler.postDelayed(resetInfo, 30000);
133             mHandler.postDelayed(this, 60000);
134         }
135     };
136
137     private Runnable resetInfo = new Runnable () {
138         public void run() {
139             Log.w("WhereAmI", "resetInfo starting");
140             if (connChangedRegistered) {
141                 unregisterReceiver(connChanged);
142                 connChangedRegistered = false;
143             }
144             if (runningtasks > 0) {
145                 for (int i = 0; i < ut.length; i++) {
146                     ut[i].cancel();
147                 }
148                 Time tm = new Time();
149                 tm.setToNow();
150                 tvs.setText(R.string.failtry);
151                 tvs.append(tm.format(" %d/%m/%Y %H:%M:%S"));
152             }
153             boolean wifion = wifiman.setWifiEnabled(false);
154             Log.w("WhereAmI", "disabling wifi result " + wifion);
155         }
156     };
157
158     private boolean connChangedRegistered = false;
159     private final BroadcastReceiver connChanged = new BroadcastReceiver() {
160         @Override
161         public void onReceive(Context context, Intent intent) {
162             ConnectivityManager cm = (ConnectivityManager)context.
163                            getSystemService(Context.CONNECTIVITY_SERVICE);
164             NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
165             boolean isConnected = activeNetwork != null &&
166                                   activeNetwork.isConnectedOrConnecting();
167             Log.w("WhereAmI", "Connectivity changed to " + isConnected);
168             if (isConnected) {
169                 for (int i = 0; i < ut.length; i++) {
170                     runningtasks++;
171                     ut[i].launch();
172                 }
173             }
174         }
175     };
176
177     /** Called when the activity is first created. */
178     @Override
179     public void onCreate(Bundle savedInstanceState)
180     {
181         super.onCreate(savedInstanceState);
182         wifiman = (WifiManager)getSystemService(Context.WIFI_SERVICE);
183         requestWindowFeature(Window.FEATURE_NO_TITLE);
184         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
185         //getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
186         //getWindow().clearFlags(WindowManager.LayoutParams.
187         //                                      FLAG_FORCE_NOT_FULLSCREEN);
188         setContentView(R.layout.main);
189         res = getResources();
190         month = res.getStringArray(R.array.month);
191         wday = res.getStringArray(R.array.wday);
192         tvt = (TextView)findViewById(R.id.time);
193         tvd = (TextView)findViewById(R.id.date);
194         tvs = (TextView)findViewById(R.id.timestamp);
195         ut = new UpdateTarget[] {
196             new UpdateTarget((TextView)findViewById(R.id.location),  1),
197             new UpdateTarget((TextView)findViewById(R.id.phonecall), 2)
198         };
199         Log.w("WhereAmI", "created UI, about to start update task");
200         mHandler.post(updateClock);
201         mHandler.post(updateCal);
202         mHandler.post(updateInfo);
203         Log.w("WhereAmI", "created UI, update task created");
204     }
205
206     /** Called when put to background */
207     @Override
208     public void onPause()
209     {
210         super.onPause();
211         Log.w("WhereAmI", "going background");
212     }
213
214     /** Called when the activity is destroyed. */
215     @Override
216     public void onDestroy()
217     {
218         super.onDestroy();
219         Log.w("WhereAmI", "going down");
220         mHandler.removeCallbacks(updateClock);
221         mHandler.removeCallbacks(updateCal);
222         mHandler.removeCallbacks(updateInfo);
223         if (connChangedRegistered) {
224             unregisterReceiver(connChanged);
225             connChangedRegistered = false;
226         }
227         boolean wifion = wifiman.setWifiEnabled(false);
228         Log.w("WhereAmI", "disabling wifi result " + wifion);
229     }
230
231     /** Called when the menu is activated. */
232     @Override
233     public boolean onCreateOptionsMenu(Menu menu) {
234         MenuInflater inflater = getMenuInflater();
235         inflater.inflate(R.menu.main_menu, menu);
236         return true;
237     }
238
239     /** Called when the menu item is selected */
240     @Override
241     public boolean onOptionsItemSelected(MenuItem item) {
242         switch (item.getItemId()) {
243         case R.id.quit:
244             finish();
245             return true;
246         case R.id.settings:
247             Log.w("WhereAmI", "settings requested");
248             return true;
249         default:
250             return super.onOptionsItemSelected(item);
251         }
252     }
253 }