source: other-projects/tipple-android/trunk-restructured/workspace/tipple-lib/src/org/greenstone/android/tipple/base/TippleActivity.java@ 24807

Last change on this file since 24807 was 24807, checked in by davidb, 12 years ago

Reloating base files into 'base' package

  • Property svn:executable set to *
File size: 17.3 KB
Line 
1package org.greenstone.android.tipple.base;
2
3import java.io.DataOutputStream;
4import java.io.File;
5import java.io.FileOutputStream;
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.ArrayList;
9import java.util.Locale;
10
11import android.location.LocationManager;
12import android.os.Bundle;
13import android.os.Environment;
14import android.preference.PreferenceManager;
15import android.speech.tts.TextToSpeech;
16import android.speech.tts.TextToSpeech.OnInitListener;
17import android.text.method.ScrollingMovementMethod;
18import android.util.Log;
19import android.view.Gravity;
20import android.view.Menu;
21import android.view.MenuItem;
22import android.view.View;
23import android.view.ViewGroup;
24import android.content.Context;
25import android.content.Intent;
26import android.content.SharedPreferences;
27import android.content.res.AssetManager;
28import android.location.LocationListener;
29import android.widget.FrameLayout;
30import android.widget.LinearLayout;
31import android.widget.LinearLayout.LayoutParams;
32import android.widget.TextView;
33
34import org.greenstone.android.tipple.R;
35import org.mapsforge.android.maps.MapActivity;
36import org.mapsforge.android.maps.MapView;
37
38
39public class TippleActivity extends MapActivity implements OnInitListener
40{
41 enum TextAudioModeEnum { TEXT_ONLY, TEXT_PLUS_AUDIO, AUDIO_ONLY, AUDIO_PLUS_TEXT };
42
43 // File storage
44 public static String geodataDirectory;
45 public static String logDirectory;
46 public static String audioDirectory;
47
48 // Preferences
49 public static SharedPreferences sharedPreferences;
50 public static boolean centreOnGPSLocation;
51 public static boolean showScaleBar;
52 public static boolean showSights;
53 public static boolean showUserTrail;
54 public static TextAudioModeEnum textAudioMode;
55
56 // Logging
57 public static TippleLog log;
58
59 // Views
60 protected TextView longlat_view_;
61 protected MapView map_view_;
62 protected TextView text_view_;
63 protected FrameLayout text_map_composite_;
64
65 protected AudioPlayerView audio_player_view_;
66
67 protected TipLocationManager tip_location_manager_;
68
69 protected ArrayList<TipLocation> locations_ = null;
70 protected ArrayList<TipLocation> user_trail_ = null;
71 protected String user_trail_filename_ = null;
72
73 // Text to Speech
74 protected TextToSpeech tts_ = null;
75
76 protected LocationManager location_manager_ = null;
77 protected LocationListener location_listener_ = null;
78
79 // Request codes
80 protected final int TTS_DATA_CHECK = 0;
81 private static final int SELECT_LOG_FILE = 1;
82
83
84 protected boolean assetToExternalStorage(String asset_filename, String external_storage_filename)
85 {
86 boolean status = true;
87
88 try {
89
90 File external_storage_file = new File(external_storage_filename);
91 if (!external_storage_file.exists()) {
92 // Need to create the /sdcard version
93
94 AssetManager assetManager = getAssets();
95
96 InputStream ais = assetManager.open(asset_filename); // ais = asset input stream
97 FileOutputStream fos = new FileOutputStream(external_storage_file); // fos = file output stream
98
99 byte [] buffer = new byte[1024];
100
101 int buflen;
102 while ((buflen = ais.read(buffer))>0) {
103 fos.write(buffer,0,buflen);
104 }
105
106 ais.close();
107 fos.close();
108 }
109
110 }
111 catch (Exception e) {
112 e.printStackTrace();
113 status = false;
114 }
115
116 return status;
117 }
118
119 protected boolean initTippleStore(String location)
120 {
121
122 // Locate map data directory
123 File external_root_file = Environment.getExternalStorageDirectory();
124 String external_root = external_root_file.getAbsolutePath();
125 String tipple_store_dir = external_root + "/tipple-store";
126
127 geodataDirectory = tipple_store_dir + "/geodata/";
128 logDirectory = tipple_store_dir + "/logs/";
129 audioDirectory = tipple_store_dir + "/audio/";
130
131 File tipple_store_file = new File(tipple_store_dir);
132 if (!tipple_store_file.exists()) {
133 if (!tipple_store_file.mkdir()) {
134 System.err.println("Failed to create directory: " + tipple_store_dir);
135 return false;
136 }
137 }
138
139 File geodataDirFile = new File(geodataDirectory);
140 if (!geodataDirFile.exists()) {
141 if (!geodataDirFile.mkdir()) {
142 System.err.println("Failed to create directory: " + geodataDirectory);
143 return false;
144 }
145 }
146
147 File logDirFile = new File(logDirectory);
148 if (!logDirFile.exists()) {
149 if (!logDirFile.mkdir()) {
150 System.err.println("Failed to create directory: " + logDirectory);
151 return false;
152 }
153 }
154
155 File audioDirFile = new File(audioDirectory);
156 if (!audioDirFile.exists()) {
157 if (!audioDirFile.mkdir()) {
158 System.err.println("Failed to create directory: " + audioDirectory);
159 return false;
160 }
161 }
162
163 // dig out the audio files
164 String[] audio_filenames = { "BeepMorseSonar.wav","Ding.wav","DingExtended.wav" };
165 for (String audio_filename: audio_filenames) {
166 String audio_asset_filename = "audio/" + audio_filename;
167 String audio_exstore_filename = audioDirectory + audio_filename;
168
169 if (!assetToExternalStorage(audio_asset_filename,audio_exstore_filename)) {
170 System.err.println("Failed to transfer asset " + audio_asset_filename + " to " + audio_exstore_filename);
171 return false;
172 }
173 }
174
175 if ((location != null) && (!location.equals(""))) {
176 // get out map and XML location file
177
178 String map_asset_filename = "geodata/" + location + ".map";
179 String map_exstore_filename = geodataDirectory + location + ".map";
180
181 if (!assetToExternalStorage(map_asset_filename,map_exstore_filename)) {
182 System.err.println("Failed to transfer asset " + map_asset_filename + " to " + map_exstore_filename);
183 return false;
184 }
185
186 String loc_asset_filename = "geodata/" + location + ".loc";
187 String loc_exstore_filename = geodataDirectory + location + ".loc";
188
189 if (!assetToExternalStorage(loc_asset_filename,loc_exstore_filename)) {
190 System.err.println("Failed to transfer asset " + loc_asset_filename + " to " + loc_exstore_filename);
191 return false;
192 }
193 }
194
195 return true;
196 }
197
198 protected boolean initTippleStore()
199 {
200 return initTippleStore(null);
201 }
202 protected TextView createLongLatView()
203 {
204 // Lat,Long line at top
205 TextView longlat_view = new TextView(this);
206 longlat_view.setText("(Long,Lat): ");
207
208 LayoutParams longlat_view_layout
209 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 35, 0);
210 longlat_view.setLayoutParams(longlat_view_layout);
211
212 return longlat_view;
213 }
214
215
216
217
218 protected MapView createMapView(String map_filename)
219 {
220 // Map view in middle
221 MapView map_view = new MapView(this);
222 map_view.setClickable(true);
223 map_view.setBuiltInZoomControls(true);
224 String full_map_filename = geodataDirectory + map_filename;
225
226 map_view.setMapFile(full_map_filename);
227
228 LayoutParams map_view_layout
229 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
230 ViewGroup.LayoutParams.WRAP_CONTENT, 1);
231
232 map_view.setLayoutParams(map_view_layout);
233
234
235 return map_view;
236 }
237
238 protected MapView createMapViewFromAsset(String map_filename)
239 {
240 // Transfer asset to file in dataDirectory if it does not already exist
241
242 String asset_filename = "geodata" + File.separator + map_filename;
243 String external_storage_filename = geodataDirectory + map_filename;
244
245 assetToExternalStorage(asset_filename,external_storage_filename);
246
247 return createMapView(map_filename);
248
249 }
250
251 protected TextView createTextView()
252 {
253 // Text view in middle (ultimately on top of map view)
254 TextView text_view = new TextView(this);
255
256 LayoutParams text_view_layout
257 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
258 ViewGroup.LayoutParams.WRAP_CONTENT, 1);
259 text_view.setLayoutParams(text_view_layout);
260
261 text_view.setGravity(Gravity.BOTTOM|Gravity.FILL_HORIZONTAL);
262
263 text_view.setPadding(12, 12, 12, 12);
264 text_view.setTextColor(0xffffffff);
265 text_view.setBackgroundColor(0xCC000000);
266 text_view.setTextSize(20.0f);
267
268 text_view.setVerticalScrollBarEnabled(true);
269 text_view.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
270
271 text_view.setMovementMethod(new ScrollingMovementMethod());
272
273 text_view.setVisibility(View.INVISIBLE);
274
275 return text_view;
276 }
277
278 protected FrameLayout compositTextViewOnMapView(MapView map_view, TextView text_view)
279 {
280 FrameLayout frame_layout = new FrameLayout(this);
281
282 LayoutParams view_layout
283 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
284 ViewGroup.LayoutParams.WRAP_CONTENT, 1);
285
286 frame_layout.setLayoutParams(view_layout);
287 frame_layout.addView(map_view);
288 frame_layout.addView(text_view);
289
290 return frame_layout;
291 }
292
293 protected AudioPlayerView createAudioPlayerView()
294 {
295 // Player at the bottom
296 AudioPlayerView audio_player_view = new AudioPlayerView(this, text_view_);
297
298 LayoutParams audio_player_layout
299 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,100, 0);
300 audio_player_view.setLayoutParams(audio_player_layout);
301
302 return audio_player_view;
303 }
304
305
306
307 protected void refreshPreferences()
308 {
309 // Restore preferences
310 sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
311
312 //shared_preferences_ = getPreferences(MODE_PRIVATE);
313 showScaleBar = sharedPreferences.getBoolean("showScaleBar", false);
314 centreOnGPSLocation = sharedPreferences.getBoolean("centreOnGPSLoc", false);
315
316 showSights = sharedPreferences.getBoolean("showSights", true);
317 showUserTrail = sharedPreferences.getBoolean("showUserTrail", false);
318
319 String textAudioModeStr = sharedPreferences.getString("textAudioMode", "AUDIO_PLUS_TEXT");
320 textAudioMode = Enum.valueOf(TextAudioModeEnum.class, textAudioModeStr);
321 }
322
323 protected void onCreateXXX(Bundle savedInstanceState)
324 {
325 System.err.println("*** TippleActivity::onCreate()");
326 super.onCreate(savedInstanceState);
327
328 if (!initTippleStore("hamilton")) {
329 System.err.println("Failed to initialize TippleStore on sdcard. Quiting");
330 onDestroy();
331 }
332
333 // Set up logging
334 log = new TippleLog(this,logDirectory);
335 log.optStartLog();
336
337 // "refresh" preferences here so views can be configured correctly
338 // and ensure showUserTrail is reset to off (as not log file has been selected yet)
339 refreshPreferences();
340 SharedPreferences.Editor editor = sharedPreferences.edit();
341 editor.putBoolean("showUserTrail",false);
342
343 // Set up Text to Speech
344 Intent checkIntent = new Intent();
345 checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
346 startActivityForResult(checkIntent, TTS_DATA_CHECK);
347
348 //startActivityForResult(new Intent(this, LogFileBrowser.class), SELECT_LOG_FILE);
349
350
351 // Screen dived into:
352 // Top: GPS location
353 // Middle: Map view
354 // Bottom: Media player
355
356 LinearLayout linearLayout = new LinearLayout(this);
357 linearLayout.setOrientation(LinearLayout.VERTICAL);
358
359 longlat_view_ = createLongLatView();
360 //map_view_ = createMapView("new-zealand.map");
361 map_view_ = createMapViewFromAsset("hamilton.map");
362
363 text_view_ = createTextView();
364 text_map_composite_ = compositTextViewOnMapView(map_view_,text_view_);
365
366 audio_player_view_ = createAudioPlayerView();
367
368 linearLayout.addView(longlat_view_);
369 linearLayout.addView(text_map_composite_);
370 linearLayout.addView(audio_player_view_);
371
372 setContentView(linearLayout);
373 }
374
375
376 @Override
377 protected void onResume()
378 {
379 System.err.println("*** TippleActivity::onResume()");
380
381 super.onResume();
382
383 refreshPreferences();
384 audio_player_view_.refreshView();
385
386 map_view_.setScaleBar(showScaleBar);
387
388 if (tip_location_manager_ != null) {
389 if (showSights) {
390 //tip_location_manager_.createTourLocationsOverlay(map_view_,locations_);
391 tip_location_manager_.addTourLocations(map_view_);
392 }
393 else {
394 tip_location_manager_.removeTourLocations(map_view_);
395 }
396
397 if (user_trail_filename_ != null) {
398
399 if (showUserTrail) {
400 //tip_location_manager_.createLogRouteLocationsOverlay(map_view_,user_trail_);
401 tip_location_manager_.addLogRouteLocations(map_view_);
402 }
403 else {
404 tip_location_manager_.removeLogRouteLocations(map_view_);
405 }
406 }
407 }
408
409 }
410
411
412
413 protected void onActivityResult(int requestCode, int resultCode, Intent data)
414 {
415 System.err.println("*** TippleActivity::onActivityResult(), requestCode: " + requestCode);
416
417 if (requestCode == TTS_DATA_CHECK) {
418 if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
419 // success, create the TTS instance
420 tts_ = new TextToSpeech(this, (TextToSpeech.OnInitListener) this);
421 tts_.setLanguage(Locale.UK);
422
423 // now TTS initialized, init TTS aware place-locations
424 String loc_filename = geodataDirectory + "hamilton.loc";
425 tip_location_manager_ = new TipLocationManager(this,audio_player_view_,tts_);
426 locations_ = tip_location_manager_.loadTour(loc_filename);
427 tip_location_manager_.createTourLocationsOverlay(map_view_,locations_);
428
429 // Set up a callback method for handling GPS location updates connected with our place-locations
430 location_manager_ = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
431 location_listener_
432 = new TippleLocationListener(this,map_view_,longlat_view_,tip_location_manager_,
433 locations_);
434
435 location_manager_.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, location_listener_);
436
437 } else {
438 // missing data, install it
439 Intent installIntent = new Intent();
440 installIntent.setAction(
441 TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
442 startActivity(installIntent);
443 }
444 }
445
446 else if (requestCode == SELECT_LOG_FILE) {
447
448 if (resultCode == RESULT_OK) {
449 if (data != null && data.getStringExtra("logFile") != null) {
450 if (user_trail_filename_ != null) {
451 // have a previously loaded route => scrub it
452 tip_location_manager_.removeLogRouteLocations(map_view_);
453 user_trail_filename_ = null;
454 }
455 // set up route overlay
456 user_trail_filename_ = data.getStringExtra("logFile");
457 user_trail_ = tip_location_manager_.loadUserTrail(user_trail_filename_);
458 tip_location_manager_.createLogRouteLocationsOverlay(map_view_,user_trail_);
459 }
460 } else if (resultCode == RESULT_CANCELED) {
461 // nothing to do
462 }
463
464 }
465
466 }
467
468
469 @Override
470 public void onInit(int status)
471 {
472 System.err.println("*** TippleActivity::onInit(), status (zero == good): " + status);
473
474 if (status == TextToSpeech.SUCCESS) {
475 Log.d("TippleActivity::onInit()","Text-to-speech engine initialized");
476 }
477 else if (status == TextToSpeech.ERROR){
478 Log.e("TippleActivity::onInit()","Text-to-speech engine failed initialized");
479 System.err.println("Error occured while initializing text-to-speech engine");
480 }
481
482 }
483
484 @Override
485 public boolean onCreateOptionsMenu(Menu menu)
486 {
487 getMenuInflater().inflate(R.menu.options_menu, menu);
488 return true;
489 }
490
491 @Override
492 public boolean onOptionsItemSelected(MenuItem item)
493 {
494 switch (item.getItemId()) {
495 case R.id.menu_info:
496 startActivity(new Intent(this, InfoView.class));
497 return true;
498
499 case R.id.menu_preferences:
500 startActivity(new Intent(this, EditPreferences.class));
501 return true;
502
503 case R.id.menu_logfile:
504 startActivityForResult(new Intent(this, TippleLogFileBrowser.class), SELECT_LOG_FILE);
505 return true;
506
507 default:
508 return false;
509 }
510 }
511
512
513
514 @Override
515 protected void onStop()
516 {
517 System.err.println("*** TippleActivity::onStop()");
518 super.onStop();
519
520 // Is this needed?
521 // Go through an Editor object to make preference changes stick
522 SharedPreferences.Editor editor = sharedPreferences.edit();
523 editor.commit();
524
525 }
526
527 @Override
528 protected void onDestroy()
529 {
530 System.err.println("*** TippleActivity::onDestroy()");
531 super.onDestroy();
532
533 tts_.shutdown();
534 tts_ = null;
535
536 // Switch off location updates
537 if (location_manager_ != null) {
538
539 if (location_listener_ != null) {
540
541 location_manager_.removeUpdates(location_listener_);
542 location_listener_ = null;
543 }
544 location_manager_ = null;
545
546 user_trail_filename_ = null;
547 }
548
549
550 TipLocationManager.stopOverlayThreads();
551
552
553 log.optStopLog();
554 }
555
556}
Note: See TracBrowser for help on using the repository browser.