source: other-projects/tipple-android/tipple-lib/src/org/greenstone/android/tipple/base/TipLocationManager.java@ 29186

Last change on this file since 29186 was 26899, checked in by davidb, 11 years ago

Tipple reborn after Chris's Summer of Code 2013

File size: 23.3 KB
Line 
1package org.greenstone.android.tipple.base;
2
3import java.io.BufferedWriter;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileWriter;
7import java.util.ArrayList;
8import java.util.HashMap;
9import java.util.List;
10
11import javax.xml.parsers.SAXParser;
12import javax.xml.parsers.SAXParserFactory;
13
14import org.greenstone.android.tipple.R;
15import org.json1.JSONStringer;
16import org.json1.JSONWriter;
17import org.mapsforge.android.maps.ArrayItemizedTextAudioOverlay;
18import org.mapsforge.core.GeoPoint;
19import org.mapsforge.android.maps.MapView;
20import org.mapsforge.android.maps.overlay.ArrayCircleOverlay;
21import org.mapsforge.android.maps.overlay.Overlay;
22import org.mapsforge.android.maps.overlay.OverlayCircle;
23import org.mapsforge.android.maps.overlay.OverlayItem;
24import org.mapsforge.android.maps.OverlayTextAudioItem;
25import org.mapsforge.android.maps.RouteOverlayResetable;
26import org.xml.sax.InputSource;
27import org.xml.sax.XMLReader;
28
29import android.app.Activity;
30import android.app.ProgressDialog;
31import android.graphics.Color;
32import android.graphics.DashPathEffect;
33import android.graphics.Paint;
34import android.graphics.drawable.Drawable;
35import android.location.Location;
36import android.os.Environment;
37import android.speech.tts.TextToSpeech;
38import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
39import android.util.Log;
40import android.view.View;
41import android.widget.Toast;
42
43public class TipLocationManager
44{
45 private Activity activity_;
46 private AudioPlayerView audio_player_view_;
47 private TextToSpeech tts_;
48
49 private static ArrayCircleOverlay circlesOverlay=null;
50 private static ArrayItemizedTextAudioOverlay itemizedMarkerOverlay;
51 private static ArrayList<OverlayItem> itemizedMarkerOverlayArrayList;
52 private ArrayList<GeoPoint> circlesOverlayGeoPoints;
53 private ArrayList<Integer> circlesOverlayRadii;
54 private ArrayList<Integer> circlesOverlayColourFill;
55 private ArrayList<Integer> circlesOverlayColourOutline;
56
57 /*
58 * These "route" overlays have not been used in quite some time.
59 */
60 private static RouteOverlayResetable routeOverlay=null;
61 private static ArrayItemizedTextAudioOverlay routeMarkerOverlay;
62 private GeoPoint[] routeOverlayArray;
63
64 private ArrayList<OverlayItem> routeMarkerOverlayArrayList;
65
66 public static String prevVisitedFilename;
67
68 private static ArrayList<HashMap<String,String>> location_hashmap_list = null;
69
70
71
72
73 private static MapView map_view_;
74
75 private ArrayList<TipLocation> locations;
76
77 public ArrayList<TipLocation> getLocations()
78 {
79 return locations;
80 }
81
82 public static ArrayList<OverlayItem> getItemizedMarkerOverlayArrayList()
83 {
84 return itemizedMarkerOverlayArrayList;
85 }
86
87 TipLocationManager(Activity activity, AudioPlayerView audio_player_view,
88 TextToSpeech tts, MapView map_view_)
89 {
90 this.activity_ = activity;
91 this.audio_player_view_ = audio_player_view;
92 this.tts_ = tts;
93 this.map_view_ = map_view_;
94
95 }
96
97 /*
98 * TODO:
99 * This method has not been used in quite some time. If you want to use it, make sure
100 * it is the same as the createMapLocations() method.
101 *
102 */
103 protected void createLogRouteLocationsOverlay(ArrayList<TipLocation> locations)
104 {
105 Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
106 fillPaint.setStyle(Paint.Style.STROKE);
107 fillPaint.setColor(Color.BLUE);
108 fillPaint.setAlpha(160);
109 fillPaint.setStrokeWidth(7);
110 fillPaint.setStrokeCap(Paint.Cap.BUTT);
111 fillPaint.setStrokeJoin(Paint.Join.ROUND);
112 fillPaint.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
113
114 Paint outlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
115 outlinePaint.setStyle(Paint.Style.STROKE);
116 outlinePaint.setColor(Color.BLUE);
117 outlinePaint.setAlpha(96);
118 outlinePaint.setStrokeWidth(7);
119 outlinePaint.setStrokeCap(Paint.Cap.BUTT);
120 outlinePaint.setStrokeJoin(Paint.Join.ROUND);
121
122 Drawable defaultMarker = activity_.getResources().getDrawable(R.drawable.routemarker);
123
124 if (routeOverlay==null) {
125 routeOverlay = new RouteOverlayResetable(fillPaint, outlinePaint);
126 routeMarkerOverlay = new ArrayItemizedTextAudioOverlay(defaultMarker,activity_,tts_);
127 routeMarkerOverlayArrayList = new ArrayList<OverlayItem>();
128
129
130 }
131 // This one needs to be done again, incase it is of a different size
132 routeOverlayArray = new GeoPoint[locations.size()];
133
134 for (int i=0; i<locations.size(); i++) {
135 TipLocation location = locations.get(i);
136 double latitude = location.getLatitude();
137 double longitude = location.getLongitude();
138 String title = location.getTitle();
139 String text = location.getText();
140 String tts_text = location.getTTSText();
141 String tts_title = location.getTitleTTS();
142 GeoPoint geoPoint = new GeoPoint(latitude,longitude);
143
144 routeOverlayArray[i] = geoPoint;
145
146 if (title.startsWith("Manual")) {
147 // ItemizedOverlay => display marker with text for info pop-up window
148 OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(geoPoint, title, tts_title, text, tts_text);
149
150 //routeMarkerOverlay.addOverlay(overlayItem);
151 routeMarkerOverlayArrayList.add(overlayItem);
152 }
153 }
154
155 //routeOverlay.setRouteData(routeOverlayArray);
156
157 // Only add in if not already present
158 List<Overlay> overlays = map_view_.getOverlays();
159 if (!overlays.contains(routeOverlay)) {
160 overlays.add(routeOverlay);
161 }
162 if (!overlays.contains(routeMarkerOverlay)) {
163 overlays.add(routeMarkerOverlay);
164 }
165 }
166
167 /*
168 * TODO:
169 * This method has not been used in quite some time. If you want to use it, make sure
170 * it is the same as the addMapLocations() method.
171 *
172 */
173 protected void addLogRouteLocations()
174 {
175 for (int i=0; i<routeMarkerOverlayArrayList.size(); i++) {
176
177 OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
178 routeMarkerOverlay.addOverlay(overlay_item);
179 }
180
181 routeOverlay.setRouteData(routeOverlayArray);
182
183 map_view_.invalidate();
184
185 }
186
187 /*
188 * TODO:
189 * This method has not been used in quite some time. If you want to use it, make sure
190 * it is the same as the removeMapLocations() method
191 *
192 */
193 protected void removeLogRouteLocations()
194 {
195 for (int i=0; i<routeMarkerOverlayArrayList.size(); i++) {
196
197 OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
198 routeMarkerOverlay.removeOverlay(overlay_item);
199
200 }
201
202 routeOverlay.reset();
203
204 map_view_.invalidate();
205 }
206
207 /**
208 * Create map locations so that they can be displayed in future with addMapLocations()
209 */
210 protected void createMapLocations()
211 {
212
213 Drawable defaultMarker = activity_.getResources().getDrawable(R.drawable.marker);
214
215 if (circlesOverlay==null) {
216 circlesOverlay = new ArrayCircleOverlay(new Paint(), new Paint());
217 circlesOverlayGeoPoints = new ArrayList<GeoPoint>();
218 circlesOverlayRadii = new ArrayList<Integer>();
219
220 itemizedMarkerOverlay = new ArrayItemizedTextAudioOverlay(defaultMarker,activity_,tts_);
221 itemizedMarkerOverlayArrayList = new ArrayList<OverlayItem>();
222
223 circlesOverlayColourFill = new ArrayList<Integer>();
224 circlesOverlayColourOutline = new ArrayList<Integer>();
225 }
226
227 for (int i=0; i<locations.size(); i++) {
228 TipLocation location = locations.get(i);
229 double latitude = location.getLatitude();
230 double longitude = location.getLongitude();
231 int radius = (int)Math.round(1000.0 * location.getRadiusKM());
232 String title = location.getTitle();
233 String text = location.getText();
234 String tts_text = location.getTTSText();
235 String tts_title = location.getTitleTTS();
236 GeoPoint geoPoint = new GeoPoint(latitude,longitude);
237
238 // CirclesOverlay => Highlight location with a circle showing catchment radius
239 //circlesOverlay.addCircleData(geoPoint, radius);
240 circlesOverlayGeoPoints.add(geoPoint);
241 circlesOverlayRadii.add(radius);
242
243 circlesOverlayColourFill.add( location.getColourFill() );
244 circlesOverlayColourOutline.add( location.getColourOutline() );
245
246 // ItemizedOverlay => display marker with text for info pop-up window
247 OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(geoPoint, title, tts_title, text, tts_text);
248
249 //itemizedMarkerOverlay.addOverlay(overlayItem);
250 itemizedMarkerOverlayArrayList.add(overlayItem);
251 }
252
253 // Only add in if not already present
254 List<Overlay> overlays = map_view_.getOverlays();
255
256 if (!overlays.contains(itemizedMarkerOverlay)) {
257 overlays.add(itemizedMarkerOverlay);
258 }
259 if (!overlays.contains(circlesOverlay)) {
260 overlays.add(circlesOverlay);
261 }
262 }
263
264 /**
265 * Add markers to the map (make sure createMapLocations() is called at least once before calling this method).
266 */
267 protected void addMapLocations()
268 {
269
270 for (int i=0; i<itemizedMarkerOverlayArrayList.size(); i++) {
271
272 OverlayItem overlay_item = itemizedMarkerOverlayArrayList.get(i);
273 itemizedMarkerOverlay.addOverlay(overlay_item);
274
275 GeoPoint geo_point = circlesOverlayGeoPoints.get(i);
276 int radius = circlesOverlayRadii.get(i);
277
278 int colour_fill = circlesOverlayColourFill.get(i);
279 int colour_outline = circlesOverlayColourOutline.get(i);
280
281 Paint circleFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
282 circleFillPaint.setStyle(Paint.Style.FILL);
283 circleFillPaint.setColor(colour_fill);
284 circleFillPaint.setAlpha(64);
285
286 Paint circleOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
287 circleOutlinePaint.setStyle(Paint.Style.STROKE);
288 circleOutlinePaint.setColor(colour_outline);
289 circleOutlinePaint.setAlpha(128);
290 circleOutlinePaint.setStrokeWidth(3);
291
292 //circlesOverlay.addCircleData(geo_point, radius);
293
294 circlesOverlay.addCircle(new OverlayCircle(geo_point, radius, circleFillPaint, circleOutlinePaint, null));
295 }
296
297 //map_view_.invalidate();
298 }
299
300 /**
301 * Remove all the markers from the map.
302 */
303 protected void removeMapLocations()
304 {
305 for (int i=0; i<itemizedMarkerOverlayArrayList.size(); i++) {
306
307 OverlayItem overlay_item = itemizedMarkerOverlayArrayList.get(i);
308 itemizedMarkerOverlay.removeOverlay(overlay_item);
309 }
310
311 circlesOverlay.clear();
312 itemizedMarkerOverlay.clear(); // just in case?
313
314 List<Overlay> overlays = map_view_.getOverlays();
315 if (overlays.contains(itemizedMarkerOverlay)) {
316 overlays.remove(itemizedMarkerOverlay);
317 }
318 if (overlays.contains(circlesOverlay)) {
319 overlays.remove(circlesOverlay);
320 }
321
322 circlesOverlay=null;
323 itemizedMarkerOverlay=null;
324
325 }
326
327 /**
328 * Parses XML file describing "tipple locations"
329 * @param xml_filename Location of XML file to parse
330 * @param lock_on_element The root elements to look for (in this case, "Location")
331 * @return Returns an array list of hashmaps, each hashmap having keys like location, title, etc.
332 */
333 protected static ArrayList<HashMap<String,String>> parseXMLToHashMapArrayList(String xml_filename,String lock_on_element)
334 {
335 ArrayList<HashMap<String,String>> hashmap_list = null;
336
337 try {
338
339 // set up XML parser
340 SAXParserFactory spf = SAXParserFactory.newInstance();
341 SAXParser sp = spf.newSAXParser();
342 XMLReader xr = sp.getXMLReader();
343
344 // Create handler that maps XML Tags within <Location> to a hashmap
345 XMLToHashmapHandler xmlTourHandler = new XMLToHashmapHandler(lock_on_element);
346 xr.setContentHandler(xmlTourHandler);
347
348 File tour_file = new File(xml_filename);
349 FileInputStream fis = new FileInputStream(tour_file);
350
351 InputSource is = new InputSource(fis);
352 xr.parse(is);
353
354 // get the HashMap List that results from parsing the file
355 hashmap_list = xmlTourHandler.getHashmapList();
356
357
358 } catch (Exception e) {
359 e.printStackTrace();
360 }
361
362 return hashmap_list;
363 }
364
365 /**
366 * Refresh the "tip location" array list, potentially if you want to remove all existing markers and re-populate the map.
367 * @param loc_now Your previous location
368 * @param loc_before Your current location
369 */
370 public void refreshTipLocations(Location loc_now, Location loc_before)
371 {
372 if(loc_now == null || loc_before == null)
373 return;
374
375 int loc_now_lat = (int) loc_now.getLatitude();
376 int loc_now_lng = (int) loc_now.getLongitude();
377
378 int loc_before_lat = (int) loc_before.getLatitude();
379 int loc_before_lng = (int) loc_before.getLongitude();
380
381 // if the previous location and current location is different by 1
382 if ( Math.abs(loc_now_lat-loc_before_lat) >= 1 || Math.abs(loc_now_lng-loc_before_lng) >= 1 )
383 {
384 Toast.makeText(activity_, "Location has changed sufficiently. Re-querying server...", Toast.LENGTH_LONG).show();
385
386 createTipLocations(loc_now_lng, loc_now_lat);
387
388 Log.d("TipLocationManager::refreshTour()", "The size of the tip location array is now: " + locations.size());
389
390 if(locations.size() != 0)
391 {
392 /*
393 * TODO:
394 *
395 * This is not really a "todo" per-se but more of a "be wary" kind of situation. We had a lot of crashes in the past
396 * because of read/write synchronization between this thread and the overlay threads, and interrupting the circle overlay / marker overlay
397 * threads prior to actually removing the overlays probably has fixed the issue, but still be wary.
398 */
399
400 circlesOverlay.interrupt();
401 itemizedMarkerOverlay.interrupt();
402 removeMapLocations();
403
404 createMapLocations();
405 addMapLocations();
406
407 map_view_.invalidate();
408
409 Toast.makeText(activity_, "Map refresh has been completed!", Toast.LENGTH_LONG).show();
410
411 }
412 else
413 {
414 Toast.makeText(activity_, "We re-queried the server but couldn't find any new points of interest!", Toast.LENGTH_LONG).show();
415 }
416 }
417 }
418
419 /**
420 * Updates its location array list with "tip locations", which you would then use to display on the map.
421 *
422 * @param tour_filename The directory of the XML tour filename, if the i-greenstone-server cannot be queried
423 * @param use_dl Set this to true if you would like Tipple to query i-greenstone-server for data
424 * @param lng Your current longitude (only relevant if use_dl = true)
425 * @param lat Your current latitude (only relevant if use_dl = true)
426 */
427 public void createTipLocations(double lng, double lat)
428 {
429 GreenstoneXMLRetriever gxr = new GreenstoneXMLRetriever("8080", "tipple-universe");
430
431 // ok, lets try connect to localhost and query
432 ArrayList<String> current_loc_hashids = gxr.query(lng, lat);
433
434 // ok, we got data, let's display it!
435 if(current_loc_hashids != null)
436 {
437 location_hashmap_list = gxr.retrieveDataFromHashIds(current_loc_hashids);
438 Toast.makeText(activity_, "Connection to server successful!", Toast.LENGTH_LONG).show();
439 }
440 // we could not query the localhost server, so let's read off this pre-built XML file that's on the SD card
441 else
442 {
443 location_hashmap_list = parseXMLToHashMapArrayList( TippleActivity.getGeodataDirectory() + TippleActivity.DEFAULT_LOC_FILE + ".loc" ,"Location");
444 Toast.makeText(activity_, "Connection to server failed. Using pre-stored XML file for locations.", Toast.LENGTH_LONG).show();
445 }
446
447 // ok, we have the location data either from a DL, or from the pre-stored XML file
448 // now create a json file for the augmented reality view (mixare)
449
450 String json_exstore_filename = TippleActivity.getGeodataDirectory() + TippleActivity.DEFAULT_LOC_FILE + ".json";
451 convertLocationHashMapForMixare(json_exstore_filename);
452
453 // --------------
454
455 if (location_hashmap_list != null) {
456 Log.d("TippleActivity::loadTour()", "XML Tour File Parsed");
457 }
458
459 locations = new ArrayList<TipLocation>();
460
461 for (int i=0; i<location_hashmap_list.size(); i++) {
462 HashMap<String,String> location_hashmap = location_hashmap_list.get(i);
463
464 Log.d("TipLocationManager::loadTour()", "Adding a TipLocation from location_hashmap_list");
465
466 TipLocation location = new TipLocation(location_hashmap);
467 locations.add(location);
468 }
469 }
470
471
472
473 /**
474 * Generate a "Mixare-friendly" .json file from the contents of the Tipple location array list
475 * @param json_exstore_filename
476 */
477 protected void convertLocationHashMapForMixare(String json_exstore_filename)
478 {
479 try
480 {
481 ArrayList<HashMap<String,String>> arr = TipLocationManager.location_hashmap_list;
482
483 if( arr != null)
484 {
485 JSONStringer jss = new JSONStringer();
486
487 // ok, do the stop stuff
488 JSONWriter f = jss.object();
489
490 f.key("status").value("OK");
491 f.key("num_results").value("3");
492
493 // now do the array
494 f.key("results").array();
495
496 for(int x = 0; x < arr.size(); x++)
497 {
498 f.object();
499
500 HashMap<String,String> loc = arr.get(x);
501
502 String id = loc.get("id");
503 String lat = loc.get("latitude");
504 String lng = loc.get("longitude");
505 String elevation = loc.get("elevation");
506 String title = loc.get("title");
507
508 //String distance = String.valueOf( Float.parseFloat(loc.get("radius")) * 1000 ); // get the XML distance, convert into meters, and make it a string
509 String distance = ""; // it appears mixare doesn't even use distance anymore...
510
511 String webpage = loc.get("webpage");
512 String has_detail_page = (webpage == null) ? "0" : "1";
513
514 f.key("id").value(id);
515 f.key("lat").value(lat);
516 f.key("lng").value(lng);
517 f.key("elevation").value(elevation);
518 f.key("title").value(title);
519 f.key("distance").value(distance);
520
521 if(webpage == null)
522 f.key("webpage").value("");
523 else
524 f.key("webpage").value(webpage);
525
526 f.key("has_detail_page").value(has_detail_page);
527
528
529
530 f.endObject();
531 }
532
533 f.endArray();
534 f.endObject();
535
536 String final_str = f.toString();
537
538 BufferedWriter bw = new BufferedWriter(new FileWriter(json_exstore_filename));
539 bw.write(final_str);
540 bw.close();
541
542 }
543 }
544 catch(Exception ex)
545 {
546 String error = "Exception occured while converting Tipple XML to AR View JSON";
547 System.err.println(error);
548
549 ex.printStackTrace();
550 }
551
552 }
553
554 /*
555 * TODO:
556 * This has not been used in a while.
557 *
558 */
559 protected ArrayList<TipLocation> loadUserTrail(String log_filename)
560 {
561 ArrayList<HashMap<String,String>> logentry_hashmap_list
562 = parseXMLToHashMapArrayList(log_filename,"LogEntry");
563
564 ArrayList<TipLocation> locations = new ArrayList<TipLocation>();
565
566 if (logentry_hashmap_list != null) {
567 Log.d("TippleActivity::loadUserTrail()", "XML User Activity Log File Parsed");
568
569
570 for (int i=0; i<logentry_hashmap_list.size(); i++) {
571 HashMap<String,String> logentry_hashmap = logentry_hashmap_list.get(i);
572
573 HashMap<String,String> location_hashmap = new HashMap<String,String>();
574 location_hashmap.put("longitude",logentry_hashmap.get("longitude"));
575 location_hashmap.put("latitude",logentry_hashmap.get("latitude"));
576 location_hashmap.put("radius",logentry_hashmap.get("accuracy"));
577 location_hashmap.put("title",logentry_hashmap.get("action"));
578 location_hashmap.put("text",logentry_hashmap.get("message"));
579
580 TipLocation location = new TipLocation(location_hashmap);
581 locations.add(location);
582 }
583 }
584
585 return locations;
586 }
587
588
589 protected String SyncSynthesizeToFile(String text, String id, String root_utterance)
590 {
591 String audio_dir = TippleActivity.getAudioDirectory();
592 File tts_file = new File(audio_dir, id+"-"+root_utterance+"-TTS.wav");
593 String tts_filename = tts_file.getAbsolutePath();
594
595 if (tts_file.exists()) {
596 // already synthesized this
597 return tts_filename;
598 }
599
600 // Rendering the supplied text of the id+utterance derived WAV file
601 HashMap<String, String> hashRender = new HashMap<String, String>();
602 hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text);
603
604 String UTTERANCE = root_utterance+"-utterance";
605
606 hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE);
607 UtteranceWaitListener listener = new UtteranceWaitListener(UTTERANCE);
608 tts_.setOnUtteranceCompletedListener(listener);
609
610 tts_.synthesizeToFile(text, hashRender, tts_filename);
611
612 try {
613 listener.waitForComplete();
614 }
615 catch (Exception e) {
616 e.printStackTrace();
617 return null;
618 }
619
620 return tts_filename;
621 }
622
623 boolean genPrevVisited = true;
624
625 public boolean textToSpeechToLocation(TipLocation tip_location, boolean visited_previously)
626 {
627 if (genPrevVisited) {
628 prevVisitedFilename = SyncSynthesizeToFile("Previously visited.","Previously-visited","cue");
629 System.err.println("** Prev visisted file = " + prevVisitedFilename);
630 genPrevVisited = false;
631 }
632
633 String title = tip_location.getTitle();
634 String text = tip_location.getText();
635 String id = tip_location.getID();
636
637 String title_filename = SyncSynthesizeToFile(title,id,"title");
638 String text_filename = SyncSynthesizeToFile(text,id,"text");
639
640 if ((title_filename!=null) && (text_filename!=null)) {
641 String audio_dir = TippleActivity.getAudioDirectory();
642 File ding_file = new File(audio_dir, "DingExtended.wav");
643 String ding_filename = ding_file.getAbsolutePath();
644
645 if (audio_player_view_.addAudio(id)) {
646 TippleActivity.log.optMessage("Queue Audio",title);
647 audio_player_view_.queueAudio(title_filename,id,title,visited_previously);
648 audio_player_view_.queueAudio(text_filename,id,text);
649 audio_player_view_.queueAudio(ding_filename,id,"[Audio Bing]");
650
651 audio_player_view_.updateTextViewIfHeadIsNewLocation();
652 }
653 }
654
655 return true;
656 }
657
658
659 public static void stopOverlayThreads()
660 {
661 //http://stackoverflow.com/questions/3957253/what-is-this-log-when-i-coded-thread-stop
662 // According to this link, we don't use thread.stop() in Android...
663
664 if (circlesOverlay!=null) {
665 //circlesOverlay.stop();
666 circlesOverlay = null;
667 }
668
669 if (itemizedMarkerOverlay!=null) {
670 //itemizedMarkerOverlay.stop();
671 itemizedMarkerOverlay = null;
672 }
673
674 if (routeOverlay!=null) {
675 //routeOverlay.stop();
676 routeOverlay = null;
677 }
678
679 if (routeMarkerOverlay!=null) {
680 //routeMarkerOverlay.stop();
681 routeMarkerOverlay = null;
682 }
683 }
684 private static class UtteranceWaitListener implements OnUtteranceCompletedListener {
685 private boolean mIsComplete = false;
686 private final String mExpectedUtterance;
687
688 public UtteranceWaitListener(String expectedUtteranceId) {
689 mExpectedUtterance = expectedUtteranceId;
690 }
691
692 public void onUtteranceCompleted(String utteranceId) {
693 if (mExpectedUtterance.equals(utteranceId)) {
694 synchronized(this) {
695 mIsComplete = true;
696 notify();
697 }
698 }
699 }
700
701 public boolean waitForComplete() throws InterruptedException {
702 if (mIsComplete) {
703 return true;
704 }
705
706 synchronized (this) {
707 int TTS_SPEECH_MAX_WAIT_TIME = 5* 1000;
708 wait(TTS_SPEECH_MAX_WAIT_TIME);
709 return mIsComplete;
710 }
711 }
712
713 }
714}
Note: See TracBrowser for help on using the repository browser.