source: other-projects/tipple-android/trunk-restructured/workspace/tipple-networked/src/org/greenstone/android/tipple/NetworkedTippleActivity.java@ 24282

Last change on this file since 24282 was 24282, checked in by davidb, 13 years ago

Name change to reflect more flexable array of applications for Tipple

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